summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/bspatch/LICENSE23
-rw-r--r--utils/bspatch/Makefile17
-rw-r--r--utils/bspatch/bspatch.c218
-rw-r--r--utils/bspatch/bspatch.h19
-rw-r--r--utils/bspatch/main.c34
-rw-r--r--utils/bzip2/LICENSE42
-rw-r--r--utils/bzip2/Makefile15
-rw-r--r--utils/bzip2/blocksort.c1094
-rw-r--r--utils/bzip2/bzlib.c1572
-rw-r--r--utils/bzip2/bzlib.h282
-rw-r--r--utils/bzip2/bzlib_private.h512
-rw-r--r--utils/bzip2/compress.c672
-rw-r--r--utils/bzip2/crctable.c104
-rw-r--r--utils/bzip2/decompress.c646
-rw-r--r--utils/bzip2/huffman.c205
-rw-r--r--utils/bzip2/randtable.c84
-rw-r--r--utils/chinachippatcher/Makefile17
-rw-r--r--utils/chinachippatcher/chinachip.c258
-rw-r--r--utils/chinachippatcher/chinachip.h52
-rw-r--r--utils/chinachippatcher/main.c55
-rw-r--r--utils/e200rpatcher/Makefile56
-rw-r--r--utils/e200rpatcher/README48
-rw-r--r--utils/e200rpatcher/e200rpatcher.c241
-rw-r--r--utils/e200rpatcher/e200rpatcher.manifest13
-rw-r--r--utils/e200rpatcher/e200rpatcher.rc1
-rw-r--r--utils/ibassoboot/jni/Android.mk14
-rw-r--r--utils/ibassoboot/jni/chooser.bmpbin0 -> 230454 bytes
-rw-r--r--utils/ibassoboot/jni/ibassodualboot.c771
-rw-r--r--utils/ibassoboot/jni/qdbmp.c798
-rw-r--r--utils/ibassoboot/jni/qdbmp.h133
-rw-r--r--utils/ibassoboot/jni/rbmissing.bmpbin0 -> 230454 bytes
-rw-r--r--utils/ibassoboot/jni/usb.bmpbin0 -> 230454 bytes
-rw-r--r--utils/ipodpatcher/Makefile53
-rw-r--r--utils/ipodpatcher/arc4.c108
-rw-r--r--utils/ipodpatcher/arc4.h47
-rw-r--r--utils/ipodpatcher/fat32format.c530
-rw-r--r--utils/ipodpatcher/ipodio-posix.c409
-rw-r--r--utils/ipodpatcher/ipodio-win32-scsi.c147
-rw-r--r--utils/ipodpatcher/ipodio-win32.c226
-rw-r--r--utils/ipodpatcher/ipodio.h115
-rw-r--r--utils/ipodpatcher/ipodpatcher.c2350
-rw-r--r--utils/ipodpatcher/ipodpatcher.h84
-rw-r--r--utils/ipodpatcher/ipodpatcher.manifest13
-rw-r--r--utils/ipodpatcher/ipodpatcher.pro47
-rw-r--r--utils/ipodpatcher/ipodpatcher.rc1
-rw-r--r--utils/ipodpatcher/main.c622
-rw-r--r--utils/ipodpatcher/parttypes.h109
-rw-r--r--utils/jztool/Makefile47
-rw-r--r--utils/jztool/README.md135
-rw-r--r--utils/jztool/include/jztool.h202
-rw-r--r--utils/jztool/jztool.c212
-rw-r--r--utils/jztool/src/buffer.c134
-rw-r--r--utils/jztool/src/context.c177
-rw-r--r--utils/jztool/src/device_info.c109
-rw-r--r--utils/jztool/src/identify_file.c170
-rw-r--r--utils/jztool/src/jztool_private.h44
-rw-r--r--utils/jztool/src/ucl_unpack.c128
-rw-r--r--utils/jztool/src/usb.c291
-rw-r--r--utils/jztool/src/x1000.c180
-rw-r--r--utils/libtools.make183
-rw-r--r--utils/mkamsboot/.gitignore2
-rw-r--r--utils/mkamsboot/Makefile31
-rw-r--r--utils/mkamsboot/README67
-rw-r--r--utils/mkamsboot/dualboot.c152
-rw-r--r--utils/mkamsboot/dualboot.h12
-rw-r--r--utils/mkamsboot/dualboot/.gitignore3
-rw-r--r--utils/mkamsboot/dualboot/Makefile61
-rw-r--r--utils/mkamsboot/dualboot/bin2c.c140
-rw-r--r--utils/mkamsboot/dualboot/dualboot.S307
-rw-r--r--utils/mkamsboot/dualboot/nrv2e_d8.S198
-rw-r--r--utils/mkamsboot/main.c174
-rw-r--r--utils/mkamsboot/md5.c246
-rw-r--r--utils/mkamsboot/md5.h25
-rw-r--r--utils/mkamsboot/mkamsboot.c595
-rw-r--r--utils/mkamsboot/mkamsboot.h195
-rw-r--r--utils/mkimxboot/Makefile46
-rw-r--r--utils/mkimxboot/dualboot.c293
-rw-r--r--utils/mkimxboot/dualboot.h8
-rw-r--r--utils/mkimxboot/dualboot/Makefile48
-rw-r--r--utils/mkimxboot/dualboot/bin2c.c140
-rw-r--r--utils/mkimxboot/dualboot/config.h26
-rw-r--r--utils/mkimxboot/dualboot/dualboot.c323
-rw-r--r--utils/mkimxboot/dualboot/dualboot.lds17
-rw-r--r--utils/mkimxboot/main.c289
-rw-r--r--utils/mkimxboot/md5.c246
-rw-r--r--utils/mkimxboot/md5.h25
-rw-r--r--utils/mkimxboot/mkimxboot.c1123
-rw-r--r--utils/mkimxboot/mkimxboot.h116
-rw-r--r--utils/mkmpioboot/Makefile23
-rw-r--r--utils/mkmpioboot/main.c55
-rw-r--r--utils/mkmpioboot/mkmpioboot.c243
-rw-r--r--utils/mkmpioboot/mkmpioboot.h46
-rw-r--r--utils/mknwzboot/Makefile52
-rw-r--r--utils/mknwzboot/install_script.sh157
-rw-r--r--utils/mknwzboot/main.c126
-rw-r--r--utils/mknwzboot/mknwzboot.c294
-rw-r--r--utils/mknwzboot/mknwzboot.h42
-rw-r--r--utils/mknwzboot/uninstall_script.sh122
-rw-r--r--utils/mkrk27boot/Makefile39
-rw-r--r--utils/mkrk27boot/ata-sim.c122
-rw-r--r--utils/mkrk27boot/autoconf.h37
-rw-r--r--utils/mkrk27boot/main.c55
-rw-r--r--utils/mkrk27boot/mkrk27boot.c281
-rw-r--r--utils/mkrk27boot/mkrk27boot.h36
-rw-r--r--utils/mks5lboot/.gitignore5
-rw-r--r--utils/mks5lboot/Makefile43
-rw-r--r--utils/mks5lboot/README228
-rw-r--r--utils/mks5lboot/dualboot.c664
-rw-r--r--utils/mks5lboot/dualboot.h4
-rw-r--r--utils/mks5lboot/dualboot/.gitignore3
-rw-r--r--utils/mks5lboot/dualboot/Makefile97
-rw-r--r--utils/mks5lboot/dualboot/autoconf.h74
-rw-r--r--utils/mks5lboot/dualboot/bin2c.c140
-rw-r--r--utils/mks5lboot/dualboot/dualboot.c287
-rw-r--r--utils/mks5lboot/dualboot/dualboot.lds59
-rw-r--r--utils/mks5lboot/dualboot/init.S43
-rw-r--r--utils/mks5lboot/ipoddfu.c1061
-rw-r--r--utils/mks5lboot/main.c296
-rw-r--r--utils/mks5lboot/mkdfu.c318
-rw-r--r--utils/mks5lboot/mks5lboot.h129
-rw-r--r--utils/mktccboot/Makefile28
-rw-r--r--utils/mktccboot/README35
-rw-r--r--utils/mktccboot/main.c133
-rw-r--r--utils/mktccboot/mktccboot.c176
-rw-r--r--utils/mktccboot/mktccboot.h50
-rw-r--r--utils/mkzenboot/Makefile30
-rw-r--r--utils/mkzenboot/dualboot.c56
-rw-r--r--utils/mkzenboot/dualboot.h6
-rw-r--r--utils/mkzenboot/dualboot/Makefile51
-rw-r--r--utils/mkzenboot/dualboot/bin2c.c140
-rw-r--r--utils/mkzenboot/dualboot/config.h22
-rw-r--r--utils/mkzenboot/dualboot/dualboot.c136
-rw-r--r--utils/mkzenboot/dualboot/dualboot.lds32
-rw-r--r--utils/mkzenboot/main.c123
-rw-r--r--utils/mkzenboot/md5.c246
-rw-r--r--utils/mkzenboot/md5.h25
-rw-r--r--utils/mkzenboot/mkzenboot.c697
-rw-r--r--utils/mkzenboot/mkzenboot.h86
-rw-r--r--utils/mkzenboot/utils.c896
-rw-r--r--utils/mkzenboot/utils.h53
-rw-r--r--utils/rbutil.pro83
-rw-r--r--utils/rbutilqt/INSTALL63
-rw-r--r--utils/rbutilqt/Info.plist24
-rw-r--r--utils/rbutilqt/Makefile.libs79
-rw-r--r--utils/rbutilqt/RockboxUtility.desktop12
-rw-r--r--utils/rbutilqt/aboutbox.ui198
-rw-r--r--utils/rbutilqt/base/archiveutil.cpp30
-rw-r--r--utils/rbutilqt/base/archiveutil.h41
-rw-r--r--utils/rbutilqt/base/autodetection.cpp376
-rw-r--r--utils/rbutilqt/base/autodetection.h72
-rw-r--r--utils/rbutilqt/base/bootloaderinstallams.cpp201
-rw-r--r--utils/rbutilqt/base/bootloaderinstallams.h42
-rw-r--r--utils/rbutilqt/base/bootloaderinstallbase.cpp302
-rw-r--r--utils/rbutilqt/base/bootloaderinstallbase.h118
-rw-r--r--utils/rbutilqt/base/bootloaderinstallbspatch.cpp178
-rw-r--r--utils/rbutilqt/base/bootloaderinstallbspatch.h47
-rw-r--r--utils/rbutilqt/base/bootloaderinstallchinachip.cpp133
-rw-r--r--utils/rbutilqt/base/bootloaderinstallchinachip.h41
-rw-r--r--utils/rbutilqt/base/bootloaderinstallfile.cpp159
-rw-r--r--utils/rbutilqt/base/bootloaderinstallfile.h48
-rw-r--r--utils/rbutilqt/base/bootloaderinstallhelper.cpp140
-rw-r--r--utils/rbutilqt/base/bootloaderinstallhelper.h36
-rw-r--r--utils/rbutilqt/base/bootloaderinstallhex.cpp271
-rw-r--r--utils/rbutilqt/base/bootloaderinstallhex.h53
-rw-r--r--utils/rbutilqt/base/bootloaderinstallimx.cpp193
-rw-r--r--utils/rbutilqt/base/bootloaderinstallimx.h47
-rw-r--r--utils/rbutilqt/base/bootloaderinstallipod.cpp272
-rw-r--r--utils/rbutilqt/base/bootloaderinstallipod.h51
-rw-r--r--utils/rbutilqt/base/bootloaderinstallmi4.cpp162
-rw-r--r--utils/rbutilqt/base/bootloaderinstallmi4.h48
-rw-r--r--utils/rbutilqt/base/bootloaderinstallmpio.cpp143
-rw-r--r--utils/rbutilqt/base/bootloaderinstallmpio.h43
-rw-r--r--utils/rbutilqt/base/bootloaderinstalls5l.cpp437
-rw-r--r--utils/rbutilqt/base/bootloaderinstalls5l.h71
-rw-r--r--utils/rbutilqt/base/bootloaderinstallsansa.cpp286
-rw-r--r--utils/rbutilqt/base/bootloaderinstallsansa.h51
-rw-r--r--utils/rbutilqt/base/bootloaderinstalltcc.cpp165
-rw-r--r--utils/rbutilqt/base/bootloaderinstalltcc.h44
-rw-r--r--utils/rbutilqt/base/encoderbase.cpp86
-rw-r--r--utils/rbutilqt/base/encoderbase.h63
-rw-r--r--utils/rbutilqt/base/encoderexe.cpp78
-rw-r--r--utils/rbutilqt/base/encoderexe.h53
-rw-r--r--utils/rbutilqt/base/encoderlame.cpp312
-rw-r--r--utils/rbutilqt/base/encoderlame.h72
-rw-r--r--utils/rbutilqt/base/encoderrbspeex.cpp119
-rw-r--r--utils/rbutilqt/base/encoderrbspeex.h61
-rw-r--r--utils/rbutilqt/base/encttssettings.cpp70
-rw-r--r--utils/rbutilqt/base/encttssettings.h128
-rw-r--r--utils/rbutilqt/base/httpget.cpp256
-rw-r--r--utils/rbutilqt/base/httpget.h111
-rw-r--r--utils/rbutilqt/base/mspackutil.cpp164
-rw-r--r--utils/rbutilqt/base/mspackutil.h51
-rw-r--r--utils/rbutilqt/base/playerbuildinfo.cpp362
-rw-r--r--utils/rbutilqt/base/playerbuildinfo.h123
-rw-r--r--utils/rbutilqt/base/progressloggerinterface.h60
-rw-r--r--utils/rbutilqt/base/rbsettings.cpp207
-rw-r--r--utils/rbutilqt/base/rbsettings.h105
-rw-r--r--utils/rbutilqt/base/rockboxinfo.cpp83
-rw-r--r--utils/rbutilqt/base/rockboxinfo.h54
-rw-r--r--utils/rbutilqt/base/system.cpp519
-rw-r--r--utils/rbutilqt/base/system.h53
-rw-r--r--utils/rbutilqt/base/talkfile.cpp300
-rw-r--r--utils/rbutilqt/base/talkfile.h83
-rw-r--r--utils/rbutilqt/base/talkgenerator.cpp337
-rw-r--r--utils/rbutilqt/base/talkgenerator.h91
-rw-r--r--utils/rbutilqt/base/ttsbase.cpp122
-rw-r--r--utils/rbutilqt/base/ttsbase.h70
-rw-r--r--utils/rbutilqt/base/ttscarbon.cpp443
-rw-r--r--utils/rbutilqt/base/ttscarbon.h73
-rw-r--r--utils/rbutilqt/base/ttsespeak.h42
-rw-r--r--utils/rbutilqt/base/ttsespeakng.h41
-rw-r--r--utils/rbutilqt/base/ttsexes.cpp127
-rw-r--r--utils/rbutilqt/base/ttsexes.h61
-rw-r--r--utils/rbutilqt/base/ttsfestival.cpp412
-rw-r--r--utils/rbutilqt/base/ttsfestival.h72
-rw-r--r--utils/rbutilqt/base/ttsflite.h43
-rw-r--r--utils/rbutilqt/base/ttsmimic.h41
-rw-r--r--utils/rbutilqt/base/ttsmssp.h43
-rw-r--r--utils/rbutilqt/base/ttssapi.cpp274
-rw-r--r--utils/rbutilqt/base/ttssapi.h77
-rw-r--r--utils/rbutilqt/base/ttssapi4.h43
-rw-r--r--utils/rbutilqt/base/ttsswift.h40
-rw-r--r--utils/rbutilqt/base/uninstall.cpp126
-rw-r--r--utils/rbutilqt/base/uninstall.h63
-rw-r--r--utils/rbutilqt/base/utils.cpp1062
-rw-r--r--utils/rbutilqt/base/utils.h64
-rw-r--r--utils/rbutilqt/base/voicefile.cpp362
-rw-r--r--utils/rbutilqt/base/voicefile.h77
-rw-r--r--utils/rbutilqt/base/zipinstaller.cpp204
-rw-r--r--utils/rbutilqt/base/zipinstaller.h88
-rw-r--r--utils/rbutilqt/base/ziputil.cpp302
-rw-r--r--utils/rbutilqt/base/ziputil.h53
-rw-r--r--utils/rbutilqt/changelog.txt42
-rw-r--r--utils/rbutilqt/configure.cpp984
-rw-r--r--utils/rbutilqt/configure.h79
-rw-r--r--utils/rbutilqt/configurefrm.ui572
-rw-r--r--utils/rbutilqt/createvoicefrm.ui217
-rw-r--r--utils/rbutilqt/createvoicewindow.cpp144
-rw-r--r--utils/rbutilqt/createvoicewindow.h56
-rw-r--r--utils/rbutilqt/dmgbuild.cfg9
-rw-r--r--utils/rbutilqt/encttscfggui.cpp384
-rw-r--r--utils/rbutilqt/encttscfggui.h79
-rw-r--r--utils/rbutilqt/gui/backupdialog.cpp152
-rw-r--r--utils/rbutilqt/gui/backupdialog.h48
-rw-r--r--utils/rbutilqt/gui/backupdialogfrm.ui145
-rw-r--r--utils/rbutilqt/gui/changelog.cpp78
-rw-r--r--utils/rbutilqt/gui/changelog.h40
-rw-r--r--utils/rbutilqt/gui/changelogfrm.ui60
-rw-r--r--utils/rbutilqt/gui/comboboxviewdelegate.cpp56
-rw-r--r--utils/rbutilqt/gui/comboboxviewdelegate.h30
-rw-r--r--utils/rbutilqt/gui/infowidget.cpp112
-rw-r--r--utils/rbutilqt/gui/infowidget.h41
-rw-r--r--utils/rbutilqt/gui/infowidgetfrm.ui43
-rw-r--r--utils/rbutilqt/gui/selectiveinstallwidget.cpp691
-rw-r--r--utils/rbutilqt/gui/selectiveinstallwidget.h74
-rw-r--r--utils/rbutilqt/gui/selectiveinstallwidgetfrm.ui316
-rw-r--r--utils/rbutilqt/icons/audio-input-microphone.svg501
-rw-r--r--utils/rbutilqt/icons/audio-volume-high.svg645
-rw-r--r--utils/rbutilqt/icons/dialog-error.svg330
-rw-r--r--utils/rbutilqt/icons/dialog-information.svg1159
-rw-r--r--utils/rbutilqt/icons/dialog-warning.svg373
-rw-r--r--utils/rbutilqt/icons/document-save.svg619
-rw-r--r--utils/rbutilqt/icons/edit-clear.svg416
-rw-r--r--utils/rbutilqt/icons/edit-find.svg750
-rw-r--r--utils/rbutilqt/icons/go-next.svg192
-rw-r--r--utils/rbutilqt/icons/input-gaming.svg530
-rw-r--r--utils/rbutilqt/icons/media-eject.svg450
-rw-r--r--utils/rbutilqt/icons/multimedia-player.svg693
-rw-r--r--utils/rbutilqt/icons/network-idle.svg1370
-rw-r--r--utils/rbutilqt/icons/package-x-generic.svg485
-rw-r--r--utils/rbutilqt/icons/players/archosfmrecorder-small.pngbin0 -> 7028 bytes
-rw-r--r--utils/rbutilqt/icons/players/archosondiofm-small.pngbin0 -> 4902 bytes
-rw-r--r--utils/rbutilqt/icons/players/archosondiosp-small.pngbin0 -> 4896 bytes
-rw-r--r--utils/rbutilqt/icons/players/archosplayer-small.pngbin0 -> 4760 bytes
-rw-r--r--utils/rbutilqt/icons/players/archosrecorder-small.pngbin0 -> 5252 bytes
-rw-r--r--utils/rbutilqt/icons/players/archosrecorderv2-small.pngbin0 -> 7028 bytes
-rw-r--r--utils/rbutilqt/icons/players/cowond2-small.pngbin0 -> 2944 bytes
-rw-r--r--utils/rbutilqt/icons/players/fonts-small.pngbin0 -> 4908 bytes
-rw-r--r--utils/rbutilqt/icons/players/gigabeatfx-small.pngbin0 -> 2264 bytes
-rw-r--r--utils/rbutilqt/icons/players/gigabeats-small.pngbin0 -> 3388 bytes
-rw-r--r--utils/rbutilqt/icons/players/gogearhdd1630-small.pngbin0 -> 2567 bytes
-rw-r--r--utils/rbutilqt/icons/players/gogearhdd6330-small.pngbin0 -> 2226 bytes
-rw-r--r--utils/rbutilqt/icons/players/gogearsa9200-small.pngbin0 -> 2181 bytes
-rw-r--r--utils/rbutilqt/icons/players/hifimanhm60x-small.pngbin0 -> 4605 bytes
-rw-r--r--utils/rbutilqt/icons/players/hifimanhm801-small.pngbin0 -> 7125 bytes
-rw-r--r--utils/rbutilqt/icons/players/iaudiom3-small.pngbin0 -> 2261 bytes
-rw-r--r--utils/rbutilqt/icons/players/iaudiom5-small.pngbin0 -> 2843 bytes
-rw-r--r--utils/rbutilqt/icons/players/iaudiox5-small.pngbin0 -> 2845 bytes
-rw-r--r--utils/rbutilqt/icons/players/ipod1g2g-small.pngbin0 -> 5243 bytes
-rw-r--r--utils/rbutilqt/icons/players/ipod3g-small.pngbin0 -> 3377 bytes
-rw-r--r--utils/rbutilqt/icons/players/ipod4g-small.pngbin0 -> 2581 bytes
-rw-r--r--utils/rbutilqt/icons/players/ipod6g-small.pngbin0 -> 2833 bytes
-rw-r--r--utils/rbutilqt/icons/players/ipodcolor-small.pngbin0 -> 2520 bytes
-rw-r--r--utils/rbutilqt/icons/players/ipodmini1g-small.pngbin0 -> 2316 bytes
-rw-r--r--utils/rbutilqt/icons/players/ipodnano1g-small.pngbin0 -> 2190 bytes
-rw-r--r--utils/rbutilqt/icons/players/ipodnano2g-small.pngbin0 -> 2270 bytes
-rw-r--r--utils/rbutilqt/icons/players/ipodvideo-small.pngbin0 -> 2771 bytes
-rw-r--r--utils/rbutilqt/icons/players/iriverh10-small.pngbin0 -> 3182 bytes
-rw-r--r--utils/rbutilqt/icons/players/iriverh100-small.pngbin0 -> 3606 bytes
-rw-r--r--utils/rbutilqt/icons/players/iriverh10_5gb-small.pngbin0 -> 2631 bytes
-rw-r--r--utils/rbutilqt/icons/players/iriverh300-small.pngbin0 -> 3180 bytes
-rw-r--r--utils/rbutilqt/icons/players/mpiohd200-small.pngbin0 -> 16883 bytes
-rw-r--r--utils/rbutilqt/icons/players/mpiohd300-small.pngbin0 -> 14701 bytes
-rw-r--r--utils/rbutilqt/icons/players/mrobe100-small.pngbin0 -> 1987 bytes
-rw-r--r--utils/rbutilqt/icons/players/mrobe500-small.pngbin0 -> 3075 bytes
-rw-r--r--utils/rbutilqt/icons/players/samsungyh820-small.pngbin0 -> 3225 bytes
-rw-r--r--utils/rbutilqt/icons/players/samsungyh920-small.pngbin0 -> 3358 bytes
-rw-r--r--utils/rbutilqt/icons/players/samsungyh925-small.pngbin0 -> 3447 bytes
-rw-r--r--utils/rbutilqt/icons/players/samsungypr0-small.pngbin0 -> 3038 bytes
-rw-r--r--utils/rbutilqt/icons/players/sansac200-small.pngbin0 -> 3625 bytes
-rw-r--r--utils/rbutilqt/icons/players/sansaclip-small.pngbin0 -> 5843 bytes
-rw-r--r--utils/rbutilqt/icons/players/sansaclipplus-small.pngbin0 -> 4542 bytes
-rw-r--r--utils/rbutilqt/icons/players/sansaclipzip-small.pngbin0 -> 7640 bytes
-rw-r--r--utils/rbutilqt/icons/players/sansaconnect-small.pngbin0 -> 6603 bytes
-rw-r--r--utils/rbutilqt/icons/players/sansae200-small.pngbin0 -> 3901 bytes
-rw-r--r--utils/rbutilqt/icons/players/sansafuze-small.pngbin0 -> 4937 bytes
-rw-r--r--utils/rbutilqt/icons/players/sansafuzeplus-small.pngbin0 -> 6753 bytes
-rw-r--r--utils/rbutilqt/icons/players/source-small.pngbin0 -> 4908 bytes
-rw-r--r--utils/rbutilqt/icons/players/vibe500-small.pngbin0 -> 2891 bytes
-rw-r--r--utils/rbutilqt/icons/players/vx747-small.pngbin0 -> 2732 bytes
-rw-r--r--utils/rbutilqt/icons/players/vx777-small.pngbin0 -> 2445 bytes
-rw-r--r--utils/rbutilqt/icons/preferences-desktop-font.svg243
-rw-r--r--utils/rbutilqt/icons/preferences-desktop-locale.svg878
-rw-r--r--utils/rbutilqt/icons/preferences-desktop-theme.svg882
-rw-r--r--utils/rbutilqt/icons/preferences-system.svg398
-rw-r--r--utils/rbutilqt/icons/process-stop.svg336
-rw-r--r--utils/rbutilqt/icons/rbutilqt.icnsbin0 -> 180474 bytes
-rw-r--r--utils/rbutilqt/icons/rockbox.icobin0 -> 100082 bytes
-rw-r--r--utils/rbutilqt/icons/system-installer.svg497
-rw-r--r--utils/rbutilqt/icons/system-search.svg313
-rw-r--r--utils/rbutilqt/icons/user-trash-full.svg728
-rw-r--r--utils/rbutilqt/icons/view-refresh.svg393
-rw-r--r--utils/rbutilqt/icons/wizard.jpgbin0 -> 16221 bytes
-rw-r--r--utils/rbutilqt/installtalkfrm.ui246
-rw-r--r--utils/rbutilqt/installtalkwindow.cpp188
-rw-r--r--utils/rbutilqt/installtalkwindow.h56
-rw-r--r--utils/rbutilqt/irivertools/h100sums.h23
-rw-r--r--utils/rbutilqt/irivertools/h120sums.h23
-rw-r--r--utils/rbutilqt/irivertools/h300sums.h19
-rwxr-xr-xutils/rbutilqt/irivertools/mksums.pl69
-rw-r--r--utils/rbutilqt/lame/lame.h1243
-rw-r--r--utils/rbutilqt/lang/rbutil_cs.ts3863
-rw-r--r--utils/rbutilqt/lang/rbutil_de.ts3788
-rw-r--r--utils/rbutilqt/lang/rbutil_fi.ts3652
-rw-r--r--utils/rbutilqt/lang/rbutil_fr.ts3701
-rw-r--r--utils/rbutilqt/lang/rbutil_gr.ts3667
-rw-r--r--utils/rbutilqt/lang/rbutil_he.ts3683
-rw-r--r--utils/rbutilqt/lang/rbutil_it.ts3655
-rw-r--r--utils/rbutilqt/lang/rbutil_ja.ts3678
-rw-r--r--utils/rbutilqt/lang/rbutil_nl.ts3697
-rw-r--r--utils/rbutilqt/lang/rbutil_pl.ts3696
-rw-r--r--utils/rbutilqt/lang/rbutil_pt.ts3665
-rw-r--r--utils/rbutilqt/lang/rbutil_pt_BR.ts2969
-rw-r--r--utils/rbutilqt/lang/rbutil_ru.ts2981
-rw-r--r--utils/rbutilqt/lang/rbutil_tr.ts4731
-rw-r--r--utils/rbutilqt/lang/rbutil_zh_CN.ts3647
-rw-r--r--utils/rbutilqt/lang/rbutil_zh_TW.ts3647
-rwxr-xr-xutils/rbutilqt/langstats.py195
-rw-r--r--utils/rbutilqt/logger/LICENSE.LGPL504
-rw-r--r--utils/rbutilqt/logger/README.ROCKBOX7
-rw-r--r--utils/rbutilqt/logger/include/AbstractAppender.h49
-rw-r--r--utils/rbutilqt/logger/include/AbstractStringAppender.h46
-rw-r--r--utils/rbutilqt/logger/include/ConsoleAppender.h36
-rw-r--r--utils/rbutilqt/logger/include/CuteLogger_global.h16
-rw-r--r--utils/rbutilqt/logger/include/FileAppender.h49
-rw-r--r--utils/rbutilqt/logger/include/Logger.h238
-rw-r--r--utils/rbutilqt/logger/include/OutputDebugAppender.h29
-rw-r--r--utils/rbutilqt/logger/logger.pri22
-rw-r--r--utils/rbutilqt/logger/src/AbstractAppender.cpp147
-rw-r--r--utils/rbutilqt/logger/src/AbstractStringAppender.cpp460
-rw-r--r--utils/rbutilqt/logger/src/ConsoleAppender.cpp64
-rw-r--r--utils/rbutilqt/logger/src/FileAppender.cpp116
-rw-r--r--utils/rbutilqt/logger/src/Logger.cpp1108
-rw-r--r--utils/rbutilqt/logger/src/OutputDebugAppender.cpp43
-rw-r--r--utils/rbutilqt/main.cpp112
-rw-r--r--utils/rbutilqt/mspack/COPYING.LIB504
-rw-r--r--utils/rbutilqt/mspack/README.ROCKBOX6
-rw-r--r--utils/rbutilqt/mspack/cab.h140
-rw-r--r--utils/rbutilqt/mspack/cabc.c24
-rw-r--r--utils/rbutilqt/mspack/cabd.c1508
-rw-r--r--utils/rbutilqt/mspack/chm.h122
-rw-r--r--utils/rbutilqt/mspack/chmc.c24
-rw-r--r--utils/rbutilqt/mspack/chmd.c1377
-rw-r--r--utils/rbutilqt/mspack/des.h15
-rw-r--r--utils/rbutilqt/mspack/hlp.h33
-rw-r--r--utils/rbutilqt/mspack/hlpc.c24
-rw-r--r--utils/rbutilqt/mspack/hlpd.c24
-rw-r--r--utils/rbutilqt/mspack/kwaj.h118
-rw-r--r--utils/rbutilqt/mspack/kwajc.c24
-rw-r--r--utils/rbutilqt/mspack/kwajd.c566
-rw-r--r--utils/rbutilqt/mspack/lit.h35
-rw-r--r--utils/rbutilqt/mspack/litc.c24
-rw-r--r--utils/rbutilqt/mspack/litd.c24
-rw-r--r--utils/rbutilqt/mspack/lzss.h66
-rw-r--r--utils/rbutilqt/mspack/lzssd.c93
-rw-r--r--utils/rbutilqt/mspack/lzx.h221
-rw-r--r--utils/rbutilqt/mspack/lzxc.c18
-rw-r--r--utils/rbutilqt/mspack/lzxd.c905
-rw-r--r--utils/rbutilqt/mspack/mspack.h2385
-rw-r--r--utils/rbutilqt/mspack/mszip.h126
-rw-r--r--utils/rbutilqt/mspack/mszipc.c18
-rw-r--r--utils/rbutilqt/mspack/mszipd.c515
-rw-r--r--utils/rbutilqt/mspack/qtm.h128
-rw-r--r--utils/rbutilqt/mspack/qtmd.c490
-rw-r--r--utils/rbutilqt/mspack/readbits.h207
-rw-r--r--utils/rbutilqt/mspack/readhuff.h172
-rw-r--r--utils/rbutilqt/mspack/sha.h15
-rw-r--r--utils/rbutilqt/mspack/system-mspack.c240
-rw-r--r--utils/rbutilqt/mspack/system-mspack.h129
-rw-r--r--utils/rbutilqt/mspack/szdd.h39
-rw-r--r--utils/rbutilqt/mspack/szddc.c24
-rw-r--r--utils/rbutilqt/mspack/szddd.c247
-rw-r--r--utils/rbutilqt/msvc/Makefile61
-rw-r--r--utils/rbutilqt/msvc/README106
-rw-r--r--utils/rbutilqt/msvc/inttypes.h305
-rw-r--r--utils/rbutilqt/msvc/stdbool.h38
-rw-r--r--utils/rbutilqt/msvc/stdint.h247
-rw-r--r--utils/rbutilqt/preview.cpp122
-rw-r--r--utils/rbutilqt/preview.h74
-rw-r--r--utils/rbutilqt/previewfrm.ui90
-rw-r--r--utils/rbutilqt/progressloggerfrm.ui101
-rw-r--r--utils/rbutilqt/progressloggergui.cpp186
-rw-r--r--utils/rbutilqt/progressloggergui.h60
-rw-r--r--utils/rbutilqt/quazip/LICENSE.LGPL458
-rw-r--r--utils/rbutilqt/quazip/README.ROCKBOX9
-rw-r--r--utils/rbutilqt/quazip/ioapi.h207
-rw-r--r--utils/rbutilqt/quazip/minizip_crypt.h135
-rw-r--r--utils/rbutilqt/quazip/qioapi.cpp363
-rw-r--r--utils/rbutilqt/quazip/quazip.cpp846
-rw-r--r--utils/rbutilqt/quazip/quazip.h611
-rw-r--r--utils/rbutilqt/quazip/quazip.pri25
-rw-r--r--utils/rbutilqt/quazip/quazip_global.h63
-rw-r--r--utils/rbutilqt/quazip/quazipfile.cpp570
-rw-r--r--utils/rbutilqt/quazip/quazipfile.h508
-rw-r--r--utils/rbutilqt/quazip/quazipfileinfo.cpp196
-rw-r--r--utils/rbutilqt/quazip/quazipfileinfo.h226
-rw-r--r--utils/rbutilqt/quazip/quazipnewinfo.cpp290
-rw-r--r--utils/rbutilqt/quazip/quazipnewinfo.h208
-rw-r--r--utils/rbutilqt/quazip/unzip.c2163
-rw-r--r--utils/rbutilqt/quazip/unzip.h461
-rw-r--r--utils/rbutilqt/quazip/zip.c2111
-rw-r--r--utils/rbutilqt/quazip/zip.h391
-rw-r--r--utils/rbutilqt/rbutil.ini1000
-rw-r--r--utils/rbutilqt/rbutilqt-lang.qrc19
-rw-r--r--utils/rbutilqt/rbutilqt-win.qrc5
-rw-r--r--utils/rbutilqt/rbutilqt.cpp721
-rw-r--r--utils/rbutilqt/rbutilqt.h104
-rw-r--r--utils/rbutilqt/rbutilqt.manifest19
-rw-r--r--utils/rbutilqt/rbutilqt.pri229
-rw-r--r--utils/rbutilqt/rbutilqt.pro248
-rw-r--r--utils/rbutilqt/rbutilqt.qrc97
-rw-r--r--utils/rbutilqt/rbutilqt.rc34
-rw-r--r--utils/rbutilqt/rbutilqtfrm.ui647
-rw-r--r--utils/rbutilqt/sysinfo.cpp95
-rw-r--r--utils/rbutilqt/sysinfo.h50
-rw-r--r--utils/rbutilqt/sysinfofrm.ui68
-rw-r--r--utils/rbutilqt/systrace.cpp138
-rw-r--r--utils/rbutilqt/systrace.h47
-rw-r--r--utils/rbutilqt/systracefrm.ui93
-rw-r--r--utils/rbutilqt/test/stubs/Logger.h11
-rw-r--r--utils/rbutilqt/test/stubs/stubs-compareversion.cpp31
-rw-r--r--utils/rbutilqt/test/stubs/stubs-playerbuildinfo.cpp36
-rw-r--r--utils/rbutilqt/test/test-compareversion.cpp145
-rw-r--r--utils/rbutilqt/test/test-compareversion.pro37
-rw-r--r--utils/rbutilqt/test/test-httpget.cpp547
-rw-r--r--utils/rbutilqt/test/test-httpget.pro31
-rw-r--r--utils/rbutilqt/test/test-playerbuildinfo.cpp240
-rw-r--r--utils/rbutilqt/test/test-playerbuildinfo.pro35
-rw-r--r--utils/rbutilqt/test/test-rockboxinfo.cpp187
-rw-r--r--utils/rbutilqt/test/test-rockboxinfo.pro30
-rw-r--r--utils/rbutilqt/test/tests.pri24
-rw-r--r--utils/rbutilqt/themesinstallfrm.ui149
-rw-r--r--utils/rbutilqt/themesinstallwindow.cpp393
-rw-r--r--utils/rbutilqt/themesinstallwindow.h77
-rw-r--r--utils/rbutilqt/uninstallfrm.ui188
-rw-r--r--utils/rbutilqt/uninstallwindow.cpp100
-rw-r--r--utils/rbutilqt/uninstallwindow.h51
-rw-r--r--utils/rbutilqt/version.h44
-rw-r--r--utils/rbutilqt/zlib/zconf.h326
-rw-r--r--utils/rbutilqt/zlib/zlib.h1200
-rw-r--r--utils/sansapatcher/Makefile52
-rw-r--r--utils/sansapatcher/README36
-rw-r--r--utils/sansapatcher/main.c420
-rw-r--r--utils/sansapatcher/parttypes.h109
-rw-r--r--utils/sansapatcher/sansaio-posix.c157
-rw-r--r--utils/sansapatcher/sansaio-win32.c217
-rw-r--r--utils/sansapatcher/sansaio.h88
-rw-r--r--utils/sansapatcher/sansapatcher.c975
-rw-r--r--utils/sansapatcher/sansapatcher.h67
-rw-r--r--utils/sansapatcher/sansapatcher.manifest13
-rw-r--r--utils/sansapatcher/sansapatcher.pro38
-rw-r--r--utils/sansapatcher/sansapatcher.rc1
-rw-r--r--utils/tools/Makefile31
-rw-r--r--utils/tools/bin2c.c174
494 files changed, 154361 insertions, 0 deletions
diff --git a/utils/bspatch/LICENSE b/utils/bspatch/LICENSE
new file mode 100644
index 0000000000..c82090b3eb
--- /dev/null
+++ b/utils/bspatch/LICENSE
@@ -0,0 +1,23 @@
1 Copyright 2003-2005 Colin Percival
2 All rights reserved
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted providing that the following conditions
6 are met:
7 1. Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 2. Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12
13 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
22 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
23 POSSIBILITY OF SUCH DAMAGE.
diff --git a/utils/bspatch/Makefile b/utils/bspatch/Makefile
new file mode 100644
index 0000000000..8f287a5ebb
--- /dev/null
+++ b/utils/bspatch/Makefile
@@ -0,0 +1,17 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10LIBSOURCES := bspatch.c
11
12SOURCES := main.c
13
14OUTPUT := bspatch
15EXTRADEPS := libbz2.a
16
17include ../libtools.make
diff --git a/utils/bspatch/bspatch.c b/utils/bspatch/bspatch.c
new file mode 100644
index 0000000000..d1d7a5aa7a
--- /dev/null
+++ b/utils/bspatch/bspatch.c
@@ -0,0 +1,218 @@
1/*-
2 * Copyright 2003-2005 Colin Percival
3 * All rights reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted providing that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
23 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#ifdef WIN32
28#include <io.h>
29#else
30#include <stdarg.h>
31#include <sys/types.h>
32#endif
33#include "../bzip2/bzlib.h"
34#include <stdlib.h>
35#include <stdio.h>
36#include <string.h>
37#include <fcntl.h>
38
39#define errx err
40void err(int exitcode, const char * fmt, ...)
41{
42 va_list valist;
43 va_start(valist, fmt);
44 vprintf(fmt, valist);
45 va_end(valist);
46 exit(exitcode);
47}
48
49static long offtin(u_char *buf)
50{
51 long y;
52
53 y = buf[7] & 0x7F;
54 y = y * 256;y += buf[6];
55 y = y * 256;y += buf[5];
56 y = y * 256;y += buf[4];
57 y = y * 256;y += buf[3];
58 y = y * 256;y += buf[2];
59 y = y * 256;y += buf[1];
60 y = y * 256;y += buf[0];
61
62 if (buf[7] & 0x80) y = -y;
63
64 return y;
65}
66
67int apply_bspatch(const char *infile, const char *outfile, const char *patchfile)
68{
69 FILE * f, *cpf, *dpf, *epf;
70 BZFILE * cpfbz2, *dpfbz2, *epfbz2;
71 int cbz2err, dbz2err, ebz2err;
72 FILE * fs;
73 long oldsize, newsize;
74 long bzctrllen, bzdatalen;
75 u_char header[32], buf[8];
76 u_char *pold, *pnew;
77 long oldpos, newpos;
78 long ctrl[3];
79 long lenread;
80 long i;
81
82 /* Open patch file */
83 if ((f = fopen(patchfile, "r")) == NULL)
84 err(1, "fopen(%s)", patchfile);
85
86 /*
87 File format:
88 0 8 "BSDIFF40"
89 8 8 X
90 16 8 Y
91 24 8 sizeof(newfile)
92 32 X bzip2(control block)
93 32+X Y bzip2(diff block)
94 32+X+Y ??? bzip2(extra block)
95 with control block a set of triples (x,y,z) meaning "add x bytes
96 from oldfile to x bytes from the diff block; copy y bytes from the
97 extra block; seek forwards in oldfile by z bytes".
98 */
99
100 /* Read header */
101 if (fread(header, 1, 32, f) < 32) {
102 if (feof(f))
103 errx(1, "Corrupt patch\n");
104 err(1, "fread(%s)", patchfile);
105 }
106
107 /* Check for appropriate magic */
108 if (memcmp(header, "BSDIFF40", 8) != 0)
109 errx(1, "Corrupt patch\n");
110
111 /* Read lengths from header */
112 bzctrllen = offtin(header + 8);
113 bzdatalen = offtin(header + 16);
114 newsize = offtin(header + 24);
115 if ((bzctrllen < 0) || (bzdatalen < 0) || (newsize < 0))
116 errx(1, "Corrupt patch\n");
117
118 /* Close patch file and re-open it via libbzip2 at the right places */
119 if (fclose(f))
120 err(1, "fclose(%s)", patchfile);
121 if ((cpf = fopen(patchfile, "rb")) == NULL)
122 err(1, "fopen(%s)", patchfile);
123 if (fseek(cpf, 32, SEEK_SET))
124 err(1, "fseeko(%s, %lld)", patchfile,
125 (long long)32);
126 if ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, cpf, 0, 0, NULL, 0)) == NULL)
127 errx(1, "BZ2_bzReadOpen, bz2err = %d", cbz2err);
128 if ((dpf = fopen(patchfile, "rb")) == NULL)
129 err(1, "fopen(%s)", patchfile);
130 if (fseek(dpf, 32 + bzctrllen, SEEK_SET))
131 err(1, "fseeko(%s, %lld)", patchfile,
132 (long long)(32 + bzctrllen));
133 if ((dpfbz2 = BZ2_bzReadOpen(&dbz2err, dpf, 0, 0, NULL, 0)) == NULL)
134 errx(1, "BZ2_bzReadOpen, bz2err = %d", dbz2err);
135 if ((epf = fopen(patchfile, "rb")) == NULL)
136 err(1, "fopen(%s)", patchfile);
137 if (fseek(epf, 32 + bzctrllen + bzdatalen, SEEK_SET))
138 err(1, "fseeko(%s, %lld)", patchfile,
139 (long long)(32 + bzctrllen + bzdatalen));
140 if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL)
141 errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err);
142
143 fs = fopen(infile, "rb");
144 if (fs == NULL)err(1, "Open failed :%s", infile);
145 if (fseek(fs, 0, SEEK_END) != 0)err(1, "Seek failed :%s", infile);
146 oldsize = ftell(fs);
147 pold = (u_char *)malloc(oldsize + 1);
148 if (pold == NULL) err(1, "Malloc failed :%s", infile);
149 fseek(fs, 0, SEEK_SET);
150 if (fread(pold, 1, oldsize, fs) == -1) err(1, "Read failed :%s", infile);
151 if (fclose(fs) == -1) err(1, "Close failed :%s", infile);
152
153 pnew = malloc(newsize + 1);
154 if (pnew == NULL)err(1, NULL);
155
156 oldpos = 0;newpos = 0;
157 while (newpos < newsize) {
158 /* Read control data */
159 for (i = 0;i <= 2;i++) {
160 lenread = BZ2_bzRead(&cbz2err, cpfbz2, buf, 8);
161 if ((lenread < 8) || ((cbz2err != BZ_OK) &&
162 (cbz2err != BZ_STREAM_END)))
163 errx(1, "Corrupt patch\n");
164 ctrl[i] = offtin(buf);
165 };
166
167 /* Sanity-check */
168 if (newpos + ctrl[0] > newsize)
169 errx(1, "Corrupt patch\n");
170
171 /* Read diff string */
172 lenread = BZ2_bzRead(&dbz2err, dpfbz2, pnew + newpos, ctrl[0]);
173 if ((lenread < ctrl[0]) ||
174 ((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END)))
175 errx(1, "Corrupt patch\n");
176
177 /* Add pold data to diff string */
178 for (i = 0;i < ctrl[0];i++)
179 if ((oldpos + i >= 0) && (oldpos + i < oldsize))
180 pnew[newpos + i] += pold[oldpos + i];
181
182 /* Adjust pointers */
183 newpos += ctrl[0];
184 oldpos += ctrl[0];
185
186 /* Sanity-check */
187 if (newpos + ctrl[1] > newsize)
188 errx(1, "Corrupt patch\n");
189
190 /* Read extra string */
191 lenread = BZ2_bzRead(&ebz2err, epfbz2, pnew + newpos, ctrl[1]);
192 if ((lenread < ctrl[1]) ||
193 ((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END)))
194 errx(1, "Corrupt patch\n");
195
196 /* Adjust pointers */
197 newpos += ctrl[1];
198 oldpos += ctrl[2];
199 };
200
201 /* Clean up the bzip2 reads */
202 BZ2_bzReadClose(&cbz2err, cpfbz2);
203 BZ2_bzReadClose(&dbz2err, dpfbz2);
204 BZ2_bzReadClose(&ebz2err, epfbz2);
205 if (fclose(cpf) || fclose(dpf) || fclose(epf))
206 err(1, "fclose(%s)", patchfile);
207
208 /* Write the pnew file */
209 fs = fopen(outfile, "wb");
210 if (fs == NULL)err(1, "Create failed :%s", outfile);
211 if (fwrite(pnew, 1, newsize, fs) == -1)err(1, "Write failed :%s", outfile);
212 if (fclose(fs) == -1)err(1, "Close failed :%s", outfile);
213
214 free(pnew);
215 free(pold);
216
217 return 0;
218}
diff --git a/utils/bspatch/bspatch.h b/utils/bspatch/bspatch.h
new file mode 100644
index 0000000000..46edd5db0c
--- /dev/null
+++ b/utils/bspatch/bspatch.h
@@ -0,0 +1,19 @@
1/*
2 * Simple wrapper for the bspatch entry point.
3 */
4
5#ifndef _BSPATCH_H
6#define _BSPATCH_H
7
8#ifdef __cplusplus
9extern "C" {
10#endif
11
12int apply_bspatch(const char *infile, const char *outfile, const char *patchfile);
13
14#ifdef __cplusplus
15}
16#endif
17
18
19#endif /* _BSPATCH_H */
diff --git a/utils/bspatch/main.c b/utils/bspatch/main.c
new file mode 100644
index 0000000000..e130457256
--- /dev/null
+++ b/utils/bspatch/main.c
@@ -0,0 +1,34 @@
1/*-
2 * Copyright 2003-2005 Colin Percival
3 * All rights reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted providing that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
23 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "bspatch.c"
28
29int main(int argc, char * argv[])
30{
31 if (argc != 4) errx(1, "usage: %s oldfile newfile patchfile\n", argv[0]);
32
33 apply_bspatch(argv[1], argv[2], argv[3]);
34}
diff --git a/utils/bzip2/LICENSE b/utils/bzip2/LICENSE
new file mode 100644
index 0000000000..cc614178cf
--- /dev/null
+++ b/utils/bzip2/LICENSE
@@ -0,0 +1,42 @@
1
2--------------------------------------------------------------------------
3
4This program, "bzip2", the associated library "libbzip2", and all
5documentation, are copyright (C) 1996-2010 Julian R Seward. All
6rights reserved.
7
8Redistribution and use in source and binary forms, with or without
9modification, are permitted provided that the following conditions
10are met:
11
121. Redistributions of source code must retain the above copyright
13 notice, this list of conditions and the following disclaimer.
14
152. The origin of this software must not be misrepresented; you must
16 not claim that you wrote the original software. If you use this
17 software in a product, an acknowledgment in the product
18 documentation would be appreciated but is not required.
19
203. Altered source versions must be plainly marked as such, and must
21 not be misrepresented as being the original software.
22
234. The name of the author may not be used to endorse or promote
24 products derived from this software without specific prior written
25 permission.
26
27THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
28OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
29WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
31DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
33GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
35WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39Julian Seward, jseward@bzip.org
40bzip2/libbzip2 version 1.0.6 of 6 September 2010
41
42--------------------------------------------------------------------------
diff --git a/utils/bzip2/Makefile b/utils/bzip2/Makefile
new file mode 100644
index 0000000000..6dc59ed025
--- /dev/null
+++ b/utils/bzip2/Makefile
@@ -0,0 +1,15 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10LIBSOURCES := blocksort.c compress.c decompress.c randtable.c \
11 bzlib.c crctable.c huffman.c
12
13OUTPUT := bz2
14
15include ../libtools.make
diff --git a/utils/bzip2/blocksort.c b/utils/bzip2/blocksort.c
new file mode 100644
index 0000000000..d0d662cd4e
--- /dev/null
+++ b/utils/bzip2/blocksort.c
@@ -0,0 +1,1094 @@
1
2/*-------------------------------------------------------------*/
3/*--- Block sorting machinery ---*/
4/*--- blocksort.c ---*/
5/*-------------------------------------------------------------*/
6
7/* ------------------------------------------------------------------
8 This file is part of bzip2/libbzip2, a program and library for
9 lossless, block-sorting data compression.
10
11 bzip2/libbzip2 version 1.0.6 of 6 September 2010
12 Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
13
14 Please read the WARNING, DISCLAIMER and PATENTS sections in the
15 README file.
16
17 This program is released under the terms of the license contained
18 in the file LICENSE.
19 ------------------------------------------------------------------ */
20
21
22#include "bzlib_private.h"
23
24/*---------------------------------------------*/
25/*--- Fallback O(N log(N)^2) sorting ---*/
26/*--- algorithm, for repetitive blocks ---*/
27/*---------------------------------------------*/
28
29/*---------------------------------------------*/
30static
31__inline__
32void fallbackSimpleSort ( UInt32* fmap,
33 UInt32* eclass,
34 Int32 lo,
35 Int32 hi )
36{
37 Int32 i, j, tmp;
38 UInt32 ec_tmp;
39
40 if (lo == hi) return;
41
42 if (hi - lo > 3) {
43 for ( i = hi-4; i >= lo; i-- ) {
44 tmp = fmap[i];
45 ec_tmp = eclass[tmp];
46 for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
47 fmap[j-4] = fmap[j];
48 fmap[j-4] = tmp;
49 }
50 }
51
52 for ( i = hi-1; i >= lo; i-- ) {
53 tmp = fmap[i];
54 ec_tmp = eclass[tmp];
55 for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
56 fmap[j-1] = fmap[j];
57 fmap[j-1] = tmp;
58 }
59}
60
61
62/*---------------------------------------------*/
63#define fswap(zz1, zz2) \
64 { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
65
66#define fvswap(zzp1, zzp2, zzn) \
67{ \
68 Int32 yyp1 = (zzp1); \
69 Int32 yyp2 = (zzp2); \
70 Int32 yyn = (zzn); \
71 while (yyn > 0) { \
72 fswap(fmap[yyp1], fmap[yyp2]); \
73 yyp1++; yyp2++; yyn--; \
74 } \
75}
76
77
78#define fmin(a,b) ((a) < (b)) ? (a) : (b)
79
80#define fpush(lz,hz) { stackLo[sp] = lz; \
81 stackHi[sp] = hz; \
82 sp++; }
83
84#define fpop(lz,hz) { sp--; \
85 lz = stackLo[sp]; \
86 hz = stackHi[sp]; }
87
88#define FALLBACK_QSORT_SMALL_THRESH 10
89#define FALLBACK_QSORT_STACK_SIZE 100
90
91
92static
93void fallbackQSort3 ( UInt32* fmap,
94 UInt32* eclass,
95 Int32 loSt,
96 Int32 hiSt )
97{
98 Int32 unLo, unHi, ltLo, gtHi, n, m;
99 Int32 sp, lo, hi;
100 UInt32 med, r, r3;
101 Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
102 Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
103
104 r = 0;
105
106 sp = 0;
107 fpush ( loSt, hiSt );
108
109 while (sp > 0) {
110
111 AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 );
112
113 fpop ( lo, hi );
114 if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
115 fallbackSimpleSort ( fmap, eclass, lo, hi );
116 continue;
117 }
118
119 /* Random partitioning. Median of 3 sometimes fails to
120 avoid bad cases. Median of 9 seems to help but
121 looks rather expensive. This too seems to work but
122 is cheaper. Guidance for the magic constants
123 7621 and 32768 is taken from Sedgewick's algorithms
124 book, chapter 35.
125 */
126 r = ((r * 7621) + 1) % 32768;
127 r3 = r % 3;
128 if (r3 == 0) med = eclass[fmap[lo]]; else
129 if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
130 med = eclass[fmap[hi]];
131
132 unLo = ltLo = lo;
133 unHi = gtHi = hi;
134
135 while (1) {
136 while (1) {
137 if (unLo > unHi) break;
138 n = (Int32)eclass[fmap[unLo]] - (Int32)med;
139 if (n == 0) {
140 fswap(fmap[unLo], fmap[ltLo]);
141 ltLo++; unLo++;
142 continue;
143 };
144 if (n > 0) break;
145 unLo++;
146 }
147 while (1) {
148 if (unLo > unHi) break;
149 n = (Int32)eclass[fmap[unHi]] - (Int32)med;
150 if (n == 0) {
151 fswap(fmap[unHi], fmap[gtHi]);
152 gtHi--; unHi--;
153 continue;
154 };
155 if (n < 0) break;
156 unHi--;
157 }
158 if (unLo > unHi) break;
159 fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
160 }
161
162 AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
163
164 if (gtHi < ltLo) continue;
165
166 n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
167 m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
168
169 n = lo + unLo - ltLo - 1;
170 m = hi - (gtHi - unHi) + 1;
171
172 if (n - lo > hi - m) {
173 fpush ( lo, n );
174 fpush ( m, hi );
175 } else {
176 fpush ( m, hi );
177 fpush ( lo, n );
178 }
179 }
180}
181
182#undef fmin
183#undef fpush
184#undef fpop
185#undef fswap
186#undef fvswap
187#undef FALLBACK_QSORT_SMALL_THRESH
188#undef FALLBACK_QSORT_STACK_SIZE
189
190
191/*---------------------------------------------*/
192/* Pre:
193 nblock > 0
194 eclass exists for [0 .. nblock-1]
195 ((UChar*)eclass) [0 .. nblock-1] holds block
196 ptr exists for [0 .. nblock-1]
197
198 Post:
199 ((UChar*)eclass) [0 .. nblock-1] holds block
200 All other areas of eclass destroyed
201 fmap [0 .. nblock-1] holds sorted order
202 bhtab [ 0 .. 2+(nblock/32) ] destroyed
203*/
204
205#define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
206#define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
207#define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
208#define WORD_BH(zz) bhtab[(zz) >> 5]
209#define UNALIGNED_BH(zz) ((zz) & 0x01f)
210
211static
212void fallbackSort ( UInt32* fmap,
213 UInt32* eclass,
214 UInt32* bhtab,
215 Int32 nblock,
216 Int32 verb )
217{
218 Int32 ftab[257];
219 Int32 ftabCopy[256];
220 Int32 H, i, j, k, l, r, cc, cc1;
221 Int32 nNotDone;
222 Int32 nBhtab;
223 UChar* eclass8 = (UChar*)eclass;
224
225 /*--
226 Initial 1-char radix sort to generate
227 initial fmap and initial BH bits.
228 --*/
229 if (verb >= 4)
230 VPrintf0 ( " bucket sorting ...\n" );
231 for (i = 0; i < 257; i++) ftab[i] = 0;
232 for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
233 for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i];
234 for (i = 1; i < 257; i++) ftab[i] += ftab[i-1];
235
236 for (i = 0; i < nblock; i++) {
237 j = eclass8[i];
238 k = ftab[j] - 1;
239 ftab[j] = k;
240 fmap[k] = i;
241 }
242
243 nBhtab = 2 + (nblock / 32);
244 for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
245 for (i = 0; i < 256; i++) SET_BH(ftab[i]);
246
247 /*--
248 Inductively refine the buckets. Kind-of an
249 "exponential radix sort" (!), inspired by the
250 Manber-Myers suffix array construction algorithm.
251 --*/
252
253 /*-- set sentinel bits for block-end detection --*/
254 for (i = 0; i < 32; i++) {
255 SET_BH(nblock + 2*i);
256 CLEAR_BH(nblock + 2*i + 1);
257 }
258
259 /*-- the log(N) loop --*/
260 H = 1;
261 while (1) {
262
263 if (verb >= 4)
264 VPrintf1 ( " depth %6d has ", H );
265
266 j = 0;
267 for (i = 0; i < nblock; i++) {
268 if (ISSET_BH(i)) j = i;
269 k = fmap[i] - H; if (k < 0) k += nblock;
270 eclass[k] = j;
271 }
272
273 nNotDone = 0;
274 r = -1;
275 while (1) {
276
277 /*-- find the next non-singleton bucket --*/
278 k = r + 1;
279 while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
280 if (ISSET_BH(k)) {
281 while (WORD_BH(k) == 0xffffffff) k += 32;
282 while (ISSET_BH(k)) k++;
283 }
284 l = k - 1;
285 if (l >= nblock) break;
286 while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
287 if (!ISSET_BH(k)) {
288 while (WORD_BH(k) == 0x00000000) k += 32;
289 while (!ISSET_BH(k)) k++;
290 }
291 r = k - 1;
292 if (r >= nblock) break;
293
294 /*-- now [l, r] bracket current bucket --*/
295 if (r > l) {
296 nNotDone += (r - l + 1);
297 fallbackQSort3 ( fmap, eclass, l, r );
298
299 /*-- scan bucket and generate header bits-- */
300 cc = -1;
301 for (i = l; i <= r; i++) {
302 cc1 = eclass[fmap[i]];
303 if (cc != cc1) { SET_BH(i); cc = cc1; };
304 }
305 }
306 }
307
308 if (verb >= 4)
309 VPrintf1 ( "%6d unresolved strings\n", nNotDone );
310
311 H *= 2;
312 if (H > nblock || nNotDone == 0) break;
313 }
314
315 /*--
316 Reconstruct the original block in
317 eclass8 [0 .. nblock-1], since the
318 previous phase destroyed it.
319 --*/
320 if (verb >= 4)
321 VPrintf0 ( " reconstructing block ...\n" );
322 j = 0;
323 for (i = 0; i < nblock; i++) {
324 while (ftabCopy[j] == 0) j++;
325 ftabCopy[j]--;
326 eclass8[fmap[i]] = (UChar)j;
327 }
328 AssertH ( j < 256, 1005 );
329}
330
331#undef SET_BH
332#undef CLEAR_BH
333#undef ISSET_BH
334#undef WORD_BH
335#undef UNALIGNED_BH
336
337
338/*---------------------------------------------*/
339/*--- The main, O(N^2 log(N)) sorting ---*/
340/*--- algorithm. Faster for "normal" ---*/
341/*--- non-repetitive blocks. ---*/
342/*---------------------------------------------*/
343
344/*---------------------------------------------*/
345static
346__inline__
347Bool mainGtU ( UInt32 i1,
348 UInt32 i2,
349 UChar* block,
350 UInt16* quadrant,
351 UInt32 nblock,
352 Int32* budget )
353{
354 Int32 k;
355 UChar c1, c2;
356 UInt16 s1, s2;
357
358 AssertD ( i1 != i2, "mainGtU" );
359 /* 1 */
360 c1 = block[i1]; c2 = block[i2];
361 if (c1 != c2) return (c1 > c2);
362 i1++; i2++;
363 /* 2 */
364 c1 = block[i1]; c2 = block[i2];
365 if (c1 != c2) return (c1 > c2);
366 i1++; i2++;
367 /* 3 */
368 c1 = block[i1]; c2 = block[i2];
369 if (c1 != c2) return (c1 > c2);
370 i1++; i2++;
371 /* 4 */
372 c1 = block[i1]; c2 = block[i2];
373 if (c1 != c2) return (c1 > c2);
374 i1++; i2++;
375 /* 5 */
376 c1 = block[i1]; c2 = block[i2];
377 if (c1 != c2) return (c1 > c2);
378 i1++; i2++;
379 /* 6 */
380 c1 = block[i1]; c2 = block[i2];
381 if (c1 != c2) return (c1 > c2);
382 i1++; i2++;
383 /* 7 */
384 c1 = block[i1]; c2 = block[i2];
385 if (c1 != c2) return (c1 > c2);
386 i1++; i2++;
387 /* 8 */
388 c1 = block[i1]; c2 = block[i2];
389 if (c1 != c2) return (c1 > c2);
390 i1++; i2++;
391 /* 9 */
392 c1 = block[i1]; c2 = block[i2];
393 if (c1 != c2) return (c1 > c2);
394 i1++; i2++;
395 /* 10 */
396 c1 = block[i1]; c2 = block[i2];
397 if (c1 != c2) return (c1 > c2);
398 i1++; i2++;
399 /* 11 */
400 c1 = block[i1]; c2 = block[i2];
401 if (c1 != c2) return (c1 > c2);
402 i1++; i2++;
403 /* 12 */
404 c1 = block[i1]; c2 = block[i2];
405 if (c1 != c2) return (c1 > c2);
406 i1++; i2++;
407
408 k = nblock + 8;
409
410 do {
411 /* 1 */
412 c1 = block[i1]; c2 = block[i2];
413 if (c1 != c2) return (c1 > c2);
414 s1 = quadrant[i1]; s2 = quadrant[i2];
415 if (s1 != s2) return (s1 > s2);
416 i1++; i2++;
417 /* 2 */
418 c1 = block[i1]; c2 = block[i2];
419 if (c1 != c2) return (c1 > c2);
420 s1 = quadrant[i1]; s2 = quadrant[i2];
421 if (s1 != s2) return (s1 > s2);
422 i1++; i2++;
423 /* 3 */
424 c1 = block[i1]; c2 = block[i2];
425 if (c1 != c2) return (c1 > c2);
426 s1 = quadrant[i1]; s2 = quadrant[i2];
427 if (s1 != s2) return (s1 > s2);
428 i1++; i2++;
429 /* 4 */
430 c1 = block[i1]; c2 = block[i2];
431 if (c1 != c2) return (c1 > c2);
432 s1 = quadrant[i1]; s2 = quadrant[i2];
433 if (s1 != s2) return (s1 > s2);
434 i1++; i2++;
435 /* 5 */
436 c1 = block[i1]; c2 = block[i2];
437 if (c1 != c2) return (c1 > c2);
438 s1 = quadrant[i1]; s2 = quadrant[i2];
439 if (s1 != s2) return (s1 > s2);
440 i1++; i2++;
441 /* 6 */
442 c1 = block[i1]; c2 = block[i2];
443 if (c1 != c2) return (c1 > c2);
444 s1 = quadrant[i1]; s2 = quadrant[i2];
445 if (s1 != s2) return (s1 > s2);
446 i1++; i2++;
447 /* 7 */
448 c1 = block[i1]; c2 = block[i2];
449 if (c1 != c2) return (c1 > c2);
450 s1 = quadrant[i1]; s2 = quadrant[i2];
451 if (s1 != s2) return (s1 > s2);
452 i1++; i2++;
453 /* 8 */
454 c1 = block[i1]; c2 = block[i2];
455 if (c1 != c2) return (c1 > c2);
456 s1 = quadrant[i1]; s2 = quadrant[i2];
457 if (s1 != s2) return (s1 > s2);
458 i1++; i2++;
459
460 if (i1 >= nblock) i1 -= nblock;
461 if (i2 >= nblock) i2 -= nblock;
462
463 k -= 8;
464 (*budget)--;
465 }
466 while (k >= 0);
467
468 return False;
469}
470
471
472/*---------------------------------------------*/
473/*--
474 Knuth's increments seem to work better
475 than Incerpi-Sedgewick here. Possibly
476 because the number of elems to sort is
477 usually small, typically <= 20.
478--*/
479static
480Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
481 9841, 29524, 88573, 265720,
482 797161, 2391484 };
483
484static
485void mainSimpleSort ( UInt32* ptr,
486 UChar* block,
487 UInt16* quadrant,
488 Int32 nblock,
489 Int32 lo,
490 Int32 hi,
491 Int32 d,
492 Int32* budget )
493{
494 Int32 i, j, h, bigN, hp;
495 UInt32 v;
496
497 bigN = hi - lo + 1;
498 if (bigN < 2) return;
499
500 hp = 0;
501 while (incs[hp] < bigN) hp++;
502 hp--;
503
504 for (; hp >= 0; hp--) {
505 h = incs[hp];
506
507 i = lo + h;
508 while (True) {
509
510 /*-- copy 1 --*/
511 if (i > hi) break;
512 v = ptr[i];
513 j = i;
514 while ( mainGtU (
515 ptr[j-h]+d, v+d, block, quadrant, nblock, budget
516 ) ) {
517 ptr[j] = ptr[j-h];
518 j = j - h;
519 if (j <= (lo + h - 1)) break;
520 }
521 ptr[j] = v;
522 i++;
523
524 /*-- copy 2 --*/
525 if (i > hi) break;
526 v = ptr[i];
527 j = i;
528 while ( mainGtU (
529 ptr[j-h]+d, v+d, block, quadrant, nblock, budget
530 ) ) {
531 ptr[j] = ptr[j-h];
532 j = j - h;
533 if (j <= (lo + h - 1)) break;
534 }
535 ptr[j] = v;
536 i++;
537
538 /*-- copy 3 --*/
539 if (i > hi) break;
540 v = ptr[i];
541 j = i;
542 while ( mainGtU (
543 ptr[j-h]+d, v+d, block, quadrant, nblock, budget
544 ) ) {
545 ptr[j] = ptr[j-h];
546 j = j - h;
547 if (j <= (lo + h - 1)) break;
548 }
549 ptr[j] = v;
550 i++;
551
552 if (*budget < 0) return;
553 }
554 }
555}
556
557
558/*---------------------------------------------*/
559/*--
560 The following is an implementation of
561 an elegant 3-way quicksort for strings,
562 described in a paper "Fast Algorithms for
563 Sorting and Searching Strings", by Robert
564 Sedgewick and Jon L. Bentley.
565--*/
566
567#define mswap(zz1, zz2) \
568 { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
569
570#define mvswap(zzp1, zzp2, zzn) \
571{ \
572 Int32 yyp1 = (zzp1); \
573 Int32 yyp2 = (zzp2); \
574 Int32 yyn = (zzn); \
575 while (yyn > 0) { \
576 mswap(ptr[yyp1], ptr[yyp2]); \
577 yyp1++; yyp2++; yyn--; \
578 } \
579}
580
581static
582__inline__
583UChar mmed3 ( UChar a, UChar b, UChar c )
584{
585 UChar t;
586 if (a > b) { t = a; a = b; b = t; };
587 if (b > c) {
588 b = c;
589 if (a > b) b = a;
590 }
591 return b;
592}
593
594#define mmin(a,b) ((a) < (b)) ? (a) : (b)
595
596#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
597 stackHi[sp] = hz; \
598 stackD [sp] = dz; \
599 sp++; }
600
601#define mpop(lz,hz,dz) { sp--; \
602 lz = stackLo[sp]; \
603 hz = stackHi[sp]; \
604 dz = stackD [sp]; }
605
606
607#define mnextsize(az) (nextHi[az]-nextLo[az])
608
609#define mnextswap(az,bz) \
610 { Int32 tz; \
611 tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
612 tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
613 tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
614
615
616#define MAIN_QSORT_SMALL_THRESH 20
617#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
618#define MAIN_QSORT_STACK_SIZE 100
619
620static
621void mainQSort3 ( UInt32* ptr,
622 UChar* block,
623 UInt16* quadrant,
624 Int32 nblock,
625 Int32 loSt,
626 Int32 hiSt,
627 Int32 dSt,
628 Int32* budget )
629{
630 Int32 unLo, unHi, ltLo, gtHi, n, m, med;
631 Int32 sp, lo, hi, d;
632
633 Int32 stackLo[MAIN_QSORT_STACK_SIZE];
634 Int32 stackHi[MAIN_QSORT_STACK_SIZE];
635 Int32 stackD [MAIN_QSORT_STACK_SIZE];
636
637 Int32 nextLo[3];
638 Int32 nextHi[3];
639 Int32 nextD [3];
640
641 sp = 0;
642 mpush ( loSt, hiSt, dSt );
643
644 while (sp > 0) {
645
646 AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 );
647
648 mpop ( lo, hi, d );
649 if (hi - lo < MAIN_QSORT_SMALL_THRESH ||
650 d > MAIN_QSORT_DEPTH_THRESH) {
651 mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
652 if (*budget < 0) return;
653 continue;
654 }
655
656 med = (Int32)
657 mmed3 ( block[ptr[ lo ]+d],
658 block[ptr[ hi ]+d],
659 block[ptr[ (lo+hi)>>1 ]+d] );
660
661 unLo = ltLo = lo;
662 unHi = gtHi = hi;
663
664 while (True) {
665 while (True) {
666 if (unLo > unHi) break;
667 n = ((Int32)block[ptr[unLo]+d]) - med;
668 if (n == 0) {
669 mswap(ptr[unLo], ptr[ltLo]);
670 ltLo++; unLo++; continue;
671 };
672 if (n > 0) break;
673 unLo++;
674 }
675 while (True) {
676 if (unLo > unHi) break;
677 n = ((Int32)block[ptr[unHi]+d]) - med;
678 if (n == 0) {
679 mswap(ptr[unHi], ptr[gtHi]);
680 gtHi--; unHi--; continue;
681 };
682 if (n < 0) break;
683 unHi--;
684 }
685 if (unLo > unHi) break;
686 mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
687 }
688
689 AssertD ( unHi == unLo-1, "mainQSort3(2)" );
690
691 if (gtHi < ltLo) {
692 mpush(lo, hi, d+1 );
693 continue;
694 }
695
696 n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
697 m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
698
699 n = lo + unLo - ltLo - 1;
700 m = hi - (gtHi - unHi) + 1;
701
702 nextLo[0] = lo; nextHi[0] = n; nextD[0] = d;
703 nextLo[1] = m; nextHi[1] = hi; nextD[1] = d;
704 nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
705
706 if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
707 if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
708 if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
709
710 AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
711 AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
712
713 mpush (nextLo[0], nextHi[0], nextD[0]);
714 mpush (nextLo[1], nextHi[1], nextD[1]);
715 mpush (nextLo[2], nextHi[2], nextD[2]);
716 }
717}
718
719#undef mswap
720#undef mvswap
721#undef mpush
722#undef mpop
723#undef mmin
724#undef mnextsize
725#undef mnextswap
726#undef MAIN_QSORT_SMALL_THRESH
727#undef MAIN_QSORT_DEPTH_THRESH
728#undef MAIN_QSORT_STACK_SIZE
729
730
731/*---------------------------------------------*/
732/* Pre:
733 nblock > N_OVERSHOOT
734 block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
735 ((UChar*)block32) [0 .. nblock-1] holds block
736 ptr exists for [0 .. nblock-1]
737
738 Post:
739 ((UChar*)block32) [0 .. nblock-1] holds block
740 All other areas of block32 destroyed
741 ftab [0 .. 65536 ] destroyed
742 ptr [0 .. nblock-1] holds sorted order
743 if (*budget < 0), sorting was abandoned
744*/
745
746#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
747#define SETMASK (1 << 21)
748#define CLEARMASK (~(SETMASK))
749
750static
751void mainSort ( UInt32* ptr,
752 UChar* block,
753 UInt16* quadrant,
754 UInt32* ftab,
755 Int32 nblock,
756 Int32 verb,
757 Int32* budget )
758{
759 Int32 i, j, k, ss, sb;
760 Int32 runningOrder[256];
761 Bool bigDone[256];
762 Int32 copyStart[256];
763 Int32 copyEnd [256];
764 UChar c1;
765 Int32 numQSorted;
766 UInt16 s;
767 if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" );
768
769 /*-- set up the 2-byte frequency table --*/
770 for (i = 65536; i >= 0; i--) ftab[i] = 0;
771
772 j = block[0] << 8;
773 i = nblock-1;
774 for (; i >= 3; i -= 4) {
775 quadrant[i] = 0;
776 j = (j >> 8) | ( ((UInt16)block[i]) << 8);
777 ftab[j]++;
778 quadrant[i-1] = 0;
779 j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
780 ftab[j]++;
781 quadrant[i-2] = 0;
782 j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
783 ftab[j]++;
784 quadrant[i-3] = 0;
785 j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
786 ftab[j]++;
787 }
788 for (; i >= 0; i--) {
789 quadrant[i] = 0;
790 j = (j >> 8) | ( ((UInt16)block[i]) << 8);
791 ftab[j]++;
792 }
793
794 /*-- (emphasises close relationship of block & quadrant) --*/
795 for (i = 0; i < BZ_N_OVERSHOOT; i++) {
796 block [nblock+i] = block[i];
797 quadrant[nblock+i] = 0;
798 }
799
800 if (verb >= 4) VPrintf0 ( " bucket sorting ...\n" );
801
802 /*-- Complete the initial radix sort --*/
803 for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
804
805 s = block[0] << 8;
806 i = nblock-1;
807 for (; i >= 3; i -= 4) {
808 s = (s >> 8) | (block[i] << 8);
809 j = ftab[s] -1;
810 ftab[s] = j;
811 ptr[j] = i;
812 s = (s >> 8) | (block[i-1] << 8);
813 j = ftab[s] -1;
814 ftab[s] = j;
815 ptr[j] = i-1;
816 s = (s >> 8) | (block[i-2] << 8);
817 j = ftab[s] -1;
818 ftab[s] = j;
819 ptr[j] = i-2;
820 s = (s >> 8) | (block[i-3] << 8);
821 j = ftab[s] -1;
822 ftab[s] = j;
823 ptr[j] = i-3;
824 }
825 for (; i >= 0; i--) {
826 s = (s >> 8) | (block[i] << 8);
827 j = ftab[s] -1;
828 ftab[s] = j;
829 ptr[j] = i;
830 }
831
832 /*--
833 Now ftab contains the first loc of every small bucket.
834 Calculate the running order, from smallest to largest
835 big bucket.
836 --*/
837 for (i = 0; i <= 255; i++) {
838 bigDone [i] = False;
839 runningOrder[i] = i;
840 }
841
842 {
843 Int32 vv;
844 Int32 h = 1;
845 do h = 3 * h + 1; while (h <= 256);
846 do {
847 h = h / 3;
848 for (i = h; i <= 255; i++) {
849 vv = runningOrder[i];
850 j = i;
851 while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
852 runningOrder[j] = runningOrder[j-h];
853 j = j - h;
854 if (j <= (h - 1)) goto zero;
855 }
856 zero:
857 runningOrder[j] = vv;
858 }
859 } while (h != 1);
860 }
861
862 /*--
863 The main sorting loop.
864 --*/
865
866 numQSorted = 0;
867
868 for (i = 0; i <= 255; i++) {
869
870 /*--
871 Process big buckets, starting with the least full.
872 Basically this is a 3-step process in which we call
873 mainQSort3 to sort the small buckets [ss, j], but
874 also make a big effort to avoid the calls if we can.
875 --*/
876 ss = runningOrder[i];
877
878 /*--
879 Step 1:
880 Complete the big bucket [ss] by quicksorting
881 any unsorted small buckets [ss, j], for j != ss.
882 Hopefully previous pointer-scanning phases have already
883 completed many of the small buckets [ss, j], so
884 we don't have to sort them at all.
885 --*/
886 for (j = 0; j <= 255; j++) {
887 if (j != ss) {
888 sb = (ss << 8) + j;
889 if ( ! (ftab[sb] & SETMASK) ) {
890 Int32 lo = ftab[sb] & CLEARMASK;
891 Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
892 if (hi > lo) {
893 if (verb >= 4)
894 VPrintf4 ( " qsort [0x%x, 0x%x] "
895 "done %d this %d\n",
896 ss, j, numQSorted, hi - lo + 1 );
897 mainQSort3 (
898 ptr, block, quadrant, nblock,
899 lo, hi, BZ_N_RADIX, budget
900 );
901 numQSorted += (hi - lo + 1);
902 if (*budget < 0) return;
903 }
904 }
905 ftab[sb] |= SETMASK;
906 }
907 }
908
909 AssertH ( !bigDone[ss], 1006 );
910
911 /*--
912 Step 2:
913 Now scan this big bucket [ss] so as to synthesise the
914 sorted order for small buckets [t, ss] for all t,
915 including, magically, the bucket [ss,ss] too.
916 This will avoid doing Real Work in subsequent Step 1's.
917 --*/
918 {
919 for (j = 0; j <= 255; j++) {
920 copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK;
921 copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
922 }
923 for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
924 k = ptr[j]-1; if (k < 0) k += nblock;
925 c1 = block[k];
926 if (!bigDone[c1])
927 ptr[ copyStart[c1]++ ] = k;
928 }
929 for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
930 k = ptr[j]-1; if (k < 0) k += nblock;
931 c1 = block[k];
932 if (!bigDone[c1])
933 ptr[ copyEnd[c1]-- ] = k;
934 }
935 }
936
937 AssertH ( (copyStart[ss]-1 == copyEnd[ss])
938 ||
939 /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
940 Necessity for this case is demonstrated by compressing
941 a sequence of approximately 48.5 million of character
942 251; 1.0.0/1.0.1 will then die here. */
943 (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
944 1007 )
945
946 for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
947
948 /*--
949 Step 3:
950 The [ss] big bucket is now done. Record this fact,
951 and update the quadrant descriptors. Remember to
952 update quadrants in the overshoot area too, if
953 necessary. The "if (i < 255)" test merely skips
954 this updating for the last bucket processed, since
955 updating for the last bucket is pointless.
956
957 The quadrant array provides a way to incrementally
958 cache sort orderings, as they appear, so as to
959 make subsequent comparisons in fullGtU() complete
960 faster. For repetitive blocks this makes a big
961 difference (but not big enough to be able to avoid
962 the fallback sorting mechanism, exponential radix sort).
963
964 The precise meaning is: at all times:
965
966 for 0 <= i < nblock and 0 <= j <= nblock
967
968 if block[i] != block[j],
969
970 then the relative values of quadrant[i] and
971 quadrant[j] are meaningless.
972
973 else {
974 if quadrant[i] < quadrant[j]
975 then the string starting at i lexicographically
976 precedes the string starting at j
977
978 else if quadrant[i] > quadrant[j]
979 then the string starting at j lexicographically
980 precedes the string starting at i
981
982 else
983 the relative ordering of the strings starting
984 at i and j has not yet been determined.
985 }
986 --*/
987 bigDone[ss] = True;
988
989 if (i < 255) {
990 Int32 bbStart = ftab[ss << 8] & CLEARMASK;
991 Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
992 Int32 shifts = 0;
993
994 while ((bbSize >> shifts) > 65534) shifts++;
995
996 for (j = bbSize-1; j >= 0; j--) {
997 Int32 a2update = ptr[bbStart + j];
998 UInt16 qVal = (UInt16)(j >> shifts);
999 quadrant[a2update] = qVal;
1000 if (a2update < BZ_N_OVERSHOOT)
1001 quadrant[a2update + nblock] = qVal;
1002 }
1003 AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
1004 }
1005
1006 }
1007
1008 if (verb >= 4)
1009 VPrintf3 ( " %d pointers, %d sorted, %d scanned\n",
1010 nblock, numQSorted, nblock - numQSorted );
1011}
1012
1013#undef BIGFREQ
1014#undef SETMASK
1015#undef CLEARMASK
1016
1017
1018/*---------------------------------------------*/
1019/* Pre:
1020 nblock > 0
1021 arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
1022 ((UChar*)arr2) [0 .. nblock-1] holds block
1023 arr1 exists for [0 .. nblock-1]
1024
1025 Post:
1026 ((UChar*)arr2) [0 .. nblock-1] holds block
1027 All other areas of block destroyed
1028 ftab [ 0 .. 65536 ] destroyed
1029 arr1 [0 .. nblock-1] holds sorted order
1030*/
1031void BZ2_blockSort ( EState* s )
1032{
1033 UInt32* ptr = s->ptr;
1034 UChar* block = s->block;
1035 UInt32* ftab = s->ftab;
1036 Int32 nblock = s->nblock;
1037 Int32 verb = s->verbosity;
1038 Int32 wfact = s->workFactor;
1039 UInt16* quadrant;
1040 Int32 budget;
1041 Int32 budgetInit;
1042 Int32 i;
1043
1044 if (nblock < 10000) {
1045 fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
1046 } else {
1047 /* Calculate the location for quadrant, remembering to get
1048 the alignment right. Assumes that &(block[0]) is at least
1049 2-byte aligned -- this should be ok since block is really
1050 the first section of arr2.
1051 */
1052 i = nblock+BZ_N_OVERSHOOT;
1053 if (i & 1) i++;
1054 quadrant = (UInt16*)(&(block[i]));
1055
1056 /* (wfact-1) / 3 puts the default-factor-30
1057 transition point at very roughly the same place as
1058 with v0.1 and v0.9.0.
1059 Not that it particularly matters any more, since the
1060 resulting compressed stream is now the same regardless
1061 of whether or not we use the main sort or fallback sort.
1062 */
1063 if (wfact < 1 ) wfact = 1;
1064 if (wfact > 100) wfact = 100;
1065 budgetInit = nblock * ((wfact-1) / 3);
1066 budget = budgetInit;
1067
1068 mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
1069 if (verb >= 3)
1070 VPrintf3 ( " %d work, %d block, ratio %5.2f\n",
1071 budgetInit - budget,
1072 nblock,
1073 (float)(budgetInit - budget) /
1074 (float)(nblock==0 ? 1 : nblock) );
1075 if (budget < 0) {
1076 if (verb >= 2)
1077 VPrintf0 ( " too repetitive; using fallback"
1078 " sorting algorithm\n" );
1079 fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
1080 }
1081 }
1082
1083 s->origPtr = -1;
1084 for (i = 0; i < s->nblock; i++)
1085 if (ptr[i] == 0)
1086 { s->origPtr = i; break; };
1087
1088 AssertH( s->origPtr != -1, 1003 );
1089}
1090
1091
1092/*-------------------------------------------------------------*/
1093/*--- end blocksort.c ---*/
1094/*-------------------------------------------------------------*/
diff --git a/utils/bzip2/bzlib.c b/utils/bzip2/bzlib.c
new file mode 100644
index 0000000000..6e78e19407
--- /dev/null
+++ b/utils/bzip2/bzlib.c
@@ -0,0 +1,1572 @@
1
2/*-------------------------------------------------------------*/
3/*--- Library top-level functions. ---*/
4/*--- bzlib.c ---*/
5/*-------------------------------------------------------------*/
6
7/* ------------------------------------------------------------------
8 This file is part of bzip2/libbzip2, a program and library for
9 lossless, block-sorting data compression.
10
11 bzip2/libbzip2 version 1.0.6 of 6 September 2010
12 Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
13
14 Please read the WARNING, DISCLAIMER and PATENTS sections in the
15 README file.
16
17 This program is released under the terms of the license contained
18 in the file LICENSE.
19 ------------------------------------------------------------------ */
20
21/* CHANGES
22 0.9.0 -- original version.
23 0.9.0a/b -- no changes in this file.
24 0.9.0c -- made zero-length BZ_FLUSH work correctly in bzCompress().
25 fixed bzWrite/bzRead to ignore zero-length requests.
26 fixed bzread to correctly handle read requests after EOF.
27 wrong parameter order in call to bzDecompressInit in
28 bzBuffToBuffDecompress. Fixed.
29*/
30
31#include "bzlib_private.h"
32
33
34/*---------------------------------------------------*/
35/*--- Compression stuff ---*/
36/*---------------------------------------------------*/
37
38
39/*---------------------------------------------------*/
40#ifndef BZ_NO_STDIO
41void BZ2_bz__AssertH__fail ( int errcode )
42{
43 fprintf(stderr,
44 "\n\nbzip2/libbzip2: internal error number %d.\n"
45 "This is a bug in bzip2/libbzip2, %s.\n"
46 "Please report it to me at: jseward@bzip.org. If this happened\n"
47 "when you were using some program which uses libbzip2 as a\n"
48 "component, you should also report this bug to the author(s)\n"
49 "of that program. Please make an effort to report this bug;\n"
50 "timely and accurate bug reports eventually lead to higher\n"
51 "quality software. Thanks. Julian Seward, 10 December 2007.\n\n",
52 errcode,
53 BZ2_bzlibVersion()
54 );
55
56 if (errcode == 1007) {
57 fprintf(stderr,
58 "\n*** A special note about internal error number 1007 ***\n"
59 "\n"
60 "Experience suggests that a common cause of i.e. 1007\n"
61 "is unreliable memory or other hardware. The 1007 assertion\n"
62 "just happens to cross-check the results of huge numbers of\n"
63 "memory reads/writes, and so acts (unintendedly) as a stress\n"
64 "test of your memory system.\n"
65 "\n"
66 "I suggest the following: try compressing the file again,\n"
67 "possibly monitoring progress in detail with the -vv flag.\n"
68 "\n"
69 "* If the error cannot be reproduced, and/or happens at different\n"
70 " points in compression, you may have a flaky memory system.\n"
71 " Try a memory-test program. I have used Memtest86\n"
72 " (www.memtest86.com). At the time of writing it is free (GPLd).\n"
73 " Memtest86 tests memory much more thorougly than your BIOSs\n"
74 " power-on test, and may find failures that the BIOS doesn't.\n"
75 "\n"
76 "* If the error can be repeatably reproduced, this is a bug in\n"
77 " bzip2, and I would very much like to hear about it. Please\n"
78 " let me know, and, ideally, save a copy of the file causing the\n"
79 " problem -- without which I will be unable to investigate it.\n"
80 "\n"
81 );
82 }
83
84 exit(3);
85}
86#endif
87
88
89/*---------------------------------------------------*/
90static
91int bz_config_ok ( void )
92{
93 if (sizeof(int) != 4) return 0;
94 if (sizeof(short) != 2) return 0;
95 if (sizeof(char) != 1) return 0;
96 return 1;
97}
98
99
100/*---------------------------------------------------*/
101static
102void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
103{
104 void* v = malloc ( items * size );
105 return v;
106}
107
108static
109void default_bzfree ( void* opaque, void* addr )
110{
111 if (addr != NULL) free ( addr );
112}
113
114
115/*---------------------------------------------------*/
116static
117void prepare_new_block ( EState* s )
118{
119 Int32 i;
120 s->nblock = 0;
121 s->numZ = 0;
122 s->state_out_pos = 0;
123 BZ_INITIALISE_CRC ( s->blockCRC );
124 for (i = 0; i < 256; i++) s->inUse[i] = False;
125 s->blockNo++;
126}
127
128
129/*---------------------------------------------------*/
130static
131void init_RL ( EState* s )
132{
133 s->state_in_ch = 256;
134 s->state_in_len = 0;
135}
136
137
138static
139Bool isempty_RL ( EState* s )
140{
141 if (s->state_in_ch < 256 && s->state_in_len > 0)
142 return False; else
143 return True;
144}
145
146
147/*---------------------------------------------------*/
148int BZ_API(BZ2_bzCompressInit)
149 ( bz_stream* strm,
150 int blockSize100k,
151 int verbosity,
152 int workFactor )
153{
154 Int32 n;
155 EState* s;
156
157 if (!bz_config_ok()) return BZ_CONFIG_ERROR;
158
159 if (strm == NULL ||
160 blockSize100k < 1 || blockSize100k > 9 ||
161 workFactor < 0 || workFactor > 250)
162 return BZ_PARAM_ERROR;
163
164 if (workFactor == 0) workFactor = 30;
165 if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
166 if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
167
168 s = BZALLOC( sizeof(EState) );
169 if (s == NULL) return BZ_MEM_ERROR;
170 s->strm = strm;
171
172 s->arr1 = NULL;
173 s->arr2 = NULL;
174 s->ftab = NULL;
175
176 n = 100000 * blockSize100k;
177 s->arr1 = BZALLOC( n * sizeof(UInt32) );
178 s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
179 s->ftab = BZALLOC( 65537 * sizeof(UInt32) );
180
181 if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
182 if (s->arr1 != NULL) BZFREE(s->arr1);
183 if (s->arr2 != NULL) BZFREE(s->arr2);
184 if (s->ftab != NULL) BZFREE(s->ftab);
185 if (s != NULL) BZFREE(s);
186 return BZ_MEM_ERROR;
187 }
188
189 s->blockNo = 0;
190 s->state = BZ_S_INPUT;
191 s->mode = BZ_M_RUNNING;
192 s->combinedCRC = 0;
193 s->blockSize100k = blockSize100k;
194 s->nblockMAX = 100000 * blockSize100k - 19;
195 s->verbosity = verbosity;
196 s->workFactor = workFactor;
197
198 s->block = (UChar*)s->arr2;
199 s->mtfv = (UInt16*)s->arr1;
200 s->zbits = NULL;
201 s->ptr = (UInt32*)s->arr1;
202
203 strm->state = s;
204 strm->total_in_lo32 = 0;
205 strm->total_in_hi32 = 0;
206 strm->total_out_lo32 = 0;
207 strm->total_out_hi32 = 0;
208 init_RL ( s );
209 prepare_new_block ( s );
210 return BZ_OK;
211}
212
213
214/*---------------------------------------------------*/
215static
216void add_pair_to_block ( EState* s )
217{
218 Int32 i;
219 UChar ch = (UChar)(s->state_in_ch);
220 for (i = 0; i < s->state_in_len; i++) {
221 BZ_UPDATE_CRC( s->blockCRC, ch );
222 }
223 s->inUse[s->state_in_ch] = True;
224 switch (s->state_in_len) {
225 case 1:
226 s->block[s->nblock] = (UChar)ch; s->nblock++;
227 break;
228 case 2:
229 s->block[s->nblock] = (UChar)ch; s->nblock++;
230 s->block[s->nblock] = (UChar)ch; s->nblock++;
231 break;
232 case 3:
233 s->block[s->nblock] = (UChar)ch; s->nblock++;
234 s->block[s->nblock] = (UChar)ch; s->nblock++;
235 s->block[s->nblock] = (UChar)ch; s->nblock++;
236 break;
237 default:
238 s->inUse[s->state_in_len-4] = True;
239 s->block[s->nblock] = (UChar)ch; s->nblock++;
240 s->block[s->nblock] = (UChar)ch; s->nblock++;
241 s->block[s->nblock] = (UChar)ch; s->nblock++;
242 s->block[s->nblock] = (UChar)ch; s->nblock++;
243 s->block[s->nblock] = ((UChar)(s->state_in_len-4));
244 s->nblock++;
245 break;
246 }
247}
248
249
250/*---------------------------------------------------*/
251static
252void flush_RL ( EState* s )
253{
254 if (s->state_in_ch < 256) add_pair_to_block ( s );
255 init_RL ( s );
256}
257
258
259/*---------------------------------------------------*/
260#define ADD_CHAR_TO_BLOCK(zs,zchh0) \
261{ \
262 UInt32 zchh = (UInt32)(zchh0); \
263 /*-- fast track the common case --*/ \
264 if (zchh != zs->state_in_ch && \
265 zs->state_in_len == 1) { \
266 UChar ch = (UChar)(zs->state_in_ch); \
267 BZ_UPDATE_CRC( zs->blockCRC, ch ); \
268 zs->inUse[zs->state_in_ch] = True; \
269 zs->block[zs->nblock] = (UChar)ch; \
270 zs->nblock++; \
271 zs->state_in_ch = zchh; \
272 } \
273 else \
274 /*-- general, uncommon cases --*/ \
275 if (zchh != zs->state_in_ch || \
276 zs->state_in_len == 255) { \
277 if (zs->state_in_ch < 256) \
278 add_pair_to_block ( zs ); \
279 zs->state_in_ch = zchh; \
280 zs->state_in_len = 1; \
281 } else { \
282 zs->state_in_len++; \
283 } \
284}
285
286
287/*---------------------------------------------------*/
288static
289Bool copy_input_until_stop ( EState* s )
290{
291 Bool progress_in = False;
292
293 if (s->mode == BZ_M_RUNNING) {
294
295 /*-- fast track the common case --*/
296 while (True) {
297 /*-- block full? --*/
298 if (s->nblock >= s->nblockMAX) break;
299 /*-- no input? --*/
300 if (s->strm->avail_in == 0) break;
301 progress_in = True;
302 ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
303 s->strm->next_in++;
304 s->strm->avail_in--;
305 s->strm->total_in_lo32++;
306 if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
307 }
308
309 } else {
310
311 /*-- general, uncommon case --*/
312 while (True) {
313 /*-- block full? --*/
314 if (s->nblock >= s->nblockMAX) break;
315 /*-- no input? --*/
316 if (s->strm->avail_in == 0) break;
317 /*-- flush/finish end? --*/
318 if (s->avail_in_expect == 0) break;
319 progress_in = True;
320 ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
321 s->strm->next_in++;
322 s->strm->avail_in--;
323 s->strm->total_in_lo32++;
324 if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
325 s->avail_in_expect--;
326 }
327 }
328 return progress_in;
329}
330
331
332/*---------------------------------------------------*/
333static
334Bool copy_output_until_stop ( EState* s )
335{
336 Bool progress_out = False;
337
338 while (True) {
339
340 /*-- no output space? --*/
341 if (s->strm->avail_out == 0) break;
342
343 /*-- block done? --*/
344 if (s->state_out_pos >= s->numZ) break;
345
346 progress_out = True;
347 *(s->strm->next_out) = s->zbits[s->state_out_pos];
348 s->state_out_pos++;
349 s->strm->avail_out--;
350 s->strm->next_out++;
351 s->strm->total_out_lo32++;
352 if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
353 }
354
355 return progress_out;
356}
357
358
359/*---------------------------------------------------*/
360static
361Bool handle_compress ( bz_stream* strm )
362{
363 Bool progress_in = False;
364 Bool progress_out = False;
365 EState* s = strm->state;
366
367 while (True) {
368
369 if (s->state == BZ_S_OUTPUT) {
370 progress_out |= copy_output_until_stop ( s );
371 if (s->state_out_pos < s->numZ) break;
372 if (s->mode == BZ_M_FINISHING &&
373 s->avail_in_expect == 0 &&
374 isempty_RL(s)) break;
375 prepare_new_block ( s );
376 s->state = BZ_S_INPUT;
377 if (s->mode == BZ_M_FLUSHING &&
378 s->avail_in_expect == 0 &&
379 isempty_RL(s)) break;
380 }
381
382 if (s->state == BZ_S_INPUT) {
383 progress_in |= copy_input_until_stop ( s );
384 if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
385 flush_RL ( s );
386 BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
387 s->state = BZ_S_OUTPUT;
388 }
389 else
390 if (s->nblock >= s->nblockMAX) {
391 BZ2_compressBlock ( s, False );
392 s->state = BZ_S_OUTPUT;
393 }
394 else
395 if (s->strm->avail_in == 0) {
396 break;
397 }
398 }
399
400 }
401
402 return progress_in || progress_out;
403}
404
405
406/*---------------------------------------------------*/
407int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
408{
409 Bool progress;
410 EState* s;
411 if (strm == NULL) return BZ_PARAM_ERROR;
412 s = strm->state;
413 if (s == NULL) return BZ_PARAM_ERROR;
414 if (s->strm != strm) return BZ_PARAM_ERROR;
415
416 preswitch:
417 switch (s->mode) {
418
419 case BZ_M_IDLE:
420 return BZ_SEQUENCE_ERROR;
421
422 case BZ_M_RUNNING:
423 if (action == BZ_RUN) {
424 progress = handle_compress ( strm );
425 return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
426 }
427 else
428 if (action == BZ_FLUSH) {
429 s->avail_in_expect = strm->avail_in;
430 s->mode = BZ_M_FLUSHING;
431 goto preswitch;
432 }
433 else
434 if (action == BZ_FINISH) {
435 s->avail_in_expect = strm->avail_in;
436 s->mode = BZ_M_FINISHING;
437 goto preswitch;
438 }
439 else
440 return BZ_PARAM_ERROR;
441
442 case BZ_M_FLUSHING:
443 if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
444 if (s->avail_in_expect != s->strm->avail_in)
445 return BZ_SEQUENCE_ERROR;
446 progress = handle_compress ( strm );
447 if (s->avail_in_expect > 0 || !isempty_RL(s) ||
448 s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
449 s->mode = BZ_M_RUNNING;
450 return BZ_RUN_OK;
451
452 case BZ_M_FINISHING:
453 if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
454 if (s->avail_in_expect != s->strm->avail_in)
455 return BZ_SEQUENCE_ERROR;
456 progress = handle_compress ( strm );
457 if (!progress) return BZ_SEQUENCE_ERROR;
458 if (s->avail_in_expect > 0 || !isempty_RL(s) ||
459 s->state_out_pos < s->numZ) return BZ_FINISH_OK;
460 s->mode = BZ_M_IDLE;
461 return BZ_STREAM_END;
462 }
463 return BZ_OK; /*--not reached--*/
464}
465
466
467/*---------------------------------------------------*/
468int BZ_API(BZ2_bzCompressEnd) ( bz_stream *strm )
469{
470 EState* s;
471 if (strm == NULL) return BZ_PARAM_ERROR;
472 s = strm->state;
473 if (s == NULL) return BZ_PARAM_ERROR;
474 if (s->strm != strm) return BZ_PARAM_ERROR;
475
476 if (s->arr1 != NULL) BZFREE(s->arr1);
477 if (s->arr2 != NULL) BZFREE(s->arr2);
478 if (s->ftab != NULL) BZFREE(s->ftab);
479 BZFREE(strm->state);
480
481 strm->state = NULL;
482
483 return BZ_OK;
484}
485
486
487/*---------------------------------------------------*/
488/*--- Decompression stuff ---*/
489/*---------------------------------------------------*/
490
491/*---------------------------------------------------*/
492int BZ_API(BZ2_bzDecompressInit)
493 ( bz_stream* strm,
494 int verbosity,
495 int small )
496{
497 DState* s;
498
499 if (!bz_config_ok()) return BZ_CONFIG_ERROR;
500
501 if (strm == NULL) return BZ_PARAM_ERROR;
502 if (small != 0 && small != 1) return BZ_PARAM_ERROR;
503 if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
504
505 if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
506 if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
507
508 s = BZALLOC( sizeof(DState) );
509 if (s == NULL) return BZ_MEM_ERROR;
510 s->strm = strm;
511 strm->state = s;
512 s->state = BZ_X_MAGIC_1;
513 s->bsLive = 0;
514 s->bsBuff = 0;
515 s->calculatedCombinedCRC = 0;
516 strm->total_in_lo32 = 0;
517 strm->total_in_hi32 = 0;
518 strm->total_out_lo32 = 0;
519 strm->total_out_hi32 = 0;
520 s->smallDecompress = (Bool)small;
521 s->ll4 = NULL;
522 s->ll16 = NULL;
523 s->tt = NULL;
524 s->currBlockNo = 0;
525 s->verbosity = verbosity;
526
527 return BZ_OK;
528}
529
530
531/*---------------------------------------------------*/
532/* Return True iff data corruption is discovered.
533 Returns False if there is no problem.
534*/
535static
536Bool unRLE_obuf_to_output_FAST ( DState* s )
537{
538 UChar k1;
539
540 if (s->blockRandomised) {
541
542 while (True) {
543 /* try to finish existing run */
544 while (True) {
545 if (s->strm->avail_out == 0) return False;
546 if (s->state_out_len == 0) break;
547 *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
548 BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
549 s->state_out_len--;
550 s->strm->next_out++;
551 s->strm->avail_out--;
552 s->strm->total_out_lo32++;
553 if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
554 }
555
556 /* can a new run be started? */
557 if (s->nblock_used == s->save_nblock+1) return False;
558
559 /* Only caused by corrupt data stream? */
560 if (s->nblock_used > s->save_nblock+1)
561 return True;
562
563 s->state_out_len = 1;
564 s->state_out_ch = s->k0;
565 BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
566 k1 ^= BZ_RAND_MASK; s->nblock_used++;
567 if (s->nblock_used == s->save_nblock+1) continue;
568 if (k1 != s->k0) { s->k0 = k1; continue; };
569
570 s->state_out_len = 2;
571 BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
572 k1 ^= BZ_RAND_MASK; s->nblock_used++;
573 if (s->nblock_used == s->save_nblock+1) continue;
574 if (k1 != s->k0) { s->k0 = k1; continue; };
575
576 s->state_out_len = 3;
577 BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
578 k1 ^= BZ_RAND_MASK; s->nblock_used++;
579 if (s->nblock_used == s->save_nblock+1) continue;
580 if (k1 != s->k0) { s->k0 = k1; continue; };
581
582 BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
583 k1 ^= BZ_RAND_MASK; s->nblock_used++;
584 s->state_out_len = ((Int32)k1) + 4;
585 BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
586 s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
587 }
588
589 } else {
590
591 /* restore */
592 UInt32 c_calculatedBlockCRC = s->calculatedBlockCRC;
593 UChar c_state_out_ch = s->state_out_ch;
594 Int32 c_state_out_len = s->state_out_len;
595 Int32 c_nblock_used = s->nblock_used;
596 Int32 c_k0 = s->k0;
597 UInt32* c_tt = s->tt;
598 UInt32 c_tPos = s->tPos;
599 char* cs_next_out = s->strm->next_out;
600 unsigned int cs_avail_out = s->strm->avail_out;
601 Int32 ro_blockSize100k = s->blockSize100k;
602 /* end restore */
603
604 UInt32 avail_out_INIT = cs_avail_out;
605 Int32 s_save_nblockPP = s->save_nblock+1;
606 unsigned int total_out_lo32_old;
607
608 while (True) {
609
610 /* try to finish existing run */
611 if (c_state_out_len > 0) {
612 while (True) {
613 if (cs_avail_out == 0) goto return_notr;
614 if (c_state_out_len == 1) break;
615 *( (UChar*)(cs_next_out) ) = c_state_out_ch;
616 BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
617 c_state_out_len--;
618 cs_next_out++;
619 cs_avail_out--;
620 }
621 s_state_out_len_eq_one:
622 {
623 if (cs_avail_out == 0) {
624 c_state_out_len = 1; goto return_notr;
625 };
626 *( (UChar*)(cs_next_out) ) = c_state_out_ch;
627 BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
628 cs_next_out++;
629 cs_avail_out--;
630 }
631 }
632 /* Only caused by corrupt data stream? */
633 if (c_nblock_used > s_save_nblockPP)
634 return True;
635
636 /* can a new run be started? */
637 if (c_nblock_used == s_save_nblockPP) {
638 c_state_out_len = 0; goto return_notr;
639 };
640 c_state_out_ch = c_k0;
641 BZ_GET_FAST_C(k1); c_nblock_used++;
642 if (k1 != c_k0) {
643 c_k0 = k1; goto s_state_out_len_eq_one;
644 };
645 if (c_nblock_used == s_save_nblockPP)
646 goto s_state_out_len_eq_one;
647
648 c_state_out_len = 2;
649 BZ_GET_FAST_C(k1); c_nblock_used++;
650 if (c_nblock_used == s_save_nblockPP) continue;
651 if (k1 != c_k0) { c_k0 = k1; continue; };
652
653 c_state_out_len = 3;
654 BZ_GET_FAST_C(k1); c_nblock_used++;
655 if (c_nblock_used == s_save_nblockPP) continue;
656 if (k1 != c_k0) { c_k0 = k1; continue; };
657
658 BZ_GET_FAST_C(k1); c_nblock_used++;
659 c_state_out_len = ((Int32)k1) + 4;
660 BZ_GET_FAST_C(c_k0); c_nblock_used++;
661 }
662
663 return_notr:
664 total_out_lo32_old = s->strm->total_out_lo32;
665 s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
666 if (s->strm->total_out_lo32 < total_out_lo32_old)
667 s->strm->total_out_hi32++;
668
669 /* save */
670 s->calculatedBlockCRC = c_calculatedBlockCRC;
671 s->state_out_ch = c_state_out_ch;
672 s->state_out_len = c_state_out_len;
673 s->nblock_used = c_nblock_used;
674 s->k0 = c_k0;
675 s->tt = c_tt;
676 s->tPos = c_tPos;
677 s->strm->next_out = cs_next_out;
678 s->strm->avail_out = cs_avail_out;
679 /* end save */
680 }
681 return False;
682}
683
684
685
686/*---------------------------------------------------*/
687__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
688{
689 Int32 nb, na, mid;
690 nb = 0;
691 na = 256;
692 do {
693 mid = (nb + na) >> 1;
694 if (indx >= cftab[mid]) nb = mid; else na = mid;
695 }
696 while (na - nb != 1);
697 return nb;
698}
699
700
701/*---------------------------------------------------*/
702/* Return True iff data corruption is discovered.
703 Returns False if there is no problem.
704*/
705static
706Bool unRLE_obuf_to_output_SMALL ( DState* s )
707{
708 UChar k1;
709
710 if (s->blockRandomised) {
711
712 while (True) {
713 /* try to finish existing run */
714 while (True) {
715 if (s->strm->avail_out == 0) return False;
716 if (s->state_out_len == 0) break;
717 *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
718 BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
719 s->state_out_len--;
720 s->strm->next_out++;
721 s->strm->avail_out--;
722 s->strm->total_out_lo32++;
723 if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
724 }
725
726 /* can a new run be started? */
727 if (s->nblock_used == s->save_nblock+1) return False;
728
729 /* Only caused by corrupt data stream? */
730 if (s->nblock_used > s->save_nblock+1)
731 return True;
732
733 s->state_out_len = 1;
734 s->state_out_ch = s->k0;
735 BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
736 k1 ^= BZ_RAND_MASK; s->nblock_used++;
737 if (s->nblock_used == s->save_nblock+1) continue;
738 if (k1 != s->k0) { s->k0 = k1; continue; };
739
740 s->state_out_len = 2;
741 BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
742 k1 ^= BZ_RAND_MASK; s->nblock_used++;
743 if (s->nblock_used == s->save_nblock+1) continue;
744 if (k1 != s->k0) { s->k0 = k1; continue; };
745
746 s->state_out_len = 3;
747 BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
748 k1 ^= BZ_RAND_MASK; s->nblock_used++;
749 if (s->nblock_used == s->save_nblock+1) continue;
750 if (k1 != s->k0) { s->k0 = k1; continue; };
751
752 BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
753 k1 ^= BZ_RAND_MASK; s->nblock_used++;
754 s->state_out_len = ((Int32)k1) + 4;
755 BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
756 s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
757 }
758
759 } else {
760
761 while (True) {
762 /* try to finish existing run */
763 while (True) {
764 if (s->strm->avail_out == 0) return False;
765 if (s->state_out_len == 0) break;
766 *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
767 BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
768 s->state_out_len--;
769 s->strm->next_out++;
770 s->strm->avail_out--;
771 s->strm->total_out_lo32++;
772 if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
773 }
774
775 /* can a new run be started? */
776 if (s->nblock_used == s->save_nblock+1) return False;
777
778 /* Only caused by corrupt data stream? */
779 if (s->nblock_used > s->save_nblock+1)
780 return True;
781
782 s->state_out_len = 1;
783 s->state_out_ch = s->k0;
784 BZ_GET_SMALL(k1); s->nblock_used++;
785 if (s->nblock_used == s->save_nblock+1) continue;
786 if (k1 != s->k0) { s->k0 = k1; continue; };
787
788 s->state_out_len = 2;
789 BZ_GET_SMALL(k1); s->nblock_used++;
790 if (s->nblock_used == s->save_nblock+1) continue;
791 if (k1 != s->k0) { s->k0 = k1; continue; };
792
793 s->state_out_len = 3;
794 BZ_GET_SMALL(k1); s->nblock_used++;
795 if (s->nblock_used == s->save_nblock+1) continue;
796 if (k1 != s->k0) { s->k0 = k1; continue; };
797
798 BZ_GET_SMALL(k1); s->nblock_used++;
799 s->state_out_len = ((Int32)k1) + 4;
800 BZ_GET_SMALL(s->k0); s->nblock_used++;
801 }
802
803 }
804}
805
806
807/*---------------------------------------------------*/
808int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
809{
810 Bool corrupt;
811 DState* s;
812 if (strm == NULL) return BZ_PARAM_ERROR;
813 s = strm->state;
814 if (s == NULL) return BZ_PARAM_ERROR;
815 if (s->strm != strm) return BZ_PARAM_ERROR;
816
817 while (True) {
818 if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
819 if (s->state == BZ_X_OUTPUT) {
820 if (s->smallDecompress)
821 corrupt = unRLE_obuf_to_output_SMALL ( s ); else
822 corrupt = unRLE_obuf_to_output_FAST ( s );
823 if (corrupt) return BZ_DATA_ERROR;
824 if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
825 BZ_FINALISE_CRC ( s->calculatedBlockCRC );
826 if (s->verbosity >= 3)
827 VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC,
828 s->calculatedBlockCRC );
829 if (s->verbosity >= 2) VPrintf0 ( "]" );
830 if (s->calculatedBlockCRC != s->storedBlockCRC)
831 return BZ_DATA_ERROR;
832 s->calculatedCombinedCRC
833 = (s->calculatedCombinedCRC << 1) |
834 (s->calculatedCombinedCRC >> 31);
835 s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
836 s->state = BZ_X_BLKHDR_1;
837 } else {
838 return BZ_OK;
839 }
840 }
841 if (s->state >= BZ_X_MAGIC_1) {
842 Int32 r = BZ2_decompress ( s );
843 if (r == BZ_STREAM_END) {
844 if (s->verbosity >= 3)
845 VPrintf2 ( "\n combined CRCs: stored = 0x%08x, computed = 0x%08x",
846 s->storedCombinedCRC, s->calculatedCombinedCRC );
847 if (s->calculatedCombinedCRC != s->storedCombinedCRC)
848 return BZ_DATA_ERROR;
849 return r;
850 }
851 if (s->state != BZ_X_OUTPUT) return r;
852 }
853 }
854
855 AssertH ( 0, 6001 );
856
857 return 0; /*NOTREACHED*/
858}
859
860
861/*---------------------------------------------------*/
862int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm )
863{
864 DState* s;
865 if (strm == NULL) return BZ_PARAM_ERROR;
866 s = strm->state;
867 if (s == NULL) return BZ_PARAM_ERROR;
868 if (s->strm != strm) return BZ_PARAM_ERROR;
869
870 if (s->tt != NULL) BZFREE(s->tt);
871 if (s->ll16 != NULL) BZFREE(s->ll16);
872 if (s->ll4 != NULL) BZFREE(s->ll4);
873
874 BZFREE(strm->state);
875 strm->state = NULL;
876
877 return BZ_OK;
878}
879
880
881#ifndef BZ_NO_STDIO
882/*---------------------------------------------------*/
883/*--- File I/O stuff ---*/
884/*---------------------------------------------------*/
885
886#define BZ_SETERR(eee) \
887{ \
888 if (bzerror != NULL) *bzerror = eee; \
889 if (bzf != NULL) bzf->lastErr = eee; \
890}
891
892typedef
893 struct {
894 FILE* handle;
895 Char buf[BZ_MAX_UNUSED];
896 Int32 bufN;
897 Bool writing;
898 bz_stream strm;
899 Int32 lastErr;
900 Bool initialisedOk;
901 }
902 bzFile;
903
904
905/*---------------------------------------------*/
906static Bool myfeof ( FILE* f )
907{
908 Int32 c = fgetc ( f );
909 if (c == EOF) return True;
910 ungetc ( c, f );
911 return False;
912}
913
914
915/*---------------------------------------------------*/
916BZFILE* BZ_API(BZ2_bzWriteOpen)
917 ( int* bzerror,
918 FILE* f,
919 int blockSize100k,
920 int verbosity,
921 int workFactor )
922{
923 Int32 ret;
924 bzFile* bzf = NULL;
925
926 BZ_SETERR(BZ_OK);
927
928 if (f == NULL ||
929 (blockSize100k < 1 || blockSize100k > 9) ||
930 (workFactor < 0 || workFactor > 250) ||
931 (verbosity < 0 || verbosity > 4))
932 { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
933
934 if (ferror(f))
935 { BZ_SETERR(BZ_IO_ERROR); return NULL; };
936
937 bzf = malloc ( sizeof(bzFile) );
938 if (bzf == NULL)
939 { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
940
941 BZ_SETERR(BZ_OK);
942 bzf->initialisedOk = False;
943 bzf->bufN = 0;
944 bzf->handle = f;
945 bzf->writing = True;
946 bzf->strm.bzalloc = NULL;
947 bzf->strm.bzfree = NULL;
948 bzf->strm.opaque = NULL;
949
950 if (workFactor == 0) workFactor = 30;
951 ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
952 verbosity, workFactor );
953 if (ret != BZ_OK)
954 { BZ_SETERR(ret); free(bzf); return NULL; };
955
956 bzf->strm.avail_in = 0;
957 bzf->initialisedOk = True;
958 return bzf;
959}
960
961
962
963/*---------------------------------------------------*/
964void BZ_API(BZ2_bzWrite)
965 ( int* bzerror,
966 BZFILE* b,
967 void* buf,
968 int len )
969{
970 Int32 n, n2, ret;
971 bzFile* bzf = (bzFile*)b;
972
973 BZ_SETERR(BZ_OK);
974 if (bzf == NULL || buf == NULL || len < 0)
975 { BZ_SETERR(BZ_PARAM_ERROR); return; };
976 if (!(bzf->writing))
977 { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
978 if (ferror(bzf->handle))
979 { BZ_SETERR(BZ_IO_ERROR); return; };
980
981 if (len == 0)
982 { BZ_SETERR(BZ_OK); return; };
983
984 bzf->strm.avail_in = len;
985 bzf->strm.next_in = buf;
986
987 while (True) {
988 bzf->strm.avail_out = BZ_MAX_UNUSED;
989 bzf->strm.next_out = bzf->buf;
990 ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
991 if (ret != BZ_RUN_OK)
992 { BZ_SETERR(ret); return; };
993
994 if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
995 n = BZ_MAX_UNUSED - bzf->strm.avail_out;
996 n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
997 n, bzf->handle );
998 if (n != n2 || ferror(bzf->handle))
999 { BZ_SETERR(BZ_IO_ERROR); return; };
1000 }
1001
1002 if (bzf->strm.avail_in == 0)
1003 { BZ_SETERR(BZ_OK); return; };
1004 }
1005}
1006
1007
1008/*---------------------------------------------------*/
1009void BZ_API(BZ2_bzWriteClose)
1010 ( int* bzerror,
1011 BZFILE* b,
1012 int abandon,
1013 unsigned int* nbytes_in,
1014 unsigned int* nbytes_out )
1015{
1016 BZ2_bzWriteClose64 ( bzerror, b, abandon,
1017 nbytes_in, NULL, nbytes_out, NULL );
1018}
1019
1020
1021void BZ_API(BZ2_bzWriteClose64)
1022 ( int* bzerror,
1023 BZFILE* b,
1024 int abandon,
1025 unsigned int* nbytes_in_lo32,
1026 unsigned int* nbytes_in_hi32,
1027 unsigned int* nbytes_out_lo32,
1028 unsigned int* nbytes_out_hi32 )
1029{
1030 Int32 n, n2, ret;
1031 bzFile* bzf = (bzFile*)b;
1032
1033 if (bzf == NULL)
1034 { BZ_SETERR(BZ_OK); return; };
1035 if (!(bzf->writing))
1036 { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
1037 if (ferror(bzf->handle))
1038 { BZ_SETERR(BZ_IO_ERROR); return; };
1039
1040 if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
1041 if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
1042 if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
1043 if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
1044
1045 if ((!abandon) && bzf->lastErr == BZ_OK) {
1046 while (True) {
1047 bzf->strm.avail_out = BZ_MAX_UNUSED;
1048 bzf->strm.next_out = bzf->buf;
1049 ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
1050 if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
1051 { BZ_SETERR(ret); return; };
1052
1053 if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
1054 n = BZ_MAX_UNUSED - bzf->strm.avail_out;
1055 n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
1056 n, bzf->handle );
1057 if (n != n2 || ferror(bzf->handle))
1058 { BZ_SETERR(BZ_IO_ERROR); return; };
1059 }
1060
1061 if (ret == BZ_STREAM_END) break;
1062 }
1063 }
1064
1065 if ( !abandon && !ferror ( bzf->handle ) ) {
1066 fflush ( bzf->handle );
1067 if (ferror(bzf->handle))
1068 { BZ_SETERR(BZ_IO_ERROR); return; };
1069 }
1070
1071 if (nbytes_in_lo32 != NULL)
1072 *nbytes_in_lo32 = bzf->strm.total_in_lo32;
1073 if (nbytes_in_hi32 != NULL)
1074 *nbytes_in_hi32 = bzf->strm.total_in_hi32;
1075 if (nbytes_out_lo32 != NULL)
1076 *nbytes_out_lo32 = bzf->strm.total_out_lo32;
1077 if (nbytes_out_hi32 != NULL)
1078 *nbytes_out_hi32 = bzf->strm.total_out_hi32;
1079
1080 BZ_SETERR(BZ_OK);
1081 BZ2_bzCompressEnd ( &(bzf->strm) );
1082 free ( bzf );
1083}
1084
1085
1086/*---------------------------------------------------*/
1087BZFILE* BZ_API(BZ2_bzReadOpen)
1088 ( int* bzerror,
1089 FILE* f,
1090 int verbosity,
1091 int small,
1092 void* unused,
1093 int nUnused )
1094{
1095 bzFile* bzf = NULL;
1096 int ret;
1097
1098 BZ_SETERR(BZ_OK);
1099
1100 if (f == NULL ||
1101 (small != 0 && small != 1) ||
1102 (verbosity < 0 || verbosity > 4) ||
1103 (unused == NULL && nUnused != 0) ||
1104 (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
1105 { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
1106
1107 if (ferror(f))
1108 { BZ_SETERR(BZ_IO_ERROR); return NULL; };
1109
1110 bzf = malloc ( sizeof(bzFile) );
1111 if (bzf == NULL)
1112 { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
1113
1114 BZ_SETERR(BZ_OK);
1115
1116 bzf->initialisedOk = False;
1117 bzf->handle = f;
1118 bzf->bufN = 0;
1119 bzf->writing = False;
1120 bzf->strm.bzalloc = NULL;
1121 bzf->strm.bzfree = NULL;
1122 bzf->strm.opaque = NULL;
1123
1124 while (nUnused > 0) {
1125 bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
1126 unused = ((void*)( 1 + ((UChar*)(unused)) ));
1127 nUnused--;
1128 }
1129
1130 ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
1131 if (ret != BZ_OK)
1132 { BZ_SETERR(ret); free(bzf); return NULL; };
1133
1134 bzf->strm.avail_in = bzf->bufN;
1135 bzf->strm.next_in = bzf->buf;
1136
1137 bzf->initialisedOk = True;
1138 return bzf;
1139}
1140
1141
1142/*---------------------------------------------------*/
1143void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
1144{
1145 bzFile* bzf = (bzFile*)b;
1146
1147 BZ_SETERR(BZ_OK);
1148 if (bzf == NULL)
1149 { BZ_SETERR(BZ_OK); return; };
1150
1151 if (bzf->writing)
1152 { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
1153
1154 if (bzf->initialisedOk)
1155 (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
1156 free ( bzf );
1157}
1158
1159
1160/*---------------------------------------------------*/
1161int BZ_API(BZ2_bzRead)
1162 ( int* bzerror,
1163 BZFILE* b,
1164 void* buf,
1165 int len )
1166{
1167 Int32 n, ret;
1168 bzFile* bzf = (bzFile*)b;
1169
1170 BZ_SETERR(BZ_OK);
1171
1172 if (bzf == NULL || buf == NULL || len < 0)
1173 { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
1174
1175 if (bzf->writing)
1176 { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
1177
1178 if (len == 0)
1179 { BZ_SETERR(BZ_OK); return 0; };
1180
1181 bzf->strm.avail_out = len;
1182 bzf->strm.next_out = buf;
1183
1184 while (True) {
1185
1186 if (ferror(bzf->handle))
1187 { BZ_SETERR(BZ_IO_ERROR); return 0; };
1188
1189 if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
1190 n = fread ( bzf->buf, sizeof(UChar),
1191 BZ_MAX_UNUSED, bzf->handle );
1192 if (ferror(bzf->handle))
1193 { BZ_SETERR(BZ_IO_ERROR); return 0; };
1194 bzf->bufN = n;
1195 bzf->strm.avail_in = bzf->bufN;
1196 bzf->strm.next_in = bzf->buf;
1197 }
1198
1199 ret = BZ2_bzDecompress ( &(bzf->strm) );
1200
1201 if (ret != BZ_OK && ret != BZ_STREAM_END)
1202 { BZ_SETERR(ret); return 0; };
1203
1204 if (ret == BZ_OK && myfeof(bzf->handle) &&
1205 bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
1206 { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
1207
1208 if (ret == BZ_STREAM_END)
1209 { BZ_SETERR(BZ_STREAM_END);
1210 return len - bzf->strm.avail_out; };
1211 if (bzf->strm.avail_out == 0)
1212 { BZ_SETERR(BZ_OK); return len; };
1213
1214 }
1215
1216 return 0; /*not reached*/
1217}
1218
1219
1220/*---------------------------------------------------*/
1221void BZ_API(BZ2_bzReadGetUnused)
1222 ( int* bzerror,
1223 BZFILE* b,
1224 void** unused,
1225 int* nUnused )
1226{
1227 bzFile* bzf = (bzFile*)b;
1228 if (bzf == NULL)
1229 { BZ_SETERR(BZ_PARAM_ERROR); return; };
1230 if (bzf->lastErr != BZ_STREAM_END)
1231 { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
1232 if (unused == NULL || nUnused == NULL)
1233 { BZ_SETERR(BZ_PARAM_ERROR); return; };
1234
1235 BZ_SETERR(BZ_OK);
1236 *nUnused = bzf->strm.avail_in;
1237 *unused = bzf->strm.next_in;
1238}
1239#endif
1240
1241
1242/*---------------------------------------------------*/
1243/*--- Misc convenience stuff ---*/
1244/*---------------------------------------------------*/
1245
1246/*---------------------------------------------------*/
1247int BZ_API(BZ2_bzBuffToBuffCompress)
1248 ( char* dest,
1249 unsigned int* destLen,
1250 char* source,
1251 unsigned int sourceLen,
1252 int blockSize100k,
1253 int verbosity,
1254 int workFactor )
1255{
1256 bz_stream strm;
1257 int ret;
1258
1259 if (dest == NULL || destLen == NULL ||
1260 source == NULL ||
1261 blockSize100k < 1 || blockSize100k > 9 ||
1262 verbosity < 0 || verbosity > 4 ||
1263 workFactor < 0 || workFactor > 250)
1264 return BZ_PARAM_ERROR;
1265
1266 if (workFactor == 0) workFactor = 30;
1267 strm.bzalloc = NULL;
1268 strm.bzfree = NULL;
1269 strm.opaque = NULL;
1270 ret = BZ2_bzCompressInit ( &strm, blockSize100k,
1271 verbosity, workFactor );
1272 if (ret != BZ_OK) return ret;
1273
1274 strm.next_in = source;
1275 strm.next_out = dest;
1276 strm.avail_in = sourceLen;
1277 strm.avail_out = *destLen;
1278
1279 ret = BZ2_bzCompress ( &strm, BZ_FINISH );
1280 if (ret == BZ_FINISH_OK) goto output_overflow;
1281 if (ret != BZ_STREAM_END) goto errhandler;
1282
1283 /* normal termination */
1284 *destLen -= strm.avail_out;
1285 BZ2_bzCompressEnd ( &strm );
1286 return BZ_OK;
1287
1288 output_overflow:
1289 BZ2_bzCompressEnd ( &strm );
1290 return BZ_OUTBUFF_FULL;
1291
1292 errhandler:
1293 BZ2_bzCompressEnd ( &strm );
1294 return ret;
1295}
1296
1297
1298/*---------------------------------------------------*/
1299int BZ_API(BZ2_bzBuffToBuffDecompress)
1300 ( char* dest,
1301 unsigned int* destLen,
1302 char* source,
1303 unsigned int sourceLen,
1304 int small,
1305 int verbosity )
1306{
1307 bz_stream strm;
1308 int ret;
1309
1310 if (dest == NULL || destLen == NULL ||
1311 source == NULL ||
1312 (small != 0 && small != 1) ||
1313 verbosity < 0 || verbosity > 4)
1314 return BZ_PARAM_ERROR;
1315
1316 strm.bzalloc = NULL;
1317 strm.bzfree = NULL;
1318 strm.opaque = NULL;
1319 ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
1320 if (ret != BZ_OK) return ret;
1321
1322 strm.next_in = source;
1323 strm.next_out = dest;
1324 strm.avail_in = sourceLen;
1325 strm.avail_out = *destLen;
1326
1327 ret = BZ2_bzDecompress ( &strm );
1328 if (ret == BZ_OK) goto output_overflow_or_eof;
1329 if (ret != BZ_STREAM_END) goto errhandler;
1330
1331 /* normal termination */
1332 *destLen -= strm.avail_out;
1333 BZ2_bzDecompressEnd ( &strm );
1334 return BZ_OK;
1335
1336 output_overflow_or_eof:
1337 if (strm.avail_out > 0) {
1338 BZ2_bzDecompressEnd ( &strm );
1339 return BZ_UNEXPECTED_EOF;
1340 } else {
1341 BZ2_bzDecompressEnd ( &strm );
1342 return BZ_OUTBUFF_FULL;
1343 };
1344
1345 errhandler:
1346 BZ2_bzDecompressEnd ( &strm );
1347 return ret;
1348}
1349
1350
1351/*---------------------------------------------------*/
1352/*--
1353 Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
1354 to support better zlib compatibility.
1355 This code is not _officially_ part of libbzip2 (yet);
1356 I haven't tested it, documented it, or considered the
1357 threading-safeness of it.
1358 If this code breaks, please contact both Yoshioka and me.
1359--*/
1360/*---------------------------------------------------*/
1361
1362/*---------------------------------------------------*/
1363/*--
1364 return version like "0.9.5d, 4-Sept-1999".
1365--*/
1366const char * BZ_API(BZ2_bzlibVersion)(void)
1367{
1368 return BZ_VERSION;
1369}
1370
1371
1372#ifndef BZ_NO_STDIO
1373/*---------------------------------------------------*/
1374
1375#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
1376# include <fcntl.h>
1377# include <io.h>
1378# define SET_BINARY_MODE(file) _setmode(_fileno(file),O_BINARY)
1379#else
1380# define SET_BINARY_MODE(file)
1381#endif
1382static
1383BZFILE * bzopen_or_bzdopen
1384 ( const char *path, /* no use when bzdopen */
1385 int fd, /* no use when bzdopen */
1386 const char *mode,
1387 int open_mode) /* bzopen: 0, bzdopen:1 */
1388{
1389 int bzerr;
1390 char unused[BZ_MAX_UNUSED];
1391 int blockSize100k = 9;
1392 int writing = 0;
1393 char mode2[10] = "";
1394 FILE *fp = NULL;
1395 BZFILE *bzfp = NULL;
1396 int verbosity = 0;
1397 int workFactor = 30;
1398 int smallMode = 0;
1399 int nUnused = 0;
1400
1401 if (mode == NULL) return NULL;
1402 while (*mode) {
1403 switch (*mode) {
1404 case 'r':
1405 writing = 0; break;
1406 case 'w':
1407 writing = 1; break;
1408 case 's':
1409 smallMode = 1; break;
1410 default:
1411 if (isdigit((int)(*mode))) {
1412 blockSize100k = *mode-BZ_HDR_0;
1413 }
1414 }
1415 mode++;
1416 }
1417 strcat(mode2, writing ? "w" : "r" );
1418 strcat(mode2,"b"); /* binary mode */
1419
1420 if (open_mode==0) {
1421 if (path==NULL || strcmp(path,"")==0) {
1422 fp = (writing ? stdout : stdin);
1423 SET_BINARY_MODE(fp);
1424 } else {
1425 fp = fopen(path,mode2);
1426 }
1427 } else {
1428#ifdef BZ_STRICT_ANSI
1429 fp = NULL;
1430#else
1431 fp = _fdopen(fd,mode2);
1432#endif
1433 }
1434 if (fp == NULL) return NULL;
1435
1436 if (writing) {
1437 /* Guard against total chaos and anarchy -- JRS */
1438 if (blockSize100k < 1) blockSize100k = 1;
1439 if (blockSize100k > 9) blockSize100k = 9;
1440 bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
1441 verbosity,workFactor);
1442 } else {
1443 bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
1444 unused,nUnused);
1445 }
1446 if (bzfp == NULL) {
1447 if (fp != stdin && fp != stdout) fclose(fp);
1448 return NULL;
1449 }
1450 return bzfp;
1451}
1452
1453
1454/*---------------------------------------------------*/
1455/*--
1456 open file for read or write.
1457 ex) bzopen("file","w9")
1458 case path="" or NULL => use stdin or stdout.
1459--*/
1460BZFILE * BZ_API(BZ2_bzopen)
1461 ( const char *path,
1462 const char *mode )
1463{
1464 return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
1465}
1466
1467
1468/*---------------------------------------------------*/
1469BZFILE * BZ_API(BZ2_bzdopen)
1470 ( int fd,
1471 const char *mode )
1472{
1473 return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
1474}
1475
1476
1477/*---------------------------------------------------*/
1478int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
1479{
1480 int bzerr, nread;
1481 if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
1482 nread = BZ2_bzRead(&bzerr,b,buf,len);
1483 if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
1484 return nread;
1485 } else {
1486 return -1;
1487 }
1488}
1489
1490
1491/*---------------------------------------------------*/
1492int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
1493{
1494 int bzerr;
1495
1496 BZ2_bzWrite(&bzerr,b,buf,len);
1497 if(bzerr == BZ_OK){
1498 return len;
1499 }else{
1500 return -1;
1501 }
1502}
1503
1504
1505/*---------------------------------------------------*/
1506int BZ_API(BZ2_bzflush) (BZFILE *b)
1507{
1508 /* do nothing now... */
1509 return 0;
1510}
1511
1512
1513/*---------------------------------------------------*/
1514void BZ_API(BZ2_bzclose) (BZFILE* b)
1515{
1516 int bzerr;
1517 FILE *fp;
1518
1519 if (b==NULL) {return;}
1520 fp = ((bzFile *)b)->handle;
1521 if(((bzFile*)b)->writing){
1522 BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
1523 if(bzerr != BZ_OK){
1524 BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
1525 }
1526 }else{
1527 BZ2_bzReadClose(&bzerr,b);
1528 }
1529 if(fp!=stdin && fp!=stdout){
1530 fclose(fp);
1531 }
1532}
1533
1534
1535/*---------------------------------------------------*/
1536/*--
1537 return last error code
1538--*/
1539static const char *bzerrorstrings[] = {
1540 "OK"
1541 ,"SEQUENCE_ERROR"
1542 ,"PARAM_ERROR"
1543 ,"MEM_ERROR"
1544 ,"DATA_ERROR"
1545 ,"DATA_ERROR_MAGIC"
1546 ,"IO_ERROR"
1547 ,"UNEXPECTED_EOF"
1548 ,"OUTBUFF_FULL"
1549 ,"CONFIG_ERROR"
1550 ,"???" /* for future */
1551 ,"???" /* for future */
1552 ,"???" /* for future */
1553 ,"???" /* for future */
1554 ,"???" /* for future */
1555 ,"???" /* for future */
1556};
1557
1558
1559const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
1560{
1561 int err = ((bzFile *)b)->lastErr;
1562
1563 if(err>0) err = 0;
1564 *errnum = err;
1565 return bzerrorstrings[err*-1];
1566}
1567#endif
1568
1569
1570/*-------------------------------------------------------------*/
1571/*--- end bzlib.c ---*/
1572/*-------------------------------------------------------------*/
diff --git a/utils/bzip2/bzlib.h b/utils/bzip2/bzlib.h
new file mode 100644
index 0000000000..8277123da8
--- /dev/null
+++ b/utils/bzip2/bzlib.h
@@ -0,0 +1,282 @@
1
2/*-------------------------------------------------------------*/
3/*--- Public header file for the library. ---*/
4/*--- bzlib.h ---*/
5/*-------------------------------------------------------------*/
6
7/* ------------------------------------------------------------------
8 This file is part of bzip2/libbzip2, a program and library for
9 lossless, block-sorting data compression.
10
11 bzip2/libbzip2 version 1.0.6 of 6 September 2010
12 Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
13
14 Please read the WARNING, DISCLAIMER and PATENTS sections in the
15 README file.
16
17 This program is released under the terms of the license contained
18 in the file LICENSE.
19 ------------------------------------------------------------------ */
20
21
22#ifndef _BZLIB_H
23#define _BZLIB_H
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29#define BZ_RUN 0
30#define BZ_FLUSH 1
31#define BZ_FINISH 2
32
33#define BZ_OK 0
34#define BZ_RUN_OK 1
35#define BZ_FLUSH_OK 2
36#define BZ_FINISH_OK 3
37#define BZ_STREAM_END 4
38#define BZ_SEQUENCE_ERROR (-1)
39#define BZ_PARAM_ERROR (-2)
40#define BZ_MEM_ERROR (-3)
41#define BZ_DATA_ERROR (-4)
42#define BZ_DATA_ERROR_MAGIC (-5)
43#define BZ_IO_ERROR (-6)
44#define BZ_UNEXPECTED_EOF (-7)
45#define BZ_OUTBUFF_FULL (-8)
46#define BZ_CONFIG_ERROR (-9)
47
48typedef
49 struct {
50 char *next_in;
51 unsigned int avail_in;
52 unsigned int total_in_lo32;
53 unsigned int total_in_hi32;
54
55 char *next_out;
56 unsigned int avail_out;
57 unsigned int total_out_lo32;
58 unsigned int total_out_hi32;
59
60 void *state;
61
62 void *(*bzalloc)(void *,int,int);
63 void (*bzfree)(void *,void *);
64 void *opaque;
65 }
66 bz_stream;
67
68
69#ifndef BZ_IMPORT
70#define BZ_EXPORT
71#endif
72
73#ifndef BZ_NO_STDIO
74/* Need a definitition for FILE */
75#include <stdio.h>
76#endif
77
78#ifdef _WIN32
79# include <windows.h>
80# ifdef small
81 /* windows.h define small to char */
82# undef small
83# endif
84# ifdef BZ_EXPORT
85# define BZ_API(func) WINAPI func
86# define BZ_EXTERN extern
87# else
88 /* import windows dll dynamically */
89# define BZ_API(func) (WINAPI * func)
90# define BZ_EXTERN
91# endif
92#else
93# define BZ_API(func) func
94# define BZ_EXTERN extern
95#endif
96
97
98/*-- Core (low-level) library functions --*/
99
100BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
101 bz_stream* strm,
102 int blockSize100k,
103 int verbosity,
104 int workFactor
105 );
106
107BZ_EXTERN int BZ_API(BZ2_bzCompress) (
108 bz_stream* strm,
109 int action
110 );
111
112BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
113 bz_stream* strm
114 );
115
116BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
117 bz_stream *strm,
118 int verbosity,
119 int small
120 );
121
122BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
123 bz_stream* strm
124 );
125
126BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
127 bz_stream *strm
128 );
129
130
131
132/*-- High(er) level library functions --*/
133
134#ifndef BZ_NO_STDIO
135#define BZ_MAX_UNUSED 5000
136
137typedef void BZFILE;
138
139BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
140 int* bzerror,
141 FILE* f,
142 int verbosity,
143 int small,
144 void* unused,
145 int nUnused
146 );
147
148BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
149 int* bzerror,
150 BZFILE* b
151 );
152
153BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
154 int* bzerror,
155 BZFILE* b,
156 void** unused,
157 int* nUnused
158 );
159
160BZ_EXTERN int BZ_API(BZ2_bzRead) (
161 int* bzerror,
162 BZFILE* b,
163 void* buf,
164 int len
165 );
166
167BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
168 int* bzerror,
169 FILE* f,
170 int blockSize100k,
171 int verbosity,
172 int workFactor
173 );
174
175BZ_EXTERN void BZ_API(BZ2_bzWrite) (
176 int* bzerror,
177 BZFILE* b,
178 void* buf,
179 int len
180 );
181
182BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
183 int* bzerror,
184 BZFILE* b,
185 int abandon,
186 unsigned int* nbytes_in,
187 unsigned int* nbytes_out
188 );
189
190BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
191 int* bzerror,
192 BZFILE* b,
193 int abandon,
194 unsigned int* nbytes_in_lo32,
195 unsigned int* nbytes_in_hi32,
196 unsigned int* nbytes_out_lo32,
197 unsigned int* nbytes_out_hi32
198 );
199#endif
200
201
202/*-- Utility functions --*/
203
204BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
205 char* dest,
206 unsigned int* destLen,
207 char* source,
208 unsigned int sourceLen,
209 int blockSize100k,
210 int verbosity,
211 int workFactor
212 );
213
214BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
215 char* dest,
216 unsigned int* destLen,
217 char* source,
218 unsigned int sourceLen,
219 int small,
220 int verbosity
221 );
222
223
224/*--
225 Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
226 to support better zlib compatibility.
227 This code is not _officially_ part of libbzip2 (yet);
228 I haven't tested it, documented it, or considered the
229 threading-safeness of it.
230 If this code breaks, please contact both Yoshioka and me.
231--*/
232
233BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
234 void
235 );
236
237#ifndef BZ_NO_STDIO
238BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
239 const char *path,
240 const char *mode
241 );
242
243BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
244 int fd,
245 const char *mode
246 );
247
248BZ_EXTERN int BZ_API(BZ2_bzread) (
249 BZFILE* b,
250 void* buf,
251 int len
252 );
253
254BZ_EXTERN int BZ_API(BZ2_bzwrite) (
255 BZFILE* b,
256 void* buf,
257 int len
258 );
259
260BZ_EXTERN int BZ_API(BZ2_bzflush) (
261 BZFILE* b
262 );
263
264BZ_EXTERN void BZ_API(BZ2_bzclose) (
265 BZFILE* b
266 );
267
268BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
269 BZFILE *b,
270 int *errnum
271 );
272#endif
273
274#ifdef __cplusplus
275}
276#endif
277
278#endif
279
280/*-------------------------------------------------------------*/
281/*--- end bzlib.h ---*/
282/*-------------------------------------------------------------*/
diff --git a/utils/bzip2/bzlib_private.h b/utils/bzip2/bzlib_private.h
new file mode 100644
index 0000000000..d2b1a97ccb
--- /dev/null
+++ b/utils/bzip2/bzlib_private.h
@@ -0,0 +1,512 @@
1
2/*-------------------------------------------------------------*/
3/*--- Private header file for the library. ---*/
4/*--- bzlib_private.h ---*/
5/*-------------------------------------------------------------*/
6
7/* ------------------------------------------------------------------
8 This file is part of bzip2/libbzip2, a program and library for
9 lossless, block-sorting data compression.
10
11 bzip2/libbzip2 version 1.0.6 of 6 September 2010
12 Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
13
14 Please read the WARNING, DISCLAIMER and PATENTS sections in the
15 README file.
16
17 This program is released under the terms of the license contained
18 in the file LICENSE.
19 ------------------------------------------------------------------ */
20
21
22#ifndef _BZLIB_PRIVATE_H
23#define _BZLIB_PRIVATE_H
24
25#include <stdlib.h>
26
27#ifndef BZ_NO_STDIO
28#include <stdio.h>
29#include <ctype.h>
30#include <string.h>
31#endif
32
33#include "bzlib.h"
34
35
36
37/*-- General stuff. --*/
38
39#define BZ_VERSION "1.0.6, 6-Sept-2010"
40
41typedef char Char;
42typedef unsigned char Bool;
43typedef unsigned char UChar;
44typedef int Int32;
45typedef unsigned int UInt32;
46typedef short Int16;
47typedef unsigned short UInt16;
48
49#define True ((Bool)1)
50#define False ((Bool)0)
51
52#ifndef __GNUC__
53#define __inline__ /* */
54#endif
55
56#ifndef BZ_NO_STDIO
57
58extern void BZ2_bz__AssertH__fail ( int errcode );
59#define AssertH(cond,errcode) \
60 { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
61
62#if BZ_DEBUG
63#define AssertD(cond,msg) \
64 { if (!(cond)) { \
65 fprintf ( stderr, \
66 "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
67 exit(1); \
68 }}
69#else
70#define AssertD(cond,msg) /* */
71#endif
72
73#define VPrintf0(zf) \
74 fprintf(stderr,zf)
75#define VPrintf1(zf,za1) \
76 fprintf(stderr,zf,za1)
77#define VPrintf2(zf,za1,za2) \
78 fprintf(stderr,zf,za1,za2)
79#define VPrintf3(zf,za1,za2,za3) \
80 fprintf(stderr,zf,za1,za2,za3)
81#define VPrintf4(zf,za1,za2,za3,za4) \
82 fprintf(stderr,zf,za1,za2,za3,za4)
83#define VPrintf5(zf,za1,za2,za3,za4,za5) \
84 fprintf(stderr,zf,za1,za2,za3,za4,za5)
85
86#else
87
88extern void bz_internal_error ( int errcode );
89#define AssertH(cond,errcode) \
90 { if (!(cond)) bz_internal_error ( errcode ); }
91#define AssertD(cond,msg) do { } while (0)
92#define VPrintf0(zf) do { } while (0)
93#define VPrintf1(zf,za1) do { } while (0)
94#define VPrintf2(zf,za1,za2) do { } while (0)
95#define VPrintf3(zf,za1,za2,za3) do { } while (0)
96#define VPrintf4(zf,za1,za2,za3,za4) do { } while (0)
97#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
98
99#endif
100
101
102#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
103#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp))
104
105
106/*-- Header bytes. --*/
107
108#define BZ_HDR_B 0x42 /* 'B' */
109#define BZ_HDR_Z 0x5a /* 'Z' */
110#define BZ_HDR_h 0x68 /* 'h' */
111#define BZ_HDR_0 0x30 /* '0' */
112
113/*-- Constants for the back end. --*/
114
115#define BZ_MAX_ALPHA_SIZE 258
116#define BZ_MAX_CODE_LEN 23
117
118#define BZ_RUNA 0
119#define BZ_RUNB 1
120
121#define BZ_N_GROUPS 6
122#define BZ_G_SIZE 50
123#define BZ_N_ITERS 4
124
125#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
126
127
128
129/*-- Stuff for randomising repetitive blocks. --*/
130
131extern Int32 BZ2_rNums[512];
132
133#define BZ_RAND_DECLS \
134 Int32 rNToGo; \
135 Int32 rTPos \
136
137#define BZ_RAND_INIT_MASK \
138 s->rNToGo = 0; \
139 s->rTPos = 0 \
140
141#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
142
143#define BZ_RAND_UPD_MASK \
144 if (s->rNToGo == 0) { \
145 s->rNToGo = BZ2_rNums[s->rTPos]; \
146 s->rTPos++; \
147 if (s->rTPos == 512) s->rTPos = 0; \
148 } \
149 s->rNToGo--;
150
151
152
153/*-- Stuff for doing CRCs. --*/
154
155extern UInt32 BZ2_crc32Table[256];
156
157#define BZ_INITIALISE_CRC(crcVar) \
158{ \
159 crcVar = 0xffffffffL; \
160}
161
162#define BZ_FINALISE_CRC(crcVar) \
163{ \
164 crcVar = ~(crcVar); \
165}
166
167#define BZ_UPDATE_CRC(crcVar,cha) \
168{ \
169 crcVar = (crcVar << 8) ^ \
170 BZ2_crc32Table[(crcVar >> 24) ^ \
171 ((UChar)cha)]; \
172}
173
174
175
176/*-- States and modes for compression. --*/
177
178#define BZ_M_IDLE 1
179#define BZ_M_RUNNING 2
180#define BZ_M_FLUSHING 3
181#define BZ_M_FINISHING 4
182
183#define BZ_S_OUTPUT 1
184#define BZ_S_INPUT 2
185
186#define BZ_N_RADIX 2
187#define BZ_N_QSORT 12
188#define BZ_N_SHELL 18
189#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
190
191
192
193
194/*-- Structure holding all the compression-side stuff. --*/
195
196typedef
197 struct {
198 /* pointer back to the struct bz_stream */
199 bz_stream* strm;
200
201 /* mode this stream is in, and whether inputting */
202 /* or outputting data */
203 Int32 mode;
204 Int32 state;
205
206 /* remembers avail_in when flush/finish requested */
207 UInt32 avail_in_expect;
208
209 /* for doing the block sorting */
210 UInt32* arr1;
211 UInt32* arr2;
212 UInt32* ftab;
213 Int32 origPtr;
214
215 /* aliases for arr1 and arr2 */
216 UInt32* ptr;
217 UChar* block;
218 UInt16* mtfv;
219 UChar* zbits;
220
221 /* for deciding when to use the fallback sorting algorithm */
222 Int32 workFactor;
223
224 /* run-length-encoding of the input */
225 UInt32 state_in_ch;
226 Int32 state_in_len;
227 BZ_RAND_DECLS;
228
229 /* input and output limits and current posns */
230 Int32 nblock;
231 Int32 nblockMAX;
232 Int32 numZ;
233 Int32 state_out_pos;
234
235 /* map of bytes used in block */
236 Int32 nInUse;
237 Bool inUse[256];
238 UChar unseqToSeq[256];
239
240 /* the buffer for bit stream creation */
241 UInt32 bsBuff;
242 Int32 bsLive;
243
244 /* block and combined CRCs */
245 UInt32 blockCRC;
246 UInt32 combinedCRC;
247
248 /* misc administratium */
249 Int32 verbosity;
250 Int32 blockNo;
251 Int32 blockSize100k;
252
253 /* stuff for coding the MTF values */
254 Int32 nMTF;
255 Int32 mtfFreq [BZ_MAX_ALPHA_SIZE];
256 UChar selector [BZ_MAX_SELECTORS];
257 UChar selectorMtf[BZ_MAX_SELECTORS];
258
259 UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
260 Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
261 Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
262 /* second dimension: only 3 needed; 4 makes index calculations faster */
263 UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
264
265 }
266 EState;
267
268
269
270/*-- externs for compression. --*/
271
272extern void
273BZ2_blockSort ( EState* );
274
275extern void
276BZ2_compressBlock ( EState*, Bool );
277
278extern void
279BZ2_bsInitWrite ( EState* );
280
281extern void
282BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
283
284extern void
285BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
286
287
288
289/*-- states for decompression. --*/
290
291#define BZ_X_IDLE 1
292#define BZ_X_OUTPUT 2
293
294#define BZ_X_MAGIC_1 10
295#define BZ_X_MAGIC_2 11
296#define BZ_X_MAGIC_3 12
297#define BZ_X_MAGIC_4 13
298#define BZ_X_BLKHDR_1 14
299#define BZ_X_BLKHDR_2 15
300#define BZ_X_BLKHDR_3 16
301#define BZ_X_BLKHDR_4 17
302#define BZ_X_BLKHDR_5 18
303#define BZ_X_BLKHDR_6 19
304#define BZ_X_BCRC_1 20
305#define BZ_X_BCRC_2 21
306#define BZ_X_BCRC_3 22
307#define BZ_X_BCRC_4 23
308#define BZ_X_RANDBIT 24
309#define BZ_X_ORIGPTR_1 25
310#define BZ_X_ORIGPTR_2 26
311#define BZ_X_ORIGPTR_3 27
312#define BZ_X_MAPPING_1 28
313#define BZ_X_MAPPING_2 29
314#define BZ_X_SELECTOR_1 30
315#define BZ_X_SELECTOR_2 31
316#define BZ_X_SELECTOR_3 32
317#define BZ_X_CODING_1 33
318#define BZ_X_CODING_2 34
319#define BZ_X_CODING_3 35
320#define BZ_X_MTF_1 36
321#define BZ_X_MTF_2 37
322#define BZ_X_MTF_3 38
323#define BZ_X_MTF_4 39
324#define BZ_X_MTF_5 40
325#define BZ_X_MTF_6 41
326#define BZ_X_ENDHDR_2 42
327#define BZ_X_ENDHDR_3 43
328#define BZ_X_ENDHDR_4 44
329#define BZ_X_ENDHDR_5 45
330#define BZ_X_ENDHDR_6 46
331#define BZ_X_CCRC_1 47
332#define BZ_X_CCRC_2 48
333#define BZ_X_CCRC_3 49
334#define BZ_X_CCRC_4 50
335
336
337
338/*-- Constants for the fast MTF decoder. --*/
339
340#define MTFA_SIZE 4096
341#define MTFL_SIZE 16
342
343
344
345/*-- Structure holding all the decompression-side stuff. --*/
346
347typedef
348 struct {
349 /* pointer back to the struct bz_stream */
350 bz_stream* strm;
351
352 /* state indicator for this stream */
353 Int32 state;
354
355 /* for doing the final run-length decoding */
356 UChar state_out_ch;
357 Int32 state_out_len;
358 Bool blockRandomised;
359 BZ_RAND_DECLS;
360
361 /* the buffer for bit stream reading */
362 UInt32 bsBuff;
363 Int32 bsLive;
364
365 /* misc administratium */
366 Int32 blockSize100k;
367 Bool smallDecompress;
368 Int32 currBlockNo;
369 Int32 verbosity;
370
371 /* for undoing the Burrows-Wheeler transform */
372 Int32 origPtr;
373 UInt32 tPos;
374 Int32 k0;
375 Int32 unzftab[256];
376 Int32 nblock_used;
377 Int32 cftab[257];
378 Int32 cftabCopy[257];
379
380 /* for undoing the Burrows-Wheeler transform (FAST) */
381 UInt32 *tt;
382
383 /* for undoing the Burrows-Wheeler transform (SMALL) */
384 UInt16 *ll16;
385 UChar *ll4;
386
387 /* stored and calculated CRCs */
388 UInt32 storedBlockCRC;
389 UInt32 storedCombinedCRC;
390 UInt32 calculatedBlockCRC;
391 UInt32 calculatedCombinedCRC;
392
393 /* map of bytes used in block */
394 Int32 nInUse;
395 Bool inUse[256];
396 Bool inUse16[16];
397 UChar seqToUnseq[256];
398
399 /* for decoding the MTF values */
400 UChar mtfa [MTFA_SIZE];
401 Int32 mtfbase[256 / MTFL_SIZE];
402 UChar selector [BZ_MAX_SELECTORS];
403 UChar selectorMtf[BZ_MAX_SELECTORS];
404 UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
405
406 Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
407 Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
408 Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
409 Int32 minLens[BZ_N_GROUPS];
410
411 /* save area for scalars in the main decompress code */
412 Int32 save_i;
413 Int32 save_j;
414 Int32 save_t;
415 Int32 save_alphaSize;
416 Int32 save_nGroups;
417 Int32 save_nSelectors;
418 Int32 save_EOB;
419 Int32 save_groupNo;
420 Int32 save_groupPos;
421 Int32 save_nextSym;
422 Int32 save_nblockMAX;
423 Int32 save_nblock;
424 Int32 save_es;
425 Int32 save_N;
426 Int32 save_curr;
427 Int32 save_zt;
428 Int32 save_zn;
429 Int32 save_zvec;
430 Int32 save_zj;
431 Int32 save_gSel;
432 Int32 save_gMinlen;
433 Int32* save_gLimit;
434 Int32* save_gBase;
435 Int32* save_gPerm;
436
437 }
438 DState;
439
440
441
442/*-- Macros for decompression. --*/
443
444#define BZ_GET_FAST(cccc) \
445 /* c_tPos is unsigned, hence test < 0 is pointless. */ \
446 if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
447 s->tPos = s->tt[s->tPos]; \
448 cccc = (UChar)(s->tPos & 0xff); \
449 s->tPos >>= 8;
450
451#define BZ_GET_FAST_C(cccc) \
452 /* c_tPos is unsigned, hence test < 0 is pointless. */ \
453 if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
454 c_tPos = c_tt[c_tPos]; \
455 cccc = (UChar)(c_tPos & 0xff); \
456 c_tPos >>= 8;
457
458#define SET_LL4(i,n) \
459 { if (((i) & 0x1) == 0) \
460 s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \
461 s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \
462 }
463
464#define GET_LL4(i) \
465 ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
466
467#define SET_LL(i,n) \
468 { s->ll16[i] = (UInt16)(n & 0x0000ffff); \
469 SET_LL4(i, n >> 16); \
470 }
471
472#define GET_LL(i) \
473 (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
474
475#define BZ_GET_SMALL(cccc) \
476 /* c_tPos is unsigned, hence test < 0 is pointless. */ \
477 if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
478 cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
479 s->tPos = GET_LL(s->tPos);
480
481
482/*-- externs for decompression. --*/
483
484extern Int32
485BZ2_indexIntoF ( Int32, Int32* );
486
487extern Int32
488BZ2_decompress ( DState* );
489
490extern void
491BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
492 Int32, Int32, Int32 );
493
494
495#endif
496
497
498/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
499
500#ifdef BZ_NO_STDIO
501#ifndef NULL
502#define NULL 0
503#endif
504#endif
505
506#ifndef WIN32
507#define _fdopen fdopen
508#endif
509
510/*-------------------------------------------------------------*/
511/*--- end bzlib_private.h ---*/
512/*-------------------------------------------------------------*/
diff --git a/utils/bzip2/compress.c b/utils/bzip2/compress.c
new file mode 100644
index 0000000000..caf7696011
--- /dev/null
+++ b/utils/bzip2/compress.c
@@ -0,0 +1,672 @@
1
2/*-------------------------------------------------------------*/
3/*--- Compression machinery (not incl block sorting) ---*/
4/*--- compress.c ---*/
5/*-------------------------------------------------------------*/
6
7/* ------------------------------------------------------------------
8 This file is part of bzip2/libbzip2, a program and library for
9 lossless, block-sorting data compression.
10
11 bzip2/libbzip2 version 1.0.6 of 6 September 2010
12 Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
13
14 Please read the WARNING, DISCLAIMER and PATENTS sections in the
15 README file.
16
17 This program is released under the terms of the license contained
18 in the file LICENSE.
19 ------------------------------------------------------------------ */
20
21
22/* CHANGES
23 0.9.0 -- original version.
24 0.9.0a/b -- no changes in this file.
25 0.9.0c -- changed setting of nGroups in sendMTFValues()
26 so as to do a bit better on small files
27*/
28
29#include "bzlib_private.h"
30
31
32/*---------------------------------------------------*/
33/*--- Bit stream I/O ---*/
34/*---------------------------------------------------*/
35
36/*---------------------------------------------------*/
37void BZ2_bsInitWrite ( EState* s )
38{
39 s->bsLive = 0;
40 s->bsBuff = 0;
41}
42
43
44/*---------------------------------------------------*/
45static
46void bsFinishWrite ( EState* s )
47{
48 while (s->bsLive > 0) {
49 s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
50 s->numZ++;
51 s->bsBuff <<= 8;
52 s->bsLive -= 8;
53 }
54}
55
56
57/*---------------------------------------------------*/
58#define bsNEEDW(nz) \
59{ \
60 while (s->bsLive >= 8) { \
61 s->zbits[s->numZ] \
62 = (UChar)(s->bsBuff >> 24); \
63 s->numZ++; \
64 s->bsBuff <<= 8; \
65 s->bsLive -= 8; \
66 } \
67}
68
69
70/*---------------------------------------------------*/
71static
72__inline__
73void bsW ( EState* s, Int32 n, UInt32 v )
74{
75 bsNEEDW ( n );
76 s->bsBuff |= (v << (32 - s->bsLive - n));
77 s->bsLive += n;
78}
79
80
81/*---------------------------------------------------*/
82static
83void bsPutUInt32 ( EState* s, UInt32 u )
84{
85 bsW ( s, 8, (u >> 24) & 0xffL );
86 bsW ( s, 8, (u >> 16) & 0xffL );
87 bsW ( s, 8, (u >> 8) & 0xffL );
88 bsW ( s, 8, u & 0xffL );
89}
90
91
92/*---------------------------------------------------*/
93static
94void bsPutUChar ( EState* s, UChar c )
95{
96 bsW( s, 8, (UInt32)c );
97}
98
99
100/*---------------------------------------------------*/
101/*--- The back end proper ---*/
102/*---------------------------------------------------*/
103
104/*---------------------------------------------------*/
105static
106void makeMaps_e ( EState* s )
107{
108 Int32 i;
109 s->nInUse = 0;
110 for (i = 0; i < 256; i++)
111 if (s->inUse[i]) {
112 s->unseqToSeq[i] = s->nInUse;
113 s->nInUse++;
114 }
115}
116
117
118/*---------------------------------------------------*/
119static
120void generateMTFValues ( EState* s )
121{
122 UChar yy[256];
123 Int32 i, j;
124 Int32 zPend;
125 Int32 wr;
126 Int32 EOB;
127
128 /*
129 After sorting (eg, here),
130 s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
131 and
132 ((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
133 holds the original block data.
134
135 The first thing to do is generate the MTF values,
136 and put them in
137 ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
138 Because there are strictly fewer or equal MTF values
139 than block values, ptr values in this area are overwritten
140 with MTF values only when they are no longer needed.
141
142 The final compressed bitstream is generated into the
143 area starting at
144 (UChar*) (&((UChar*)s->arr2)[s->nblock])
145
146 These storage aliases are set up in bzCompressInit(),
147 except for the last one, which is arranged in
148 compressBlock().
149 */
150 UInt32* ptr = s->ptr;
151 UChar* block = s->block;
152 UInt16* mtfv = s->mtfv;
153
154 makeMaps_e ( s );
155 EOB = s->nInUse+1;
156
157 for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
158
159 wr = 0;
160 zPend = 0;
161 for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
162
163 for (i = 0; i < s->nblock; i++) {
164 UChar ll_i;
165 AssertD ( wr <= i, "generateMTFValues(1)" );
166 j = ptr[i]-1; if (j < 0) j += s->nblock;
167 ll_i = s->unseqToSeq[block[j]];
168 AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
169
170 if (yy[0] == ll_i) {
171 zPend++;
172 } else {
173
174 if (zPend > 0) {
175 zPend--;
176 while (True) {
177 if (zPend & 1) {
178 mtfv[wr] = BZ_RUNB; wr++;
179 s->mtfFreq[BZ_RUNB]++;
180 } else {
181 mtfv[wr] = BZ_RUNA; wr++;
182 s->mtfFreq[BZ_RUNA]++;
183 }
184 if (zPend < 2) break;
185 zPend = (zPend - 2) / 2;
186 };
187 zPend = 0;
188 }
189 {
190 register UChar rtmp;
191 register UChar* ryy_j;
192 register UChar rll_i;
193 rtmp = yy[1];
194 yy[1] = yy[0];
195 ryy_j = &(yy[1]);
196 rll_i = ll_i;
197 while ( rll_i != rtmp ) {
198 register UChar rtmp2;
199 ryy_j++;
200 rtmp2 = rtmp;
201 rtmp = *ryy_j;
202 *ryy_j = rtmp2;
203 };
204 yy[0] = rtmp;
205 j = ryy_j - &(yy[0]);
206 mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
207 }
208
209 }
210 }
211
212 if (zPend > 0) {
213 zPend--;
214 while (True) {
215 if (zPend & 1) {
216 mtfv[wr] = BZ_RUNB; wr++;
217 s->mtfFreq[BZ_RUNB]++;
218 } else {
219 mtfv[wr] = BZ_RUNA; wr++;
220 s->mtfFreq[BZ_RUNA]++;
221 }
222 if (zPend < 2) break;
223 zPend = (zPend - 2) / 2;
224 };
225 zPend = 0;
226 }
227
228 mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
229
230 s->nMTF = wr;
231}
232
233
234/*---------------------------------------------------*/
235#define BZ_LESSER_ICOST 0
236#define BZ_GREATER_ICOST 15
237
238static
239void sendMTFValues ( EState* s )
240{
241 Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
242 Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
243 Int32 nGroups, nBytes;
244
245 /*--
246 UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
247 is a global since the decoder also needs it.
248
249 Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
250 Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
251 are also globals only used in this proc.
252 Made global to keep stack frame size small.
253 --*/
254
255
256 UInt16 cost[BZ_N_GROUPS];
257 Int32 fave[BZ_N_GROUPS];
258
259 UInt16* mtfv = s->mtfv;
260
261 if (s->verbosity >= 3)
262 VPrintf3( " %d in block, %d after MTF & 1-2 coding, "
263 "%d+2 syms in use\n",
264 s->nblock, s->nMTF, s->nInUse );
265
266 alphaSize = s->nInUse+2;
267 for (t = 0; t < BZ_N_GROUPS; t++)
268 for (v = 0; v < alphaSize; v++)
269 s->len[t][v] = BZ_GREATER_ICOST;
270
271 /*--- Decide how many coding tables to use ---*/
272 AssertH ( s->nMTF > 0, 3001 );
273 if (s->nMTF < 200) nGroups = 2; else
274 if (s->nMTF < 600) nGroups = 3; else
275 if (s->nMTF < 1200) nGroups = 4; else
276 if (s->nMTF < 2400) nGroups = 5; else
277 nGroups = 6;
278
279 /*--- Generate an initial set of coding tables ---*/
280 {
281 Int32 nPart, remF, tFreq, aFreq;
282
283 nPart = nGroups;
284 remF = s->nMTF;
285 gs = 0;
286 while (nPart > 0) {
287 tFreq = remF / nPart;
288 ge = gs-1;
289 aFreq = 0;
290 while (aFreq < tFreq && ge < alphaSize-1) {
291 ge++;
292 aFreq += s->mtfFreq[ge];
293 }
294
295 if (ge > gs
296 && nPart != nGroups && nPart != 1
297 && ((nGroups-nPart) % 2 == 1)) {
298 aFreq -= s->mtfFreq[ge];
299 ge--;
300 }
301
302 if (s->verbosity >= 3)
303 VPrintf5( " initial group %d, [%d .. %d], "
304 "has %d syms (%4.1f%%)\n",
305 nPart, gs, ge, aFreq,
306 (100.0 * (float)aFreq) / (float)(s->nMTF) );
307
308 for (v = 0; v < alphaSize; v++)
309 if (v >= gs && v <= ge)
310 s->len[nPart-1][v] = BZ_LESSER_ICOST; else
311 s->len[nPart-1][v] = BZ_GREATER_ICOST;
312
313 nPart--;
314 gs = ge+1;
315 remF -= aFreq;
316 }
317 }
318
319 /*---
320 Iterate up to BZ_N_ITERS times to improve the tables.
321 ---*/
322 for (iter = 0; iter < BZ_N_ITERS; iter++) {
323
324 for (t = 0; t < nGroups; t++) fave[t] = 0;
325
326 for (t = 0; t < nGroups; t++)
327 for (v = 0; v < alphaSize; v++)
328 s->rfreq[t][v] = 0;
329
330 /*---
331 Set up an auxiliary length table which is used to fast-track
332 the common case (nGroups == 6).
333 ---*/
334 if (nGroups == 6) {
335 for (v = 0; v < alphaSize; v++) {
336 s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
337 s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
338 s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
339 }
340 }
341
342 nSelectors = 0;
343 totc = 0;
344 gs = 0;
345 while (True) {
346
347 /*--- Set group start & end marks. --*/
348 if (gs >= s->nMTF) break;
349 ge = gs + BZ_G_SIZE - 1;
350 if (ge >= s->nMTF) ge = s->nMTF-1;
351
352 /*--
353 Calculate the cost of this group as coded
354 by each of the coding tables.
355 --*/
356 for (t = 0; t < nGroups; t++) cost[t] = 0;
357
358 if (nGroups == 6 && 50 == ge-gs+1) {
359 /*--- fast track the common case ---*/
360 register UInt32 cost01, cost23, cost45;
361 register UInt16 icv;
362 cost01 = cost23 = cost45 = 0;
363
364# define BZ_ITER(nn) \
365 icv = mtfv[gs+(nn)]; \
366 cost01 += s->len_pack[icv][0]; \
367 cost23 += s->len_pack[icv][1]; \
368 cost45 += s->len_pack[icv][2]; \
369
370 BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
371 BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
372 BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
373 BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
374 BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
375 BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
376 BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
377 BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
378 BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
379 BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
380
381# undef BZ_ITER
382
383 cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
384 cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
385 cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
386
387 } else {
388 /*--- slow version which correctly handles all situations ---*/
389 for (i = gs; i <= ge; i++) {
390 UInt16 icv = mtfv[i];
391 for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
392 }
393 }
394
395 /*--
396 Find the coding table which is best for this group,
397 and record its identity in the selector table.
398 --*/
399 bc = 999999999; bt = -1;
400 for (t = 0; t < nGroups; t++)
401 if (cost[t] < bc) { bc = cost[t]; bt = t; };
402 totc += bc;
403 fave[bt]++;
404 s->selector[nSelectors] = bt;
405 nSelectors++;
406
407 /*--
408 Increment the symbol frequencies for the selected table.
409 --*/
410 if (nGroups == 6 && 50 == ge-gs+1) {
411 /*--- fast track the common case ---*/
412
413# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
414
415 BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
416 BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
417 BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
418 BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
419 BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
420 BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
421 BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
422 BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
423 BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
424 BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
425
426# undef BZ_ITUR
427
428 } else {
429 /*--- slow version which correctly handles all situations ---*/
430 for (i = gs; i <= ge; i++)
431 s->rfreq[bt][ mtfv[i] ]++;
432 }
433
434 gs = ge+1;
435 }
436 if (s->verbosity >= 3) {
437 VPrintf2 ( " pass %d: size is %d, grp uses are ",
438 iter+1, totc/8 );
439 for (t = 0; t < nGroups; t++)
440 VPrintf1 ( "%d ", fave[t] );
441 VPrintf0 ( "\n" );
442 }
443
444 /*--
445 Recompute the tables based on the accumulated frequencies.
446 --*/
447 /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See
448 comment in huffman.c for details. */
449 for (t = 0; t < nGroups; t++)
450 BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
451 alphaSize, 17 /*20*/ );
452 }
453
454
455 AssertH( nGroups < 8, 3002 );
456 AssertH( nSelectors < 32768 &&
457 nSelectors <= (2 + (900000 / BZ_G_SIZE)),
458 3003 );
459
460
461 /*--- Compute MTF values for the selectors. ---*/
462 {
463 UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
464 for (i = 0; i < nGroups; i++) pos[i] = i;
465 for (i = 0; i < nSelectors; i++) {
466 ll_i = s->selector[i];
467 j = 0;
468 tmp = pos[j];
469 while ( ll_i != tmp ) {
470 j++;
471 tmp2 = tmp;
472 tmp = pos[j];
473 pos[j] = tmp2;
474 };
475 pos[0] = tmp;
476 s->selectorMtf[i] = j;
477 }
478 };
479
480 /*--- Assign actual codes for the tables. --*/
481 for (t = 0; t < nGroups; t++) {
482 minLen = 32;
483 maxLen = 0;
484 for (i = 0; i < alphaSize; i++) {
485 if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
486 if (s->len[t][i] < minLen) minLen = s->len[t][i];
487 }
488 AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
489 AssertH ( !(minLen < 1), 3005 );
490 BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
491 minLen, maxLen, alphaSize );
492 }
493
494 /*--- Transmit the mapping table. ---*/
495 {
496 Bool inUse16[16];
497 for (i = 0; i < 16; i++) {
498 inUse16[i] = False;
499 for (j = 0; j < 16; j++)
500 if (s->inUse[i * 16 + j]) inUse16[i] = True;
501 }
502
503 nBytes = s->numZ;
504 for (i = 0; i < 16; i++)
505 if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
506
507 for (i = 0; i < 16; i++)
508 if (inUse16[i])
509 for (j = 0; j < 16; j++) {
510 if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
511 }
512
513 if (s->verbosity >= 3)
514 VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes );
515 }
516
517 /*--- Now the selectors. ---*/
518 nBytes = s->numZ;
519 bsW ( s, 3, nGroups );
520 bsW ( s, 15, nSelectors );
521 for (i = 0; i < nSelectors; i++) {
522 for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
523 bsW(s,1,0);
524 }
525 if (s->verbosity >= 3)
526 VPrintf1( "selectors %d, ", s->numZ-nBytes );
527
528 /*--- Now the coding tables. ---*/
529 nBytes = s->numZ;
530
531 for (t = 0; t < nGroups; t++) {
532 Int32 curr = s->len[t][0];
533 bsW ( s, 5, curr );
534 for (i = 0; i < alphaSize; i++) {
535 while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
536 while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
537 bsW ( s, 1, 0 );
538 }
539 }
540
541 if (s->verbosity >= 3)
542 VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
543
544 /*--- And finally, the block data proper ---*/
545 nBytes = s->numZ;
546 selCtr = 0;
547 gs = 0;
548 while (True) {
549 if (gs >= s->nMTF) break;
550 ge = gs + BZ_G_SIZE - 1;
551 if (ge >= s->nMTF) ge = s->nMTF-1;
552 AssertH ( s->selector[selCtr] < nGroups, 3006 );
553
554 if (nGroups == 6 && 50 == ge-gs+1) {
555 /*--- fast track the common case ---*/
556 UInt16 mtfv_i;
557 UChar* s_len_sel_selCtr
558 = &(s->len[s->selector[selCtr]][0]);
559 Int32* s_code_sel_selCtr
560 = &(s->code[s->selector[selCtr]][0]);
561
562# define BZ_ITAH(nn) \
563 mtfv_i = mtfv[gs+(nn)]; \
564 bsW ( s, \
565 s_len_sel_selCtr[mtfv_i], \
566 s_code_sel_selCtr[mtfv_i] )
567
568 BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
569 BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
570 BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
571 BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
572 BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
573 BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
574 BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
575 BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
576 BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
577 BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
578
579# undef BZ_ITAH
580
581 } else {
582 /*--- slow version which correctly handles all situations ---*/
583 for (i = gs; i <= ge; i++) {
584 bsW ( s,
585 s->len [s->selector[selCtr]] [mtfv[i]],
586 s->code [s->selector[selCtr]] [mtfv[i]] );
587 }
588 }
589
590
591 gs = ge+1;
592 selCtr++;
593 }
594 AssertH( selCtr == nSelectors, 3007 );
595
596 if (s->verbosity >= 3)
597 VPrintf1( "codes %d\n", s->numZ-nBytes );
598}
599
600
601/*---------------------------------------------------*/
602void BZ2_compressBlock ( EState* s, Bool is_last_block )
603{
604 if (s->nblock > 0) {
605
606 BZ_FINALISE_CRC ( s->blockCRC );
607 s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
608 s->combinedCRC ^= s->blockCRC;
609 if (s->blockNo > 1) s->numZ = 0;
610
611 if (s->verbosity >= 2)
612 VPrintf4( " block %d: crc = 0x%08x, "
613 "combined CRC = 0x%08x, size = %d\n",
614 s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
615
616 BZ2_blockSort ( s );
617 }
618
619 s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
620
621 /*-- If this is the first block, create the stream header. --*/
622 if (s->blockNo == 1) {
623 BZ2_bsInitWrite ( s );
624 bsPutUChar ( s, BZ_HDR_B );
625 bsPutUChar ( s, BZ_HDR_Z );
626 bsPutUChar ( s, BZ_HDR_h );
627 bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
628 }
629
630 if (s->nblock > 0) {
631
632 bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
633 bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
634 bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
635
636 /*-- Now the block's CRC, so it is in a known place. --*/
637 bsPutUInt32 ( s, s->blockCRC );
638
639 /*--
640 Now a single bit indicating (non-)randomisation.
641 As of version 0.9.5, we use a better sorting algorithm
642 which makes randomisation unnecessary. So always set
643 the randomised bit to 'no'. Of course, the decoder
644 still needs to be able to handle randomised blocks
645 so as to maintain backwards compatibility with
646 older versions of bzip2.
647 --*/
648 bsW(s,1,0);
649
650 bsW ( s, 24, s->origPtr );
651 generateMTFValues ( s );
652 sendMTFValues ( s );
653 }
654
655
656 /*-- If this is the last block, add the stream trailer. --*/
657 if (is_last_block) {
658
659 bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
660 bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
661 bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
662 bsPutUInt32 ( s, s->combinedCRC );
663 if (s->verbosity >= 2)
664 VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC );
665 bsFinishWrite ( s );
666 }
667}
668
669
670/*-------------------------------------------------------------*/
671/*--- end compress.c ---*/
672/*-------------------------------------------------------------*/
diff --git a/utils/bzip2/crctable.c b/utils/bzip2/crctable.c
new file mode 100644
index 0000000000..1fea7e946c
--- /dev/null
+++ b/utils/bzip2/crctable.c
@@ -0,0 +1,104 @@
1
2/*-------------------------------------------------------------*/
3/*--- Table for doing CRCs ---*/
4/*--- crctable.c ---*/
5/*-------------------------------------------------------------*/
6
7/* ------------------------------------------------------------------
8 This file is part of bzip2/libbzip2, a program and library for
9 lossless, block-sorting data compression.
10
11 bzip2/libbzip2 version 1.0.6 of 6 September 2010
12 Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
13
14 Please read the WARNING, DISCLAIMER and PATENTS sections in the
15 README file.
16
17 This program is released under the terms of the license contained
18 in the file LICENSE.
19 ------------------------------------------------------------------ */
20
21
22#include "bzlib_private.h"
23
24/*--
25 I think this is an implementation of the AUTODIN-II,
26 Ethernet & FDDI 32-bit CRC standard. Vaguely derived
27 from code by Rob Warnock, in Section 51 of the
28 comp.compression FAQ.
29--*/
30
31UInt32 BZ2_crc32Table[256] = {
32
33 /*-- Ugly, innit? --*/
34
35 0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
36 0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
37 0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
38 0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
39 0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
40 0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
41 0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
42 0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
43 0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
44 0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
45 0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
46 0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
47 0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
48 0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
49 0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
50 0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
51 0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
52 0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
53 0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
54 0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
55 0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
56 0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
57 0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
58 0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
59 0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
60 0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
61 0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
62 0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
63 0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
64 0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
65 0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
66 0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
67 0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
68 0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
69 0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
70 0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
71 0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
72 0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
73 0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
74 0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
75 0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
76 0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
77 0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
78 0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
79 0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
80 0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
81 0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
82 0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
83 0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
84 0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
85 0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
86 0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
87 0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
88 0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
89 0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
90 0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
91 0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
92 0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
93 0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
94 0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
95 0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
96 0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
97 0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
98 0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
99};
100
101
102/*-------------------------------------------------------------*/
103/*--- end crctable.c ---*/
104/*-------------------------------------------------------------*/
diff --git a/utils/bzip2/decompress.c b/utils/bzip2/decompress.c
new file mode 100644
index 0000000000..311f5668f9
--- /dev/null
+++ b/utils/bzip2/decompress.c
@@ -0,0 +1,646 @@
1
2/*-------------------------------------------------------------*/
3/*--- Decompression machinery ---*/
4/*--- decompress.c ---*/
5/*-------------------------------------------------------------*/
6
7/* ------------------------------------------------------------------
8 This file is part of bzip2/libbzip2, a program and library for
9 lossless, block-sorting data compression.
10
11 bzip2/libbzip2 version 1.0.6 of 6 September 2010
12 Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
13
14 Please read the WARNING, DISCLAIMER and PATENTS sections in the
15 README file.
16
17 This program is released under the terms of the license contained
18 in the file LICENSE.
19 ------------------------------------------------------------------ */
20
21
22#include "bzlib_private.h"
23
24
25/*---------------------------------------------------*/
26static
27void makeMaps_d ( DState* s )
28{
29 Int32 i;
30 s->nInUse = 0;
31 for (i = 0; i < 256; i++)
32 if (s->inUse[i]) {
33 s->seqToUnseq[s->nInUse] = i;
34 s->nInUse++;
35 }
36}
37
38
39/*---------------------------------------------------*/
40#define RETURN(rrr) \
41 { retVal = rrr; goto save_state_and_return; };
42
43#define GET_BITS(lll,vvv,nnn) \
44 case lll: s->state = lll; \
45 while (True) { \
46 if (s->bsLive >= nnn) { \
47 UInt32 v; \
48 v = (s->bsBuff >> \
49 (s->bsLive-nnn)) & ((1 << nnn)-1); \
50 s->bsLive -= nnn; \
51 vvv = v; \
52 break; \
53 } \
54 if (s->strm->avail_in == 0) RETURN(BZ_OK); \
55 s->bsBuff \
56 = (s->bsBuff << 8) | \
57 ((UInt32) \
58 (*((UChar*)(s->strm->next_in)))); \
59 s->bsLive += 8; \
60 s->strm->next_in++; \
61 s->strm->avail_in--; \
62 s->strm->total_in_lo32++; \
63 if (s->strm->total_in_lo32 == 0) \
64 s->strm->total_in_hi32++; \
65 }
66
67#define GET_UCHAR(lll,uuu) \
68 GET_BITS(lll,uuu,8)
69
70#define GET_BIT(lll,uuu) \
71 GET_BITS(lll,uuu,1)
72
73/*---------------------------------------------------*/
74#define GET_MTF_VAL(label1,label2,lval) \
75{ \
76 if (groupPos == 0) { \
77 groupNo++; \
78 if (groupNo >= nSelectors) \
79 RETURN(BZ_DATA_ERROR); \
80 groupPos = BZ_G_SIZE; \
81 gSel = s->selector[groupNo]; \
82 gMinlen = s->minLens[gSel]; \
83 gLimit = &(s->limit[gSel][0]); \
84 gPerm = &(s->perm[gSel][0]); \
85 gBase = &(s->base[gSel][0]); \
86 } \
87 groupPos--; \
88 zn = gMinlen; \
89 GET_BITS(label1, zvec, zn); \
90 while (1) { \
91 if (zn > 20 /* the longest code */) \
92 RETURN(BZ_DATA_ERROR); \
93 if (zvec <= gLimit[zn]) break; \
94 zn++; \
95 GET_BIT(label2, zj); \
96 zvec = (zvec << 1) | zj; \
97 }; \
98 if (zvec - gBase[zn] < 0 \
99 || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
100 RETURN(BZ_DATA_ERROR); \
101 lval = gPerm[zvec - gBase[zn]]; \
102}
103
104
105/*---------------------------------------------------*/
106Int32 BZ2_decompress ( DState* s )
107{
108 UChar uc;
109 Int32 retVal;
110 Int32 minLen, maxLen;
111 bz_stream* strm = s->strm;
112
113 /* stuff that needs to be saved/restored */
114 Int32 i;
115 Int32 j;
116 Int32 t;
117 Int32 alphaSize;
118 Int32 nGroups;
119 Int32 nSelectors;
120 Int32 EOB;
121 Int32 groupNo;
122 Int32 groupPos;
123 Int32 nextSym;
124 Int32 nblockMAX;
125 Int32 nblock;
126 Int32 es;
127 Int32 N;
128 Int32 curr;
129 Int32 zt;
130 Int32 zn;
131 Int32 zvec;
132 Int32 zj;
133 Int32 gSel;
134 Int32 gMinlen;
135 Int32* gLimit;
136 Int32* gBase;
137 Int32* gPerm;
138
139 if (s->state == BZ_X_MAGIC_1) {
140 /*initialise the save area*/
141 s->save_i = 0;
142 s->save_j = 0;
143 s->save_t = 0;
144 s->save_alphaSize = 0;
145 s->save_nGroups = 0;
146 s->save_nSelectors = 0;
147 s->save_EOB = 0;
148 s->save_groupNo = 0;
149 s->save_groupPos = 0;
150 s->save_nextSym = 0;
151 s->save_nblockMAX = 0;
152 s->save_nblock = 0;
153 s->save_es = 0;
154 s->save_N = 0;
155 s->save_curr = 0;
156 s->save_zt = 0;
157 s->save_zn = 0;
158 s->save_zvec = 0;
159 s->save_zj = 0;
160 s->save_gSel = 0;
161 s->save_gMinlen = 0;
162 s->save_gLimit = NULL;
163 s->save_gBase = NULL;
164 s->save_gPerm = NULL;
165 }
166
167 /*restore from the save area*/
168 i = s->save_i;
169 j = s->save_j;
170 t = s->save_t;
171 alphaSize = s->save_alphaSize;
172 nGroups = s->save_nGroups;
173 nSelectors = s->save_nSelectors;
174 EOB = s->save_EOB;
175 groupNo = s->save_groupNo;
176 groupPos = s->save_groupPos;
177 nextSym = s->save_nextSym;
178 nblockMAX = s->save_nblockMAX;
179 nblock = s->save_nblock;
180 es = s->save_es;
181 N = s->save_N;
182 curr = s->save_curr;
183 zt = s->save_zt;
184 zn = s->save_zn;
185 zvec = s->save_zvec;
186 zj = s->save_zj;
187 gSel = s->save_gSel;
188 gMinlen = s->save_gMinlen;
189 gLimit = s->save_gLimit;
190 gBase = s->save_gBase;
191 gPerm = s->save_gPerm;
192
193 retVal = BZ_OK;
194
195 switch (s->state) {
196
197 GET_UCHAR(BZ_X_MAGIC_1, uc);
198 if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
199
200 GET_UCHAR(BZ_X_MAGIC_2, uc);
201 if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
202
203 GET_UCHAR(BZ_X_MAGIC_3, uc)
204 if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
205
206 GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
207 if (s->blockSize100k < (BZ_HDR_0 + 1) ||
208 s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
209 s->blockSize100k -= BZ_HDR_0;
210
211 if (s->smallDecompress) {
212 s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
213 s->ll4 = BZALLOC(
214 ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
215 );
216 if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
217 } else {
218 s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
219 if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
220 }
221
222 GET_UCHAR(BZ_X_BLKHDR_1, uc);
223
224 if (uc == 0x17) goto endhdr_2;
225 if (uc != 0x31) RETURN(BZ_DATA_ERROR);
226 GET_UCHAR(BZ_X_BLKHDR_2, uc);
227 if (uc != 0x41) RETURN(BZ_DATA_ERROR);
228 GET_UCHAR(BZ_X_BLKHDR_3, uc);
229 if (uc != 0x59) RETURN(BZ_DATA_ERROR);
230 GET_UCHAR(BZ_X_BLKHDR_4, uc);
231 if (uc != 0x26) RETURN(BZ_DATA_ERROR);
232 GET_UCHAR(BZ_X_BLKHDR_5, uc);
233 if (uc != 0x53) RETURN(BZ_DATA_ERROR);
234 GET_UCHAR(BZ_X_BLKHDR_6, uc);
235 if (uc != 0x59) RETURN(BZ_DATA_ERROR);
236
237 s->currBlockNo++;
238 if (s->verbosity >= 2)
239 VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
240
241 s->storedBlockCRC = 0;
242 GET_UCHAR(BZ_X_BCRC_1, uc);
243 s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
244 GET_UCHAR(BZ_X_BCRC_2, uc);
245 s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
246 GET_UCHAR(BZ_X_BCRC_3, uc);
247 s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
248 GET_UCHAR(BZ_X_BCRC_4, uc);
249 s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
250
251 GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
252
253 s->origPtr = 0;
254 GET_UCHAR(BZ_X_ORIGPTR_1, uc);
255 s->origPtr = (s->origPtr << 8) | ((Int32)uc);
256 GET_UCHAR(BZ_X_ORIGPTR_2, uc);
257 s->origPtr = (s->origPtr << 8) | ((Int32)uc);
258 GET_UCHAR(BZ_X_ORIGPTR_3, uc);
259 s->origPtr = (s->origPtr << 8) | ((Int32)uc);
260
261 if (s->origPtr < 0)
262 RETURN(BZ_DATA_ERROR);
263 if (s->origPtr > 10 + 100000*s->blockSize100k)
264 RETURN(BZ_DATA_ERROR);
265
266 /*--- Receive the mapping table ---*/
267 for (i = 0; i < 16; i++) {
268 GET_BIT(BZ_X_MAPPING_1, uc);
269 if (uc == 1)
270 s->inUse16[i] = True; else
271 s->inUse16[i] = False;
272 }
273
274 for (i = 0; i < 256; i++) s->inUse[i] = False;
275
276 for (i = 0; i < 16; i++)
277 if (s->inUse16[i])
278 for (j = 0; j < 16; j++) {
279 GET_BIT(BZ_X_MAPPING_2, uc);
280 if (uc == 1) s->inUse[i * 16 + j] = True;
281 }
282 makeMaps_d ( s );
283 if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
284 alphaSize = s->nInUse+2;
285
286 /*--- Now the selectors ---*/
287 GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
288 if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
289 GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
290 if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
291 for (i = 0; i < nSelectors; i++) {
292 j = 0;
293 while (True) {
294 GET_BIT(BZ_X_SELECTOR_3, uc);
295 if (uc == 0) break;
296 j++;
297 if (j >= nGroups) RETURN(BZ_DATA_ERROR);
298 }
299 s->selectorMtf[i] = j;
300 }
301
302 /*--- Undo the MTF values for the selectors. ---*/
303 {
304 UChar pos[BZ_N_GROUPS], tmp, v;
305 for (v = 0; v < nGroups; v++) pos[v] = v;
306
307 for (i = 0; i < nSelectors; i++) {
308 v = s->selectorMtf[i];
309 tmp = pos[v];
310 while (v > 0) { pos[v] = pos[v-1]; v--; }
311 pos[0] = tmp;
312 s->selector[i] = tmp;
313 }
314 }
315
316 /*--- Now the coding tables ---*/
317 for (t = 0; t < nGroups; t++) {
318 GET_BITS(BZ_X_CODING_1, curr, 5);
319 for (i = 0; i < alphaSize; i++) {
320 while (True) {
321 if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
322 GET_BIT(BZ_X_CODING_2, uc);
323 if (uc == 0) break;
324 GET_BIT(BZ_X_CODING_3, uc);
325 if (uc == 0) curr++; else curr--;
326 }
327 s->len[t][i] = curr;
328 }
329 }
330
331 /*--- Create the Huffman decoding tables ---*/
332 for (t = 0; t < nGroups; t++) {
333 minLen = 32;
334 maxLen = 0;
335 for (i = 0; i < alphaSize; i++) {
336 if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
337 if (s->len[t][i] < minLen) minLen = s->len[t][i];
338 }
339 BZ2_hbCreateDecodeTables (
340 &(s->limit[t][0]),
341 &(s->base[t][0]),
342 &(s->perm[t][0]),
343 &(s->len[t][0]),
344 minLen, maxLen, alphaSize
345 );
346 s->minLens[t] = minLen;
347 }
348
349 /*--- Now the MTF values ---*/
350
351 EOB = s->nInUse+1;
352 nblockMAX = 100000 * s->blockSize100k;
353 groupNo = -1;
354 groupPos = 0;
355
356 for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
357
358 /*-- MTF init --*/
359 {
360 Int32 ii, jj, kk;
361 kk = MTFA_SIZE-1;
362 for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
363 for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
364 s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
365 kk--;
366 }
367 s->mtfbase[ii] = kk + 1;
368 }
369 }
370 /*-- end MTF init --*/
371
372 nblock = 0;
373 GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
374
375 while (True) {
376
377 if (nextSym == EOB) break;
378
379 if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
380
381 es = -1;
382 N = 1;
383 do {
384 /* Check that N doesn't get too big, so that es doesn't
385 go negative. The maximum value that can be
386 RUNA/RUNB encoded is equal to the block size (post
387 the initial RLE), viz, 900k, so bounding N at 2
388 million should guard against overflow without
389 rejecting any legitimate inputs. */
390 if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
391 if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
392 if (nextSym == BZ_RUNB) es = es + (1+1) * N;
393 N = N * 2;
394 GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
395 }
396 while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
397
398 es++;
399 uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
400 s->unzftab[uc] += es;
401
402 if (s->smallDecompress)
403 while (es > 0) {
404 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
405 s->ll16[nblock] = (UInt16)uc;
406 nblock++;
407 es--;
408 }
409 else
410 while (es > 0) {
411 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
412 s->tt[nblock] = (UInt32)uc;
413 nblock++;
414 es--;
415 };
416
417 continue;
418
419 } else {
420
421 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
422
423 /*-- uc = MTF ( nextSym-1 ) --*/
424 {
425 Int32 ii, jj, kk, pp, lno, off;
426 UInt32 nn;
427 nn = (UInt32)(nextSym - 1);
428
429 if (nn < MTFL_SIZE) {
430 /* avoid general-case expense */
431 pp = s->mtfbase[0];
432 uc = s->mtfa[pp+nn];
433 while (nn > 3) {
434 Int32 z = pp+nn;
435 s->mtfa[(z) ] = s->mtfa[(z)-1];
436 s->mtfa[(z)-1] = s->mtfa[(z)-2];
437 s->mtfa[(z)-2] = s->mtfa[(z)-3];
438 s->mtfa[(z)-3] = s->mtfa[(z)-4];
439 nn -= 4;
440 }
441 while (nn > 0) {
442 s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
443 };
444 s->mtfa[pp] = uc;
445 } else {
446 /* general case */
447 lno = nn / MTFL_SIZE;
448 off = nn % MTFL_SIZE;
449 pp = s->mtfbase[lno] + off;
450 uc = s->mtfa[pp];
451 while (pp > s->mtfbase[lno]) {
452 s->mtfa[pp] = s->mtfa[pp-1]; pp--;
453 };
454 s->mtfbase[lno]++;
455 while (lno > 0) {
456 s->mtfbase[lno]--;
457 s->mtfa[s->mtfbase[lno]]
458 = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
459 lno--;
460 }
461 s->mtfbase[0]--;
462 s->mtfa[s->mtfbase[0]] = uc;
463 if (s->mtfbase[0] == 0) {
464 kk = MTFA_SIZE-1;
465 for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
466 for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
467 s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
468 kk--;
469 }
470 s->mtfbase[ii] = kk + 1;
471 }
472 }
473 }
474 }
475 /*-- end uc = MTF ( nextSym-1 ) --*/
476
477 s->unzftab[s->seqToUnseq[uc]]++;
478 if (s->smallDecompress)
479 s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
480 s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
481 nblock++;
482
483 GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
484 continue;
485 }
486 }
487
488 /* Now we know what nblock is, we can do a better sanity
489 check on s->origPtr.
490 */
491 if (s->origPtr < 0 || s->origPtr >= nblock)
492 RETURN(BZ_DATA_ERROR);
493
494 /*-- Set up cftab to facilitate generation of T^(-1) --*/
495 /* Check: unzftab entries in range. */
496 for (i = 0; i <= 255; i++) {
497 if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
498 RETURN(BZ_DATA_ERROR);
499 }
500 /* Actually generate cftab. */
501 s->cftab[0] = 0;
502 for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
503 for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
504 /* Check: cftab entries in range. */
505 for (i = 0; i <= 256; i++) {
506 if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
507 /* s->cftab[i] can legitimately be == nblock */
508 RETURN(BZ_DATA_ERROR);
509 }
510 }
511 /* Check: cftab entries non-descending. */
512 for (i = 1; i <= 256; i++) {
513 if (s->cftab[i-1] > s->cftab[i]) {
514 RETURN(BZ_DATA_ERROR);
515 }
516 }
517
518 s->state_out_len = 0;
519 s->state_out_ch = 0;
520 BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
521 s->state = BZ_X_OUTPUT;
522 if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
523
524 if (s->smallDecompress) {
525
526 /*-- Make a copy of cftab, used in generation of T --*/
527 for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
528
529 /*-- compute the T vector --*/
530 for (i = 0; i < nblock; i++) {
531 uc = (UChar)(s->ll16[i]);
532 SET_LL(i, s->cftabCopy[uc]);
533 s->cftabCopy[uc]++;
534 }
535
536 /*-- Compute T^(-1) by pointer reversal on T --*/
537 i = s->origPtr;
538 j = GET_LL(i);
539 do {
540 Int32 tmp = GET_LL(j);
541 SET_LL(j, i);
542 i = j;
543 j = tmp;
544 }
545 while (i != s->origPtr);
546
547 s->tPos = s->origPtr;
548 s->nblock_used = 0;
549 if (s->blockRandomised) {
550 BZ_RAND_INIT_MASK;
551 BZ_GET_SMALL(s->k0); s->nblock_used++;
552 BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
553 } else {
554 BZ_GET_SMALL(s->k0); s->nblock_used++;
555 }
556
557 } else {
558
559 /*-- compute the T^(-1) vector --*/
560 for (i = 0; i < nblock; i++) {
561 uc = (UChar)(s->tt[i] & 0xff);
562 s->tt[s->cftab[uc]] |= (i << 8);
563 s->cftab[uc]++;
564 }
565
566 s->tPos = s->tt[s->origPtr] >> 8;
567 s->nblock_used = 0;
568 if (s->blockRandomised) {
569 BZ_RAND_INIT_MASK;
570 BZ_GET_FAST(s->k0); s->nblock_used++;
571 BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
572 } else {
573 BZ_GET_FAST(s->k0); s->nblock_used++;
574 }
575
576 }
577
578 RETURN(BZ_OK);
579
580
581
582 endhdr_2:
583
584 GET_UCHAR(BZ_X_ENDHDR_2, uc);
585 if (uc != 0x72) RETURN(BZ_DATA_ERROR);
586 GET_UCHAR(BZ_X_ENDHDR_3, uc);
587 if (uc != 0x45) RETURN(BZ_DATA_ERROR);
588 GET_UCHAR(BZ_X_ENDHDR_4, uc);
589 if (uc != 0x38) RETURN(BZ_DATA_ERROR);
590 GET_UCHAR(BZ_X_ENDHDR_5, uc);
591 if (uc != 0x50) RETURN(BZ_DATA_ERROR);
592 GET_UCHAR(BZ_X_ENDHDR_6, uc);
593 if (uc != 0x90) RETURN(BZ_DATA_ERROR);
594
595 s->storedCombinedCRC = 0;
596 GET_UCHAR(BZ_X_CCRC_1, uc);
597 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
598 GET_UCHAR(BZ_X_CCRC_2, uc);
599 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
600 GET_UCHAR(BZ_X_CCRC_3, uc);
601 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
602 GET_UCHAR(BZ_X_CCRC_4, uc);
603 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
604
605 s->state = BZ_X_IDLE;
606 RETURN(BZ_STREAM_END);
607
608 default: AssertH ( False, 4001 );
609 }
610
611 AssertH ( False, 4002 );
612
613 save_state_and_return:
614
615 s->save_i = i;
616 s->save_j = j;
617 s->save_t = t;
618 s->save_alphaSize = alphaSize;
619 s->save_nGroups = nGroups;
620 s->save_nSelectors = nSelectors;
621 s->save_EOB = EOB;
622 s->save_groupNo = groupNo;
623 s->save_groupPos = groupPos;
624 s->save_nextSym = nextSym;
625 s->save_nblockMAX = nblockMAX;
626 s->save_nblock = nblock;
627 s->save_es = es;
628 s->save_N = N;
629 s->save_curr = curr;
630 s->save_zt = zt;
631 s->save_zn = zn;
632 s->save_zvec = zvec;
633 s->save_zj = zj;
634 s->save_gSel = gSel;
635 s->save_gMinlen = gMinlen;
636 s->save_gLimit = gLimit;
637 s->save_gBase = gBase;
638 s->save_gPerm = gPerm;
639
640 return retVal;
641}
642
643
644/*-------------------------------------------------------------*/
645/*--- end decompress.c ---*/
646/*-------------------------------------------------------------*/
diff --git a/utils/bzip2/huffman.c b/utils/bzip2/huffman.c
new file mode 100644
index 0000000000..2283fdbc5a
--- /dev/null
+++ b/utils/bzip2/huffman.c
@@ -0,0 +1,205 @@
1
2/*-------------------------------------------------------------*/
3/*--- Huffman coding low-level stuff ---*/
4/*--- huffman.c ---*/
5/*-------------------------------------------------------------*/
6
7/* ------------------------------------------------------------------
8 This file is part of bzip2/libbzip2, a program and library for
9 lossless, block-sorting data compression.
10
11 bzip2/libbzip2 version 1.0.6 of 6 September 2010
12 Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
13
14 Please read the WARNING, DISCLAIMER and PATENTS sections in the
15 README file.
16
17 This program is released under the terms of the license contained
18 in the file LICENSE.
19 ------------------------------------------------------------------ */
20
21
22#include "bzlib_private.h"
23
24/*---------------------------------------------------*/
25#define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
26#define DEPTHOF(zz1) ((zz1) & 0x000000ff)
27#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
28
29#define ADDWEIGHTS(zw1,zw2) \
30 (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
31 (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
32
33#define UPHEAP(z) \
34{ \
35 Int32 zz, tmp; \
36 zz = z; tmp = heap[zz]; \
37 while (weight[tmp] < weight[heap[zz >> 1]]) { \
38 heap[zz] = heap[zz >> 1]; \
39 zz >>= 1; \
40 } \
41 heap[zz] = tmp; \
42}
43
44#define DOWNHEAP(z) \
45{ \
46 Int32 zz, yy, tmp; \
47 zz = z; tmp = heap[zz]; \
48 while (True) { \
49 yy = zz << 1; \
50 if (yy > nHeap) break; \
51 if (yy < nHeap && \
52 weight[heap[yy+1]] < weight[heap[yy]]) \
53 yy++; \
54 if (weight[tmp] < weight[heap[yy]]) break; \
55 heap[zz] = heap[yy]; \
56 zz = yy; \
57 } \
58 heap[zz] = tmp; \
59}
60
61
62/*---------------------------------------------------*/
63void BZ2_hbMakeCodeLengths ( UChar *len,
64 Int32 *freq,
65 Int32 alphaSize,
66 Int32 maxLen )
67{
68 /*--
69 Nodes and heap entries run from 1. Entry 0
70 for both the heap and nodes is a sentinel.
71 --*/
72 Int32 nNodes, nHeap, n1, n2, i, j, k;
73 Bool tooLong;
74
75 Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
76 Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
77 Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
78
79 for (i = 0; i < alphaSize; i++)
80 weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
81
82 while (True) {
83
84 nNodes = alphaSize;
85 nHeap = 0;
86
87 heap[0] = 0;
88 weight[0] = 0;
89 parent[0] = -2;
90
91 for (i = 1; i <= alphaSize; i++) {
92 parent[i] = -1;
93 nHeap++;
94 heap[nHeap] = i;
95 UPHEAP(nHeap);
96 }
97
98 AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
99
100 while (nHeap > 1) {
101 n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
102 n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
103 nNodes++;
104 parent[n1] = parent[n2] = nNodes;
105 weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
106 parent[nNodes] = -1;
107 nHeap++;
108 heap[nHeap] = nNodes;
109 UPHEAP(nHeap);
110 }
111
112 AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
113
114 tooLong = False;
115 for (i = 1; i <= alphaSize; i++) {
116 j = 0;
117 k = i;
118 while (parent[k] >= 0) { k = parent[k]; j++; }
119 len[i-1] = j;
120 if (j > maxLen) tooLong = True;
121 }
122
123 if (! tooLong) break;
124
125 /* 17 Oct 04: keep-going condition for the following loop used
126 to be 'i < alphaSize', which missed the last element,
127 theoretically leading to the possibility of the compressor
128 looping. However, this count-scaling step is only needed if
129 one of the generated Huffman code words is longer than
130 maxLen, which up to and including version 1.0.2 was 20 bits,
131 which is extremely unlikely. In version 1.0.3 maxLen was
132 changed to 17 bits, which has minimal effect on compression
133 ratio, but does mean this scaling step is used from time to
134 time, enough to verify that it works.
135
136 This means that bzip2-1.0.3 and later will only produce
137 Huffman codes with a maximum length of 17 bits. However, in
138 order to preserve backwards compatibility with bitstreams
139 produced by versions pre-1.0.3, the decompressor must still
140 handle lengths of up to 20. */
141
142 for (i = 1; i <= alphaSize; i++) {
143 j = weight[i] >> 8;
144 j = 1 + (j / 2);
145 weight[i] = j << 8;
146 }
147 }
148}
149
150
151/*---------------------------------------------------*/
152void BZ2_hbAssignCodes ( Int32 *code,
153 UChar *length,
154 Int32 minLen,
155 Int32 maxLen,
156 Int32 alphaSize )
157{
158 Int32 n, vec, i;
159
160 vec = 0;
161 for (n = minLen; n <= maxLen; n++) {
162 for (i = 0; i < alphaSize; i++)
163 if (length[i] == n) { code[i] = vec; vec++; };
164 vec <<= 1;
165 }
166}
167
168
169/*---------------------------------------------------*/
170void BZ2_hbCreateDecodeTables ( Int32 *limit,
171 Int32 *base,
172 Int32 *perm,
173 UChar *length,
174 Int32 minLen,
175 Int32 maxLen,
176 Int32 alphaSize )
177{
178 Int32 pp, i, j, vec;
179
180 pp = 0;
181 for (i = minLen; i <= maxLen; i++)
182 for (j = 0; j < alphaSize; j++)
183 if (length[j] == i) { perm[pp] = j; pp++; };
184
185 for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
186 for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
187
188 for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
189
190 for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
191 vec = 0;
192
193 for (i = minLen; i <= maxLen; i++) {
194 vec += (base[i+1] - base[i]);
195 limit[i] = vec-1;
196 vec <<= 1;
197 }
198 for (i = minLen + 1; i <= maxLen; i++)
199 base[i] = ((limit[i-1] + 1) << 1) - base[i];
200}
201
202
203/*-------------------------------------------------------------*/
204/*--- end huffman.c ---*/
205/*-------------------------------------------------------------*/
diff --git a/utils/bzip2/randtable.c b/utils/bzip2/randtable.c
new file mode 100644
index 0000000000..6d62459906
--- /dev/null
+++ b/utils/bzip2/randtable.c
@@ -0,0 +1,84 @@
1
2/*-------------------------------------------------------------*/
3/*--- Table for randomising repetitive blocks ---*/
4/*--- randtable.c ---*/
5/*-------------------------------------------------------------*/
6
7/* ------------------------------------------------------------------
8 This file is part of bzip2/libbzip2, a program and library for
9 lossless, block-sorting data compression.
10
11 bzip2/libbzip2 version 1.0.6 of 6 September 2010
12 Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
13
14 Please read the WARNING, DISCLAIMER and PATENTS sections in the
15 README file.
16
17 This program is released under the terms of the license contained
18 in the file LICENSE.
19 ------------------------------------------------------------------ */
20
21
22#include "bzlib_private.h"
23
24
25/*---------------------------------------------*/
26Int32 BZ2_rNums[512] = {
27 619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
28 985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
29 733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
30 419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
31 878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
32 862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
33 150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
34 170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
35 73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
36 909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
37 641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
38 161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
39 382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
40 98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
41 227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
42 469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
43 184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
44 715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
45 951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
46 652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
47 645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
48 609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
49 653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
50 411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
51 170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
52 857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
53 669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
54 944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
55 344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
56 897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
57 433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
58 686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
59 946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
60 978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
61 680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
62 707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
63 297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
64 134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
65 343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
66 140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
67 170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
68 369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
69 804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
70 896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
71 661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
72 768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
73 61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
74 372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
75 780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
76 920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
77 645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
78 936, 638
79};
80
81
82/*-------------------------------------------------------------*/
83/*--- end randtable.c ---*/
84/*-------------------------------------------------------------*/
diff --git a/utils/chinachippatcher/Makefile b/utils/chinachippatcher/Makefile
new file mode 100644
index 0000000000..c8defcb5c4
--- /dev/null
+++ b/utils/chinachippatcher/Makefile
@@ -0,0 +1,17 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9CFLAGS += -g -Wall
10
11OUTPUT = chinachippatcher
12
13LIBSOURCES = chinachip.c
14SOURCES = main.c
15
16include ../libtools.make
17
diff --git a/utils/chinachippatcher/chinachip.c b/utils/chinachippatcher/chinachip.c
new file mode 100644
index 0000000000..79b5acad66
--- /dev/null
+++ b/utils/chinachippatcher/chinachip.c
@@ -0,0 +1,258 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 by Maurus Cuelenaere
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <stdio.h>
22#include <stddef.h>
23#include <stdlib.h>
24#include <stdint.h>
25#include <string.h>
26#include <time.h>
27#include "chinachip.h"
28
29/* From http://www.rockbox.org/wiki/ChinaChip */
30struct header
31{
32 uint32_t signature; /* WADF */
33 uint32_t unk;
34 int8_t timestamp[12]; /* 200805081100 */
35 uint32_t size;
36 uint32_t checksum;
37 uint32_t unk2;
38 int8_t identifier[32]; /* Chinachip PMP firmware V1.0 */
39} __attribute__ ((packed));
40
41static inline void int2le(unsigned char* addr, unsigned int val)
42{
43 addr[0] = val & 0xff;
44 addr[1] = (val >> 8) & 0xff;
45 addr[2] = (val >> 16) & 0xff;
46 addr[3] = (val >> 24) & 0xff;
47}
48
49static inline unsigned int le2int(unsigned char* buf)
50{
51 return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
52}
53
54static long int filesize(FILE* fd)
55{
56 long int len;
57 fseek(fd, 0, SEEK_END);
58 len = ftell(fd);
59 fseek(fd, 0, SEEK_SET);
60 return len;
61}
62
63#define FCLOSE(fd) fclose(fd); fd = NULL;
64#define CCPMPBIN_HEADER_SIZE (sizeof(uint32_t)*2 + sizeof(uint8_t) + 9)
65#define TOTAL_SIZE (fsize + CCPMPBIN_HEADER_SIZE + bsize)
66enum cc_error chinachip_patch(const char* firmware, const char* bootloader,
67 const char* output, const char* ccpmp_backup)
68{
69 char header_time[13];
70 time_t cur_time;
71 struct tm* time_info;
72 unsigned char* buf = NULL;
73 FILE *fd = NULL, *bd = NULL, *od = NULL;
74 unsigned int ccpmp_size = 0, i, fsize, bsize;
75 signed int checksum = 0, ccpmp_pos;
76 int result = E_OK;
77
78 fd = fopen(firmware, "rb");
79 if(!fd)
80 {
81 fprintf(stderr, "[ERR] Can't open file %s!\n", firmware);
82 result = E_OPEN_FIRMWARE;
83 goto err;
84 }
85 bd = fopen(bootloader, "rb");
86 if(!bd)
87 {
88 fprintf(stderr, "[ERR] Can't open file %s!\n", bootloader);
89 result = E_OPEN_BOOTLOADER;
90 goto err;
91 }
92
93 bsize = filesize(bd);
94 fprintf(stderr, "[INFO] Bootloader size is %d bytes\n", bsize);
95 FCLOSE(bd);
96
97 fsize = filesize(fd);
98 fprintf(stderr, "[INFO] Firmware size is %d bytes\n", fsize);
99
100 buf = malloc(TOTAL_SIZE);
101 if(buf == NULL)
102 {
103 fprintf(stderr, "[ERR] Can't allocate %d bytes!\n", fsize);
104 result = E_MEMALLOC;
105 goto err;
106 }
107 memset(buf, 0, TOTAL_SIZE);
108
109 fprintf(stderr, "[INFO] Reading %s into memory...\n", firmware);
110 if(fread(buf, fsize, 1, fd) != 1)
111 {
112 fprintf(stderr, "[ERR] Can't read file %s to memory!\n", firmware);
113 result = E_LOAD_FIRMWARE;
114 goto err;
115 }
116 FCLOSE(fd);
117
118 if(memcmp(buf, "WADF", 4))
119 {
120 fprintf(stderr, "[ERR] File %s isn't a valid ChinaChip firmware!\n", firmware);
121 result = E_INVALID_FILE;
122 goto err;
123 }
124
125 ccpmp_pos = -1, i = 0x40;
126 do
127 {
128 int filenamesize = le2int(&buf[i]);
129 i += sizeof(uint32_t);
130
131 if(!strncmp((char*) &buf[i], "ccpmp.bin", 9))
132 {
133 ccpmp_pos = i;
134 ccpmp_size = le2int(&buf[i + sizeof(uint8_t) + filenamesize]);
135 }
136 else
137 i += filenamesize + le2int(&buf[i + sizeof(uint8_t) + filenamesize])
138 + sizeof(uint32_t) + sizeof(uint8_t);
139 } while(ccpmp_pos < 0 && i < fsize);
140
141 if(i >= fsize)
142 {
143 fprintf(stderr, "[ERR] Couldn't find ccpmp.bin in %s!\n", firmware);
144 result = E_NO_CCPMP;
145 goto err;
146 }
147 fprintf(stderr, "[INFO] Found ccpmp.bin at %d bytes\n", ccpmp_pos);
148
149 if(ccpmp_backup)
150 {
151 int ccpmp_data_pos = ccpmp_pos + 9;
152 bd = fopen(ccpmp_backup, "wb");
153 if(!bd)
154 {
155 fprintf(stderr, "[ERR] Can't open file %s!\n", ccpmp_backup);
156 result = E_OPEN_BACKUP;
157 goto err;
158 }
159
160 fprintf(stderr, "[INFO] Writing %d bytes to %s...\n", ccpmp_size, ccpmp_backup);
161 if(fwrite(&buf[ccpmp_data_pos], ccpmp_size, 1, bd) != 1)
162 {
163 fprintf(stderr, "[ERR] Can't write to file %s!\n", ccpmp_backup);
164 result = E_WRITE_BACKUP;
165 goto err;
166 }
167 FCLOSE(bd);
168 }
169
170 fprintf(stderr, "[INFO] Renaming it to ccpmp.old...\n");
171 buf[ccpmp_pos + 6] = 'o';
172 buf[ccpmp_pos + 7] = 'l';
173 buf[ccpmp_pos + 8] = 'd';
174
175 bd = fopen(bootloader, "rb");
176 if(!bd)
177 {
178 fprintf(stderr, "[ERR] Can't open file %s!\n", bootloader);
179 result = E_OPEN_BOOTLOADER;
180 goto err;
181 }
182
183 /* Also include path size */
184 ccpmp_pos -= sizeof(uint32_t);
185
186 fprintf(stderr, "[INFO] Making place for ccpmp.bin...\n");
187 memmove(&buf[ccpmp_pos + bsize + CCPMPBIN_HEADER_SIZE],
188 &buf[ccpmp_pos], fsize - ccpmp_pos);
189
190 fprintf(stderr, "[INFO] Reading %s into memory...\n", bootloader);
191 if(fread(&buf[ccpmp_pos + CCPMPBIN_HEADER_SIZE],
192 bsize, 1, bd) != 1)
193 {
194 fprintf(stderr, "[ERR] Can't read file %s to memory!\n", bootloader);
195 result = E_LOAD_BOOTLOADER;
196 goto err;
197 }
198 FCLOSE(bd);
199
200 fprintf(stderr, "[INFO] Adding header to %s...\n", bootloader);
201 int2le(&buf[ccpmp_pos ], 9); /* Pathname Size */
202 memcpy(&buf[ccpmp_pos + 4 ], "ccpmp.bin", 9); /* Pathname */
203 memset(&buf[ccpmp_pos + 4 + 9 ], 0x20, sizeof(uint8_t)); /* File Type */
204 int2le(&buf[ccpmp_pos + 4 + 9 + 1], bsize); /* File Size */
205
206 time(&cur_time);
207 time_info = localtime(&cur_time);
208 if(time_info == NULL)
209 {
210 fprintf(stderr, "[ERR] Can't obtain current time!\n");
211 result = E_GET_TIME;
212 goto err;
213 }
214
215 snprintf(header_time, 13, "%04d%02d%02d%02d%02d", time_info->tm_year + 1900,
216 time_info->tm_mon,
217 time_info->tm_mday,
218 time_info->tm_hour,
219 time_info->tm_min);
220
221 fprintf(stderr, "[INFO] Computing checksum...\n");
222 for(i = sizeof(struct header); i < TOTAL_SIZE; i+=4)
223 checksum += le2int(&buf[i]);
224
225 fprintf(stderr, "[INFO] Updating main header...\n");
226 memcpy(&buf[offsetof(struct header, timestamp)], header_time, 12);
227 int2le(&buf[offsetof(struct header, size) ], TOTAL_SIZE);
228 int2le(&buf[offsetof(struct header, checksum) ], checksum);
229
230 od = fopen(output, "wb");
231 if(!od)
232 {
233 fprintf(stderr, "[ERR] Can't open file %s!\n", output);
234 result = E_OPEN_OUTFILE;
235 goto err;
236 }
237
238 fprintf(stderr, "[INFO] Writing output to %s...\n", output);
239 if(fwrite(buf, TOTAL_SIZE, 1, od) != 1)
240 {
241 fprintf(stderr, "[ERR] Can't write to file %s!\n", output);
242 result = E_WRITE_OUTFILE;
243 goto err;
244 }
245
246err:
247 if(buf)
248 free(buf);
249 if(fd)
250 fclose(fd);
251 if(bd)
252 fclose(bd);
253 if(od)
254 fclose(od);
255
256 return result;
257}
258
diff --git a/utils/chinachippatcher/chinachip.h b/utils/chinachippatcher/chinachip.h
new file mode 100644
index 0000000000..b92066bb8b
--- /dev/null
+++ b/utils/chinachippatcher/chinachip.h
@@ -0,0 +1,52 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 by Maurus Cuelenaere
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef __INCLUDE_CHINACHIP_H_
23#define __INCLUDE_CHINACHIP_H_
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29enum cc_error {
30 E_OK,
31 E_OPEN_FIRMWARE,
32 E_OPEN_BOOTLOADER,
33 E_MEMALLOC,
34 E_LOAD_FIRMWARE,
35 E_INVALID_FILE,
36 E_NO_CCPMP,
37 E_OPEN_BACKUP,
38 E_WRITE_BACKUP,
39 E_LOAD_BOOTLOADER,
40 E_GET_TIME,
41 E_OPEN_OUTFILE,
42 E_WRITE_OUTFILE,
43};
44
45enum cc_error chinachip_patch(const char* firmware, const char* bootloader,
46 const char* output, const char* ccpmp_backup);
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif /* __INCLUDE_CHINACHIP_H_ */
diff --git a/utils/chinachippatcher/main.c b/utils/chinachippatcher/main.c
new file mode 100644
index 0000000000..e7779774c9
--- /dev/null
+++ b/utils/chinachippatcher/main.c
@@ -0,0 +1,55 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 by Maurus Cuelenaere
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <stdio.h>
22#include <stdarg.h>
23#include "chinachip.h"
24
25#ifndef VERSION /* allow setting version from outside for svn builds */
26#define VERSION "0.1"
27#endif
28#define PRINT(fmt, ...) fprintf(stderr, fmt"\n", ##__VA_ARGS__)
29
30void usage(char* name)
31{
32 PRINT("Usage:");
33 PRINT(" %s <firmware> <bootloader> <firmware_output> [backup]", name);
34 PRINT("\nExample:");
35 PRINT(" %s VX747.HXF bootloader.bin output.HXF ccpmp.bak", name);
36 PRINT(" This will copy ccpmp.bin in VX747.HXF as ccpmp.old and replace it\n"
37 " with bootloader.bin, the output will get written to output.HXF.\n"
38 " The old ccpmp.bin will get written to ccpmp.bak.\n");
39}
40
41int main(int argc, char* argv[])
42{
43 PRINT("ChinaChipPatcher v" VERSION " - (C) Maurus Cuelenaere 2009");
44 PRINT("This is free software; see the source for copying conditions. There is NO");
45 PRINT("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
46
47 if(argc < 4)
48 {
49 usage(argv[0]);
50 return 1;
51 }
52
53 return chinachip_patch(argv[1], argv[2], argv[3], argc > 4 ? argv[4] : NULL);
54}
55
diff --git a/utils/e200rpatcher/Makefile b/utils/e200rpatcher/Makefile
new file mode 100644
index 0000000000..dfe5c1e037
--- /dev/null
+++ b/utils/e200rpatcher/Makefile
@@ -0,0 +1,56 @@
1CFLAGS=-Wall -W
2
3ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN)
4OUTPUT=e200rpatcher.exe
5CROSS=
6CFLAGS+=-mno-cygwin
7else
8OUTPUT=e200rpatcher
9CROSS=i586-mingw32msvc-
10endif
11
12LIBS = -lusb
13WINLIBS = -I libusb-win32-device-bin-0.1.12.1/include libusb-win32-device-bin-0.1.12.1/lib/dynamic/libusb_dyn.c
14
15NATIVECC = gcc
16CC = $(CROSS)gcc
17WINDRES = $(CROSS)windres
18
19all: $(OUTPUT)
20
21e200rpatcher: e200rpatcher.c bootimg.c
22 gcc $(CFLAGS) $(LIBS) -o e200rpatcher e200rpatcher.c bootimg.c
23 strip e200rpatcher
24
25e200rpatcher.exe: e200rpatcher.c bootimg.c e200rpatcher-rc.o
26 $(CC) $(CFLAGS) $(WINLIBS) -o e200rpatcher.exe e200rpatcher.c bootimg.c e200rpatcher-rc.o
27 $(CROSS)strip e200rpatcher.exe
28
29e200rpatcher-rc.o: e200rpatcher.rc e200rpatcher.manifest
30 $(WINDRES) -i e200rpatcher.rc -o e200rpatcher-rc.o
31
32e200rpatcher-mac: e200rpatcher-i386 e200rpatcher-ppc
33 lipo -create e200rpatcher-ppc e200rpatcher-i386 -output e200rpatcher-mac
34
35e200rpatcher.dmg: e200rpatcher-mac
36 mkdir -p e200rpatcher-dmg
37 cp -p e200rpatcher-mac e200rpatcher-dmg
38 hdiutil create -srcfolder e200rpatcher-dmg e200rpatcher.dmg
39
40e200rpatcher-i386: e200rpatcher.c bootimg.c usb.h libusb-i386.a
41 gcc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -framework iokit -framework coreservices -arch i386 $(CFLAGS) -o e200rpatcher-i386 e200rpatcher.c bootimg.c -I. libusb-i386.a
42 strip e200rpatcher-i386
43
44e200rpatcher-ppc: e200rpatcher.c bootimg.c usb.h libusb-ppc.a
45 gcc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -framework iokit -framework coreservices -arch ppc $(CFLAGS) -o e200rpatcher-ppc e200rpatcher.c bootimg.c -I. libusb-ppc.a
46 strip e200rpatcher-ppc
47
48bin2c: ../tools/bin2c.c
49 $(NATIVECC) $(CFLAGS) -o bin2c ../tools/bin2c.c
50
51bootimg.c: bootloader.bin bin2c
52 ./bin2c bootloader.bin bootimg
53
54clean:
55 rm -f e200rpatcher.exe e200rpatcher-mac e200rpatcher-i386 e200rpatcher-ppc e200rpatcher bin2c bootimg.c bootimg.h *~ e200rpatcher.dmg
56 rm -rf e200rpatcher-dmg
diff --git a/utils/e200rpatcher/README b/utils/e200rpatcher/README
new file mode 100644
index 0000000000..1942b3aa7a
--- /dev/null
+++ b/utils/e200rpatcher/README
@@ -0,0 +1,48 @@
1INTRODUCTION
2
3e200rpatcher is a tool for uploading and executing an application to
4an E200R in manufacturing mode. It is intended to be used to upload
5the patching application to allow Rockbox installs.
6
7e200rpatcher requires libusb (v0.1.2 has been tested successfully) for
8cross-platform USB access. No-one has yet successfully installed
9e200rpatcher on Windows, but it works on Linux and Mac OS X (and
10should be fine on other Unix-like systems that libusb supports).
11
12GENERAL BUILD INSTRUCTIONS
13
14A pre-requisite for compiling e200rpatcher is a file called
15"bootloader.bin" - this is the output of running an "I" (installer)
16build for the E200R target.
17
18In the Rockbox source directory, do:
19
20mkdir build-e200rbootbin
21cd build-e200rbootbin
22../tools/configure
23[Select E200R, then I for installer]
24make
25
26This should give you a bootloader/bootloader/bin file which you should
27copy to the e200rpatcher source directory.
28
29BUILDING ON LINUX
30
31The Makefile expects libusb (and the headers) to be installed on your
32system and will link dynamically. Just type "make".
33
34BUILDING ON A MAC
35
36To build the mac version (target e200rpatcher-mac in the Makefile)
37requires three files from libusb to be copied to the current
38directory:
39
40usb.h (copied from your libusb build directory)
41libusb-i386.a (copied and renamed from .libs/libusb.a in an i386 build)
42libusb-ppc.a (copied and renamed from .libs/libusb.a in a PPC build)
43
44To build the required libusb.a files, just run ./configure && make for
45libusb. If anyone knows how to cross-compile a static libusb.a please
46make the information known - this is currently done by compiling
47natively on the appropriate hardware.
48
diff --git a/utils/e200rpatcher/e200rpatcher.c b/utils/e200rpatcher/e200rpatcher.c
new file mode 100644
index 0000000000..be09370997
--- /dev/null
+++ b/utils/e200rpatcher/e200rpatcher.c
@@ -0,0 +1,241 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 Dave Chapman
11 *
12 * USB code based on ifp-line - http://ifp-driver.sourceforge.net
13 *
14 * ifp-line is (C) Pavel Kriz, Jun Yamishiro and Joe Roback and
15 * licensed under the GPL (v2)
16 *
17 *
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
22 *
23 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
24 * KIND, either express or implied.
25 *
26 ****************************************************************************/
27
28
29#include <stdio.h>
30#include <inttypes.h>
31#include <usb.h>
32#include <string.h>
33#include "stdbool.h"
34
35#include "bootimg.h"
36
37#define VERSION "0.2"
38
39/* USB IDs for Manufacturing Mode */
40#define E200R_VENDORID 0x0781
41#define E200R_PRODUCTID 0x0720
42
43#define E200R_BULK_TO 1
44#define TOUT 5000
45#define MAX_TRANSFER 64 /* Number of bytes to send in one write */
46
47#ifndef MAX
48#define MAX(a,b) (((a)>(b))?(a):(b))
49#endif
50
51static void put_int32le(uint32_t x, char* p)
52{
53 p[0] = x & 0xff;
54 p[1] = (x >> 8) & 0xff;
55 p[2] = (x >> 16) & 0xff;
56 p[3] = (x >> 24) & 0xff;
57}
58
59int upload_app(usb_dev_handle* dh)
60{
61 char buf[4];
62 int err;
63 int tosend;
64 char* p = (char*)bootimg;
65 int bytesleft = LEN_bootimg;
66
67 /* Write the data length */
68
69 put_int32le(LEN_bootimg, buf);
70
71 err = usb_bulk_write(dh, E200R_BULK_TO, buf, 4, TOUT);
72
73 if (err < 0)
74 {
75 fprintf(stderr,"[ERR] Error writing data length\n");
76 fprintf(stderr,"[ERR] Bulk write error (%d, %s)\n", err, strerror(-err));
77 return -1;
78 }
79
80 /* Now send the data, MAX_TRANSFER bytes at a time. */
81
82 while (bytesleft > 0)
83 {
84 tosend = MAX(MAX_TRANSFER, bytesleft);
85
86 err = usb_bulk_write(dh, E200R_BULK_TO, p, tosend, TOUT);
87
88 if (err < 0)
89 {
90 fprintf(stderr,"[ERR] Error writing data\n");
91 fprintf(stderr,"[ERR] Bulk write error (%d, %s)\n", err, strerror(-err));
92 return -1;
93 }
94
95 p += tosend;
96 bytesleft -= tosend;
97 }
98
99 return 0;
100}
101
102
103/* The main function */
104
105void do_patching(void)
106{
107 struct usb_bus *busses;
108 struct usb_bus *bus;
109 struct usb_device *tmp_dev;
110 struct usb_device *dev = NULL;
111 usb_dev_handle *dh;
112 int err;
113
114 fprintf(stderr,"[INFO] Searching for E200R\n");
115
116 usb_init();
117
118 if(usb_find_busses() < 0) {
119 fprintf(stderr, "[ERR] Could not find any USB busses.\n");
120 return;
121 }
122
123 if (usb_find_devices() < 0) {
124 fprintf(stderr, "[ERR] USB devices not found(nor hubs!).\n");
125 return;
126 }
127
128 /* C calling convention, it's not nice to use global stuff */
129 busses = usb_get_busses();
130
131 for (bus = busses; bus; bus = bus->next) {
132 for (tmp_dev = bus->devices; tmp_dev; tmp_dev = tmp_dev->next) {
133 if (tmp_dev->descriptor.idVendor == E200R_VENDORID &&
134 tmp_dev->descriptor.idProduct == E200R_PRODUCTID ) {
135
136 dev = tmp_dev;
137 goto found;
138
139 }
140 }
141 }
142
143 if (dev == NULL) {
144 fprintf(stderr, "[ERR] E200R device not found.\n");
145 fprintf(stderr, "[ERR] Ensure your E200R is in manufacturing mode and run e200rpatcher again.\n");
146 return;
147 }
148
149found:
150 if ( (dh = usb_open(dev)) == NULL) {
151 fprintf(stderr,"[ERR] Unable to open E200R device.\n");
152 return;
153 }
154
155 err = usb_set_configuration(dh, 1);
156
157 if (err < 0) {
158 fprintf(stderr, "[ERR] usb_set_configuration failed (%d)\n", err);
159 usb_close(dh);
160 return;
161 }
162
163 /* "must be called" written in the libusb documentation */
164 err = usb_claim_interface(dh, dev->config->interface->altsetting->bInterfaceNumber);
165 if (err < 0) {
166 fprintf(stderr, "[ERR] Unable to claim interface (%d)\n", err);
167 usb_close(dh);
168 return;
169 }
170
171 fprintf(stderr,"[INFO] Found E200R, uploading patching application.\n");
172
173 /* Now we can transfer the application to the device. */
174
175 if (upload_app(dh) < 0)
176 {
177 fprintf(stderr,"[ERR] Upload of application failed.\n");
178 }
179 else
180 {
181 fprintf(stderr,"[INFO] Patching application uploaded successfully!\n");
182 }
183
184 /* release claimed interface */
185 usb_release_interface(dh, dev->config->interface->altsetting->bInterfaceNumber);
186
187 usb_close(dh);
188}
189void print_usage(void)
190{
191 fprintf(stderr,"Usage: e200rpatcher [options]\n");
192 fprintf(stderr,"Options:\n");
193 fprintf(stderr," -s, --silent\t\tDont display instructions\n");
194}
195
196int main(int argc, char* argv[])
197{
198 char input[4];
199 int silent = 0;
200 int i;
201
202 /* check args */
203 if ((argc > 1) && ((strcmp(argv[1],"-h")==0) || (strcmp(argv[1],"--help")==0))) {
204 print_usage();
205 return 1;
206 }
207 for (i=1;i<argc;i++)
208 {
209 if (!strcmp(argv[i], "--silent") || !strcmp(argv[i], "-s"))
210 silent = 1;
211 }
212
213 printf("e200rpatcher v" VERSION " - (C) 2007 Jonathan Gordon & Dave Chapman\n");
214 printf("This is free software; see the source for copying conditions. There is NO\n");
215 printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
216
217 if (!silent)
218 {
219 printf("Attach your E200R in \"manufacturing mode\" as follows:\n");
220 printf(" 1) Power-off your E200R\n");
221 printf(" 2) Turn ON the lock/hold switch\n");
222 printf(" 3) Press and hold the SELECT button and whilst it is held down,\n");
223 printf(" attach your E200R to your computer via USB\n");
224 printf(" 4) After attaching to USB, keep the SELECT button held for 10 seconds.\n");
225 printf("\n");
226 printf("NOTE: If your E200R starts in the normal Sansa firmware, you have\n");
227 printf(" failed to enter manufacturing mode and should try again at step 1).\n\n");
228
229 printf("[INFO] Press Enter to continue:");
230 fgets(input, 4, stdin);
231 }
232 do_patching();
233
234 if (!silent)
235 {
236 printf("[INFO] Press ENTER to exit: ");
237 fgets(input, 4, stdin);
238 }
239
240 return 0;
241}
diff --git a/utils/e200rpatcher/e200rpatcher.manifest b/utils/e200rpatcher/e200rpatcher.manifest
new file mode 100644
index 0000000000..ec0c49df33
--- /dev/null
+++ b/utils/e200rpatcher/e200rpatcher.manifest
@@ -0,0 +1,13 @@
1<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
3 <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="e200rpatcher.exe" type="win32"/>
4
5 <!-- Identify the application security requirements. -->
6 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
7 <security>
8 <requestedPrivileges>
9 <requestedExecutionLevel level="requireAdministrator"/>
10 </requestedPrivileges>
11 </security>
12 </trustInfo>
13</assembly>
diff --git a/utils/e200rpatcher/e200rpatcher.rc b/utils/e200rpatcher/e200rpatcher.rc
new file mode 100644
index 0000000000..4d80442d44
--- /dev/null
+++ b/utils/e200rpatcher/e200rpatcher.rc
@@ -0,0 +1 @@
1 24 MOVEABLE PURE "e200rpatcher.manifest"
diff --git a/utils/ibassoboot/jni/Android.mk b/utils/ibassoboot/jni/Android.mk
new file mode 100644
index 0000000000..9cd667c5b9
--- /dev/null
+++ b/utils/ibassoboot/jni/Android.mk
@@ -0,0 +1,14 @@
1LOCAL_PATH := $(call my-dir)
2include $(CLEAR_VARS)
3
4LOCAL_MODULE := MangoPlayer
5LOCAL_SRC_FILES := ibassodualboot.c qdbmp.c
6
7TARGET_ARCH=arm
8TARGET_PLATFORM=android-14
9TARGET_ARCH_ABI=armeabi
10
11#LOCAL_CFLAGS := -DDEBUG
12#LOCAL_LDLIBS := -llog
13
14include $(BUILD_EXECUTABLE)
diff --git a/utils/ibassoboot/jni/chooser.bmp b/utils/ibassoboot/jni/chooser.bmp
new file mode 100644
index 0000000000..3e6742d600
--- /dev/null
+++ b/utils/ibassoboot/jni/chooser.bmp
Binary files differ
diff --git a/utils/ibassoboot/jni/ibassodualboot.c b/utils/ibassoboot/jni/ibassodualboot.c
new file mode 100644
index 0000000000..0458ff1b71
--- /dev/null
+++ b/utils/ibassoboot/jni/ibassodualboot.c
@@ -0,0 +1,771 @@
1/***************************************************************************
2 * __________ __ ___
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
10 * Copyright (C) 2014 by Mario Basister: iBasso DX90 port
11 * Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
12 * Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24
25#include <dirent.h>
26#include <fcntl.h>
27#include <pthread.h>
28#include <stdbool.h>
29#include <stdlib.h>
30#include <unistd.h>
31#include <linux/fb.h>
32#include <linux/input.h>
33#include <sys/mman.h>
34#include <sys/poll.h>
35#include <sys/reboot.h>
36#include <sys/socket.h>
37#include <sys/un.h>
38#include <sys/wait.h>
39
40#include "qdbmp.h"
41
42
43/*- Android logcat ------------------------------------------------------------------------------*/
44
45
46#ifdef DEBUG
47#include <android/log.h>
48
49
50static const char log_tag[] = "Rockbox Boot";
51
52
53void debugf(const char *fmt, ...)
54{
55 va_list ap;
56 va_start(ap, fmt);
57 __android_log_vprint(ANDROID_LOG_DEBUG, log_tag, fmt, ap);
58 va_end(ap);
59}
60
61
62void ldebugf(const char* file, int line, const char *fmt, ...)
63{
64 va_list ap;
65 /* 13: 5 literal chars and 8 chars for the line number. */
66 char buf[strlen(file) + strlen(fmt) + 13];
67 snprintf(buf, sizeof(buf), "%s (%d): %s", file, line, fmt);
68 va_start(ap, fmt);
69 __android_log_vprint(ANDROID_LOG_DEBUG, log_tag, buf, ap);
70 va_end(ap);
71}
72
73
74void debug_trace(const char* function)
75{
76 static const char trace_tag[] = "TRACE: ";
77 char msg[strlen(trace_tag) + strlen(function) + 1];
78 snprintf(msg, sizeof(msg), "%s%s", trace_tag, function);
79 __android_log_write(ANDROID_LOG_DEBUG, log_tag, msg);
80}
81
82
83#define DEBUGF debugf
84#define TRACE debug_trace(__func__)
85#else
86#define DEBUGF(...)
87#define TRACE
88#endif /* DEBUG */
89
90
91/*- Vold monitor --------------------------------------------------------------------------------*/
92
93
94/*
95 Without this socket iBasso Vold will not start.
96 iBasso Vold uses this to send status messages about storage devices.
97*/
98static const char VOLD_MONITOR_SOCKET_NAME[] = "UNIX_domain";
99static int _vold_monitor_socket_fd = -1;
100
101
102static void vold_monitor_open_socket(void)
103{
104 TRACE;
105
106 unlink(VOLD_MONITOR_SOCKET_NAME);
107
108 _vold_monitor_socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
109
110 if(_vold_monitor_socket_fd < 0)
111 {
112 _vold_monitor_socket_fd = -1;
113 return;
114 }
115
116 struct sockaddr_un addr;
117 memset(&addr, 0, sizeof(addr));
118 addr.sun_family = AF_UNIX;
119 strncpy(addr.sun_path, VOLD_MONITOR_SOCKET_NAME, sizeof(addr.sun_path) - 1);
120
121 if(bind(_vold_monitor_socket_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0)
122 {
123 close(_vold_monitor_socket_fd);
124 unlink(VOLD_MONITOR_SOCKET_NAME);
125 _vold_monitor_socket_fd = -1;
126 return;
127 }
128
129 if(listen(_vold_monitor_socket_fd, 1) < 0)
130 {
131 close(_vold_monitor_socket_fd);
132 unlink(VOLD_MONITOR_SOCKET_NAME);
133 _vold_monitor_socket_fd = -1;
134 return;
135 }
136}
137
138
139/*
140 bionic does not have pthread_cancel.
141 0: Vold monitor thread stopped/ending.
142 1: Vold monitor thread started/running.
143*/
144static volatile sig_atomic_t _vold_monitor_active = 0;
145
146
147/* true: sdcard not mounted. */
148static bool _sdcard_not_mounted = true;
149
150
151/* Mutex for sdcard mounted flag. */
152static pthread_mutex_t _sdcard_mount_mtx = PTHREAD_MUTEX_INITIALIZER;
153
154
155/* Signal condition for sdcard mounted flag. */
156static pthread_cond_t _sdcard_mount_cond = PTHREAD_COND_INITIALIZER;
157
158
159static void* vold_monitor_run(void* nothing)
160{
161 _vold_monitor_active = 1;
162
163 (void) nothing;
164
165 DEBUGF("DEBUG %s: Thread start.", __func__);
166
167 vold_monitor_open_socket();
168 if(_vold_monitor_socket_fd < 0)
169 {
170 DEBUGF("ERROR %s: Thread end: No socket.", __func__);
171
172 _vold_monitor_active = 0;
173 return 0;
174 }
175
176 struct pollfd fds[1];
177 fds[0].fd = _vold_monitor_socket_fd;
178 fds[0].events = POLLIN;
179
180 while(_vold_monitor_active == 1)
181 {
182 poll(fds, 1, 10);
183 if(! (fds[0].revents & POLLIN))
184 {
185 continue;
186 }
187
188 int socket_fd = accept(_vold_monitor_socket_fd, NULL, NULL);
189
190 if(socket_fd < 0)
191 {
192 DEBUGF("ERROR %s: accept failed.", __func__);
193
194 continue;
195 }
196
197 while(true)
198 {
199 char msg[1024];
200 memset(msg, 0, sizeof(msg));
201 int length = read(socket_fd, msg, sizeof(msg));
202
203 if(length <= 0)
204 {
205 close(socket_fd);
206 break;
207 }
208
209 DEBUGF("DEBUG %s: msg: %s", __func__, msg);
210
211 if(strcmp(msg, "Volume flash /mnt/sdcard state changed from 3 (Checking) to 4 (Mounted)") == 0)
212 {
213 pthread_mutex_lock(&_sdcard_mount_mtx);
214 _sdcard_not_mounted = false;
215 pthread_cond_signal(&_sdcard_mount_cond);
216 pthread_mutex_unlock(&_sdcard_mount_mtx);
217 }
218 }
219 }
220
221 close(_vold_monitor_socket_fd);
222 unlink(VOLD_MONITOR_SOCKET_NAME);
223 _vold_monitor_socket_fd = -1;
224
225 DEBUGF("DEBUG %s: Thread end.", __func__);
226
227 _vold_monitor_active = 0;
228 return 0;
229}
230
231
232/* Vold monitor thread. */
233static pthread_t _vold_monitor_thread;
234
235
236static void vold_monitor_start(void)
237{
238 TRACE;
239
240 if(_vold_monitor_active == 0)
241 {
242 pthread_create(&_vold_monitor_thread, NULL, vold_monitor_run, NULL);
243 }
244}
245
246
247static void vold_monitor_stop(void)
248{
249 TRACE;
250
251 if(_vold_monitor_active == 1)
252 {
253 _vold_monitor_active = 0;
254 int ret = pthread_join(_vold_monitor_thread, NULL);
255 DEBUGF("DEBUG %s: Thread joined: ret: %d.", __func__, ret);
256 }
257}
258
259
260/*- Input handler -------------------------------------------------------------------------------*/
261
262
263/* Input devices monitored with poll API. */
264static struct pollfd* _fds = NULL;
265
266
267/* Number of input devices monitored with poll API. */
268static nfds_t _nfds = 0;
269
270
271/* The names of the devices in _fds. */
272static char** _device_names = NULL;
273
274
275/* Open device device_name and add it to the list of polled devices. */
276static void open_device(const char* device_name)
277{
278 int fd = open(device_name, O_RDONLY);
279 if(fd == -1)
280 {
281 DEBUGF("ERROR %s: open failed on %s.", __func__, device_name);
282 exit(-1);
283 }
284
285 struct pollfd* new_fds = realloc(_fds, sizeof(struct pollfd) * (_nfds + 1));
286 if(new_fds == NULL)
287 {
288 DEBUGF("ERROR %s: realloc for _fds failed.", __func__);
289 exit(-1);
290 }
291
292 _fds = new_fds;
293 _fds[_nfds].fd = fd;
294 _fds[_nfds].events = POLLIN;
295
296 char** new_device_names = realloc(_device_names, sizeof(char*) * (_nfds + 1));
297 if(new_device_names == NULL)
298 {
299 DEBUGF("ERROR %s: realloc for _device_names failed.", __func__);
300 exit(-1);
301 }
302
303 _device_names = new_device_names;
304 _device_names[_nfds] = strdup(device_name);
305 if(_device_names[_nfds] == NULL)
306 {
307 DEBUGF("ERROR %s: strdup failed.", __func__);
308 exit(-1);
309 }
310
311 ++_nfds;
312
313 DEBUGF("DEBUG %s: Opened device %s.", __func__, device_name);
314}
315
316
317static void button_init_device(void)
318{
319 TRACE;
320
321 if((_fds != NULL) || (_nfds != 0) || (_device_names != NULL))
322 {
323 DEBUGF("ERROR %s: Allready initialized.", __func__);
324 return;
325 }
326
327 /* The input device directory. */
328 static const char device_path[] = "/dev/input";
329
330 /* Path delimeter. */
331 static const char delimeter[] = "/";
332
333 /* Open all devices in device_path. */
334 DIR* dir = opendir(device_path);
335 if(dir == NULL)
336 {
337 DEBUGF("ERROR %s: opendir failed: errno: %d.", __func__, errno);
338 exit(errno);
339 }
340
341 char device_name[PATH_MAX];
342 strcpy(device_name, device_path);
343 strcat(device_name, delimeter);
344 char* device_name_idx = device_name + strlen(device_name);
345
346 struct dirent* dir_entry;
347 while((dir_entry = readdir(dir)))
348 {
349 if( ((dir_entry->d_name[0] == '.') && (dir_entry->d_name[1] == '\0'))
350 || ((dir_entry->d_name[0] == '.') && (dir_entry->d_name[1] == '.') && (dir_entry->d_name[2] == '\0')))
351 {
352 continue;
353 }
354
355 strcpy(device_name_idx, dir_entry->d_name);
356
357 /* Open and add device to _fds. */
358 open_device(device_name);
359 }
360
361 closedir(dir);
362
363 /* Sanity check. */
364 if(_nfds < 2)
365 {
366 DEBUGF("ERROR %s: No input devices.", __func__);
367 exit(-1);
368 }
369}
370
371
372#define EVENT_TYPE_BUTTON 1
373
374
375#define EVENT_CODE_BUTTON_PWR_LONG 117
376#define EVENT_CODE_BUTTON_REV 160
377#define EVENT_CODE_BUTTON_NEXT 162
378
379
380#define EVENT_TYPE_TOUCHSCREEN 3
381
382
383#define EVENT_CODE_TOUCHSCREEN_X 53
384
385
386enum user_choice
387{
388 CHOICE_NONE = -1,
389 CHOICE_MANGO,
390 CHOICE_ROCKBOX,
391 CHOICE_POWEROFF
392};
393
394
395static int get_user_choice(void)
396{
397 TRACE;
398
399 button_init_device();
400
401 enum user_choice choice = CHOICE_NONE;
402
403 while(choice == CHOICE_NONE)
404 {
405 /* Poll all input devices. */
406 poll(_fds, _nfds, 0);
407
408 nfds_t fds_idx = 0;
409 for( ; fds_idx < _nfds; ++fds_idx)
410 {
411 if(! (_fds[fds_idx].revents & POLLIN))
412 {
413 continue;
414 }
415
416 struct input_event event;
417 if(read(_fds[fds_idx].fd, &event, sizeof(event)) < (int) sizeof(event))
418 {
419 DEBUGF("ERROR %s: Read of input devices failed.", __func__);
420 continue;
421 }
422
423 DEBUGF("DEBUG %s: device: %s, event.type: %d, event.code: %d, event.value: %d", __func__, _device_names[fds_idx], event.type, event.code, event.value);
424
425 if(event.type == EVENT_TYPE_BUTTON)
426 {
427 switch(event.code)
428 {
429 case EVENT_CODE_BUTTON_REV:
430 {
431 choice = CHOICE_MANGO;
432 break;
433 }
434
435 case EVENT_CODE_BUTTON_NEXT:
436 {
437 choice = CHOICE_ROCKBOX;
438 break;
439 }
440
441 case EVENT_CODE_BUTTON_PWR_LONG:
442 {
443 choice = CHOICE_POWEROFF;
444 break;
445 }
446 }
447 }
448 else if((event.type == EVENT_TYPE_TOUCHSCREEN) && (event.code == EVENT_CODE_TOUCHSCREEN_X))
449 {
450 if(event.value < 160)
451 {
452 choice = CHOICE_MANGO;
453 }
454 else
455 {
456 choice = CHOICE_ROCKBOX;
457 }
458 }
459 }
460 }
461
462 if(_fds)
463 {
464 nfds_t fds_idx = 0;
465 for( ; fds_idx < _nfds; ++fds_idx)
466 {
467 close(_fds[fds_idx].fd);
468 }
469 free(_fds);
470 _fds = NULL;
471 }
472
473 if(_device_names)
474 {
475 nfds_t fds_idx = 0;
476 for( ; fds_idx < _nfds; ++fds_idx)
477 {
478 free(_device_names[fds_idx]);
479 }
480 free(_device_names);
481 _device_names = NULL;
482 }
483
484 _nfds = 0;
485
486 return choice;
487}
488
489
490/*
491 Changing bit, when hold switch is toggled.
492 Bit is off when hold switch is engaged.
493*/
494#define HOLD_SWITCH_BIT 16
495
496
497static bool check_for_hold(void)
498{
499 TRACE;
500
501 char hold_state;
502
503 FILE* f = fopen("/sys/class/axppower/holdkey", "r");
504 fscanf(f, "%c", &hold_state);
505 fclose(f);
506
507 return(! (hold_state & HOLD_SWITCH_BIT));
508}
509
510
511/*- Display -------------------------------------------------------------------------------------*/
512
513
514static void draw(const char* file)
515{
516 DEBUGF("DEBUG %s: file: %s.", __func__, file);
517
518 int dev_fd = open("/dev/graphics/fb0", O_RDWR);
519 if(dev_fd == -1)
520 {
521 DEBUGF("ERROR %s: open failed on /dev/graphics/fb0, errno: %d.", __func__, errno);
522 exit(errno);
523 }
524
525 /* Get fixed screen information. */
526 struct fb_fix_screeninfo finfo;
527 if(ioctl(dev_fd, FBIOGET_FSCREENINFO, &finfo) < 0)
528 {
529 DEBUGF("ERROR %s: ioctl FBIOGET_FSCREENINFO failed on /dev/graphics/fb0, errno: %d.", __func__, errno);
530 exit(errno);
531 }
532
533 /* Get the changeable information. */
534 struct fb_var_screeninfo vinfo;
535 if(ioctl(dev_fd, FBIOGET_VSCREENINFO, &vinfo) < 0)
536 {
537 DEBUGF("ERROR %s: ioctl FBIOGET_VSCREENINFO failed on /dev/graphics/fb0, errno: %d.", __func__, errno);
538 exit(errno);
539 }
540
541 DEBUGF("DEBUG %s: bits_per_pixel: %u, width: %u, height: %u.", __func__, vinfo.bits_per_pixel, vinfo.width, vinfo.height);
542
543 size_t screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
544
545 /* ToDo: Is this needed? */
546 vinfo.xres = 320;
547 vinfo.xres_virtual = 320;
548 vinfo.width = 320;
549 vinfo.yres = 240;
550 vinfo.yres_virtual = 240;
551 vinfo.height = 240;
552 vinfo.xoffset = 0;
553 vinfo.yoffset = 0;
554 vinfo.sync = 0;
555 vinfo.vmode = 0;
556 vinfo.pixclock = 104377;
557 vinfo.left_margin = 20;
558 vinfo.right_margin = 50;
559 vinfo.upper_margin = 2;
560 vinfo.lower_margin = 4;
561 vinfo.hsync_len = 10;
562 vinfo.vsync_len = 2;
563 vinfo.red.offset = 11;
564 vinfo.red.length = 5;
565 vinfo.red.msb_right = 0;
566 vinfo.green.offset = 5;
567 vinfo.green.length = 6;
568 vinfo.green.msb_right = 0;
569 vinfo.blue.offset = 0;
570 vinfo.blue.length = 5;
571 vinfo.blue.msb_right = 0;
572 vinfo.transp.offset = 0;
573 vinfo.transp.length = 0;
574 vinfo.transp.msb_right = 0;
575 vinfo.nonstd = 4;
576 if(ioctl(dev_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0)
577 {
578 DEBUGF("ERROR %s: ioctl FBIOPUT_VSCREENINFO failed on /dev/graphics/fb0, errno: %d.", __func__, errno);
579 exit(errno);
580 }
581
582 /* Map the device to memory. */
583 char* dev_fb = (char*) mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, 0);
584 if(dev_fb == MAP_FAILED)
585 {
586 DEBUGF("ERROR %s: mmap failed on /dev/graphics/fb0, errno: %d.", __func__, errno);
587 exit(errno);
588 }
589
590 BMP* bmp = BMP_ReadFile(file);
591 if(BMP_GetError() != BMP_OK )
592 {
593 DEBUGF("ERROR %s: BMP_ReadFile failed on %s: %d.", __func__, file, BMP_GetError());
594 exit(BMP_GetError());
595 }
596
597 int y = 0;
598 for( ; y < 240; ++y)
599 {
600 int x = 0;
601 for( ; x < 320; ++x)
602 {
603 long int position = (x + vinfo.xoffset) * (vinfo.bits_per_pixel / 8 )
604 + (y + vinfo.yoffset) * finfo.line_length;
605 UCHAR r, g, b;
606 BMP_GetPixelRGB(bmp, x, y, &r, &g, &b);
607 unsigned short int pixel = (r >> 3) << 11 | (g >> 2) << 5 | (b >> 3);
608 *((unsigned short int*)(dev_fb + position)) = pixel;
609 }
610 }
611
612 BMP_Free(bmp);
613 munmap(dev_fb, screensize);
614 close(dev_fd);
615}
616
617
618/*-----------------------------------------------------------------------------------------------*/
619
620
621static const char ROCKBOX_BIN[] = "/mnt/sdcard/.rockbox/rockbox";
622static const char OF_PLAYER_BIN[] = "/system/bin/MangoPlayer_original";
623static const char PLAYER_FILE[] = "/data/chosen_player";
624
625
626int main(int argc, char **argv)
627{
628 TRACE;
629
630 /*
631 Create the iBasso Vold socket and monitor it.
632 Do this early to not block Vold.
633 */
634 vold_monitor_start();
635
636 int last_chosen_player = CHOICE_NONE;
637
638 FILE* f = fopen(PLAYER_FILE, "r");
639 if(f != NULL)
640 {
641 fscanf(f, "%d", &last_chosen_player);
642 fclose(f);
643 }
644
645 DEBUGF("DEBUG %s: Current player choice: %d.", __func__, last_chosen_player);
646
647 if(check_for_hold() || (last_chosen_player == CHOICE_NONE))
648 {
649 draw("/system/chooser.bmp");
650
651 enum user_choice choice = get_user_choice();
652
653 if(choice == CHOICE_POWEROFF)
654 {
655 reboot(RB_POWER_OFF);
656 while(true)
657 {
658 sleep(1);
659 }
660 }
661
662 if(choice != last_chosen_player)
663 {
664 last_chosen_player = choice;
665
666 f = fopen(PLAYER_FILE, "w");
667 fprintf(f, "%d", last_chosen_player);
668 fclose(f);
669 }
670
671 DEBUGF("DEBUG %s: New player choice: %d.", __func__, last_chosen_player);
672 }
673
674 /* true, Rockbox was started at least once. */
675 bool rockboxStarted = false;
676
677 while(true)
678 {
679 /* Excecute OF MangoPlayer or Rockbox and restart it if it crashes. */
680
681 if(last_chosen_player == CHOICE_ROCKBOX)
682 {
683 if(rockboxStarted)
684 {
685 /*
686 At this point it is assumed, that Rockbox has exited due to a USB connection
687 triggering a remount of the internal storage for mass storage access.
688 Rockbox will eventually restart, when /mnt/sdcard becomes available again.
689 */
690 draw("/system/usb.bmp");
691 }
692
693 pthread_mutex_lock(&_sdcard_mount_mtx);
694 while(_sdcard_not_mounted)
695 {
696 DEBUGF("DEBUG %s: Waiting on /mnt/sdcard/.", __func__);
697
698 pthread_cond_wait(&_sdcard_mount_cond, &_sdcard_mount_mtx);
699
700 DEBUGF("DEBUG %s: /mnt/sdcard/ available.", __func__);
701 }
702 pthread_mutex_unlock(&_sdcard_mount_mtx);
703
704 /* To be able to execute rockbox. */
705 system("mount -o remount,exec /mnt/sdcard");
706
707 /* This symlink is needed mainly to keep themes functional. */
708 system("ln -s /mnt/sdcard/.rockbox /.rockbox");
709
710 if(access(ROCKBOX_BIN, X_OK) != -1)
711 {
712 /* Start Rockbox. */
713
714 /* Rockbox has its own vold monitor. */
715 vold_monitor_stop();
716
717 DEBUGF("DEBUG %s: Excecuting %s.", __func__, ROCKBOX_BIN);
718
719 int ret_code = system(ROCKBOX_BIN);
720 rockboxStarted = true;
721
722 DEBUGF("DEBUG %s: ret_code: %d.", __func__, ret_code);
723
724 if(WIFEXITED(ret_code) && (WEXITSTATUS(ret_code) == 42))
725 {
726 /*
727 Rockbox terminated to prevent a froced shutdown due to a USB connection
728 triggering a remount of the internal storage for mass storage access.
729 */
730 _sdcard_not_mounted = true;
731 }
732 /* else Rockbox crashed ... */
733
734 vold_monitor_start();
735 }
736 else
737 {
738 /* Rockbox executable missing. Show info screen for 30 seconds. */
739 draw("/system/rbmissing.bmp");
740 sleep(30);
741
742 /* Do not block Vold, so stop after sleep. */
743 vold_monitor_stop();
744
745#ifdef DEBUG
746 system("setprop persist.sys.usb.config adb");
747 system("setprop persist.usb.debug 1");
748#endif
749
750 DEBUGF("DEBUG %s: Rockbox missing, excecuting %s.", __func__, OF_PLAYER_BIN);
751
752 /* Start OF MangoPlayer. */
753 int ret_code = system(OF_PLAYER_BIN);
754
755 DEBUGF("DEBUG %s: ret_code: %d.", __func__, ret_code);
756 }
757 }
758 else /* if(last_chosen_player == CHOICE_MANGO) */
759 {
760 vold_monitor_stop();
761
762 DEBUGF("DEBUG %s: Excecuting %s.", __func__, OF_PLAYER_BIN);
763
764 int ret_code = system(OF_PLAYER_BIN);
765
766 DEBUGF("DEBUG %s: ret_code: %d.", __func__, ret_code);
767 }
768 }
769
770 return 0;
771}
diff --git a/utils/ibassoboot/jni/qdbmp.c b/utils/ibassoboot/jni/qdbmp.c
new file mode 100644
index 0000000000..fd1337277d
--- /dev/null
+++ b/utils/ibassoboot/jni/qdbmp.c
@@ -0,0 +1,798 @@
1#include "qdbmp.h"
2#include <stdlib.h>
3#include <string.h>
4
5
6/* Bitmap header */
7typedef struct _BMP_Header
8{
9 USHORT Magic; /* Magic identifier: "BM" */
10 UINT FileSize; /* Size of the BMP file in bytes */
11 USHORT Reserved1; /* Reserved */
12 USHORT Reserved2; /* Reserved */
13 UINT DataOffset; /* Offset of image data relative to the file's start */
14 UINT HeaderSize; /* Size of the header in bytes */
15 UINT Width; /* Bitmap's width */
16 UINT Height; /* Bitmap's height */
17 USHORT Planes; /* Number of color planes in the bitmap */
18 USHORT BitsPerPixel; /* Number of bits per pixel */
19 UINT CompressionType; /* Compression type */
20 UINT ImageDataSize; /* Size of uncompressed image's data */
21 UINT HPixelsPerMeter; /* Horizontal resolution (pixels per meter) */
22 UINT VPixelsPerMeter; /* Vertical resolution (pixels per meter) */
23 UINT ColorsUsed; /* Number of color indexes in the color table that are actually used by the bitmap */
24 UINT ColorsRequired; /* Number of color indexes that are required for displaying the bitmap */
25} BMP_Header;
26
27
28/* Private data structure */
29struct _BMP
30{
31 BMP_Header Header;
32 UCHAR* Palette;
33 UCHAR* Data;
34};
35
36
37/* Holds the last error code */
38static BMP_STATUS BMP_LAST_ERROR_CODE = 0;
39
40
41/* Error description strings */
42static const char* BMP_ERROR_STRING[] =
43{
44 "",
45 "General error",
46 "Could not allocate enough memory to complete the operation",
47 "File input/output error",
48 "File not found",
49 "File is not a supported BMP variant (must be uncompressed 8, 24 or 32 BPP)",
50 "File is not a valid BMP image",
51 "An argument is invalid or out of range",
52 "The requested action is not compatible with the BMP's type"
53};
54
55
56/* Size of the palette data for 8 BPP bitmaps */
57#define BMP_PALETTE_SIZE ( 256 * 4 )
58
59
60
61/*********************************** Forward declarations **********************************/
62int ReadHeader ( BMP* bmp, FILE* f );
63int WriteHeader ( BMP* bmp, FILE* f );
64
65int ReadUINT ( UINT* x, FILE* f );
66int ReadUSHORT ( USHORT *x, FILE* f );
67
68int WriteUINT ( UINT x, FILE* f );
69int WriteUSHORT ( USHORT x, FILE* f );
70
71
72
73
74
75
76/*********************************** Public methods **********************************/
77
78
79/**************************************************************
80 Creates a blank BMP image with the specified dimensions
81 and bit depth.
82**************************************************************/
83BMP* BMP_Create( UINT width, UINT height, USHORT depth )
84{
85 BMP* bmp;
86 int bytes_per_pixel = depth >> 3;
87 UINT bytes_per_row;
88
89 if ( height <= 0 || width <= 0 )
90 {
91 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
92 return NULL;
93 }
94
95 if ( depth != 8 && depth != 24 && depth != 32 )
96 {
97 BMP_LAST_ERROR_CODE = BMP_FILE_NOT_SUPPORTED;
98 return NULL;
99 }
100
101
102 /* Allocate the bitmap data structure */
103 bmp = calloc( 1, sizeof( BMP ) );
104 if ( bmp == NULL )
105 {
106 BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
107 return NULL;
108 }
109
110
111 /* Set header' default values */
112 bmp->Header.Magic = 0x4D42;
113 bmp->Header.Reserved1 = 0;
114 bmp->Header.Reserved2 = 0;
115 bmp->Header.HeaderSize = 40;
116 bmp->Header.Planes = 1;
117 bmp->Header.CompressionType = 0;
118 bmp->Header.HPixelsPerMeter = 0;
119 bmp->Header.VPixelsPerMeter = 0;
120 bmp->Header.ColorsUsed = 0;
121 bmp->Header.ColorsRequired = 0;
122
123
124 /* Calculate the number of bytes used to store a single image row. This is always
125 rounded up to the next multiple of 4. */
126 bytes_per_row = width * bytes_per_pixel;
127 bytes_per_row += ( bytes_per_row % 4 ? 4 - bytes_per_row % 4 : 0 );
128
129
130 /* Set header's image specific values */
131 bmp->Header.Width = width;
132 bmp->Header.Height = height;
133 bmp->Header.BitsPerPixel = depth;
134 bmp->Header.ImageDataSize = bytes_per_row * height;
135 bmp->Header.FileSize = bmp->Header.ImageDataSize + 54 + ( depth == 8 ? BMP_PALETTE_SIZE : 0 );
136 bmp->Header.DataOffset = 54 + ( depth == 8 ? BMP_PALETTE_SIZE : 0 );
137
138
139 /* Allocate palette */
140 if ( bmp->Header.BitsPerPixel == 8 )
141 {
142 bmp->Palette = (UCHAR*) calloc( BMP_PALETTE_SIZE, sizeof( UCHAR ) );
143 if ( bmp->Palette == NULL )
144 {
145 BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
146 free( bmp );
147 return NULL;
148 }
149 }
150 else
151 {
152 bmp->Palette = NULL;
153 }
154
155
156 /* Allocate pixels */
157 bmp->Data = (UCHAR*) calloc( bmp->Header.ImageDataSize, sizeof( UCHAR ) );
158 if ( bmp->Data == NULL )
159 {
160 BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
161 free( bmp->Palette );
162 free( bmp );
163 return NULL;
164 }
165
166
167 BMP_LAST_ERROR_CODE = BMP_OK;
168
169 return bmp;
170}
171
172
173/**************************************************************
174 Frees all the memory used by the specified BMP image.
175**************************************************************/
176void BMP_Free( BMP* bmp )
177{
178 if ( bmp == NULL )
179 {
180 return;
181 }
182
183 if ( bmp->Palette != NULL )
184 {
185 free( bmp->Palette );
186 }
187
188 if ( bmp->Data != NULL )
189 {
190 free( bmp->Data );
191 }
192
193 free( bmp );
194
195 BMP_LAST_ERROR_CODE = BMP_OK;
196}
197
198
199/**************************************************************
200 Reads the specified BMP image file.
201**************************************************************/
202BMP* BMP_ReadFile( const char* filename )
203{
204 BMP* bmp;
205 FILE* f;
206
207 if ( filename == NULL )
208 {
209 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
210 return NULL;
211 }
212
213
214 /* Allocate */
215 bmp = calloc( 1, sizeof( BMP ) );
216 if ( bmp == NULL )
217 {
218 BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
219 return NULL;
220 }
221
222
223 /* Open file */
224 f = fopen( filename, "rb" );
225 if ( f == NULL )
226 {
227 BMP_LAST_ERROR_CODE = BMP_FILE_NOT_FOUND;
228 free( bmp );
229 return NULL;
230 }
231
232
233 /* Read header */
234 if ( ReadHeader( bmp, f ) != BMP_OK || bmp->Header.Magic != 0x4D42 )
235 {
236 BMP_LAST_ERROR_CODE = BMP_FILE_INVALID;
237 fclose( f );
238 free( bmp );
239 return NULL;
240 }
241
242
243 /* Verify that the bitmap variant is supported */
244 if ( ( bmp->Header.BitsPerPixel != 32 && bmp->Header.BitsPerPixel != 24 && bmp->Header.BitsPerPixel != 8 )
245 || bmp->Header.CompressionType != 0 || bmp->Header.HeaderSize != 40 )
246 {
247 BMP_LAST_ERROR_CODE = BMP_FILE_NOT_SUPPORTED;
248 fclose( f );
249 free( bmp );
250 return NULL;
251 }
252
253
254 /* Allocate and read palette */
255 if ( bmp->Header.BitsPerPixel == 8 )
256 {
257 bmp->Palette = (UCHAR*) malloc( BMP_PALETTE_SIZE * sizeof( UCHAR ) );
258 if ( bmp->Palette == NULL )
259 {
260 BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
261 fclose( f );
262 free( bmp );
263 return NULL;
264 }
265
266 if ( fread( bmp->Palette, sizeof( UCHAR ), BMP_PALETTE_SIZE, f ) != BMP_PALETTE_SIZE )
267 {
268 BMP_LAST_ERROR_CODE = BMP_FILE_INVALID;
269 fclose( f );
270 free( bmp->Palette );
271 free( bmp );
272 return NULL;
273 }
274 }
275 else /* Not an indexed image */
276 {
277 bmp->Palette = NULL;
278 }
279
280
281 /* Allocate memory for image data */
282 bmp->Data = (UCHAR*) malloc( bmp->Header.ImageDataSize );
283 if ( bmp->Data == NULL )
284 {
285 BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
286 fclose( f );
287 free( bmp->Palette );
288 free( bmp );
289 return NULL;
290 }
291
292
293 /* Read image data */
294 if ( fread( bmp->Data, sizeof( UCHAR ), bmp->Header.ImageDataSize, f ) != bmp->Header.ImageDataSize )
295 {
296 BMP_LAST_ERROR_CODE = BMP_FILE_INVALID;
297 fclose( f );
298 free( bmp->Data );
299 free( bmp->Palette );
300 free( bmp );
301 return NULL;
302 }
303
304
305 fclose( f );
306
307 BMP_LAST_ERROR_CODE = BMP_OK;
308
309 return bmp;
310}
311
312
313/**************************************************************
314 Writes the BMP image to the specified file.
315**************************************************************/
316void BMP_WriteFile( BMP* bmp, const char* filename )
317{
318 FILE* f;
319
320 if ( filename == NULL )
321 {
322 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
323 return;
324 }
325
326
327 /* Open file */
328 f = fopen( filename, "wb" );
329 if ( f == NULL )
330 {
331 BMP_LAST_ERROR_CODE = BMP_FILE_NOT_FOUND;
332 return;
333 }
334
335
336 /* Write header */
337 if ( WriteHeader( bmp, f ) != BMP_OK )
338 {
339 BMP_LAST_ERROR_CODE = BMP_IO_ERROR;
340 fclose( f );
341 return;
342 }
343
344
345 /* Write palette */
346 if ( bmp->Palette )
347 {
348 if ( fwrite( bmp->Palette, sizeof( UCHAR ), BMP_PALETTE_SIZE, f ) != BMP_PALETTE_SIZE )
349 {
350 BMP_LAST_ERROR_CODE = BMP_IO_ERROR;
351 fclose( f );
352 return;
353 }
354 }
355
356
357 /* Write data */
358 if ( fwrite( bmp->Data, sizeof( UCHAR ), bmp->Header.ImageDataSize, f ) != bmp->Header.ImageDataSize )
359 {
360 BMP_LAST_ERROR_CODE = BMP_IO_ERROR;
361 fclose( f );
362 return;
363 }
364
365
366 BMP_LAST_ERROR_CODE = BMP_OK;
367 fclose( f );
368}
369
370
371/**************************************************************
372 Returns the image's width.
373**************************************************************/
374UINT BMP_GetWidth( BMP* bmp )
375{
376 if ( bmp == NULL )
377 {
378 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
379 return -1;
380 }
381
382 BMP_LAST_ERROR_CODE = BMP_OK;
383
384 return ( bmp->Header.Width );
385}
386
387
388/**************************************************************
389 Returns the image's height.
390**************************************************************/
391UINT BMP_GetHeight( BMP* bmp )
392{
393 if ( bmp == NULL )
394 {
395 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
396 return -1;
397 }
398
399 BMP_LAST_ERROR_CODE = BMP_OK;
400
401 return ( bmp->Header.Height );
402}
403
404
405/**************************************************************
406 Returns the image's color depth (bits per pixel).
407**************************************************************/
408USHORT BMP_GetDepth( BMP* bmp )
409{
410 if ( bmp == NULL )
411 {
412 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
413 return -1;
414 }
415
416 BMP_LAST_ERROR_CODE = BMP_OK;
417
418 return ( bmp->Header.BitsPerPixel );
419}
420
421
422/**************************************************************
423 Populates the arguments with the specified pixel's RGB
424 values.
425**************************************************************/
426void BMP_GetPixelRGB( BMP* bmp, UINT x, UINT y, UCHAR* r, UCHAR* g, UCHAR* b )
427{
428 UCHAR* pixel;
429 UINT bytes_per_row;
430 UCHAR bytes_per_pixel;
431
432 if ( bmp == NULL || x < 0 || x >= bmp->Header.Width || y < 0 || y >= bmp->Header.Height )
433 {
434 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
435 }
436 else
437 {
438 BMP_LAST_ERROR_CODE = BMP_OK;
439
440 bytes_per_pixel = bmp->Header.BitsPerPixel >> 3;
441
442 /* Row's size is rounded up to the next multiple of 4 bytes */
443 bytes_per_row = bmp->Header.ImageDataSize / bmp->Header.Height;
444
445 /* Calculate the location of the relevant pixel (rows are flipped) */
446 pixel = bmp->Data + ( ( bmp->Header.Height - y - 1 ) * bytes_per_row + x * bytes_per_pixel );
447
448
449 /* In indexed color mode the pixel's value is an index within the palette */
450 if ( bmp->Header.BitsPerPixel == 8 )
451 {
452 pixel = bmp->Palette + *pixel * 4;
453 }
454
455 /* Note: colors are stored in BGR order */
456 if ( r ) *r = *( pixel + 2 );
457 if ( g ) *g = *( pixel + 1 );
458 if ( b ) *b = *( pixel + 0 );
459 }
460}
461
462
463/**************************************************************
464 Sets the specified pixel's RGB values.
465**************************************************************/
466void BMP_SetPixelRGB( BMP* bmp, UINT x, UINT y, UCHAR r, UCHAR g, UCHAR b )
467{
468 UCHAR* pixel;
469 UINT bytes_per_row;
470 UCHAR bytes_per_pixel;
471
472 if ( bmp == NULL || x < 0 || x >= bmp->Header.Width || y < 0 || y >= bmp->Header.Height )
473 {
474 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
475 }
476
477 else if ( bmp->Header.BitsPerPixel != 24 && bmp->Header.BitsPerPixel != 32 )
478 {
479 BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH;
480 }
481
482 else
483 {
484 BMP_LAST_ERROR_CODE = BMP_OK;
485
486 bytes_per_pixel = bmp->Header.BitsPerPixel >> 3;
487
488 /* Row's size is rounded up to the next multiple of 4 bytes */
489 bytes_per_row = bmp->Header.ImageDataSize / bmp->Header.Height;
490
491 /* Calculate the location of the relevant pixel (rows are flipped) */
492 pixel = bmp->Data + ( ( bmp->Header.Height - y - 1 ) * bytes_per_row + x * bytes_per_pixel );
493
494 /* Note: colors are stored in BGR order */
495 *( pixel + 2 ) = r;
496 *( pixel + 1 ) = g;
497 *( pixel + 0 ) = b;
498 }
499}
500
501
502/**************************************************************
503 Gets the specified pixel's color index.
504**************************************************************/
505void BMP_GetPixelIndex( BMP* bmp, UINT x, UINT y, UCHAR* val )
506{
507 UCHAR* pixel;
508 UINT bytes_per_row;
509
510 if ( bmp == NULL || x < 0 || x >= bmp->Header.Width || y < 0 || y >= bmp->Header.Height )
511 {
512 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
513 }
514
515 else if ( bmp->Header.BitsPerPixel != 8 )
516 {
517 BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH;
518 }
519
520 else
521 {
522 BMP_LAST_ERROR_CODE = BMP_OK;
523
524 /* Row's size is rounded up to the next multiple of 4 bytes */
525 bytes_per_row = bmp->Header.ImageDataSize / bmp->Header.Height;
526
527 /* Calculate the location of the relevant pixel */
528 pixel = bmp->Data + ( ( bmp->Header.Height - y - 1 ) * bytes_per_row + x );
529
530
531 if ( val ) *val = *pixel;
532 }
533}
534
535
536/**************************************************************
537 Sets the specified pixel's color index.
538**************************************************************/
539void BMP_SetPixelIndex( BMP* bmp, UINT x, UINT y, UCHAR val )
540{
541 UCHAR* pixel;
542 UINT bytes_per_row;
543
544 if ( bmp == NULL || x < 0 || x >= bmp->Header.Width || y < 0 || y >= bmp->Header.Height )
545 {
546 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
547 }
548
549 else if ( bmp->Header.BitsPerPixel != 8 )
550 {
551 BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH;
552 }
553
554 else
555 {
556 BMP_LAST_ERROR_CODE = BMP_OK;
557
558 /* Row's size is rounded up to the next multiple of 4 bytes */
559 bytes_per_row = bmp->Header.ImageDataSize / bmp->Header.Height;
560
561 /* Calculate the location of the relevant pixel */
562 pixel = bmp->Data + ( ( bmp->Header.Height - y - 1 ) * bytes_per_row + x );
563
564 *pixel = val;
565 }
566}
567
568
569/**************************************************************
570 Gets the color value for the specified palette index.
571**************************************************************/
572void BMP_GetPaletteColor( BMP* bmp, UCHAR index, UCHAR* r, UCHAR* g, UCHAR* b )
573{
574 if ( bmp == NULL )
575 {
576 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
577 }
578
579 else if ( bmp->Header.BitsPerPixel != 8 )
580 {
581 BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH;
582 }
583
584 else
585 {
586 if ( r ) *r = *( bmp->Palette + index * 4 + 2 );
587 if ( g ) *g = *( bmp->Palette + index * 4 + 1 );
588 if ( b ) *b = *( bmp->Palette + index * 4 + 0 );
589
590 BMP_LAST_ERROR_CODE = BMP_OK;
591 }
592}
593
594
595/**************************************************************
596 Sets the color value for the specified palette index.
597**************************************************************/
598void BMP_SetPaletteColor( BMP* bmp, UCHAR index, UCHAR r, UCHAR g, UCHAR b )
599{
600 if ( bmp == NULL )
601 {
602 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
603 }
604
605 else if ( bmp->Header.BitsPerPixel != 8 )
606 {
607 BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH;
608 }
609
610 else
611 {
612 *( bmp->Palette + index * 4 + 2 ) = r;
613 *( bmp->Palette + index * 4 + 1 ) = g;
614 *( bmp->Palette + index * 4 + 0 ) = b;
615
616 BMP_LAST_ERROR_CODE = BMP_OK;
617 }
618}
619
620
621/**************************************************************
622 Returns the last error code.
623**************************************************************/
624BMP_STATUS BMP_GetError()
625{
626 return BMP_LAST_ERROR_CODE;
627}
628
629
630/**************************************************************
631 Returns a description of the last error code.
632**************************************************************/
633const char* BMP_GetErrorDescription()
634{
635 if ( BMP_LAST_ERROR_CODE > 0 && BMP_LAST_ERROR_CODE < BMP_ERROR_NUM )
636 {
637 return BMP_ERROR_STRING[ BMP_LAST_ERROR_CODE ];
638 }
639 else
640 {
641 return NULL;
642 }
643}
644
645
646
647
648
649/*********************************** Private methods **********************************/
650
651
652/**************************************************************
653 Reads the BMP file's header into the data structure.
654 Returns BMP_OK on success.
655**************************************************************/
656int ReadHeader( BMP* bmp, FILE* f )
657{
658 if ( bmp == NULL || f == NULL )
659 {
660 return BMP_INVALID_ARGUMENT;
661 }
662
663 /* The header's fields are read one by one, and converted from the format's
664 little endian to the system's native representation. */
665 if ( !ReadUSHORT( &( bmp->Header.Magic ), f ) ) return BMP_IO_ERROR;
666 if ( !ReadUINT( &( bmp->Header.FileSize ), f ) ) return BMP_IO_ERROR;
667 if ( !ReadUSHORT( &( bmp->Header.Reserved1 ), f ) ) return BMP_IO_ERROR;
668 if ( !ReadUSHORT( &( bmp->Header.Reserved2 ), f ) ) return BMP_IO_ERROR;
669 if ( !ReadUINT( &( bmp->Header.DataOffset ), f ) ) return BMP_IO_ERROR;
670 if ( !ReadUINT( &( bmp->Header.HeaderSize ), f ) ) return BMP_IO_ERROR;
671 if ( !ReadUINT( &( bmp->Header.Width ), f ) ) return BMP_IO_ERROR;
672 if ( !ReadUINT( &( bmp->Header.Height ), f ) ) return BMP_IO_ERROR;
673 if ( !ReadUSHORT( &( bmp->Header.Planes ), f ) ) return BMP_IO_ERROR;
674 if ( !ReadUSHORT( &( bmp->Header.BitsPerPixel ), f ) ) return BMP_IO_ERROR;
675 if ( !ReadUINT( &( bmp->Header.CompressionType ), f ) ) return BMP_IO_ERROR;
676 if ( !ReadUINT( &( bmp->Header.ImageDataSize ), f ) ) return BMP_IO_ERROR;
677 if ( !ReadUINT( &( bmp->Header.HPixelsPerMeter ), f ) ) return BMP_IO_ERROR;
678 if ( !ReadUINT( &( bmp->Header.VPixelsPerMeter ), f ) ) return BMP_IO_ERROR;
679 if ( !ReadUINT( &( bmp->Header.ColorsUsed ), f ) ) return BMP_IO_ERROR;
680 if ( !ReadUINT( &( bmp->Header.ColorsRequired ), f ) ) return BMP_IO_ERROR;
681
682 return BMP_OK;
683}
684
685
686/**************************************************************
687 Writes the BMP file's header into the data structure.
688 Returns BMP_OK on success.
689**************************************************************/
690int WriteHeader( BMP* bmp, FILE* f )
691{
692 if ( bmp == NULL || f == NULL )
693 {
694 return BMP_INVALID_ARGUMENT;
695 }
696
697 /* The header's fields are written one by one, and converted to the format's
698 little endian representation. */
699 if ( !WriteUSHORT( bmp->Header.Magic, f ) ) return BMP_IO_ERROR;
700 if ( !WriteUINT( bmp->Header.FileSize, f ) ) return BMP_IO_ERROR;
701 if ( !WriteUSHORT( bmp->Header.Reserved1, f ) ) return BMP_IO_ERROR;
702 if ( !WriteUSHORT( bmp->Header.Reserved2, f ) ) return BMP_IO_ERROR;
703 if ( !WriteUINT( bmp->Header.DataOffset, f ) ) return BMP_IO_ERROR;
704 if ( !WriteUINT( bmp->Header.HeaderSize, f ) ) return BMP_IO_ERROR;
705 if ( !WriteUINT( bmp->Header.Width, f ) ) return BMP_IO_ERROR;
706 if ( !WriteUINT( bmp->Header.Height, f ) ) return BMP_IO_ERROR;
707 if ( !WriteUSHORT( bmp->Header.Planes, f ) ) return BMP_IO_ERROR;
708 if ( !WriteUSHORT( bmp->Header.BitsPerPixel, f ) ) return BMP_IO_ERROR;
709 if ( !WriteUINT( bmp->Header.CompressionType, f ) ) return BMP_IO_ERROR;
710 if ( !WriteUINT( bmp->Header.ImageDataSize, f ) ) return BMP_IO_ERROR;
711 if ( !WriteUINT( bmp->Header.HPixelsPerMeter, f ) ) return BMP_IO_ERROR;
712 if ( !WriteUINT( bmp->Header.VPixelsPerMeter, f ) ) return BMP_IO_ERROR;
713 if ( !WriteUINT( bmp->Header.ColorsUsed, f ) ) return BMP_IO_ERROR;
714 if ( !WriteUINT( bmp->Header.ColorsRequired, f ) ) return BMP_IO_ERROR;
715
716 return BMP_OK;
717}
718
719
720/**************************************************************
721 Reads a little-endian unsigned int from the file.
722 Returns non-zero on success.
723**************************************************************/
724int ReadUINT( UINT* x, FILE* f )
725{
726 UCHAR little[ 4 ]; /* BMPs use 32 bit ints */
727
728 if ( x == NULL || f == NULL )
729 {
730 return 0;
731 }
732
733 if ( fread( little, 4, 1, f ) != 1 )
734 {
735 return 0;
736 }
737
738 *x = ( little[ 3 ] << 24 | little[ 2 ] << 16 | little[ 1 ] << 8 | little[ 0 ] );
739
740 return 1;
741}
742
743
744/**************************************************************
745 Reads a little-endian unsigned short int from the file.
746 Returns non-zero on success.
747**************************************************************/
748int ReadUSHORT( USHORT *x, FILE* f )
749{
750 UCHAR little[ 2 ]; /* BMPs use 16 bit shorts */
751
752 if ( x == NULL || f == NULL )
753 {
754 return 0;
755 }
756
757 if ( fread( little, 2, 1, f ) != 1 )
758 {
759 return 0;
760 }
761
762 *x = ( little[ 1 ] << 8 | little[ 0 ] );
763
764 return 1;
765}
766
767
768/**************************************************************
769 Writes a little-endian unsigned int to the file.
770 Returns non-zero on success.
771**************************************************************/
772int WriteUINT( UINT x, FILE* f )
773{
774 UCHAR little[ 4 ]; /* BMPs use 32 bit ints */
775
776 little[ 3 ] = (UCHAR)( ( x & 0xff000000 ) >> 24 );
777 little[ 2 ] = (UCHAR)( ( x & 0x00ff0000 ) >> 16 );
778 little[ 1 ] = (UCHAR)( ( x & 0x0000ff00 ) >> 8 );
779 little[ 0 ] = (UCHAR)( ( x & 0x000000ff ) >> 0 );
780
781 return ( f && fwrite( little, 4, 1, f ) == 1 );
782}
783
784
785/**************************************************************
786 Writes a little-endian unsigned short int to the file.
787 Returns non-zero on success.
788**************************************************************/
789int WriteUSHORT( USHORT x, FILE* f )
790{
791 UCHAR little[ 2 ]; /* BMPs use 16 bit shorts */
792
793 little[ 1 ] = (UCHAR)( ( x & 0xff00 ) >> 8 );
794 little[ 0 ] = (UCHAR)( ( x & 0x00ff ) >> 0 );
795
796 return ( f && fwrite( little, 2, 1, f ) == 1 );
797}
798
diff --git a/utils/ibassoboot/jni/qdbmp.h b/utils/ibassoboot/jni/qdbmp.h
new file mode 100644
index 0000000000..d6c0e6c452
--- /dev/null
+++ b/utils/ibassoboot/jni/qdbmp.h
@@ -0,0 +1,133 @@
1#ifndef _BMP_H_
2#define _BMP_H_
3
4
5/**************************************************************
6
7 QDBMP - Quick n' Dirty BMP
8
9 v1.0.0 - 2007-04-07
10 http://qdbmp.sourceforge.net
11
12
13 The library supports the following BMP variants:
14 1. Uncompressed 32 BPP (alpha values are ignored)
15 2. Uncompressed 24 BPP
16 3. Uncompressed 8 BPP (indexed color)
17
18 QDBMP is free and open source software, distributed
19 under the MIT licence.
20
21 Copyright (c) 2007 Chai Braudo (braudo@users.sourceforge.net)
22
23 Permission is hereby granted, free of charge, to any person obtaining a copy
24 of this software and associated documentation files (the "Software"), to deal
25 in the Software without restriction, including without limitation the rights
26 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27 copies of the Software, and to permit persons to whom the Software is
28 furnished to do so, subject to the following conditions:
29
30 The above copyright notice and this permission notice shall be included in
31 all copies or substantial portions of the Software.
32
33 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
39 THE SOFTWARE.
40
41**************************************************************/
42
43#include <stdio.h>
44
45
46
47/* Type definitions */
48#ifndef UINT
49 #define UINT unsigned long int
50#endif
51
52#ifndef USHORT
53 #define USHORT unsigned short
54#endif
55
56#ifndef UCHAR
57 #define UCHAR unsigned char
58#endif
59
60
61/* Version */
62#define QDBMP_VERSION_MAJOR 1
63#define QDBMP_VERSION_MINOR 0
64#define QDBMP_VERSION_PATCH 1
65
66
67/* Error codes */
68typedef enum
69{
70 BMP_OK = 0, /* No error */
71 BMP_ERROR, /* General error */
72 BMP_OUT_OF_MEMORY, /* Could not allocate enough memory to complete the operation */
73 BMP_IO_ERROR, /* General input/output error */
74 BMP_FILE_NOT_FOUND, /* File not found */
75 BMP_FILE_NOT_SUPPORTED, /* File is not a supported BMP variant */
76 BMP_FILE_INVALID, /* File is not a BMP image or is an invalid BMP */
77 BMP_INVALID_ARGUMENT, /* An argument is invalid or out of range */
78 BMP_TYPE_MISMATCH, /* The requested action is not compatible with the BMP's type */
79 BMP_ERROR_NUM
80} BMP_STATUS;
81
82
83/* Bitmap image */
84typedef struct _BMP BMP;
85
86
87
88
89/*********************************** Public methods **********************************/
90
91
92/* Construction/destruction */
93BMP* BMP_Create ( UINT width, UINT height, USHORT depth );
94void BMP_Free ( BMP* bmp );
95
96
97/* I/O */
98BMP* BMP_ReadFile ( const char* filename );
99void BMP_WriteFile ( BMP* bmp, const char* filename );
100
101
102/* Meta info */
103UINT BMP_GetWidth ( BMP* bmp );
104UINT BMP_GetHeight ( BMP* bmp );
105USHORT BMP_GetDepth ( BMP* bmp );
106
107
108/* Pixel access */
109void BMP_GetPixelRGB ( BMP* bmp, UINT x, UINT y, UCHAR* r, UCHAR* g, UCHAR* b );
110void BMP_SetPixelRGB ( BMP* bmp, UINT x, UINT y, UCHAR r, UCHAR g, UCHAR b );
111void BMP_GetPixelIndex ( BMP* bmp, UINT x, UINT y, UCHAR* val );
112void BMP_SetPixelIndex ( BMP* bmp, UINT x, UINT y, UCHAR val );
113
114
115/* Palette handling */
116void BMP_GetPaletteColor ( BMP* bmp, UCHAR index, UCHAR* r, UCHAR* g, UCHAR* b );
117void BMP_SetPaletteColor ( BMP* bmp, UCHAR index, UCHAR r, UCHAR g, UCHAR b );
118
119
120/* Error handling */
121BMP_STATUS BMP_GetError ();
122const char* BMP_GetErrorDescription ();
123
124
125/* Useful macro that may be used after each BMP operation to check for an error */
126#define BMP_CHECK_ERROR( output_file, return_value ) \
127 if ( BMP_GetError() != BMP_OK ) \
128 { \
129 fprintf( ( output_file ), "BMP error: %s\n", BMP_GetErrorDescription() ); \
130 return( return_value ); \
131 } \
132
133#endif
diff --git a/utils/ibassoboot/jni/rbmissing.bmp b/utils/ibassoboot/jni/rbmissing.bmp
new file mode 100644
index 0000000000..1e97066d8c
--- /dev/null
+++ b/utils/ibassoboot/jni/rbmissing.bmp
Binary files differ
diff --git a/utils/ibassoboot/jni/usb.bmp b/utils/ibassoboot/jni/usb.bmp
new file mode 100644
index 0000000000..c462de2236
--- /dev/null
+++ b/utils/ibassoboot/jni/usb.bmp
Binary files differ
diff --git a/utils/ipodpatcher/Makefile b/utils/ipodpatcher/Makefile
new file mode 100644
index 0000000000..4254995d22
--- /dev/null
+++ b/utils/ipodpatcher/Makefile
@@ -0,0 +1,53 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10CFLAGS += -Wall -W
11
12# Build with "make BOOTOBJS=1" to build with embedded bootloaders and the
13# --install option and interactive mode. You need the full set of Rockbox
14# bootloaders in this directory - download them from
15# http://download.rockbox.org/bootloader/ipod/bootloaders.zip
16
17# Releases of ipodpatcher are created with "make RELEASE=1". This
18# enables BOOTOBJS and uses the VERSION string defined in main.c
19ifdef RELEASE
20CFLAGS += -DRELEASE
21BOOTOBJS=1
22endif
23
24ifdef BOOTOBJS
25BOOTSRC = ipod1g2g.c ipod3g.c ipod4g.c ipodcolor.c ipodmini1g.c \
26 ipodmini2g.c ipodnano1g.c ipodvideo.c ipodnano2g.c
27CFLAGS += -DWITH_BOOTOBJS
28endif
29
30# additional frameworks to link on on OS X
31LDOPTS_OSX = -framework CoreFoundation -framework IOKit
32
33LIBSOURCES = ipodpatcher.c fat32format.c arc4.c \
34 ipodio-posix.c ipodio-win32-scsi.c ipodio-win32.c
35SOURCES = main.c $(BOOTSRC)
36ipodpatcher: SOURCES+= ipodio-posix.c
37
38OUTPUT = ipodpatcher
39include ../libtools.make
40
41ipodpatcher.exe: $(OBJDIR)ipodpatcher-rc.o
42$(OBJDIR)ipodpatcher-rc.o: ipodpatcher.rc ipodpatcher.manifest
43 @echo WINDRES $(notdir $<)
44 $(SILENT)$(CROSS)$(WINDRES) -i $< -o $@
45
46%.c: bootloader-%.ipod $(BIN2C)
47 @echo BIN2C $<
48 $(SILENT)$(BIN2C) -i $< $*
49
50%.c: bootloader-%.ipodx $(BIN2C)
51 @echo BIN2C $<
52 $(SILENT)$(BIN2C) -i $< $*
53
diff --git a/utils/ipodpatcher/arc4.c b/utils/ipodpatcher/arc4.c
new file mode 100644
index 0000000000..75b1862b89
--- /dev/null
+++ b/utils/ipodpatcher/arc4.c
@@ -0,0 +1,108 @@
1/*
2 * arc4.c
3 * Release $Name: MATRIXSSL_1_8_3_OPEN $
4 *
5 * ARC4 stream cipher implementation
6 */
7/*
8 * Copyright (c) PeerSec Networks, 2002-2007. All Rights Reserved.
9 * The latest version of this code is available at http://www.matrixssl.org
10 *
11 * This software is open source; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This General Public License does NOT permit incorporating this software
17 * into proprietary programs. If you are unable to comply with the GPL, a
18 * commercial license for this software may be purchased from PeerSec Networks
19 * at http://www.peersec.com
20 *
21 * This program is distributed in WITHOUT ANY WARRANTY; without even the
22 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23 * See the GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 * http://www.gnu.org/copyleft/gpl.html
29 */
30/******************************************************************************/
31
32#include "arc4.h"
33
34/*
35 Some accounts, such as O'Reilly's Secure Programming Cookbook say that no
36 more than 2^30 bytes should be processed without rekeying, so we
37 enforce that limit here. FYI, this is equal to 1GB of data transferred.
38*/
39#define ARC4_MAX_BYTES 0x40000000
40
41/******************************************************************************/
42/*
43 SSL_RSA_WITH_RC4_* cipher callbacks
44 */
45void matrixArc4Init(struct rc4_key_t *ctx, unsigned char *key, int32_t keylen)
46{
47 unsigned char index1, index2, tmp, *state;
48 int16_t counter;
49
50 ctx->byteCount = 0;
51 state = &ctx->state[0];
52
53 for (counter = 0; counter < 256; counter++) {
54 state[counter] = (unsigned char)counter;
55 }
56 ctx->x = 0;
57 ctx->y = 0;
58 index1 = 0;
59 index2 = 0;
60
61 for (counter = 0; counter < 256; counter++) {
62 index2 = (key[index1] + state[counter] + index2) & 0xff;
63
64 tmp = state[counter];
65 state[counter] = state[index2];
66 state[index2] = tmp;
67
68 index1 = (index1 + 1) % keylen;
69 }
70}
71
72int32_t matrixArc4(struct rc4_key_t *ctx, unsigned char *in,
73 unsigned char *out, int32_t len)
74{
75 unsigned char x, y, *state, xorIndex, tmp;
76 int counter; /* NOTE BY DAVE CHAPMAN: This was a short in
77 the original code, which caused a segfault
78 when attempting to process data > 32767
79 bytes. */
80
81 ctx->byteCount += len;
82 if (ctx->byteCount > ARC4_MAX_BYTES) {
83 return -1;
84 }
85
86 x = ctx->x;
87 y = ctx->y;
88 state = &ctx->state[0];
89 for (counter = 0; counter < len; counter++) {
90 x = (x + 1) & 0xff;
91 y = (state[x] + y) & 0xff;
92
93 tmp = state[x];
94 state[x] = state[y];
95 state[y] = tmp;
96
97 xorIndex = (state[x] + state[y]) & 0xff;
98
99 tmp = in[counter];
100 tmp ^= state[xorIndex];
101 out[counter] = tmp;
102 }
103 ctx->x = x;
104 ctx->y = y;
105 return len;
106}
107
108/*****************************************************************************/
diff --git a/utils/ipodpatcher/arc4.h b/utils/ipodpatcher/arc4.h
new file mode 100644
index 0000000000..8bff0e2dc1
--- /dev/null
+++ b/utils/ipodpatcher/arc4.h
@@ -0,0 +1,47 @@
1/*
2 arc4.h - based on matrixssl-1-8-3-open
3
4*/
5
6/*
7 * Copyright (c) PeerSec Networks, 2002-2007. All Rights Reserved.
8 * The latest version of this code is available at http://www.matrixssl.org
9 *
10 * This software is open source; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This General Public License does NOT permit incorporating this software
16 * into proprietary programs. If you are unable to comply with the GPL, a
17 * commercial license for this software may be purchased from PeerSec Networks
18 * at http://www.peersec.com
19 *
20 * This program is distributed in WITHOUT ANY WARRANTY; without even the
21 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22 * See the GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 * http://www.gnu.org/copyleft/gpl.html
28 */
29/*****************************************************************************/
30
31#ifndef _ARC4_H
32
33#include <stdint.h>
34
35struct rc4_key_t
36{
37 unsigned char state[256];
38 uint32_t byteCount;
39 unsigned char x;
40 unsigned char y;
41};
42
43void matrixArc4Init(struct rc4_key_t *ctx, unsigned char *key, int32_t keylen);
44int32_t matrixArc4(struct rc4_key_t *ctx, unsigned char *in,
45 unsigned char *out, int32_t len);
46
47#endif
diff --git a/utils/ipodpatcher/fat32format.c b/utils/ipodpatcher/fat32format.c
new file mode 100644
index 0000000000..7ee8021cbf
--- /dev/null
+++ b/utils/ipodpatcher/fat32format.c
@@ -0,0 +1,530 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 *
11 * FAT32 formatting functions. Based on:
12 *
13 * Fat32 formatter version 1.03
14 * (c) Tom Thornhill 2005
15 * This software is covered by the GPL.
16 * By using this tool, you agree to absolve Ridgecrop of an liabilities for
17 * lost data.
18 * Please backup any data you value before using this tool.
19 *
20 *
21 * Modified June 2007 by Dave Chapman for use in ipodpatcher
22 *
23 *
24 * This program is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU General Public License
26 * as published by the Free Software Foundation; either version 2
27 * of the License, or (at your option) any later version.
28 *
29 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
30 * KIND, either express or implied.
31 *
32 ****************************************************************************/
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <stdbool.h>
38#include <stdint.h>
39#include <inttypes.h>
40
41#include "ipodio.h"
42
43static inline uint16_t swap16(uint16_t value)
44{
45 return (value >> 8) | (value << 8);
46}
47
48static inline uint32_t swap32(uint32_t value)
49{
50 uint32_t hi = swap16(value >> 16);
51 uint32_t lo = swap16(value & 0xffff);
52 return (lo << 16) | hi;
53}
54
55/* The following functions are not the most efficient, but are
56 self-contained and don't require needing to know endianness of CPU
57 at compile-time.
58
59 Note that htole16/htole32 exist on some platforms, so for
60 simplicity we use different names.
61
62*/
63
64static uint16_t rb_htole16(uint16_t x)
65{
66 uint16_t test = 0x1234;
67 unsigned char* p = (unsigned char*)&test;
68
69 if (p[0]==0x12) {
70 /* Big-endian */
71 return swap16(x);
72 } else {
73 return x;
74 }
75}
76
77static uint32_t rb_htole32(uint32_t x)
78{
79 uint32_t test = 0x12345678;
80 unsigned char* p = (unsigned char*)&test;
81
82 if (p[0]==0x12) {
83 /* Big-endian */
84 return swap32(x);
85 } else {
86 return x;
87 }
88}
89
90
91/* TODO: Pass these as parameters to the various create_ functions */
92
93/* can be zero for default or 1,2,4,8,16,32 or 64 */
94static int sectors_per_cluster = 0;
95
96/* Recommended values */
97static uint32_t ReservedSectCount = 32;
98static uint32_t NumFATs = 2;
99static uint32_t BackupBootSect = 6;
100static uint32_t VolumeId=0; /* calculated before format */
101
102/* Calculated later */
103static uint32_t FatSize=0;
104static uint32_t BytesPerSect=0;
105static uint32_t SectorsPerCluster=0;
106static uint32_t TotalSectors=0;
107static uint32_t SystemAreaSize=0;
108static uint32_t UserAreaSize=0;
109static uint8_t VolId[12] = "NO NAME ";
110
111
112struct FAT_BOOTSECTOR32
113{
114 /* Common fields. */
115 uint8_t sJmpBoot[3];
116 char sOEMName[8];
117 uint16_t wBytsPerSec;
118 uint8_t bSecPerClus;
119 uint16_t wRsvdSecCnt;
120 uint8_t bNumFATs;
121 uint16_t wRootEntCnt;
122 uint16_t wTotSec16; /* if zero, use dTotSec32 instead */
123 uint8_t bMedia;
124 uint16_t wFATSz16;
125 uint16_t wSecPerTrk;
126 uint16_t wNumHeads;
127 uint32_t dHiddSec;
128 uint32_t dTotSec32;
129
130 /* Fat 32/16 only */
131 uint32_t dFATSz32;
132 uint16_t wExtFlags;
133 uint16_t wFSVer;
134 uint32_t dRootClus;
135 uint16_t wFSInfo;
136 uint16_t wBkBootSec;
137 uint8_t Reserved[12];
138 uint8_t bDrvNum;
139 uint8_t Reserved1;
140 uint8_t bBootSig; /* == 0x29 if next three fields are ok */
141 uint32_t dBS_VolID;
142 uint8_t sVolLab[11];
143 uint8_t sBS_FilSysType[8];
144} __attribute__((packed));
145
146struct FAT_FSINFO {
147 uint32_t dLeadSig; // 0x41615252
148 uint8_t sReserved1[480]; // zeros
149 uint32_t dStrucSig; // 0x61417272
150 uint32_t dFree_Count; // 0xFFFFFFFF
151 uint32_t dNxt_Free; // 0xFFFFFFFF
152 uint8_t sReserved2[12]; // zeros
153 uint32_t dTrailSig; // 0xAA550000
154} __attribute__((packed));
155
156
157/* Write "count" zero sectors, starting at sector "sector" */
158static int zero_sectors(struct ipod_t* ipod, uint64_t sector, int count)
159{
160 int n;
161
162 if (ipod_seek(ipod, sector * ipod->sector_size) < 0) {
163 fprintf(stderr,"[ERR] Seek failed\n");
164 return -1;
165 }
166
167 memset(ipod->sectorbuf, 0, 128 * ipod->sector_size);
168
169 /* Write 128 sectors at a time */
170 while (count) {
171 if (count >= 128)
172 n = 128;
173 else
174 n = count;
175
176 if (ipod_write(ipod,n * ipod->sector_size) < 0) {
177 perror("[ERR] Write failed in zero_sectors\n");
178 return -1;
179 }
180
181 count -= n;
182 }
183
184 return 0;
185}
186
187
188/*
18928.2 CALCULATING THE VOLUME SERIAL NUMBER
190
191For example, say a disk was formatted on 26 Dec 95 at 9:55 PM and 41.94
192seconds. DOS takes the date and time just before it writes it to the
193disk.
194
195Low order word is calculated: Volume Serial Number is:
196 Month & Day 12/26 0c1ah
197 Sec & Hundrenths 41:94 295eh 3578:1d02
198 -----
199 3578h
200
201High order word is calculated:
202 Hours & Minutes 21:55 1537h
203 Year 1995 07cbh
204 -----
205 1d02h
206*/
207static uint32_t get_volume_id ( )
208{
209 /* TODO */
210#if 0
211 SYSTEMTIME s;
212 uint32_t d;
213 uint16_t lo,hi,tmp;
214
215 GetLocalTime( &s );
216
217 lo = s.wDay + ( s.wMonth << 8 );
218 tmp = (s.wMilliseconds/10) + (s.wSecond << 8 );
219 lo += tmp;
220
221 hi = s.wMinute + ( s.wHour << 8 );
222 hi += s.wYear;
223
224 d = lo + (hi << 16);
225 return(d);
226#endif
227 return(0);
228}
229
230/*
231This is the Microsoft calculation from FATGEN
232
233 uint32_t RootDirSectors = 0;
234 uint32_t TmpVal1, TmpVal2, FATSz;
235
236 TmpVal1 = DskSize - ( ReservedSecCnt + RootDirSectors);
237 TmpVal2 = (256 * SecPerClus) + NumFATs;
238 TmpVal2 = TmpVal2 / 2;
239 FATSz = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2;
240
241 return( FatSz );
242*/
243
244
245static uint32_t get_fat_size_sectors(uint32_t DskSize, uint32_t ReservedSecCnt,
246 uint32_t SecPerClus, uint32_t NumFATs,
247 uint32_t BytesPerSect)
248{
249 uint64_t Numerator, Denominator;
250 uint64_t FatElementSize = 4;
251 uint64_t FatSz;
252
253 /* This is based on
254 http://hjem.get2net.dk/rune_moeller_barnkob/filesystems/fat.html
255 I've made the obvious changes for FAT32
256 */
257
258 Numerator = FatElementSize * ( DskSize - ReservedSecCnt );
259 Denominator = ( SecPerClus * BytesPerSect ) + ( FatElementSize * NumFATs );
260 FatSz = Numerator / Denominator;
261
262 /* round up */
263 FatSz += 1;
264
265 return((uint32_t)FatSz);
266}
267
268static uint8_t get_spc(uint32_t ClusterSizeKB, uint32_t BytesPerSect)
269{
270 uint32_t spc = ( ClusterSizeKB * 1024 ) / BytesPerSect;
271 return( (uint8_t) spc );
272}
273
274static uint8_t get_sectors_per_cluster(uint32_t DiskSizeSectors,
275 uint32_t BytesPerSect)
276{
277 uint8_t ret = 0x01; /* 1 sector per cluster */
278 uint64_t DiskSizeBytes = (uint64_t)DiskSizeSectors * (uint64_t)BytesPerSect;
279 int64_t DiskSizeMB = DiskSizeBytes / ( 1024*1024 );
280
281 /* 512 MB to 8,191 MB 4 KB */
282 if ( DiskSizeMB > 512 )
283 ret = get_spc( 4, BytesPerSect ); /* ret = 0x8; */
284
285 /* 8,192 MB to 16,383 MB 8 KB */
286 if ( DiskSizeMB > 8192 )
287 ret = get_spc( 8, BytesPerSect ); /* ret = 0x10; */
288
289 /* 16,384 MB to 32,767 MB 16 KB */
290 if ( DiskSizeMB > 16384 )
291 ret = get_spc( 16, BytesPerSect ); /* ret = 0x20; */
292
293 /* Larger than 32,768 MB 32 KB */
294 if ( DiskSizeMB > 32768 )
295 ret = get_spc( 32, BytesPerSect ); /* ret = 0x40; */
296
297 return( ret );
298
299}
300
301static void create_boot_sector(unsigned char* buf,
302 struct ipod_t* ipod, int partition)
303{
304 struct FAT_BOOTSECTOR32* pFAT32BootSect = (struct FAT_BOOTSECTOR32*)buf;
305
306 /* fill out the boot sector and fs info */
307 pFAT32BootSect->sJmpBoot[0]=0xEB;
308 pFAT32BootSect->sJmpBoot[1]=0x5A;
309 pFAT32BootSect->sJmpBoot[2]=0x90;
310 memcpy(pFAT32BootSect->sOEMName, "MSWIN4.1", 8 );
311 pFAT32BootSect->wBytsPerSec = rb_htole16(BytesPerSect);
312 pFAT32BootSect->bSecPerClus = SectorsPerCluster ;
313 pFAT32BootSect->wRsvdSecCnt = rb_htole16(ReservedSectCount);
314 pFAT32BootSect->bNumFATs = NumFATs;
315 pFAT32BootSect->wRootEntCnt = rb_htole16(0);
316 pFAT32BootSect->wTotSec16 = rb_htole16(0);
317 pFAT32BootSect->bMedia = 0xF8;
318 pFAT32BootSect->wFATSz16 = rb_htole16(0);
319 pFAT32BootSect->wSecPerTrk = rb_htole16(ipod->sectors_per_track);
320 pFAT32BootSect->wNumHeads = rb_htole16(ipod->num_heads);
321 pFAT32BootSect->dHiddSec = rb_htole16(ipod->pinfo[partition].start);
322 pFAT32BootSect->dTotSec32 = rb_htole32(TotalSectors);
323 pFAT32BootSect->dFATSz32 = rb_htole32(FatSize);
324 pFAT32BootSect->wExtFlags = rb_htole16(0);
325 pFAT32BootSect->wFSVer = rb_htole16(0);
326 pFAT32BootSect->dRootClus = rb_htole32(2);
327 pFAT32BootSect->wFSInfo = rb_htole16(1);
328 pFAT32BootSect->wBkBootSec = rb_htole16(BackupBootSect);
329 pFAT32BootSect->bDrvNum = 0x80;
330 pFAT32BootSect->Reserved1 = 0;
331 pFAT32BootSect->bBootSig = 0x29;
332 pFAT32BootSect->dBS_VolID = rb_htole32(VolumeId);
333 memcpy(pFAT32BootSect->sVolLab, VolId, 11);
334 memcpy(pFAT32BootSect->sBS_FilSysType, "FAT32 ", 8 );
335
336 buf[510] = 0x55;
337 buf[511] = 0xaa;
338}
339
340static void create_fsinfo(unsigned char* buf)
341{
342 struct FAT_FSINFO* pFAT32FsInfo = (struct FAT_FSINFO*)buf;
343
344 /* FSInfo sect */
345 pFAT32FsInfo->dLeadSig = rb_htole32(0x41615252);
346 pFAT32FsInfo->dStrucSig = rb_htole32(0x61417272);
347 pFAT32FsInfo->dFree_Count = rb_htole32((uint32_t) -1);
348 pFAT32FsInfo->dNxt_Free = rb_htole32((uint32_t) -1);
349 pFAT32FsInfo->dTrailSig = rb_htole32(0xaa550000);
350 pFAT32FsInfo->dFree_Count = rb_htole32((UserAreaSize/SectorsPerCluster)-1);
351
352 /* clusters 0-1 reserved, we used cluster 2 for the root dir */
353 pFAT32FsInfo->dNxt_Free = rb_htole32(3);
354}
355
356static void create_firstfatsector(unsigned char* buf)
357{
358 uint32_t* p = (uint32_t*)buf; /* We know the buffer is aligned */
359
360 /* First FAT Sector */
361 p[0] = rb_htole32(0x0ffffff8); /* Reserved cluster 1 media id in low byte */
362 p[1] = rb_htole32(0x0fffffff); /* Reserved cluster 2 EOC */
363 p[2] = rb_htole32(0x0fffffff); /* end of cluster chain for root dir */
364}
365
366int format_partition(struct ipod_t* ipod, int partition)
367{
368 uint32_t i;
369 uint64_t qTotalSectors=0;
370 uint64_t FatNeeded;
371
372 VolumeId = get_volume_id( );
373
374 /* Only support hard disks at the moment */
375 if ( ipod->sector_size != 512 )
376 {
377 fprintf(stderr,"[ERR] Only disks with 512 bytes per sector are supported.\n");
378 return -1;
379 }
380 BytesPerSect = ipod->sector_size;
381
382 /* Checks on Disk Size */
383 qTotalSectors = ipod->pinfo[partition].size;
384
385 /* low end limit - 65536 sectors */
386 if ( qTotalSectors < 65536 )
387 {
388 /* I suspect that most FAT32 implementations would mount this
389 volume just fine, but the spec says that we shouldn't do
390 this, so we won't */
391
392 fprintf(stderr,"[ERR] This drive is too small for FAT32 - there must be at least 64K clusters\n" );
393 return -1;
394 }
395
396 if ( qTotalSectors >= 0xffffffff )
397 {
398 /* This is a more fundamental limitation on FAT32 - the total
399 sector count in the root dir is 32bit. With a bit of
400 creativity, FAT32 could be extended to handle at least 2^28
401 clusters There would need to be an extra field in the
402 FSInfo sector, and the old sector count could be set to
403 0xffffffff. This is non standard though, the Windows FAT
404 driver FASTFAT.SYS won't understand this. Perhaps a future
405 version of FAT32 and FASTFAT will handle this. */
406
407 fprintf(stderr,"[ERR] This drive is too big for FAT32 - max 2TB supported\n");
408 }
409
410 if ( sectors_per_cluster ) {
411 SectorsPerCluster = sectors_per_cluster;
412 } else {
413 SectorsPerCluster = get_sectors_per_cluster(ipod->pinfo[partition].size,
414 BytesPerSect );
415 }
416
417 TotalSectors = (uint32_t) qTotalSectors;
418
419 FatSize = get_fat_size_sectors(TotalSectors, ReservedSectCount,
420 SectorsPerCluster, NumFATs, BytesPerSect );
421
422 UserAreaSize = TotalSectors - ReservedSectCount - (NumFATs*FatSize);
423
424 /* First zero out ReservedSect + FatSize * NumFats + SectorsPerCluster */
425 SystemAreaSize = (ReservedSectCount+(NumFATs*FatSize) + SectorsPerCluster);
426
427 /* Work out the Cluster count */
428 FatNeeded = UserAreaSize/SectorsPerCluster;
429
430 /* check for a cluster count of >2^28, since the upper 4 bits of
431 the cluster values in the FAT are reserved. */
432 if (FatNeeded > 0x0FFFFFFF) {
433 fprintf(stderr,"[ERR] This drive has more than 2^28 clusters, try to specify a larger cluster size\n" );
434 return -1;
435 }
436
437 /* Sanity check, make sure the fat is big enough.
438 Convert the cluster count into a Fat sector count, and check
439 the fat size value we calculated earlier is OK. */
440
441 FatNeeded *=4;
442 FatNeeded += (BytesPerSect-1);
443 FatNeeded /= BytesPerSect;
444
445 if ( FatNeeded > FatSize ) {
446 fprintf(stderr,"[ERR] Drive too big to format\n");
447 return -1;
448 }
449
450 /*
451 Write boot sector, fats
452 Sector 0 Boot Sector
453 Sector 1 FSInfo
454 Sector 2 More boot code - we write zeros here
455 Sector 3 unused
456 Sector 4 unused
457 Sector 5 unused
458 Sector 6 Backup boot sector
459 Sector 7 Backup FSInfo sector
460 Sector 8 Backup 'more boot code'
461 zero'd sectors upto ReservedSectCount
462 FAT1 ReservedSectCount to ReservedSectCount + FatSize
463 ...
464 FATn ReservedSectCount to ReservedSectCount + FatSize
465 RootDir - allocated to cluster2
466 */
467
468 fprintf(stderr,"[INFO] Heads - %d, sectors/track = %d\n",ipod->num_heads,ipod->sectors_per_track);
469 fprintf(stderr,"[INFO] Size : %" PRIu64 "GB %u sectors\n",
470 ((uint64_t)ipod->pinfo[partition].size * (uint64_t)ipod->sector_size) / (1000*1000*1000), TotalSectors );
471 fprintf(stderr,"[INFO] %d Bytes Per Sector, Cluster size %d bytes\n", BytesPerSect, SectorsPerCluster*BytesPerSect );
472 fprintf(stderr,"[INFO] Volume ID is %x:%x\n", VolumeId>>16, VolumeId&0xffff );
473 fprintf(stderr,"[INFO] %d Reserved Sectors, %d Sectors per FAT, %d fats\n", ReservedSectCount, FatSize, NumFATs );
474 fprintf (stderr,"[INFO] %d Total clusters\n", UserAreaSize/SectorsPerCluster );
475
476 fprintf(stderr,"[INFO] Formatting partition %d:...\n",partition);
477
478 /* Once zero_sectors has run, any data on the drive is basically lost... */
479 fprintf(stderr,"[INFO] Clearing out %d sectors for Reserved sectors, fats and root cluster...\n", SystemAreaSize );
480
481 zero_sectors(ipod, ipod->pinfo[partition].start, SystemAreaSize);
482
483 fprintf(stderr,"[INFO] Initialising reserved sectors and FATs...\n" );
484
485 /* Create the boot sector structure */
486 create_boot_sector(ipod->sectorbuf, ipod, partition);
487 create_fsinfo(ipod->sectorbuf + 512);
488
489 /* Write boot sector and fsinfo at start of partition */
490 if (ipod_seek(ipod, ipod->pinfo[partition].start * ipod->sector_size) < 0) {
491 fprintf(stderr,"[ERR] Seek failed\n");
492 return -1;
493 }
494 if (ipod_write(ipod,512 * 2) < 0) {
495 perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n");
496 return -1;
497 }
498
499 /* Write backup copy of boot sector and fsinfo */
500 if (ipod_seek(ipod, (ipod->pinfo[partition].start + BackupBootSect) * ipod->sector_size) < 0) {
501 fprintf(stderr,"[ERR] Seek failed\n");
502 return -1;
503 }
504 if (ipod_write(ipod,512 * 2) < 0) {
505 perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n");
506 return -1;
507 }
508
509 /* Create the first FAT sector */
510 create_firstfatsector(ipod->sectorbuf);
511
512 /* Write the first fat sector in the right places */
513 for ( i=0; i<NumFATs; i++ ) {
514 int SectorStart = ReservedSectCount + (i * FatSize );
515
516 if (ipod_seek(ipod, (ipod->pinfo[partition].start + SectorStart) * ipod->sector_size) < 0) {
517 fprintf(stderr,"[ERR] Seek failed\n");
518 return -1;
519 }
520
521 if (ipod_write(ipod,512) < 0) {
522 perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n");
523 return -1;
524 }
525 }
526
527 fprintf(stderr,"[INFO] Format successful\n");
528
529 return 0;
530}
diff --git a/utils/ipodpatcher/ipodio-posix.c b/utils/ipodpatcher/ipodio-posix.c
new file mode 100644
index 0000000000..9b386d994f
--- /dev/null
+++ b/utils/ipodpatcher/ipodio-posix.c
@@ -0,0 +1,409 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006-2007 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#if !defined(_WIN32) /* all non-Windows platforms are considered POSIX. */
23
24#include <stdio.h>
25#include <unistd.h>
26#include <fcntl.h>
27#include <string.h>
28#include <stdlib.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <sys/ioctl.h>
32#include <errno.h>
33
34#include "ipodio.h"
35
36#if defined(linux) || defined (__linux)
37#include <sys/mount.h>
38#include <linux/hdreg.h>
39#include <scsi/scsi_ioctl.h>
40#include <scsi/sg.h>
41
42#define IPOD_SECTORSIZE_IOCTL BLKSSZGET
43
44static void get_geometry(struct ipod_t* ipod)
45{
46 struct hd_geometry geometry;
47
48 if (!ioctl(ipod->dh, HDIO_GETGEO, &geometry)) {
49 /* never use geometry.cylinders - it is truncated */
50 ipod->num_heads = geometry.heads;
51 ipod->sectors_per_track = geometry.sectors;
52 } else {
53 ipod->num_heads = 0;
54 ipod->sectors_per_track = 0;
55 }
56}
57
58/* Linux SCSI Inquiry code based on the documentation and example code from
59 http://www.ibm.com/developerworks/linux/library/l-scsi-api/index.html
60*/
61
62int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code,
63 unsigned char* buf, int bufsize)
64{
65 unsigned char cdb[6];
66 struct sg_io_hdr hdr;
67 unsigned char sense_buffer[255];
68
69 memset(&hdr, 0, sizeof(hdr));
70
71 hdr.interface_id = 'S'; /* this is the only choice we have! */
72 hdr.flags = SG_FLAG_LUN_INHIBIT; /* this would put the LUN to 2nd byte of cdb*/
73
74 /* Set xfer data */
75 hdr.dxferp = buf;
76 hdr.dxfer_len = bufsize;
77
78 /* Set sense data */
79 hdr.sbp = sense_buffer;
80 hdr.mx_sb_len = sizeof(sense_buffer);
81
82 /* Set the cdb format */
83 cdb[0] = 0x12;
84 cdb[1] = 1; /* Enable Vital Product Data (EVPD) */
85 cdb[2] = page_code & 0xff;
86 cdb[3] = 0;
87 cdb[4] = 0xff;
88 cdb[5] = 0; /* For control filed, just use 0 */
89
90 hdr.dxfer_direction = SG_DXFER_FROM_DEV;
91 hdr.cmdp = cdb;
92 hdr.cmd_len = 6;
93
94 int ret = ioctl(ipod->dh, SG_IO, &hdr);
95
96 if (ret < 0) {
97 return -1;
98 } else {
99 return 0;
100 }
101}
102
103#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \
104 || defined(__bsdi__) || defined(__DragonFly__)
105#include <sys/disk.h>
106#define IPOD_SECTORSIZE_IOCTL DIOCGSECTORSIZE
107
108/* TODO: Implement this function for BSD */
109static void get_geometry(struct ipod_t* ipod)
110{
111 /* Are these universal for all ipods? */
112 ipod->num_heads = 255;
113 ipod->sectors_per_track = 63;
114}
115
116int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code,
117 unsigned char* buf, int bufsize)
118{
119 /* TODO: Implement for BSD */
120 (void)ipod;
121 (void)page_code;
122 (void)buf;
123 (void)bufsize;
124 return -1;
125}
126
127#elif defined(__APPLE__) && defined(__MACH__)
128/* OS X IOKit includes don't like VERSION being defined! */
129#undef VERSION
130#include <sys/disk.h>
131#include <CoreFoundation/CoreFoundation.h>
132#include <IOKit/IOKitLib.h>
133#include <IOKit/scsi/SCSITaskLib.h>
134#include <IOKit/scsi/SCSICommandOperationCodes.h>
135#define IPOD_SECTORSIZE_IOCTL DKIOCGETBLOCKSIZE
136
137/* TODO: Implement this function for Mac OS X */
138static void get_geometry(struct ipod_t* ipod)
139{
140 /* Are these universal for all ipods? */
141 ipod->num_heads = 255;
142 ipod->sectors_per_track = 63;
143}
144
145int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code,
146 unsigned char* buf, int bufsize)
147{
148 /* OS X doesn't allow to simply send out a SCSI inquiry request but
149 * requires registering an interface handler first.
150 * Currently this is done on each inquiry request which is somewhat
151 * inefficient but the current ipodpatcher API doesn't really fit here.
152 * Based on the documentation in Apple's document
153 * "SCSI Architecture Model Device Interface Guide".
154 *
155 * WARNING: this code currently doesn't take the selected device into
156 * account. It simply looks for an Ipod on the system and uses
157 * the first match.
158 */
159 (void)ipod;
160 int result = 0;
161 /* first, create a dictionary to match the device. This is needed to get the
162 * service. */
163 CFMutableDictionaryRef match_dict;
164 match_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL);
165 if(match_dict == NULL)
166 return -1;
167
168 /* set value to match. In case of the Ipod this is "iPodUserClientDevice". */
169 CFMutableDictionaryRef sub_dict;
170 sub_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL);
171 if(sub_dict == NULL)
172 return -1;
173 CFDictionarySetValue(sub_dict, CFSTR(kIOPropertySCSITaskDeviceCategory),
174 CFSTR("iPodUserClientDevice"));
175 CFDictionarySetValue(match_dict, CFSTR(kIOPropertyMatchKey), sub_dict);
176
177 /* get an iterator for searching for the service. */
178 kern_return_t kr;
179 io_iterator_t iterator = IO_OBJECT_NULL;
180 /* get matching services from IO registry. Consumes one reference to
181 * the dictionary, so no need to release that. */
182 kr = IOServiceGetMatchingServices(kIOMasterPortDefault, match_dict, &iterator);
183
184 if(!iterator | (kr != kIOReturnSuccess))
185 return -1;
186
187 /* get interface and obtain exclusive access */
188 SInt32 score;
189 HRESULT herr;
190 kern_return_t err;
191 IOCFPlugInInterface **plugin_interface = NULL;
192 SCSITaskDeviceInterface **interface = NULL;
193 io_service_t device = IO_OBJECT_NULL;
194 device = IOIteratorNext(iterator);
195
196 err = IOCreatePlugInInterfaceForService(device, kIOSCSITaskDeviceUserClientTypeID,
197 kIOCFPlugInInterfaceID, &plugin_interface,
198 &score);
199
200 if(err != noErr) {
201 return -1;
202 }
203 /* query the plugin interface for task interface */
204 herr = (*plugin_interface)->QueryInterface(plugin_interface,
205 CFUUIDGetUUIDBytes(kIOSCSITaskDeviceInterfaceID), (LPVOID*)&interface);
206 if(herr != S_OK) {
207 IODestroyPlugInInterface(plugin_interface);
208 return -1;
209 }
210
211 err = (*interface)->ObtainExclusiveAccess(interface);
212 if(err != noErr) {
213 (*interface)->Release(interface);
214 IODestroyPlugInInterface(plugin_interface);
215 return -1;
216 }
217
218 /* do the inquiry */
219 SCSITaskInterface **task = NULL;
220
221 task = (*interface)->CreateSCSITask(interface);
222 if(task != NULL) {
223 kern_return_t err;
224 SCSITaskStatus task_status;
225 IOVirtualRange* range;
226 SCSI_Sense_Data sense_data;
227 SCSICommandDescriptorBlock cdb;
228 UInt64 transfer_count = 0;
229 memset(buf, 0, bufsize);
230 /* allocate virtual range for buffer. */
231 range = (IOVirtualRange*) malloc(sizeof(IOVirtualRange));
232 memset(&sense_data, 0, sizeof(sense_data));
233 memset(cdb, 0, sizeof(cdb));
234 /* set up range. address is buffer address, length is request size. */
235 range->address = (IOVirtualAddress)buf;
236 range->length = bufsize;
237 /* setup CDB */
238 cdb[0] = 0x12; /* inquiry */
239 cdb[1] = 1;
240 cdb[2] = page_code;
241 cdb[4] = bufsize;
242
243 /* set cdb in task */
244 err = (*task)->SetCommandDescriptorBlock(task, cdb, kSCSICDBSize_6Byte);
245 if(err != kIOReturnSuccess) {
246 result = -1;
247 goto cleanup;
248 }
249 err = (*task)->SetScatterGatherEntries(task, range, 1, bufsize,
250 kSCSIDataTransfer_FromTargetToInitiator);
251 if(err != kIOReturnSuccess) {
252 result = -1;
253 goto cleanup;
254 }
255 /* set timeout */
256 err = (*task)->SetTimeoutDuration(task, 10000);
257 if(err != kIOReturnSuccess) {
258 result = -1;
259 goto cleanup;
260 }
261
262 /* request data */
263 err = (*task)->ExecuteTaskSync(task, &sense_data, &task_status, &transfer_count);
264 if(err != kIOReturnSuccess) {
265 result = -1;
266 goto cleanup;
267 }
268 /* cleanup */
269 free(range);
270
271 /* release task interface */
272 (*task)->Release(task);
273 }
274 else {
275 result = -1;
276 }
277cleanup:
278 /* cleanup interface */
279 (*interface)->ReleaseExclusiveAccess(interface);
280 (*interface)->Release(interface);
281 IODestroyPlugInInterface(plugin_interface);
282
283 return result;
284}
285
286#else
287 #error No sector-size detection implemented for this platform
288#endif
289
290#if defined(__APPLE__) && defined(__MACH__)
291static int ipod_unmount(struct ipod_t* ipod)
292{
293 char cmd[4096];
294 int res;
295
296 sprintf(cmd, "/usr/sbin/diskutil unmount \"%ss2\"",ipod->diskname);
297 fprintf(stderr,"[INFO] ");
298 res = system(cmd);
299
300 if (res==0) {
301 return 0;
302 } else {
303 perror("Unmount failed");
304 return -1;
305 }
306}
307#endif
308
309void ipod_print_error(char* msg)
310{
311 perror(msg);
312}
313
314int ipod_open(struct ipod_t* ipod, int silent)
315{
316 ipod->dh=open(ipod->diskname,O_RDONLY);
317 if (ipod->dh < 0) {
318 if (!silent) perror(ipod->diskname);
319 if(errno == EACCES) return -2;
320 else return -1;
321 }
322
323 /* Read information about the disk */
324
325 if(ioctl(ipod->dh,IPOD_SECTORSIZE_IOCTL,&ipod->sector_size) < 0) {
326 ipod->sector_size=512;
327 if (!silent) {
328 fprintf(stderr,"[ERR] ioctl() call to get sector size failed, defaulting to %d\n"
329 ,ipod->sector_size);
330 }
331 }
332
333 get_geometry(ipod);
334
335 return 0;
336}
337
338
339int ipod_reopen_rw(struct ipod_t* ipod)
340{
341#if defined(__APPLE__) && defined(__MACH__)
342 if (ipod_unmount(ipod) < 0)
343 return -1;
344#endif
345
346 close(ipod->dh);
347 ipod->dh=open(ipod->diskname,O_RDWR);
348 if (ipod->dh < 0) {
349 perror(ipod->diskname);
350 return -1;
351 }
352 return 0;
353}
354
355int ipod_close(struct ipod_t* ipod)
356{
357 close(ipod->dh);
358 return 0;
359}
360
361int ipod_alloc_buffer(struct ipod_t* ipod, int bufsize)
362{
363 ipod->sectorbuf = malloc(bufsize);
364 if (ipod->sectorbuf== NULL) {
365 return -1;
366 }
367 return 0;
368}
369
370int ipod_dealloc_buffer(struct ipod_t* ipod)
371{
372 if (ipod->sectorbuf == NULL) {
373 return -1;
374 }
375 free(ipod->sectorbuf);
376 ipod->sectorbuf = NULL;
377 return 0;
378}
379
380int ipod_seek(struct ipod_t* ipod, unsigned long pos)
381{
382 off_t res;
383
384 res = lseek(ipod->dh, pos, SEEK_SET);
385
386 if (res == -1) {
387 return -1;
388 }
389 return 0;
390}
391
392ssize_t ipod_read(struct ipod_t* ipod, int nbytes)
393{
394 if(ipod->sectorbuf == NULL) {
395 return -1;
396 }
397 return read(ipod->dh, ipod->sectorbuf, nbytes);
398}
399
400ssize_t ipod_write(struct ipod_t* ipod, int nbytes)
401{
402 if(ipod->sectorbuf == NULL) {
403 return -1;
404 }
405 return write(ipod->dh, ipod->sectorbuf, nbytes);
406}
407
408#endif
409
diff --git a/utils/ipodpatcher/ipodio-win32-scsi.c b/utils/ipodpatcher/ipodio-win32-scsi.c
new file mode 100644
index 0000000000..16460cfba3
--- /dev/null
+++ b/utils/ipodpatcher/ipodio-win32-scsi.c
@@ -0,0 +1,147 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 *
21 * Based on the getCapsUsingSCSIPassThrough() function from "cddrv.cpp":
22 * - http://www.farmanager.com/svn/trunk/unicode_far/cddrv.cpp
23 *
24 * Copyright (c) 1996 Eugene Roshal
25 * Copyright (c) 2000 Far Group
26 * All rights reserved.
27 *
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
30 * are met:
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. The name of the authors may not be used to endorse or promote products
37 * derived from this software without specific prior written permission.
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
40 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
42 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
43 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
45 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
46 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
47 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
48 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49 *
50 ****************************************************************************/
51
52#if defined(_WIN32)
53#include <windows.h>
54#include <stddef.h>
55#include <stdio.h>
56
57#include "ipodio.h"
58
59/* from ddk/ntddscsi.h */
60#define SCSI_IOCTL_DATA_OUT 0
61#define SCSI_IOCTL_DATA_IN 1
62#define SCSI_IOCTL_DATA_UNSPECIFIED 2
63
64#define IOCTL_SCSI_PASS_THROUGH \
65 CTL_CODE(FILE_DEVICE_CONTROLLER, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
66
67typedef struct _SCSI_PASS_THROUGH {
68 USHORT Length;
69 UCHAR ScsiStatus;
70 UCHAR PathId;
71 UCHAR TargetId;
72 UCHAR Lun;
73 UCHAR CdbLength;
74 UCHAR SenseInfoLength;
75 UCHAR DataIn;
76 ULONG DataTransferLength;
77 ULONG TimeOutValue;
78 ULONG_PTR DataBufferOffset;
79 ULONG SenseInfoOffset;
80 UCHAR Cdb[16];
81} SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH;
82
83typedef struct _SCSI_PASS_THROUGH_WITH_BUFFERS {
84 SCSI_PASS_THROUGH Spt;
85 ULONG Filler; /* realign buffers to double word boundary */
86 UCHAR SenseBuf[32];
87 UCHAR DataBuf[512];
88} SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS;
89
90int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code,
91 unsigned char* buf, int bufsize)
92{
93 SCSI_PASS_THROUGH_WITH_BUFFERS sptwb;
94 ULONG length;
95 DWORD returned;
96 BOOL status;
97
98 if (bufsize > 255) {
99 fprintf(stderr,"[ERR] Invalid bufsize in ipod_scsi_inquiry\n");
100 return -1;
101 }
102
103 memset(&sptwb, 0, sizeof(sptwb));
104
105 sptwb.Spt.Length = sizeof(SCSI_PASS_THROUGH);
106 sptwb.Spt.PathId = 0;
107 sptwb.Spt.TargetId = 1;
108 sptwb.Spt.Lun = 0;
109 sptwb.Spt.CdbLength = 6;
110 sptwb.Spt.SenseInfoLength = 32; /* sbuf size */;
111 sptwb.Spt.DataIn = SCSI_IOCTL_DATA_IN;
112 sptwb.Spt.DataTransferLength = bufsize;
113 sptwb.Spt.TimeOutValue = 2; /* 2 seconds */
114 sptwb.Spt.DataBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, DataBuf);
115 sptwb.Spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, SenseBuf);
116 length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, DataBuf) +
117 sptwb.Spt.DataTransferLength;
118
119 /* Set cdb info */
120 sptwb.Spt.Cdb[0] = 0x12; /* SCSI Inquiry */
121 sptwb.Spt.Cdb[1] = 1;
122 sptwb.Spt.Cdb[2] = page_code;
123 sptwb.Spt.Cdb[3] = 0;
124 sptwb.Spt.Cdb[4] = bufsize;
125 sptwb.Spt.Cdb[5] = 0;
126
127 status = DeviceIoControl(ipod->dh,
128 IOCTL_SCSI_PASS_THROUGH,
129 &sptwb,
130 sizeof(SCSI_PASS_THROUGH),
131 &sptwb,
132 length,
133 &returned,
134 FALSE);
135
136 if (status) {
137 /* W32 sometimes returns more bytes with additional garbage.
138 * Make sure to not copy that garbage. */
139 memcpy(buf, sptwb.DataBuf,
140 (DWORD)bufsize >= returned ? returned : (DWORD)bufsize);
141 return 0;
142 } else {
143 return -1;
144 }
145}
146#endif
147
diff --git a/utils/ipodpatcher/ipodio-win32.c b/utils/ipodpatcher/ipodio-win32.c
new file mode 100644
index 0000000000..cea218774a
--- /dev/null
+++ b/utils/ipodpatcher/ipodio-win32.c
@@ -0,0 +1,226 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006-2007 Dave Chapman
11 *
12 * error(), lock_volume() and unlock_volume() functions and inspiration taken
13 * from:
14 * RawDisk - Direct Disk Read/Write Access for NT/2000/XP
15 * Copyright (c) 2003 Jan Kiszka
16 * http://www.stud.uni-hannover.de/user/73174/RawDisk/
17 *
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
22 *
23 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
24 * KIND, either express or implied.
25 *
26 ****************************************************************************/
27
28#if defined(_WIN32)
29
30#include <stdio.h>
31#include <unistd.h>
32#include <fcntl.h>
33#include <string.h>
34#include <stdlib.h>
35#include <sys/types.h>
36#include <sys/stat.h>
37#include <windows.h>
38#include <stddef.h>
39#include <winioctl.h>
40
41#include "ipodio.h"
42
43static int lock_volume(HANDLE hDisk)
44{
45 DWORD dummy;
46
47 return DeviceIoControl(hDisk, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0,
48 &dummy, NULL);
49}
50
51static int unlock_volume(HANDLE hDisk)
52{
53 DWORD dummy;
54
55 return DeviceIoControl(hDisk, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0,
56 &dummy, NULL);
57}
58
59void ipod_print_error(char* msg)
60{
61 LPSTR pMsgBuf = NULL;
62
63 printf(msg);
64 FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
65 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(),
66 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), pMsgBuf,
67 0, NULL);
68 printf(pMsgBuf);
69 LocalFree(pMsgBuf);
70}
71
72int ipod_open(struct ipod_t* ipod, int silent)
73{
74 DISK_GEOMETRY_EX diskgeometry_ex;
75 DISK_GEOMETRY diskgeometry;
76 unsigned long n;
77
78 ipod->dh = CreateFileA(ipod->diskname, GENERIC_READ,
79 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
80 FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL);
81
82 if (ipod->dh == INVALID_HANDLE_VALUE) {
83 if (!silent) ipod_print_error(" Error opening disk: ");
84 if(GetLastError() == ERROR_ACCESS_DENIED)
85 return -2;
86 else
87 return -1;
88 }
89
90 if (!lock_volume(ipod->dh)) {
91 if (!silent) ipod_print_error(" Error locking disk: ");
92 return -1;
93 }
94
95 /* Defaults */
96 ipod->num_heads = 0;
97 ipod->sectors_per_track = 0;
98
99 if (!DeviceIoControl(ipod->dh,
100 IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
101 NULL,
102 0,
103 &diskgeometry_ex,
104 sizeof(diskgeometry_ex),
105 &n,
106 NULL)) {
107 if (!DeviceIoControl(ipod->dh,
108 IOCTL_DISK_GET_DRIVE_GEOMETRY,
109 NULL,
110 0,
111 &diskgeometry,
112 sizeof(diskgeometry),
113 &n,
114 NULL)) {
115 if (!silent) ipod_print_error(" Error reading disk geometry: ");
116 return -1;
117 } else {
118 ipod->sector_size = diskgeometry.BytesPerSector;
119 ipod->num_heads = diskgeometry.TracksPerCylinder;
120 ipod->sectors_per_track = diskgeometry.SectorsPerTrack;
121 }
122 } else {
123 ipod->sector_size = diskgeometry_ex.Geometry.BytesPerSector;
124 ipod->num_heads = diskgeometry_ex.Geometry.TracksPerCylinder;
125 ipod->sectors_per_track = diskgeometry_ex.Geometry.SectorsPerTrack;
126 }
127
128 return 0;
129}
130
131int ipod_reopen_rw(struct ipod_t* ipod)
132{
133 /* Close existing file and re-open for writing */
134 unlock_volume(ipod->dh);
135 CloseHandle(ipod->dh);
136
137 ipod->dh = CreateFileA(ipod->diskname, GENERIC_READ | GENERIC_WRITE,
138 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
139 FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL);
140
141 if (ipod->dh == INVALID_HANDLE_VALUE) {
142 ipod_print_error(" Error opening disk: ");
143 return -1;
144 }
145
146 if (!lock_volume(ipod->dh)) {
147 ipod_print_error(" Error locking disk: ");
148 return -1;
149 }
150
151 return 0;
152}
153
154int ipod_close(struct ipod_t* ipod)
155{
156 unlock_volume(ipod->dh);
157 CloseHandle(ipod->dh);
158 return 0;
159}
160
161int ipod_alloc_buffer(struct ipod_t* ipod, int bufsize)
162{
163 /* The ReadFile function requires a memory buffer aligned to a multiple of
164 the disk sector size. */
165 ipod->sectorbuf = (unsigned char*)VirtualAlloc(NULL, bufsize, MEM_COMMIT, PAGE_READWRITE);
166 if (ipod->sectorbuf== NULL) {
167 ipod_print_error(" Error allocating a buffer: ");
168 return -1;
169 }
170 return 0;
171}
172
173int ipod_dealloc_buffer(struct ipod_t* ipod)
174{
175 if (ipod->sectorbuf == NULL) {
176 return -1;
177 }
178 if(!VirtualFree(ipod->sectorbuf, 0, MEM_RELEASE)) {
179 ipod_print_error(" Error releasing buffer ");
180 return -1;
181 }
182 ipod->sectorbuf = NULL;
183 return 0;
184}
185
186int ipod_seek(struct ipod_t* ipod, unsigned long pos)
187{
188 if (SetFilePointer(ipod->dh, pos, NULL, FILE_BEGIN)==0xffffffff) {
189 ipod_print_error(" Seek error ");
190 return -1;
191 }
192 return 0;
193}
194
195ssize_t ipod_read(struct ipod_t* ipod, int nbytes)
196{
197 unsigned long count;
198
199 if(ipod->sectorbuf == NULL) {
200 return -1;
201 }
202 if (!ReadFile(ipod->dh, ipod->sectorbuf, nbytes, &count, NULL)) {
203 ipod_print_error(" Error reading from disk: ");
204 return -1;
205 }
206
207 return count;
208}
209
210ssize_t ipod_write(struct ipod_t* ipod, int nbytes)
211{
212 unsigned long count;
213
214 if(ipod->sectorbuf == NULL) {
215 return -1;
216 }
217 if (!WriteFile(ipod->dh, ipod->sectorbuf, nbytes, &count, NULL)) {
218 ipod_print_error(" Error writing to disk: ");
219 return -1;
220 }
221
222 return count;
223}
224
225#endif
226
diff --git a/utils/ipodpatcher/ipodio.h b/utils/ipodpatcher/ipodio.h
new file mode 100644
index 0000000000..4f1a35dd09
--- /dev/null
+++ b/utils/ipodpatcher/ipodio.h
@@ -0,0 +1,115 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006-2007 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef __IPODIO_H
23#define __IPODIO_H
24
25#include <stdint.h>
26#if !defined(_WIN32)
27#include <unistd.h>
28#elif defined(_MSC_VER)
29/* MSVC uses a different name for ssize_t */
30#define ssize_t SSIZE_T
31#endif
32
33#if defined(__WIN32__) || defined(_WIN32)
34#include <windows.h>
35#else
36#define HANDLE int
37#define O_BINARY 0
38#endif
39
40/* The maximum number of images in a firmware partition - a guess... */
41#define MAX_IMAGES 10
42
43enum firmwaretype_t {
44 FTYPE_OSOS = 0,
45 FTYPE_RSRC,
46 FTYPE_AUPD,
47 FTYPE_HIBE,
48 FTYPE_OSBK
49};
50
51struct ipod_directory_t {
52 enum firmwaretype_t ftype;
53 int id;
54 uint32_t devOffset; /* Offset of image relative to one sector into bootpart*/
55 uint32_t len;
56 uint32_t addr;
57 uint32_t entryOffset;
58 uint32_t chksum;
59 uint32_t vers;
60 uint32_t loadAddr;
61};
62
63/* A fake partition type - DOS partition tables can't include HFS partitions */
64#define PARTTYPE_HFS 0xffff
65
66struct partinfo_t {
67 uint32_t start; /* first sector (LBA) */
68 uint32_t size; /* number of sectors */
69 uint32_t type;
70};
71
72struct ipod_t {
73 unsigned char* sectorbuf;
74 HANDLE dh;
75 char diskname[4096];
76 int sector_size;
77 int sectors_per_track;
78 int num_heads;
79 struct ipod_directory_t ipod_directory[MAX_IMAGES];
80 int nimages;
81 int ososimage;
82 off_t diroffset;
83 off_t start; /* Offset in bytes of firmware partition from start of disk */
84 off_t fwoffset; /* Offset in bytes of start of firmware images from start of disk */
85 struct partinfo_t pinfo[4];
86 int modelnum;
87 char* modelname;
88 char* modelstr;
89 char* targetname;
90 int macpod;
91 char* xmlinfo; /* The XML Device Information (if available) */
92 int xmlinfo_len;
93 int ramsize; /* The amount of RAM in the ipod (if available) */
94#ifdef WITH_BOOTOBJS
95 unsigned char* bootloader;
96 int bootloader_len;
97#endif
98};
99
100void ipod_print_error(char* msg);
101int ipod_open(struct ipod_t* ipod, int silent);
102int ipod_reopen_rw(struct ipod_t* ipod);
103int ipod_close(struct ipod_t* ipod);
104int ipod_seek(struct ipod_t* ipod, unsigned long pos);
105int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code,
106 unsigned char* buf, int bufsize);
107ssize_t ipod_read(struct ipod_t* ipod, int nbytes);
108ssize_t ipod_write(struct ipod_t* ipod, int nbytes);
109int ipod_alloc_buffer(struct ipod_t* ipod, int bufsize);
110int ipod_dealloc_buffer(struct ipod_t* ipod);
111
112/* In fat32format.c */
113int format_partition(struct ipod_t* ipod, int partition);
114
115#endif
diff --git a/utils/ipodpatcher/ipodpatcher.c b/utils/ipodpatcher/ipodpatcher.c
new file mode 100644
index 0000000000..e047e52abe
--- /dev/null
+++ b/utils/ipodpatcher/ipodpatcher.c
@@ -0,0 +1,2350 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006-2007 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdio.h>
23#include <unistd.h>
24#include <fcntl.h>
25#include <string.h>
26#include <stdlib.h>
27#include <inttypes.h>
28#include <stdbool.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31
32#include "parttypes.h"
33#include "ipodio.h"
34#include "ipodpatcher.h"
35
36#ifdef WITH_BOOTOBJS
37#include "ipod1g2g.h"
38#include "ipod3g.h"
39#include "ipod4g.h"
40#include "ipodmini1g.h"
41#include "ipodmini2g.h"
42#include "ipodcolor.h"
43#include "ipodnano1g.h"
44#include "ipodvideo.h"
45#include "ipodnano2g.h"
46#endif
47
48#ifndef RBUTIL
49#include "arc4.h"
50#endif
51
52int ipod_verbose = 0;
53
54
55/* The following string appears at the start of the firmware partition */
56static const char apple_stop_sign[] = "{{~~ /-----\\ "\
57 "{{~~ / \\ "\
58 "{{~~| | "\
59 "{{~~| S T O P | "\
60 "{{~~| | "\
61 "{{~~ \\ / "\
62 "{{~~ \\-----/ "\
63 "Copyright(C) 200"\
64 "1 Apple Computer"\
65 ", Inc.----------"\
66 "----------------"\
67 "----------------"\
68 "----------------"\
69 "----------------"\
70 "----------------"\
71 "---------------";
72
73/* Windows requires the buffer for disk I/O to be aligned in memory on a
74 multiple of the disk volume size - so we use a single global variable
75 and initialise it with ipod_alloc_buf()
76*/
77
78char* get_parttype(unsigned int pt)
79{
80 int i;
81 static char unknown[]="Unknown";
82
83 if (pt == PARTTYPE_HFS) {
84 return "HFS/HFS+";
85 }
86
87 i=0;
88 while (parttypes[i].name != NULL) {
89 if (parttypes[i].type == pt) {
90 return (parttypes[i].name);
91 }
92 i++;
93 }
94
95 return unknown;
96}
97
98off_t filesize(int fd) {
99 struct stat buf;
100
101 if (fstat(fd,&buf) < 0) {
102 perror("[ERR] Checking filesize of input file");
103 return -1;
104 } else {
105 return(buf.st_size);
106 }
107}
108
109/* Partition table parsing code taken from Rockbox */
110
111#define MAX_SECTOR_SIZE 2048
112#define SECTOR_SIZE 512
113
114static inline unsigned short le2ushort(unsigned char* buf)
115{
116 unsigned short res = (buf[1] << 8) | buf[0];
117
118 return res;
119}
120
121static inline int le2int(unsigned char* buf)
122{
123 int32_t res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
124
125 return res;
126}
127
128static inline int be2int(unsigned char* buf)
129{
130 int32_t res = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
131
132 return res;
133}
134
135static inline int getint16le(char* buf)
136{
137 int16_t res = (buf[1] << 8) | buf[0];
138
139 return res;
140}
141
142static inline void short2le(unsigned short val, unsigned char* addr)
143{
144 addr[0] = val & 0xFF;
145 addr[1] = (val >> 8) & 0xff;
146}
147
148static inline void int2le(unsigned int val, unsigned char* addr)
149{
150 addr[0] = val & 0xFF;
151 addr[1] = (val >> 8) & 0xff;
152 addr[2] = (val >> 16) & 0xff;
153 addr[3] = (val >> 24) & 0xff;
154}
155
156static inline void int2be(unsigned int val, unsigned char* addr)
157{
158 addr[0] = (val >> 24) & 0xff;
159 addr[1] = (val >> 16) & 0xff;
160 addr[2] = (val >> 8) & 0xff;
161 addr[3] = val & 0xFF;
162}
163
164
165#define BYTES2INT32(array,pos)\
166 ((long)array[pos] | ((long)array[pos+1] << 8 ) |\
167 ((long)array[pos+2] << 16 ) | ((long)array[pos+3] << 24 ))
168
169int read_partinfo(struct ipod_t* ipod, int silent)
170{
171 int i;
172 unsigned long count;
173
174 if(ipod->sectorbuf == NULL) {
175 fprintf(stderr,"[ERR] Buffer not initialized.");
176 return -1;
177 }
178
179 count = ipod_read(ipod,ipod->sector_size);
180
181 if (count <= 0) {
182 ipod_print_error(" Error reading from disk: ");
183 return -1;
184 }
185
186 memset(ipod->pinfo, 0, sizeof(ipod->pinfo));
187
188 if ((ipod->sectorbuf[510] == 0x55) && (ipod->sectorbuf[511] == 0xaa)) {
189 /* DOS partition table */
190 ipod->macpod = 0;
191 /* parse partitions */
192 for ( i = 0; i < 4; i++ ) {
193 unsigned char* ptr = ipod->sectorbuf + 0x1be + 16*i;
194 ipod->pinfo[i].type = ptr[4];
195 ipod->pinfo[i].start = BYTES2INT32(ptr, 8);
196 ipod->pinfo[i].size = BYTES2INT32(ptr, 12);
197
198 /* extended? */
199 if ( ipod->pinfo[i].type == 5 ) {
200 /* not handled yet */
201 }
202 }
203 } else if ((ipod->sectorbuf[0] == 'E') && (ipod->sectorbuf[1] == 'R')) {
204 /* Apple Partition Map */
205
206 /* APM parsing code based on the check_mac_partitions() function in
207 ipodloader2 - written by Thomas Tempelmann and released
208 under the GPL. */
209
210 int blkNo = 1;
211 int partBlkCount = 1;
212 int partBlkSizMul = ipod->sectorbuf[2] / 2;
213
214 int pmMapBlkCnt; /* # of blks in partition map */
215 int pmPyPartStart; /* physical start blk of partition */
216 int pmPartBlkCnt; /* # of blks in this partition */
217 int i = 0;
218
219 ipod->macpod = 1;
220
221 memset(ipod->pinfo,0,sizeof(ipod->pinfo));
222
223 while (blkNo <= partBlkCount) {
224 if (ipod_seek(ipod, blkNo * partBlkSizMul * 512) < 0) {
225 fprintf(stderr,"[ERR] Seek failed whilst reading APM\n");
226 return -1;
227 }
228
229 count = ipod_read(ipod, ipod->sector_size);
230
231 if (count <= 0) {
232 ipod_print_error(" Error reading from disk: ");
233 return -1;
234 }
235
236 /* see if it's a partition entry */
237 if ((ipod->sectorbuf[0] != 'P') || (ipod->sectorbuf[1] != 'M')) {
238 /* end of partition table -> leave the loop */
239 break;
240 }
241
242 /* Extract the interesting entries */
243 pmMapBlkCnt = be2int(ipod->sectorbuf + 4);
244 pmPyPartStart = be2int(ipod->sectorbuf + 8);
245 pmPartBlkCnt = be2int(ipod->sectorbuf + 12);
246
247 /* update the number of part map blocks */
248 partBlkCount = pmMapBlkCnt;
249
250 if (strncmp((char*)(ipod->sectorbuf + 48), "Apple_MDFW", 32)==0) {
251 /* A Firmware partition */
252 ipod->pinfo[i].start = pmPyPartStart;
253 ipod->pinfo[i].size = pmPartBlkCnt;
254 ipod->pinfo[i].type = 0;
255 i++;
256 } else if (strncmp((char*)(ipod->sectorbuf + 48), "Apple_HFS", 32)==0) {
257 /* A HFS partition */
258 ipod->pinfo[i].start = pmPyPartStart;
259 ipod->pinfo[i].size = pmPartBlkCnt;
260 ipod->pinfo[i].type = PARTTYPE_HFS;
261 i++;
262 }
263
264 blkNo++; /* read next partition map entry */
265 }
266 } else {
267 if (!silent) fprintf(stderr,"[ERR] Bad boot sector signature\n");
268 return -1;
269 }
270
271 /* Check that the partition table looks like an ipod:
272 1) Partition 1 is of type 0 (Empty) but isn't empty.
273 2) Partition 2 is of type 0xb or 0xc (winpod) or -1 (macpod)
274 */
275 if ((ipod->pinfo[0].type != 0) || (ipod->pinfo[0].size == 0) ||
276 ((ipod->pinfo[1].type != 0xb) && (ipod->pinfo[1].type != 0xc) &&
277 (ipod->pinfo[1].type != PARTTYPE_HFS))) {
278 if (!silent) fprintf(stderr,"[ERR] Partition layout is not an ipod\n");
279 return -1;
280 }
281
282 ipod->start = ipod->pinfo[0].start*ipod->sector_size;
283 return 0;
284}
285
286int read_partition(struct ipod_t* ipod, int outfile)
287{
288 int res;
289 ssize_t n;
290 int bytesleft;
291 int chunksize;
292 int count = ipod->pinfo[0].size;
293
294 if (ipod_seek(ipod, ipod->start) < 0) {
295 return -1;
296 }
297 if(ipod->sectorbuf == NULL) {
298 fprintf(stderr,"[ERR] Buffer not initialized.");
299 return -1;
300 }
301
302 fprintf(stderr,"[INFO] Writing %d sectors to output file\n",count);
303
304 bytesleft = count * ipod->sector_size;
305 while (bytesleft > 0) {
306 if (bytesleft > BUFFER_SIZE) {
307 chunksize = BUFFER_SIZE;
308 } else {
309 chunksize = bytesleft;
310 }
311
312 n = ipod_read(ipod, chunksize);
313
314 if (n < 0) {
315 return -1;
316 }
317
318 if (n < chunksize) {
319 fprintf(stderr,
320 "[ERR] Short read in disk_read() - requested %d, got %d\n",
321 chunksize,(int)n);
322 return -1;
323 }
324
325 bytesleft -= n;
326
327 res = write(outfile,ipod->sectorbuf,n);
328
329 if (res < 0) {
330 perror("[ERR] write in disk_read");
331 return -1;
332 }
333
334 if (res != n) {
335 fprintf(stderr,
336 "Short write - requested %d, received %d - aborting.\n",(int)n,res);
337 return -1;
338 }
339 }
340
341 fprintf(stderr,"[INFO] Done.\n");
342 return 0;
343}
344
345int write_partition(struct ipod_t* ipod, int infile)
346{
347 ssize_t res;
348 int n;
349 int bytesread;
350 int byteswritten = 0;
351 int eof;
352 int padding = 0;
353
354 if (ipod_seek(ipod, ipod->start) < 0) {
355 return -1;
356 }
357 if(ipod->sectorbuf == NULL) {
358 fprintf(stderr,"[ERR] Buffer not initialized.");
359 return -1;
360 }
361
362 fprintf(stderr,"[INFO] Writing input file to device\n");
363 bytesread = 0;
364 eof = 0;
365 while (!eof) {
366 n = read(infile,ipod->sectorbuf,BUFFER_SIZE);
367
368 if (n < 0) {
369 perror("[ERR] read in disk_write");
370 return -1;
371 }
372
373 if (n < BUFFER_SIZE) {
374 eof = 1;
375 /* We need to pad the last write to a multiple of SECTOR_SIZE */
376 if ((n % ipod->sector_size) != 0) {
377 padding = (ipod->sector_size-(n % ipod->sector_size));
378 n += padding;
379 }
380 }
381
382 bytesread += n;
383
384 res = ipod_write(ipod, n);
385
386 if (res < 0) {
387 ipod_print_error(" Error writing to disk: ");
388 fprintf(stderr,"Bytes written: %d\n",byteswritten);
389 return -1;
390 }
391
392 if (res != n) {
393 fprintf(stderr,"[ERR] Short write - requested %d, received %d - aborting.\n",n,(int)res);
394 return -1;
395 }
396
397 byteswritten += res;
398 }
399
400 fprintf(stderr,"[INFO] Wrote %d bytes plus %d bytes padding.\n",
401 byteswritten-padding,padding);
402 return 0;
403}
404
405char* ftypename[] = { "OSOS", "RSRC", "AUPD", "HIBE", "OSBK" };
406
407int diskmove(struct ipod_t* ipod, int delta)
408{
409 int src_start;
410 int src_end;
411 int bytesleft;
412 int chunksize;
413 int n;
414
415 src_start = ipod->ipod_directory[1].devOffset;
416 src_end = (ipod->ipod_directory[ipod->nimages-1].devOffset + ipod->sector_size +
417 ipod->ipod_directory[ipod->nimages-1].len +
418 (ipod->sector_size-1)) & ~(ipod->sector_size-1);
419 bytesleft = src_end - src_start;
420
421 if (ipod_verbose) {
422 fprintf(stderr,"[INFO] Need to move images 2-%d forward %08x bytes\n", ipod->nimages,delta);
423 fprintf(stderr,"[VERB] src_start = %08x\n",src_start);
424 fprintf(stderr,"[VERB] src_end = %08x\n",src_end);
425 fprintf(stderr,"[VERB] dest_start = %08x\n",src_start+delta);
426 fprintf(stderr,"[VERB] dest_end = %08x\n",src_end+delta);
427 fprintf(stderr,"[VERB] bytes to copy = %08x\n",bytesleft);
428 }
429
430 while (bytesleft > 0) {
431 if (bytesleft <= BUFFER_SIZE) {
432 chunksize = bytesleft;
433 } else {
434 chunksize = BUFFER_SIZE;
435 }
436
437 if (ipod_verbose) {
438 fprintf(stderr,"[VERB] Copying %08x bytes from %08x to %08x (absolute %08x to %08x)\n",
439 chunksize,
440 src_end-chunksize,
441 src_end-chunksize+delta,
442 (unsigned int)(ipod->start+src_end-chunksize),
443 (unsigned int)(ipod->start+src_end-chunksize+delta));
444 }
445
446
447 if (ipod_seek(ipod, ipod->start+src_end-chunksize) < 0) {
448 fprintf(stderr,"[ERR] Seek failed\n");
449 return -1;
450 }
451
452 if ((n = ipod_read(ipod,chunksize)) < 0) {
453 perror("[ERR] Write failed\n");
454 return -1;
455 }
456
457 if (n < chunksize) {
458 fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n",
459 chunksize,n);
460 return -1;
461 }
462
463 if (ipod_seek(ipod, ipod->start+src_end-chunksize+delta) < 0) {
464 fprintf(stderr,"[ERR] Seek failed\n");
465 return -1;
466 }
467
468 if ((n = ipod_write(ipod,chunksize)) < 0) {
469 perror("[ERR] Write failed\n");
470 return -1;
471 }
472
473 if (n < chunksize) {
474 fprintf(stderr,"[ERR] Short write - requested %d bytes, received %d\n"
475 ,chunksize,n);
476 return -1;
477 }
478
479 src_end -= chunksize;
480 bytesleft -= chunksize;
481 }
482
483 return 0;
484}
485
486static int rename_image(struct ipod_t* ipod, char* from, char* to)
487{
488 int n;
489 int x;
490 int found;
491 int i;
492 unsigned char* p;
493
494 /* diroffset may not be sector-aligned */
495 x = ipod->diroffset % ipod->sector_size;
496
497 if(ipod->sectorbuf == NULL) {
498 fprintf(stderr,"[ERR] Buffer not initialized.");
499 return -1;
500 }
501 /* Read directory */
502 if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) {
503 fprintf(stderr,"[ERR] Seek to diroffset (%08x) failed.\n",(unsigned)ipod->diroffset);
504 return -1;
505 }
506
507 n=ipod_read(ipod, ipod->sector_size);
508 if (n < 0) {
509 fprintf(stderr,"[ERR] Read of directory failed.\n");
510 return -1;
511 }
512
513 p = ipod->sectorbuf + x;
514
515 /* A hack to detect 2nd gen Nanos - maybe there is a better way? */
516 if (p[0] == 0)
517 {
518 /* Adjust diroffset */
519 ipod->diroffset += ipod->sector_size - x;
520
521 n=ipod_read(ipod, ipod->sector_size);
522 if (n < 0) {
523 fprintf(stderr,"[ERR] Read of directory failed.\n");
524 return -1;
525 }
526 p = ipod->sectorbuf;
527 }
528
529 found = 0;
530 for (i=0 ; !found && i < MAX_IMAGES; i++) {
531 if (memcmp(p + 4, from, 4) == 0) {
532 memcpy(p + 4, to, 4);
533
534 found = 1;
535 }
536 p += 40;
537 }
538
539 if (!found) {
540 fprintf(stderr,"[ERR] Unexpected error - no \"%s\" image!\n", from);
541 return -1;
542 }
543
544 /* Write directory back to disk */
545 if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) {
546 fprintf(stderr,"[ERR] Seek to diroffset (%08x) failed.\n",(unsigned)ipod->diroffset);
547 return -1;
548 }
549
550 n=ipod_write(ipod, ipod->sector_size);
551 if (n < 0) {
552 fprintf(stderr,"[ERR] Write of directory failed in rename_image.\n");
553 return -1;
554 }
555
556 return 0;
557}
558
559static int delete_image(struct ipod_t* ipod, char* name)
560{
561 int n;
562 int x;
563 int found;
564 int i;
565 unsigned char* p;
566
567 /* diroffset may not be sector-aligned */
568 x = ipod->diroffset % ipod->sector_size;
569
570 /* Read directory */
571 if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) {
572 fprintf(stderr,"[ERR] Seek to diroffset (%08x) failed.\n",(unsigned)ipod->diroffset);
573 return -1;
574 }
575
576 n=ipod_read(ipod, ipod->sector_size);
577 if (n < 0) {
578 fprintf(stderr,"[ERR] Read of directory failed.\n");
579 return -1;
580 }
581
582 p = ipod->sectorbuf + x;
583
584 /* A hack to detect 2nd gen Nanos - maybe there is a better way? */
585 if (p[0] == 0)
586 {
587 /* Adjust diroffset */
588 ipod->diroffset += ipod->sector_size - x;
589
590 n=ipod_read(ipod, ipod->sector_size);
591 if (n < 0) {
592 fprintf(stderr,"[ERR] Read of directory failed.\n");
593 return -1;
594 }
595 p = ipod->sectorbuf;
596 }
597
598 found = 0;
599 for (i=0 ; !found && i < MAX_IMAGES; i++) {
600 if (memcmp(p + 4, name, 4) == 0) {
601 memset(p, 0, 40); /* Delete directory entry */
602 found = 1;
603 }
604 p += 40;
605 }
606
607 if (!found) {
608 fprintf(stderr,"[ERR] Unexpected error - no \"%s\" image!\n", name);
609 return -1;
610 }
611
612 /* Write directory back to disk */
613 if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) {
614 fprintf(stderr,"[ERR] Seek to diroffset (%08x) failed.\n",(unsigned)ipod->diroffset);
615 return -1;
616 }
617
618 n=ipod_write(ipod, ipod->sector_size);
619 if (n < 0) {
620 fprintf(stderr,"[ERR] Write of directory failed in delete_image.\n");
621 return -1;
622 }
623
624 return 0;
625}
626
627int add_new_image(struct ipod_t* ipod, char* imagename, char* filename, int type)
628{
629 int length;
630 int found;
631 int i;
632 int x;
633 int n;
634 int infile;
635 int newsize;
636 unsigned long chksum=0;
637 unsigned long filechksum=0;
638 unsigned long offset;
639 unsigned char header[8]; /* Header for .ipod file */
640 unsigned char* p;
641
642 if(ipod->sectorbuf == NULL) {
643 fprintf(stderr,"[ERR] Buffer not initialized.");
644 return -1;
645 }
646#ifdef WITH_BOOTOBJS
647 if (type == FILETYPE_INTERNAL) {
648 fprintf(stderr,"[INFO] Using internal bootloader - %d bytes\n",ipod->bootloader_len);
649 length = ipod->bootloader_len;
650 infile = -1;
651 }
652 else
653#endif
654 {
655 /* First check that the input file is the correct type for this ipod. */
656 infile=open(filename,O_RDONLY);
657 if (infile < 0) {
658 fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename);
659 return -1;
660 }
661
662 if (type==FILETYPE_DOT_IPOD) {
663 n = read(infile,header,8);
664 if (n < 8) {
665 fprintf(stderr,"[ERR] Failed to read header from %s\n",filename);
666 close(infile);
667 return -1;
668 }
669
670 if (memcmp(header+4, ipod->modelname,4)!=0) {
671 fprintf(stderr,"[ERR] Model name in input file (%c%c%c%c) doesn't match ipod model (%s)\n",
672 header[4],header[5],header[6],header[7], ipod->modelname);
673 close(infile);
674 return -1;
675 }
676
677 filechksum = be2int(header);
678
679 length = filesize(infile)-8;
680 } else {
681 length = filesize(infile);
682 }
683 }
684
685 newsize=(length+ipod->sector_size-1)&~(ipod->sector_size-1);
686
687 fprintf(stderr,"[INFO] Padding input file from 0x%08x to 0x%08x bytes\n",
688 length,newsize);
689
690 if (newsize > BUFFER_SIZE) {
691 fprintf(stderr,"[ERR] Input file too big for buffer\n");
692 if (infile >= 0) close(infile);
693 return -1;
694 }
695
696 /* TODO: Check if we have enough space in the partition for the new image */
697
698#ifdef WITH_BOOTOBJS
699 if (type == FILETYPE_INTERNAL) {
700 memcpy(ipod->sectorbuf,ipod->bootloader,ipod->bootloader_len);
701 }
702 else
703#endif
704 {
705 fprintf(stderr,"[INFO] Reading input file...\n");
706
707 n = read(infile,ipod->sectorbuf,length);
708 if (n < 0) {
709 fprintf(stderr,"[ERR] Couldn't read input file\n");
710 close(infile);
711 return -1;
712 }
713 close(infile);
714 }
715
716 /* Pad the data with zeros */
717 memset(ipod->sectorbuf+length,0,newsize-length);
718
719 if (type==FILETYPE_DOT_IPOD) {
720 chksum = ipod->modelnum;
721 for (i = 0; i < length; i++) {
722 /* add 8 unsigned bits but keep a 32 bit sum */
723 chksum += ipod->sectorbuf[i];
724 }
725
726 if (chksum == filechksum) {
727 fprintf(stderr,"[INFO] Checksum OK in %s\n",filename);
728 } else {
729 fprintf(stderr,"[ERR] Checksum in %s failed check\n",filename);
730 return -1;
731 }
732 }
733
734
735 offset = ipod->fwoffset + ipod->ipod_directory[ipod->nimages - 1].devOffset +
736 ipod->ipod_directory[ipod->nimages - 1].len + ipod->sector_size;
737
738 /* 2nd Gen Nano has encrypted firmware, and the sector
739 preceeding the firmware contains hashes that need to be
740 preserved. Nano 2G images include these extra 2048 (0x800)
741 bytes
742 */
743 if (ipod_seek(ipod, offset - (ipod->modelnum == 62 ? 0x800 : 0)) < 0) {
744 fprintf(stderr,"[ERR] Seek failed\n");
745 return -1;
746 }
747
748 if ((n = ipod_write(ipod,newsize)) < 0) {
749 perror("[ERR] Write failed\n");
750 return -1;
751 }
752
753 if (n < newsize) {
754 fprintf(stderr,"[ERR] Short write - requested %d bytes, received %d\n"
755 ,newsize,n);
756 return -1;
757 }
758 fprintf(stderr,"[INFO] Wrote %d bytes to firmware partition\n",n);
759
760 /* Now we need to create a new directory entry
761
762 NOTE: On the Nano 2G, the checksum is the checksum of the
763 unencrypted firmware. But this isn't checked by the NOR
764 bootloader (there are cryptographic hashes in the
765 firmware itself), so it doesn't matter that this is
766 wrong.
767 */
768 chksum = 0;
769 for (i = 0; i < length; i++) {
770 /* add 8 unsigned bits but keep a 32 bit sum */
771 chksum += ipod->sectorbuf[i];
772 }
773
774 x = ipod->diroffset % ipod->sector_size;
775
776 /* Read directory */
777 if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
778
779 n=ipod_read(ipod, ipod->sector_size);
780 if (n < 0) { return -1; }
781
782 /* Create a new directory entry */
783
784 /* Copy OSOS or OSBK details - we assume one of them exists */
785 p = ipod->sectorbuf + x;
786 found = 0;
787 for (i = 0; !found && i < ipod->nimages; i++) {
788 if ((memcmp(p + 4, "soso", 4)==0) || (memcmp(p + 4, "kbso", 4)==0)) {
789 found = 1;
790 } else {
791 p += 40;
792 }
793 }
794
795 if (!found) {
796 fprintf(stderr,"[ERR] No OSOS or OSBK image to copy directory from\n");
797 return -1;
798 }
799
800 /* Copy directory image */
801 memcpy(ipod->sectorbuf + x + (ipod->nimages * 40), p, 40);
802 p = ipod->sectorbuf + x + (ipod->nimages * 40);
803
804 /* Modify directory. */
805 memcpy(p + 4, imagename, 4);
806 int2le(offset - ipod->fwoffset, p + 12); /* devOffset */
807 int2le(length - (ipod->modelnum==62 ? 0x800: 0), p + 16); /* len */
808 int2le(chksum, p + 28); /* checksum */
809
810 /* Write directory */
811 if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
812 n=ipod_write(ipod, ipod->sector_size);
813 if (n < 0) { return -1; }
814
815 return 0;
816}
817
818
819int ipod_has_bootloader(struct ipod_t* ipod)
820{
821 /* The 2nd gen Nano is installed differently */
822 if (ipod->modelnum == 62) {
823 int i;
824 int has_osbk = 0;
825 /* Check if we have an OSBK image */
826 for (i = 0; i < ipod->nimages; i++) {
827 if (ipod->ipod_directory[i].ftype==FTYPE_OSBK) {
828 has_osbk = 1;
829 }
830 }
831 return has_osbk;
832 }
833 else {
834 return (ipod->ipod_directory[0].entryOffset != 0);
835 }
836}
837
838
839/*
840 Bootloader installation on the Nano2G consists of renaming the
841 OSOS image to OSBK and then writing the Rockbox bootloader as a
842 new OSOS image.
843
844 Maybe this approach can/should be adapted for other ipods, as it
845 prevents the Apple bootloader loading the original firmware into
846 RAM along with the Rockbox bootloader (and hence will give a
847 faster boot when the user just wants to start Rockbox).
848
849*/
850
851static int add_bootloader_nano2g(struct ipod_t* ipod, char* filename, int type)
852{
853 /* Check if we already have an OSBK image */
854 if (ipod_has_bootloader(ipod) == 0) {
855 /* First-time install - rename OSOS to OSBK and create new OSOS for bootloader */
856 fprintf(stderr,"[INFO] Creating OSBK backup image of original firmware\n");
857
858 if (rename_image(ipod, "soso", "kbso") < 0) {
859 fprintf(stderr,"[ERR] Could not rename OSOS image\n");
860 return -1;
861 }
862
863 /* Add our bootloader as a brand new image */
864 return add_new_image(ipod, "soso", filename, type);
865 } else {
866 /* This is an update, just replace OSOS with our bootloader */
867
868 return write_firmware(ipod, filename, type);
869 }
870}
871
872
873static int delete_bootloader_nano2g(struct ipod_t* ipod)
874{
875 /* Check if we have an OSBK image */
876 if (ipod_has_bootloader(ipod) == 0) {
877 fprintf(stderr,"[ERR] No OSBK image found - nothing to uninstall\n");
878 return -1;
879 } else {
880 /* Delete our bootloader image */
881 if (delete_image(ipod, "soso") < 0) {
882 fprintf(stderr,"[WARN] Could not delete OSOS image\n");
883 } else {
884 fprintf(stderr,"[INFO] OSOS image deleted\n");
885 }
886
887 if (rename_image(ipod, "kbso", "soso") < 0) {
888 fprintf(stderr,"[ERR] Could not rename OSBK image\n");
889 return -1;
890 }
891
892
893 fprintf(stderr,"[INFO] OSBK image renamed to OSOS - bootloader uninstalled.\n");
894 return 0;
895 }
896}
897
898
899int add_bootloader(struct ipod_t* ipod, char* filename, int type)
900{
901 int length;
902 int i;
903 int x;
904 int n;
905 int infile;
906 int paddedlength;
907 int entryOffset;
908 int delta = 0;
909 unsigned long chksum=0;
910 unsigned long filechksum=0;
911 unsigned char header[8]; /* Header for .ipod file */
912 unsigned char* bootloader_buf;
913
914 /* The 2nd gen Nano is installed differently */
915 if (ipod->modelnum == 62) {
916 return add_bootloader_nano2g(ipod, filename, type);
917 }
918 if(ipod->sectorbuf == NULL) {
919 fprintf(stderr,"[ERR] Buffer not initialized.");
920 return -1;
921 }
922
923 /* Calculate the position in the OSOS image where our bootloader will go. */
924 if (ipod->ipod_directory[0].entryOffset>0) {
925 /* Keep the same entryOffset */
926 entryOffset = ipod->ipod_directory[0].entryOffset;
927 } else {
928 entryOffset = (ipod->ipod_directory[0].len+ipod->sector_size-1)&~(ipod->sector_size-1);
929 }
930
931#ifdef WITH_BOOTOBJS
932 if (type == FILETYPE_INTERNAL) {
933 fprintf(stderr,"[INFO] Using internal bootloader - %d bytes\n",ipod->bootloader_len);
934 memcpy(ipod->sectorbuf+entryOffset,ipod->bootloader,ipod->bootloader_len);
935 length = ipod->bootloader_len;
936 paddedlength=(ipod->bootloader_len+ipod->sector_size-1)&~(ipod->sector_size-1);
937 }
938 else
939#endif
940 {
941 infile=open(filename,O_RDONLY);
942 if (infile < 0) {
943 fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename);
944 return -1;
945 }
946
947 if (type==FILETYPE_DOT_IPOD) {
948 /* First check that the input file is the correct type for this ipod. */
949 n = read(infile,header,8);
950 if (n < 8) {
951 fprintf(stderr,"[ERR] Failed to read header from %s\n",filename);
952 close(infile);
953 return -1;
954 }
955
956 if (memcmp(header+4, ipod->modelname,4)!=0) {
957 fprintf(stderr,"[ERR] Model name in input file (%c%c%c%c) doesn't match ipod model (%s)\n",
958 header[4],header[5],header[6],header[7], ipod->modelname);
959 close(infile);
960 return -1;
961 }
962
963 filechksum = be2int(header);
964
965 length=filesize(infile)-8;
966 } else {
967 length=filesize(infile);
968 }
969 paddedlength=(length+ipod->sector_size-1)&~(ipod->sector_size-1);
970
971 bootloader_buf = malloc(length);
972 if (bootloader_buf == NULL) {
973 fprintf(stderr,"[ERR] Can not allocate memory for bootloader\n");
974 return -1;
975 }
976 /* Now read our bootloader - we need to check it before modifying the partition*/
977 n = read(infile,bootloader_buf,length);
978 close(infile);
979
980 if (n < 0) {
981 fprintf(stderr,"[ERR] Couldn't read input file\n");
982 return -1;
983 }
984
985 if (type==FILETYPE_DOT_IPOD) {
986 /* Calculate and confirm bootloader checksum */
987 chksum = ipod->modelnum;
988 for (i = 0; i < length; i++) {
989 /* add 8 unsigned bits but keep a 32 bit sum */
990 chksum += bootloader_buf[i];
991 }
992
993 if (chksum == filechksum) {
994 fprintf(stderr,"[INFO] Checksum OK in %s\n",filename);
995 } else {
996 fprintf(stderr,"[ERR] Checksum in %s failed check\n",filename);
997 return -1;
998 }
999 }
1000 }
1001
1002 if (entryOffset+paddedlength > BUFFER_SIZE) {
1003 fprintf(stderr,"[ERR] Input file too big for buffer\n");
1004 return -1;
1005 }
1006
1007 if (ipod_verbose) {
1008 fprintf(stderr,"[VERB] Original firmware begins at 0x%08x\n", ipod->ipod_directory[0].devOffset + ipod->sector_size);
1009 fprintf(stderr,"[VERB] New entryOffset will be 0x%08x\n",entryOffset);
1010 fprintf(stderr,"[VERB] End of bootloader will be at 0x%08x\n",entryOffset+paddedlength);
1011 }
1012
1013 /* Check if we have enough space */
1014 /* TODO: Check the size of the partition. */
1015 if (ipod->nimages > 1) {
1016 if ((ipod->ipod_directory[0].devOffset+entryOffset+paddedlength) >
1017 ipod->ipod_directory[1].devOffset) {
1018 fprintf(stderr,"[INFO] Moving images to create room for new firmware...\n");
1019 delta = ipod->ipod_directory[0].devOffset + entryOffset+paddedlength
1020 - ipod->ipod_directory[1].devOffset + ipod->sector_size;
1021
1022 if (diskmove(ipod, delta) < 0) {
1023 fprintf(stderr,"[ERR] Image movement failed.\n");
1024 return -1;
1025 }
1026 }
1027 }
1028
1029
1030 /* We have moved the partitions, now we can write our bootloader */
1031
1032 /* Firstly read the original firmware into ipod->sectorbuf */
1033 fprintf(stderr,"[INFO] Reading original firmware...\n");
1034 if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[0].devOffset) < 0) {
1035 fprintf(stderr,"[ERR] Seek failed\n");
1036 return -1;
1037 }
1038
1039 if ((n = ipod_read(ipod,entryOffset)) < 0) {
1040 perror("[ERR] Read failed\n");
1041 return -1;
1042 }
1043
1044 if (n < entryOffset) {
1045 fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n"
1046 ,entryOffset,n);
1047 return -1;
1048 }
1049
1050#ifdef WITH_BOOTOBJS
1051 if (type == FILETYPE_INTERNAL) {
1052 memcpy(ipod->sectorbuf+entryOffset,ipod->bootloader,ipod->bootloader_len);
1053 }
1054 else
1055#endif
1056 {
1057 memcpy(ipod->sectorbuf+entryOffset,bootloader_buf,length);
1058 free(bootloader_buf);
1059 }
1060
1061 /* Calculate new checksum for combined image */
1062 chksum = 0;
1063 for (i=0;i<entryOffset + length; i++) {
1064 chksum += ipod->sectorbuf[i];
1065 }
1066
1067 /* Now write the combined firmware image to the disk */
1068
1069 if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[0].devOffset) < 0) {
1070 fprintf(stderr,"[ERR] Seek failed\n");
1071 return -1;
1072 }
1073
1074 if ((n = ipod_write(ipod,entryOffset+paddedlength)) < 0) {
1075 perror("[ERR] Write failed\n");
1076 return -1;
1077 }
1078
1079 if (n < (entryOffset+paddedlength)) {
1080 fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n"
1081 ,entryOffset+paddedlength,n);
1082 return -1;
1083 }
1084
1085 fprintf(stderr,"[INFO] Wrote %d bytes to firmware partition\n",entryOffset+paddedlength);
1086
1087 x = ipod->diroffset % ipod->sector_size;
1088
1089 /* Read directory */
1090 if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) {
1091 fprintf(stderr,"[ERR] Seek failed\n");
1092 return -1;
1093 }
1094
1095 n=ipod_read(ipod, ipod->sector_size);
1096 if (n < 0) {
1097 fprintf(stderr,"[ERR] Directory read failed\n");
1098 return -1;
1099 }
1100
1101 /* Update entries for image 0 */
1102 int2le(entryOffset+length,ipod->sectorbuf+x+16);
1103 int2le(entryOffset,ipod->sectorbuf+x+24);
1104 int2le(chksum,ipod->sectorbuf+x+28);
1105 int2le(0xffffffff,ipod->sectorbuf+x+36); /* loadAddr */
1106
1107 /* Update devOffset entries for other images, if we have moved them */
1108 if (delta > 0) {
1109 for (i=1;i<ipod->nimages;i++) {
1110 int2le(le2int(ipod->sectorbuf+x+i*40+12)+delta,ipod->sectorbuf+x+i*40+12);
1111 }
1112 }
1113
1114 /* Write directory */
1115 if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) {
1116 fprintf(stderr,"[ERR] Seek to %d failed\n", (int)(ipod->start+ipod->diroffset-x));
1117 return -1;
1118 }
1119 n=ipod_write(ipod, ipod->sector_size);
1120 if (n < 0) {
1121 fprintf(stderr,"[ERR] Directory write failed\n");
1122 return -1;
1123 }
1124
1125 return 0;
1126}
1127
1128int delete_bootloader(struct ipod_t* ipod)
1129{
1130 int length;
1131 int i;
1132 int x;
1133 int n;
1134 unsigned long chksum=0; /* 32 bit checksum - Rockbox .ipod style*/
1135
1136 /* The 2nd gen Nano is installed differently */
1137 if (ipod->modelnum == 62) {
1138 return delete_bootloader_nano2g(ipod);
1139 }
1140 if(ipod->sectorbuf == NULL) {
1141 fprintf(stderr,"[ERR] Buffer not initialized.");
1142 return -1;
1143 }
1144
1145 /* Removing the bootloader involves adjusting the "length",
1146 "chksum" and "entryOffset" values in the osos image's directory
1147 entry. */
1148
1149 /* Firstly check we have a bootloader... */
1150
1151 if (ipod_has_bootloader(ipod) == 0) {
1152 fprintf(stderr,"[ERR] No bootloader found.\n");
1153 return -1;
1154 }
1155
1156 length = ipod->ipod_directory[0].entryOffset;
1157
1158 /* Read the firmware so we can calculate the checksum */
1159 fprintf(stderr,"[INFO] Reading firmware (%d bytes)\n",length);
1160
1161 if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[0].devOffset) < 0) {
1162 return -1;
1163 }
1164
1165 i = (length+ipod->sector_size-1) & ~(ipod->sector_size-1);
1166 fprintf(stderr,"[INFO] Padding read from 0x%08x to 0x%08x bytes\n",
1167 length,i);
1168
1169 if ((n = ipod_read(ipod,i)) < 0) {
1170 return -1;
1171 }
1172
1173 if (n < i) {
1174 fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n",
1175 i,n);
1176 return -1;
1177 }
1178
1179 chksum = 0;
1180 for (i = 0; i < length; i++) {
1181 /* add 8 unsigned bits but keep a 32 bit sum */
1182 chksum += ipod->sectorbuf[i];
1183 }
1184
1185 /* Now write back the updated directory entry */
1186
1187 fprintf(stderr,"[INFO] Updating firmware checksum\n");
1188
1189 x = ipod->diroffset % ipod->sector_size;
1190
1191 /* Read directory */
1192 if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
1193
1194 n=ipod_read(ipod, ipod->sector_size);
1195 if (n < 0) { return -1; }
1196
1197 /* Update entries for image 0 */
1198 int2le(length,ipod->sectorbuf+x+16);
1199 int2le(0,ipod->sectorbuf+x+24);
1200 int2le(chksum,ipod->sectorbuf+x+28);
1201
1202 /* Write directory */
1203 if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
1204 n=ipod_write(ipod, ipod->sector_size);
1205 if (n < 0) { return -1; }
1206
1207 return 0;
1208}
1209
1210int write_firmware(struct ipod_t* ipod, char* filename, int type)
1211{
1212 int length;
1213 int i;
1214 int x;
1215 int n;
1216 int infile;
1217 int newsize;
1218 int bytesavailable;
1219 unsigned long chksum=0;
1220 unsigned long filechksum=0;
1221 unsigned long offset;
1222 unsigned char header[8]; /* Header for .ipod file */
1223 unsigned char* p;
1224
1225 if(ipod->sectorbuf == NULL) {
1226 fprintf(stderr,"[ERR] Buffer not initialized.");
1227 return -1;
1228 }
1229#ifdef WITH_BOOTOBJS
1230 if (type == FILETYPE_INTERNAL) {
1231 fprintf(stderr,"[INFO] Using internal bootloader - %d bytes\n",ipod->bootloader_len);
1232 length = ipod->bootloader_len;
1233 infile = -1;
1234 }
1235 else
1236#endif
1237 {
1238 /* First check that the input file is the correct type for this ipod. */
1239 infile=open(filename,O_RDONLY);
1240 if (infile < 0) {
1241 fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename);
1242 return -1;
1243 }
1244
1245 if (type==FILETYPE_DOT_IPOD) {
1246 n = read(infile,header,8);
1247 if (n < 8) {
1248 fprintf(stderr,"[ERR] Failed to read header from %s\n",filename);
1249 close(infile);
1250 return -1;
1251 }
1252
1253 if (memcmp(header+4, ipod->modelname,4)!=0) {
1254 fprintf(stderr,"[ERR] Model name in input file (%c%c%c%c) doesn't match ipod model (%s)\n",
1255 header[4],header[5],header[6],header[7], ipod->modelname);
1256 close(infile);
1257 return -1;
1258 }
1259
1260 filechksum = be2int(header);
1261
1262 length = filesize(infile)-8;
1263 } else {
1264 length = filesize(infile);
1265 }
1266 }
1267
1268 newsize=(length+ipod->sector_size-1)&~(ipod->sector_size-1);
1269
1270 fprintf(stderr,"[INFO] Padding input file from 0x%08x to 0x%08x bytes\n",
1271 length,newsize);
1272
1273 if (newsize > BUFFER_SIZE) {
1274 fprintf(stderr,"[ERR] Input file too big for buffer\n");
1275 if (infile >= 0) close(infile);
1276 return -1;
1277 }
1278
1279 /* Check if we have enough space */
1280 /* TODO: Check the size of the partition. */
1281 if (ipod->nimages > 1) {
1282 bytesavailable=ipod->ipod_directory[1].devOffset-ipod->ipod_directory[0].devOffset;
1283 if (bytesavailable < newsize) {
1284 fprintf(stderr,"[INFO] Moving images to create room for new firmware...\n");
1285
1286 /* TODO: Implement image movement */
1287 fprintf(stderr,"[ERR] Image movement not yet implemented.\n");
1288 close(infile);
1289 return -1;
1290 }
1291 }
1292
1293#ifdef WITH_BOOTOBJS
1294 if (type == FILETYPE_INTERNAL) {
1295 memcpy(ipod->sectorbuf,ipod->bootloader,ipod->bootloader_len);
1296 }
1297 else
1298#endif
1299 {
1300 fprintf(stderr,"[INFO] Reading input file...\n");
1301 /* We now know we have enough space, so write it. */
1302 n = read(infile,ipod->sectorbuf,length);
1303 if (n < 0) {
1304 fprintf(stderr,"[ERR] Couldn't read input file\n");
1305 close(infile);
1306 return -1;
1307 }
1308 close(infile);
1309 }
1310
1311 /* Pad the data with zeros */
1312 memset(ipod->sectorbuf+length,0,newsize-length);
1313
1314 if (type==FILETYPE_DOT_IPOD) {
1315 chksum = ipod->modelnum;
1316 for (i = 0; i < length; i++) {
1317 /* add 8 unsigned bits but keep a 32 bit sum */
1318 chksum += ipod->sectorbuf[i];
1319 }
1320
1321 if (chksum == filechksum) {
1322 fprintf(stderr,"[INFO] Checksum OK in %s\n",filename);
1323 } else {
1324 fprintf(stderr,"[ERR] Checksum in %s failed check\n",filename);
1325 return -1;
1326 }
1327 }
1328
1329
1330 offset = ipod->fwoffset+ipod->ipod_directory[ipod->ososimage].devOffset;
1331
1332 if (ipod->modelnum==62) {
1333
1334 /* 2nd Gen Nano has encrypted firmware, and the sector
1335 preceeding the firmware contains hashes that need to be
1336 preserved. Nano 2G images include these extra 2048 (0x800)
1337 bytes
1338 */
1339
1340 offset -= 0x800;
1341
1342 /* TODO: The above checks need to take into account this 0x800 bytes */
1343 }
1344
1345 if (ipod_seek(ipod, offset) < 0) {
1346 fprintf(stderr,"[ERR] Seek failed\n");
1347 return -1;
1348 }
1349
1350 if ((n = ipod_write(ipod,newsize)) < 0) {
1351 perror("[ERR] Write failed\n");
1352 return -1;
1353 }
1354
1355 if (n < newsize) {
1356 fprintf(stderr,"[ERR] Short write - requested %d bytes, received %d\n"
1357 ,newsize,n);
1358 return -1;
1359 }
1360 fprintf(stderr,"[INFO] Wrote %d bytes to firmware partition\n",n);
1361
1362 /* Now we need to update the "len", "entryOffset" and "chksum" fields
1363
1364 NOTE: On the Nano 2G, the checksum is the checksum of the
1365 unencrypted firmware. But this isn't checked by the NOR
1366 bootloader (there are cryptographic hashes in the
1367 firmware itself), so it doesn't matter that this is
1368 wrong.
1369 */
1370 chksum = 0;
1371 for (i = 0; i < length; i++) {
1372 /* add 8 unsigned bits but keep a 32 bit sum */
1373 chksum += ipod->sectorbuf[i];
1374 }
1375
1376 x = ipod->diroffset % ipod->sector_size;
1377
1378 /* Read directory */
1379 if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
1380
1381 n=ipod_read(ipod, ipod->sector_size);
1382 if (n < 0) { return -1; }
1383
1384 /* Update entries for image */
1385 p = ipod->sectorbuf + x + (ipod->ososimage * 40);
1386 int2le(length - (ipod->modelnum==62 ? 0x800: 0), p + 16);
1387 int2le(0, p + 24);
1388 int2le(chksum, p + 28);
1389
1390 /* Write directory */
1391 if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
1392 n=ipod_write(ipod, ipod->sector_size);
1393 if (n < 0) { return -1; }
1394
1395 return 0;
1396}
1397
1398int read_firmware(struct ipod_t* ipod, char* filename, int type)
1399{
1400 int length;
1401 int i;
1402 int outfile;
1403 int n;
1404 unsigned long offset;
1405 unsigned long chksum=0; /* 32 bit checksum - Rockbox .ipod style*/
1406 unsigned char header[8]; /* Header for .ipod file */
1407
1408 if(ipod->sectorbuf == NULL) {
1409 fprintf(stderr,"[ERR] Buffer not initialized.");
1410 return -1;
1411 }
1412 if (ipod->ipod_directory[ipod->ososimage].entryOffset != 0) {
1413 /* We have a bootloader... */
1414 length = ipod->ipod_directory[ipod->ososimage].entryOffset;
1415 } else {
1416 length = ipod->ipod_directory[ipod->ososimage].len;
1417 }
1418
1419 fprintf(stderr,"[INFO] Reading firmware (%d bytes)\n",length);
1420
1421 offset = ipod->fwoffset + ipod->ipod_directory[ipod->ososimage].devOffset;
1422 i = (length+ipod->sector_size-1) & ~(ipod->sector_size-1);
1423 fprintf(stderr,"[INFO] Padding read from 0x%08x to 0x%08x bytes\n",
1424 length,i);
1425
1426 if (ipod->modelnum==62) {
1427 /* 2nd Gen Nano has encrypted firmware, and we need to dump the
1428 sector preceeding the image - it contains hashes */
1429 offset -= 0x800;
1430 length += 0x800;
1431 i += 0x800;
1432 }
1433
1434 if (ipod_seek(ipod, offset)) {
1435 return -1;
1436 }
1437
1438 if ((n = ipod_read(ipod,i)) < 0) {
1439 return -1;
1440 }
1441
1442 if (n < i) {
1443 fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n",
1444 i,n);
1445 return -1;
1446 }
1447
1448 outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666);
1449 if (outfile < 0) {
1450 fprintf(stderr,"[ERR] Couldn't open file %s\n",filename);
1451 return -1;
1452 }
1453
1454 if (type == FILETYPE_DOT_IPOD) {
1455 chksum = ipod->modelnum;
1456 for (i = 0; i < length; i++) {
1457 /* add 8 unsigned bits but keep a 32 bit sum */
1458 chksum += ipod->sectorbuf[i];
1459 }
1460
1461 int2be(chksum,header);
1462 memcpy(header+4, ipod->modelname,4);
1463
1464 n = write(outfile,header,8);
1465 if (n != 8) {
1466 fprintf(stderr,"[ERR] Write error - %d\n",n);
1467 }
1468 }
1469
1470 n = write(outfile,ipod->sectorbuf,length);
1471 if (n != length) {
1472 fprintf(stderr,"[ERR] Write error - %d\n",n);
1473 }
1474 close(outfile);
1475
1476 return 0;
1477}
1478
1479int read_directory(struct ipod_t* ipod)
1480{
1481 ssize_t n;
1482 int x;
1483 unsigned char* p;
1484 unsigned short version;
1485
1486 ipod->nimages=0;
1487
1488 /* Read firmware partition header (first 512 bytes of disk - but
1489 let's read a whole sector) */
1490
1491 if (ipod_seek(ipod, ipod->start) < 0) {
1492 fprintf(stderr,"[ERR] Seek to 0x%08x in read_directory() failed.\n",
1493 (unsigned int)(ipod->start));
1494 return -1;
1495 }
1496
1497 n=ipod_read(ipod, ipod->sector_size);
1498 if (n < 0) {
1499 fprintf(stderr,"[ERR] ipod_read(ipod,0x%08x) failed in read_directory()\n", ipod->sector_size);
1500 return -1;
1501 }
1502
1503 if (memcmp(ipod->sectorbuf,apple_stop_sign,sizeof(apple_stop_sign))!=0) {
1504 fprintf(stderr,"[ERR] Firmware partition doesn't contain Apple copyright, aborting.\n");
1505 return -1;
1506 }
1507
1508 if (memcmp(ipod->sectorbuf+0x100,"]ih[",4)!=0) {
1509 fprintf(stderr,"[ERR] Bad firmware directory\n");
1510 return -1;
1511 }
1512
1513 version = le2ushort(ipod->sectorbuf+0x10a);
1514 if ((version != 2) && (version != 3)) {
1515 fprintf(stderr,"[ERR] Unknown firmware format version %04x\n",
1516 version);
1517 }
1518 ipod->diroffset=le2int(ipod->sectorbuf+0x104) + 0x200;
1519
1520 /* diroffset may not be sector-aligned */
1521 x = ipod->diroffset % ipod->sector_size;
1522
1523 /* Read directory */
1524 if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) {
1525 fprintf(stderr,"[ERR] Seek to diroffset (%08x) failed.\n",(unsigned)ipod->diroffset);
1526 return -1;
1527 }
1528
1529 n=ipod_read(ipod, ipod->sector_size);
1530 if (n < 0) {
1531 fprintf(stderr,"[ERR] Read of directory failed.\n");
1532 return -1;
1533 }
1534
1535 p = ipod->sectorbuf + x;
1536
1537 /* A hack to detect 2nd gen Nanos - maybe there is a better way? */
1538 if (p[0] == 0)
1539 {
1540 /* Adjust diroffset */
1541 ipod->diroffset += ipod->sector_size - x;
1542
1543 n=ipod_read(ipod, ipod->sector_size);
1544 if (n < 0) {
1545 fprintf(stderr,"[ERR] Read of directory failed.\n");
1546 return -1;
1547 }
1548 p = ipod->sectorbuf;
1549 }
1550
1551 ipod->ososimage = -1;
1552 while ((ipod->nimages < MAX_IMAGES) && (p < (ipod->sectorbuf + x + 400)) &&
1553 ((memcmp(p,"!ATA",4)==0) || (memcmp(p,"DNAN",4)==0))) {
1554 p+=4;
1555 if (memcmp(p,"soso",4)==0) {
1556 ipod->ipod_directory[ipod->nimages].ftype=FTYPE_OSOS;
1557 ipod->ososimage = ipod->nimages;
1558 } else if (memcmp(p,"crsr",4)==0) {
1559 ipod->ipod_directory[ipod->nimages].ftype=FTYPE_RSRC;
1560 } else if (memcmp(p,"dpua",4)==0) {
1561 ipod->ipod_directory[ipod->nimages].ftype=FTYPE_AUPD;
1562 } else if (memcmp(p,"kbso",4)==0) {
1563 ipod->ipod_directory[ipod->nimages].ftype=FTYPE_OSBK;
1564 } else if (memcmp(p,"ebih",4)==0) {
1565 ipod->ipod_directory[ipod->nimages].ftype=FTYPE_HIBE;
1566 } else {
1567 fprintf(stderr,"[ERR] Unknown image type %c%c%c%c\n",
1568 p[0],p[1],p[2],p[3]);
1569 }
1570 p+=4;
1571 ipod->ipod_directory[ipod->nimages].id=le2int(p);
1572 p+=4;
1573 ipod->ipod_directory[ipod->nimages].devOffset=le2int(p);
1574 p+=4;
1575 ipod->ipod_directory[ipod->nimages].len=le2int(p);
1576 p+=4;
1577 ipod->ipod_directory[ipod->nimages].addr=le2int(p);
1578 p+=4;
1579 ipod->ipod_directory[ipod->nimages].entryOffset=le2int(p);
1580 p+=4;
1581 ipod->ipod_directory[ipod->nimages].chksum=le2int(p);
1582 p+=4;
1583 ipod->ipod_directory[ipod->nimages].vers=le2int(p);
1584 p+=4;
1585 ipod->ipod_directory[ipod->nimages].loadAddr=le2int(p);
1586 p+=4;
1587 ipod->nimages++;
1588 }
1589
1590 if (ipod->ososimage < 0) {
1591 fprintf(stderr,"[ERR] No OSOS image found.\n");
1592 return -1;
1593 }
1594
1595 if ((ipod->nimages > 1) && (version==2)) {
1596 /* The 3g firmware image doesn't appear to have a version, so
1597 let's make one up... Note that this is never written back to the
1598 ipod, so it's OK to do. */
1599
1600 if (ipod->ipod_directory[ipod->ososimage].vers == 0) { ipod->ipod_directory[ipod->ososimage].vers = 3; }
1601
1602 ipod->fwoffset = ipod->start;
1603 } else {
1604 ipod->fwoffset = ipod->start + ipod->sector_size;
1605 }
1606
1607 return 0;
1608}
1609
1610int list_images(struct ipod_t* ipod)
1611{
1612 int i;
1613
1614 if (ipod_verbose) {
1615 printf(" Type id devOffset len addr entryOffset chksum vers loadAddr devOffset+len\n");
1616 for (i = 0 ; i < ipod->nimages; i++) {
1617 printf("%d - %s 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",i,
1618 ftypename[ipod->ipod_directory[i].ftype],
1619 ipod->ipod_directory[i].id,
1620 ipod->ipod_directory[i].devOffset,
1621 ipod->ipod_directory[i].len,
1622 ipod->ipod_directory[i].addr,
1623 ipod->ipod_directory[i].entryOffset,
1624 ipod->ipod_directory[i].chksum,
1625 ipod->ipod_directory[i].vers,
1626 ipod->ipod_directory[i].loadAddr,
1627 ipod->ipod_directory[i].devOffset+((ipod->ipod_directory[i].len+ipod->sector_size-1)&~(ipod->sector_size-1)));
1628 }
1629 }
1630
1631 printf("\n");
1632 printf("Listing firmware partition contents:\n");
1633 printf("\n");
1634
1635 for (i = 0 ; i < ipod->nimages; i++) {
1636 printf("Image %d:\n",i+1);
1637 switch(ipod->ipod_directory[i].ftype) {
1638 case FTYPE_OSOS:
1639 if (ipod->ipod_directory[i].entryOffset==0) {
1640 printf(" Main firmware - %d bytes\n",
1641 ipod->ipod_directory[i].len);
1642 } else {
1643 printf(" Main firmware - %d bytes\n",
1644 ipod->ipod_directory[i].entryOffset);
1645 printf(" Third-party bootloader - %d bytes\n",
1646 ipod->ipod_directory[i].len-ipod->ipod_directory[i].entryOffset);
1647 }
1648 break;
1649 default:
1650 printf(" %s - %d bytes\n",
1651 ftypename[ipod->ipod_directory[i].ftype],
1652 ipod->ipod_directory[i].len);
1653 }
1654 }
1655 printf("\n");
1656
1657 return 0;
1658}
1659
1660int getmodel(struct ipod_t* ipod, int ipod_version)
1661{
1662 switch (ipod_version) {
1663 case 0x01:
1664 ipod->modelstr="1st or 2nd Generation";
1665 ipod->modelnum = 19;
1666 ipod->modelname = "1g2g";
1667 ipod->targetname = "ipod1g2g";
1668#ifdef WITH_BOOTOBJS
1669 ipod->bootloader = ipod1g2g;
1670 ipod->bootloader_len = LEN_ipod1g2g;
1671#endif
1672 break;
1673 case 0x02:
1674 ipod->modelstr="3rd Generation";
1675 ipod->modelnum = 7;
1676 ipod->modelname = "ip3g";
1677 ipod->targetname = "ipod3g";
1678#ifdef WITH_BOOTOBJS
1679 ipod->bootloader = ipod3g;
1680 ipod->bootloader_len = LEN_ipod3g;
1681#endif
1682 break;
1683 case 0x40:
1684 ipod->modelstr="1st Generation Mini";
1685 ipod->modelnum = 9;
1686 ipod->modelname = "mini";
1687 ipod->targetname = "ipodmini1g";
1688#ifdef WITH_BOOTOBJS
1689 ipod->bootloader = ipodmini1g;
1690 ipod->bootloader_len = LEN_ipodmini1g;
1691#endif
1692 break;
1693 case 0x50:
1694 ipod->modelstr="4th Generation";
1695 ipod->modelnum = 8;
1696 ipod->modelname = "ip4g";
1697 ipod->targetname = "ipod4gray";
1698#ifdef WITH_BOOTOBJS
1699 ipod->bootloader = ipod4g;
1700 ipod->bootloader_len = LEN_ipod4g;
1701#endif
1702 break;
1703 case 0x60:
1704 ipod->modelstr="Photo/Color";
1705 ipod->modelnum = 3;
1706 ipod->modelname = "ipco";
1707 ipod->targetname = "ipodcolor";
1708#ifdef WITH_BOOTOBJS
1709 ipod->bootloader = ipodcolor;
1710 ipod->bootloader_len = LEN_ipodcolor;
1711#endif
1712 break;
1713 case 0x70:
1714 ipod->modelstr="2nd Generation Mini";
1715 ipod->modelnum = 11;
1716 ipod->modelname = "mn2g";
1717 ipod->targetname = "ipodmini2g";
1718#ifdef WITH_BOOTOBJS
1719 ipod->bootloader = ipodmini2g;
1720 ipod->bootloader_len = LEN_ipodmini2g;
1721#endif
1722 break;
1723 case 0xc0:
1724 ipod->modelstr="1st Generation Nano";
1725 ipod->modelnum = 4;
1726 ipod->modelname = "nano";
1727 ipod->targetname = "ipodnano1g";
1728#ifdef WITH_BOOTOBJS
1729 ipod->bootloader = ipodnano1g;
1730 ipod->bootloader_len = LEN_ipodnano1g;
1731#endif
1732 break;
1733 case 0xb0:
1734 ipod->modelstr="Video (aka 5th Generation)";
1735 ipod->modelnum = 5;
1736 ipod->modelname = "ipvd";
1737 ipod->targetname = "ipodvideo";
1738#ifdef WITH_BOOTOBJS
1739 ipod->bootloader = ipodvideo;
1740 ipod->bootloader_len = LEN_ipodvideo;
1741#endif
1742 break;
1743 case 0x100:
1744 ipod->modelstr="2nd Generation Nano";
1745 ipod->modelnum = 62;
1746 ipod->modelname = "nn2x";
1747 ipod->targetname = "ipodnano2g";
1748#ifdef WITH_BOOTOBJS
1749 ipod->bootloader = ipodnano2g;
1750 ipod->bootloader_len = LEN_ipodnano2g;
1751#endif
1752 break;
1753 default:
1754 ipod->modelname = NULL;
1755 ipod->modelnum = 0;
1756 ipod->targetname = NULL;
1757#ifdef WITH_BOOTOBJS
1758 ipod->bootloader = NULL;
1759 ipod->bootloader_len = 0;
1760#endif
1761 return -1;
1762 }
1763 return 0;
1764}
1765
1766/* returns number of found ipods or -1 if no ipods found and permission
1767 * for raw disc access was denied. */
1768int ipod_scan(struct ipod_t* ipod)
1769{
1770 int i;
1771 int n = 0;
1772 int ipod_version;
1773 struct ipod_t ipod_found;
1774 int denied = 0;
1775 int result;
1776
1777 printf("[INFO] Scanning disk devices...\n");
1778
1779 for (i = 0; i <= 25 ; i++) {
1780#ifdef __WIN32__
1781 sprintf(ipod->diskname,"\\\\.\\PhysicalDrive%d",i);
1782#elif defined(linux) || defined (__linux)
1783 sprintf(ipod->diskname,"/dev/sd%c",'a'+i);
1784#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \
1785 || defined(__bsdi__) || defined(__DragonFly__)
1786 sprintf(ipod->diskname,"/dev/da%d",i);
1787#elif defined(__APPLE__) && defined(__MACH__)
1788 sprintf(ipod->diskname,"/dev/disk%d",i);
1789#else
1790 #error No disk paths defined for this platform
1791#endif
1792 if ((result = ipod_open(ipod, 1)) < 0) {
1793 if(result == -2) {
1794 denied++;
1795 }
1796 ipod_close(ipod);
1797 continue;
1798 }
1799
1800 if (read_partinfo(ipod,1) < 0) {
1801 ipod_close(ipod);
1802 continue;
1803 }
1804
1805 if ((ipod->pinfo[0].start==0) || (ipod->pinfo[0].type != 0)) {
1806 ipod_close(ipod);
1807 continue;
1808 }
1809
1810 if (read_directory(ipod) < 0) {
1811 ipod_close(ipod);
1812 continue;
1813 }
1814
1815 ipod_version=(ipod->ipod_directory[ipod->ososimage].vers>>8);
1816 ipod->ramsize = 0;
1817#ifdef __WIN32__
1818 /* Windows requires the ipod in R/W mode for SCSI Inquiry.
1819 * ipod_reopen_rw does unmount the player on OS X so do this on
1820 * W32 only during scanning. */
1821 ipod_reopen_rw(ipod);
1822#endif
1823 ipod_get_xmlinfo(ipod);
1824 ipod_get_ramsize(ipod);
1825 if (getmodel(ipod,ipod_version) < 0) {
1826 ipod_close(ipod);
1827 continue;
1828 }
1829
1830#ifdef __WIN32__
1831 printf("[INFO] Ipod found - %s (\"%s\") - disk device %d\n",
1832 ipod->modelstr,ipod->macpod ? "macpod" : "winpod",i);
1833#else
1834 printf("[INFO] Ipod found - %s (\"%s\") - %s\n",
1835 ipod->modelstr,ipod->macpod ? "macpod" : "winpod",ipod->diskname);
1836#endif
1837 n++;
1838 /* save the complete ipod_t structure for match. The for loop might
1839 * overwrite it, so we need to restore it later if only one found. */
1840 memcpy(&ipod_found, ipod, sizeof(struct ipod_t));
1841 ipod_close(ipod);
1842 }
1843
1844 if (n==1) {
1845 /* restore the ipod_t structure, it might have been overwritten */
1846 memcpy(ipod, &ipod_found, sizeof(struct ipod_t));
1847 }
1848 else if(n == 0 && denied) {
1849 printf("[ERR] FATAL: Permission denied on %d device(s) and no ipod detected.\n", denied);
1850#ifdef __WIN32__
1851 printf("[ERR] You need to run this program with administrator priviledges!\n");
1852#else
1853 printf("[ERR] You need permissions for raw disc access for this program to work!\n");
1854#endif
1855 }
1856 return (n == 0 && denied) ? -1 : n;
1857}
1858
1859static void put_int32le(uint32_t x, unsigned char* p)
1860{
1861 p[0] = x & 0xff;
1862 p[1] = (x >> 8) & 0xff;
1863 p[2] = (x >> 16) & 0xff;
1864 p[3] = (x >> 24) & 0xff;
1865}
1866
1867int write_dos_partition_table(struct ipod_t* ipod)
1868{
1869 unsigned char* p;
1870 int i, n;
1871 uint32_t type;
1872
1873 /* Only support 512-byte sectors at the moment */
1874 if ( ipod->sector_size != 512 )
1875 {
1876 fprintf(stderr,"[ERR] Only ipods with 512 bytes per sector are supported.\n");
1877 return -1;
1878 }
1879 if(ipod->sectorbuf == NULL) {
1880 fprintf(stderr,"[ERR] Buffer not initialized.");
1881 return -1;
1882 }
1883
1884 /* Firstly zero the entire MBR */
1885 memset(ipod->sectorbuf, 0, ipod->sector_size);
1886
1887 /* Now add the partition info */
1888 for (i=0; i < 4 ; i++)
1889 {
1890 p = ipod->sectorbuf + 0x1be + i*16;
1891
1892 /* Ensure first partition is type 0, and second is 0xb */
1893 if (i==0) { type = 0; }
1894 else if (i==1) { type = 0xb; }
1895 else { type = ipod->pinfo[i].type; }
1896
1897 put_int32le(type, p + 4);
1898 put_int32le(ipod->pinfo[i].start, p + 8);
1899 put_int32le(ipod->pinfo[i].size, p + 12);
1900 }
1901
1902 /* Finally add the magic */
1903 ipod->sectorbuf[0x1fe] = 0x55;
1904 ipod->sectorbuf[0x1ff] = 0xaa;
1905
1906 if (ipod_seek(ipod, 0) < 0) {
1907 fprintf(stderr,"[ERR] Seek failed writing MBR\n");
1908 return -1;
1909 }
1910
1911 /* Write MBR */
1912 if ((n = ipod_write(ipod, ipod->sector_size)) < 0) {
1913 perror("[ERR] Write failed\n");
1914 return -1;
1915 }
1916
1917 return 0;
1918}
1919
1920/* Get the XML Device Information, as documented here:
1921
1922 http://www.ipodlinux.org/wiki/Device_Information
1923*/
1924
1925int ipod_get_xmlinfo(struct ipod_t* ipod)
1926{
1927 unsigned char hdr[255];
1928 unsigned char buf[255];
1929 char* p;
1930 int psize;
1931 int npages;
1932 int i;
1933
1934 if (ipod_scsi_inquiry(ipod, 0xc0, buf, sizeof(buf)) < 0)
1935 {
1936 fprintf(stderr,"[ERR] Sending SCSI Command failed.\n");
1937 return -1;
1938 }
1939
1940 /* Reading directly into hdr[] causes problems (for an unknown reason) on
1941 win32 */
1942 memcpy(hdr, buf, sizeof(hdr));
1943
1944 npages = hdr[3];
1945
1946 psize = npages * 0xf8; /* Hopefully this is enough. */
1947
1948 ipod->xmlinfo = malloc(psize);
1949 ipod->xmlinfo_len = 0;
1950
1951 if (ipod->xmlinfo == NULL) {
1952 fprintf(stderr,"[ERR] Could not allocate RAM for xmlinfo\n");
1953 return -1;
1954 }
1955
1956 p = ipod->xmlinfo;
1957
1958 for (i=0; i < npages; i++) {
1959 if (ipod_scsi_inquiry(ipod, hdr[i+4], buf, sizeof(buf)) < 0) {
1960 fprintf(stderr,"[ERR] Sending SCSI Command failed.\n");
1961 return -1;
1962 }
1963
1964 if ((buf[3] + ipod->xmlinfo_len) > psize) {
1965 fprintf(stderr,"[ERR] Ran out of memory reading xmlinfo\n");
1966 free(ipod->xmlinfo);
1967 ipod->xmlinfo = NULL;
1968 ipod->xmlinfo_len = 0;
1969 return -1;
1970 }
1971
1972 memcpy(p, buf + 4, buf[3]);
1973 p += buf[3];
1974 ipod->xmlinfo_len += buf[3];
1975 }
1976
1977 /* NULL-terminate the XML info */
1978 *p = 0;
1979
1980 fprintf(stderr,"[INFO] Read XML info (%d bytes)\n",ipod->xmlinfo_len);
1981
1982 return 0;
1983}
1984
1985void ipod_get_ramsize(struct ipod_t* ipod)
1986{
1987 const char needle[] = "<key>RAM</key>\n<integer>";
1988 char* p;
1989
1990 if (ipod->xmlinfo == NULL)
1991 return;
1992
1993 p = strstr(ipod->xmlinfo, needle);
1994
1995 if (p) {
1996 ipod->ramsize = atoi(p + sizeof(needle) - 1);
1997 }
1998}
1999
2000#ifndef RBUTIL
2001
2002static inline uint32_t getuint32le(unsigned char* buf)
2003{
2004 int32_t res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
2005
2006 return res;
2007}
2008
2009/* testMarker and GetSecurityBlockKey based on code from BadBlocks and
2010 Kingstone, posted at http://ipodlinux.org/Flash_Decryption
2011
2012*/
2013
2014static bool testMarker(int marker)
2015{
2016 int mask, decrypt, temp1, temp2;
2017
2018 mask = (marker&0xff)|((marker&0xff)<<8)|((marker&0xff)<<16)|((marker&0xff)<<24);
2019 decrypt = marker ^ mask;
2020 temp1=(int)((unsigned int)decrypt>>24);
2021 temp2=decrypt<<8;
2022
2023 if (temp1==0)
2024 return false;
2025
2026 temp2=(int)((unsigned int)temp2>>24);
2027 decrypt=decrypt<<16;
2028 decrypt=(int)((unsigned int)decrypt>>24);
2029
2030 if ((temp1 < temp2) && (temp2 < decrypt))
2031 {
2032 temp1 = temp1 & 0xf;
2033 temp2 = temp2 & 0xf;
2034 decrypt = decrypt & 0xf;
2035
2036 if ((temp1 > temp2) && (temp2 > decrypt) && (decrypt != 0))
2037 {
2038 return true;
2039 }
2040 }
2041 return false;
2042}
2043
2044static int GetSecurityBlockKey(unsigned char *data, unsigned char* this_key)
2045{
2046 int constant = 0x54c3a298;
2047 int key=0;
2048 int nkeys = 0;
2049 int aMarker=0;
2050 int pos=0;
2051 int c, count;
2052 int temp1;
2053 static const int offset[8]={0x5,0x25,0x6f,0x69,0x15,0x4d,0x40,0x34};
2054
2055 for (c = 0; c < 8; c++)
2056 {
2057 pos = offset[c]*4;
2058 aMarker = getuint32le(data + pos);
2059
2060 if (testMarker(aMarker))
2061 {
2062 if (c<7)
2063 pos =(offset[c+1]*4)+4;
2064 else
2065 pos =(offset[0]*4)+4;
2066
2067 key=0;
2068
2069 temp1=aMarker;
2070
2071 for (count=0;count<2;count++){
2072 int word = getuint32le(data + pos);
2073 temp1 = aMarker;
2074 temp1 = temp1^word;
2075 temp1 = temp1^constant;
2076 key = temp1;
2077 pos = pos+4;
2078 }
2079 int r1=0x6f;
2080 int r2=0;
2081 int r12;
2082 int r14;
2083 unsigned int r_tmp;
2084
2085 for (count=2;count<128;count=count+2){
2086 r2=getuint32le(data+count*4);
2087 r12=getuint32le(data+(count*4)+4);
2088 r_tmp=(unsigned int)r12>>16;
2089 r14=r2 | ((int)r_tmp);
2090 r2=r2&0xffff;
2091 r2=r2 | r12;
2092 r1=r1^r14;
2093 r1=r1+r2;
2094 }
2095 key=key^r1;
2096
2097 // Invert key, little endian
2098 this_key[0] = key & 0xff;
2099 this_key[1] = (key >> 8) & 0xff;
2100 this_key[2] = (key >> 16) & 0xff;
2101 this_key[3] = (key >> 24) & 0xff;
2102 nkeys++;
2103 }
2104 }
2105 return nkeys;
2106}
2107
2108static int find_key(struct ipod_t* ipod, int aupd, unsigned char* key)
2109{
2110 int n;
2111
2112 /* Firstly read the security block and find the RC4 key. This is
2113 in the sector preceeding the AUPD image. */
2114
2115 if(ipod->sectorbuf == NULL) {
2116 fprintf(stderr,"[ERR] Buffer not initialized.");
2117 return -1;
2118 }
2119 fprintf(stderr, "[INFO] Reading security block at offset 0x%08x\n",ipod->ipod_directory[aupd].devOffset-ipod->sector_size);
2120 if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset-ipod->sector_size) < 0) {
2121 return -1;
2122 }
2123
2124 if ((n = ipod_read(ipod, 512)) < 0) {
2125 return -1;
2126 }
2127
2128 n = GetSecurityBlockKey(ipod->sectorbuf, key);
2129
2130 if (n != 1)
2131 {
2132 fprintf(stderr, "[ERR] %d keys found in security block, can not continue\n",n);
2133 return -1;
2134 }
2135
2136 return 0;
2137}
2138
2139int read_aupd(struct ipod_t* ipod, char* filename)
2140{
2141 int length;
2142 int i;
2143 int outfile;
2144 int n;
2145 int aupd;
2146 struct rc4_key_t rc4;
2147 unsigned char key[4];
2148 unsigned long chksum=0;
2149
2150 if(ipod->sectorbuf == NULL) {
2151 fprintf(stderr,"[ERR] Buffer not initialized.");
2152 return -1;
2153 }
2154 aupd = 0;
2155 while ((aupd < ipod->nimages) && (ipod->ipod_directory[aupd].ftype != FTYPE_AUPD))
2156 {
2157 aupd++;
2158 }
2159
2160 if (aupd == ipod->nimages)
2161 {
2162 fprintf(stderr,"[ERR] No AUPD image in firmware partition.\n");
2163 return -1;
2164 }
2165
2166 length = ipod->ipod_directory[aupd].len;
2167
2168 fprintf(stderr,"[INFO] Reading firmware (%d bytes)\n",length);
2169
2170 if (find_key(ipod, aupd, key) < 0)
2171 {
2172 return -1;
2173 }
2174
2175 fprintf(stderr, "[INFO] Decrypting AUPD image with key %02x%02x%02x%02x\n",key[0],key[1],key[2],key[3]);
2176
2177 if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset) < 0) {
2178 return -1;
2179 }
2180
2181 i = (length+ipod->sector_size-1) & ~(ipod->sector_size-1);
2182
2183 if ((n = ipod_read(ipod,i)) < 0) {
2184 return -1;
2185 }
2186
2187 if (n < i) {
2188 fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n",
2189 i,n);
2190 return -1;
2191 }
2192
2193 /* Perform the decryption - this is standard (A)RC4 */
2194 matrixArc4Init(&rc4, key, 4);
2195 matrixArc4(&rc4, ipod->sectorbuf, ipod->sectorbuf, length);
2196
2197 chksum = 0;
2198 for (i = 0; i < (int)length; i++) {
2199 /* add 8 unsigned bits but keep a 32 bit sum */
2200 chksum += ipod->sectorbuf[i];
2201 }
2202
2203 if (chksum != ipod->ipod_directory[aupd].chksum)
2204 {
2205 fprintf(stderr,"[ERR] Decryption failed - checksum error\n");
2206 return -1;
2207 }
2208 fprintf(stderr,"[INFO] Decrypted OK (checksum matches header)\n");
2209
2210 outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666);
2211 if (outfile < 0) {
2212 fprintf(stderr,"[ERR] Couldn't open file %s\n",filename);
2213 return -1;
2214 }
2215
2216 n = write(outfile,ipod->sectorbuf,length);
2217 if (n != length) {
2218 fprintf(stderr,"[ERR] Write error - %d\n",n);
2219 }
2220 close(outfile);
2221
2222 return 0;
2223}
2224
2225int write_aupd(struct ipod_t* ipod, char* filename)
2226{
2227 unsigned int length;
2228 int i;
2229 int x;
2230 int n;
2231 int infile;
2232 int newsize;
2233 int aupd;
2234 unsigned long chksum=0;
2235 struct rc4_key_t rc4;
2236 unsigned char key[4];
2237
2238 if(ipod->sectorbuf == NULL) {
2239 fprintf(stderr,"[ERR] Buffer not initialized.");
2240 return -1;
2241 }
2242 /* First check that the input file is the correct type for this ipod. */
2243 infile=open(filename,O_RDONLY);
2244 if (infile < 0) {
2245 fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename);
2246 return -1;
2247 }
2248
2249 length = filesize(infile);
2250 newsize=(length+ipod->sector_size-1)&~(ipod->sector_size-1);
2251
2252 fprintf(stderr,"[INFO] Padding input file from 0x%08x to 0x%08x bytes\n",
2253 length,newsize);
2254
2255 if (newsize > BUFFER_SIZE) {
2256 fprintf(stderr,"[ERR] Input file too big for buffer\n");
2257 if (infile >= 0) close(infile);
2258 return -1;
2259 }
2260
2261 /* Find aupd image number */
2262 aupd = 0;
2263 while ((aupd < ipod->nimages) && (ipod->ipod_directory[aupd].ftype != FTYPE_AUPD))
2264 {
2265 aupd++;
2266 }
2267
2268 if (aupd == ipod->nimages)
2269 {
2270 fprintf(stderr,"[ERR] No AUPD image in firmware partition.\n");
2271 return -1;
2272 }
2273
2274 if (length != ipod->ipod_directory[aupd].len)
2275 {
2276 fprintf(stderr,"[ERR] AUPD image (%d bytes) differs in size to %s (%d bytes).\n",
2277 ipod->ipod_directory[aupd].len, filename, length);
2278 return -1;
2279 }
2280
2281 if (find_key(ipod, aupd, key) < 0)
2282 {
2283 return -1;
2284 }
2285
2286 fprintf(stderr, "[INFO] Encrypting AUPD image with key %02x%02x%02x%02x\n",key[0],key[1],key[2],key[3]);
2287
2288 /* We now know we have enough space, so write it. */
2289
2290 fprintf(stderr,"[INFO] Reading input file...\n");
2291 n = read(infile,ipod->sectorbuf,length);
2292 if (n < 0) {
2293 fprintf(stderr,"[ERR] Couldn't read input file\n");
2294 close(infile);
2295 return -1;
2296 }
2297 close(infile);
2298
2299 /* Pad the data with zeros */
2300 memset(ipod->sectorbuf+length,0,newsize-length);
2301
2302 /* Calculate the new checksum (before we encrypt) */
2303 chksum = 0;
2304 for (i = 0; i < (int)length; i++) {
2305 /* add 8 unsigned bits but keep a 32 bit sum */
2306 chksum += ipod->sectorbuf[i];
2307 }
2308
2309 /* Perform the encryption - this is standard (A)RC4 */
2310 matrixArc4Init(&rc4, key, 4);
2311 matrixArc4(&rc4, ipod->sectorbuf, ipod->sectorbuf, length);
2312
2313 if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset) < 0) {
2314 fprintf(stderr,"[ERR] Seek failed\n");
2315 return -1;
2316 }
2317
2318 if ((n = ipod_write(ipod,newsize)) < 0) {
2319 perror("[ERR] Write failed\n");
2320 return -1;
2321 }
2322
2323 if (n < newsize) {
2324 fprintf(stderr,"[ERR] Short write - requested %d bytes, received %d\n"
2325 ,newsize,n);
2326 return -1;
2327 }
2328 fprintf(stderr,"[INFO] Wrote %d bytes to firmware partition\n",n);
2329
2330 x = ipod->diroffset % ipod->sector_size;
2331
2332 /* Read directory */
2333 if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
2334
2335 n=ipod_read(ipod, ipod->sector_size);
2336 if (n < 0) { return -1; }
2337
2338 /* Update checksum */
2339 fprintf(stderr,"[INFO] Updating checksum to 0x%08x (was 0x%08x)\n",(unsigned int)chksum,le2int(ipod->sectorbuf + x + aupd*40 + 28));
2340 int2le(chksum,ipod->sectorbuf+x+aupd*40+28);
2341
2342 /* Write directory */
2343 if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
2344 n=ipod_write(ipod, ipod->sector_size);
2345 if (n < 0) { return -1; }
2346
2347 return 0;
2348}
2349
2350#endif
diff --git a/utils/ipodpatcher/ipodpatcher.h b/utils/ipodpatcher/ipodpatcher.h
new file mode 100644
index 0000000000..2cd2331666
--- /dev/null
+++ b/utils/ipodpatcher/ipodpatcher.h
@@ -0,0 +1,84 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006-2007 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef IPODPATCHER_H
23#define IPODPATCHER_H
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29#include "ipodio.h"
30
31/* exit codes */
32#define IPOD_OK 0
33#define IPOD_WRONG_ARGUMENTS 1
34#define IPOD_OPEN_INFILE_FAILED 2
35#define IPOD_PARTITION_ERROR 3
36#define IPOD_OPEN_OUTFILE_FAILED 4
37#define IPOD_CANNOT_REOPEN 5
38#define IPOD_ACCESS_DENIED 10
39#define IPOD_NOT_FOUND 11
40#define IPOD_WRONG_DEVICE_COUNT 12
41#define IPOD_IMAGE_ERROR 13
42#define IPOD_DUMP_FAILED 14
43#define IPOD_MULTIPLE_DEVICES 15
44#define IPOD_WRONG_TYPE 16
45#define IPOD_UNKNOWN_FW_VERSION -1
46
47/* Size of buffer for disk I/O - 8MB is large enough for any version
48 of the Apple firmware, but not the Nano's RSRC image. */
49#define BUFFER_SIZE 8*1024*1024
50
51extern int ipod_verbose;
52
53#define FILETYPE_DOT_IPOD 0
54#define FILETYPE_DOT_BIN 1
55#ifdef WITH_BOOTOBJS
56 #define FILETYPE_INTERNAL 2
57#endif
58
59char* get_parttype(unsigned int pt);
60int read_partinfo(struct ipod_t* ipod, int silent);
61int read_partition(struct ipod_t* ipod, int outfile);
62int write_partition(struct ipod_t* ipod, int infile);
63int diskmove(struct ipod_t* ipod, int delta);
64int add_bootloader(struct ipod_t* ipod, char* filename, int type);
65int delete_bootloader(struct ipod_t* ipod);
66int write_firmware(struct ipod_t* ipod, char* filename, int type);
67int read_firmware(struct ipod_t* ipod, char* filename, int type);
68int read_directory(struct ipod_t* ipod);
69int list_images(struct ipod_t* ipod);
70int getmodel(struct ipod_t* ipod, int ipod_version);
71int ipod_scan(struct ipod_t* ipod);
72int write_dos_partition_table(struct ipod_t* ipod);
73int ipod_get_xmlinfo(struct ipod_t* ipod);
74void ipod_get_ramsize(struct ipod_t* ipod);
75int read_aupd(struct ipod_t* ipod, char* filename);
76int write_aupd(struct ipod_t* ipod, char* filename);
77off_t filesize(int fd);
78int ipod_has_bootloader(struct ipod_t* ipod);
79
80#ifdef __cplusplus
81}
82#endif
83#endif
84
diff --git a/utils/ipodpatcher/ipodpatcher.manifest b/utils/ipodpatcher/ipodpatcher.manifest
new file mode 100644
index 0000000000..695ecb26ea
--- /dev/null
+++ b/utils/ipodpatcher/ipodpatcher.manifest
@@ -0,0 +1,13 @@
1<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
3 <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="ipodpatcher.exe" type="win32"/>
4
5 <!-- Identify the application security requirements. -->
6 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
7 <security>
8 <requestedPrivileges>
9 <requestedExecutionLevel level="requireAdministrator"/>
10 </requestedPrivileges>
11 </security>
12 </trustInfo>
13</assembly>
diff --git a/utils/ipodpatcher/ipodpatcher.pro b/utils/ipodpatcher/ipodpatcher.pro
new file mode 100644
index 0000000000..fac1e35f00
--- /dev/null
+++ b/utils/ipodpatcher/ipodpatcher.pro
@@ -0,0 +1,47 @@
1#
2# __________ __ ___.
3# Open \______ \ ____ ____ | | _\_ |__ _______ ___
4# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7# \/ \/ \/ \/ \/
8#
9# All files in this archive are subject to the GNU General Public License.
10# See the file COPYING in the source tree root for full license agreement.
11#
12# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
13# KIND, either express or implied.
14#
15
16TEMPLATE = app
17TARGET = ipodpatcher
18QT -= core
19
20SOURCES += \
21 main.c \
22 ipodpatcher.c \
23 ipodio-posix.c \
24 ipodio-win32-scsi.c \
25 ipodio-win32.c \
26 fat32format.c \
27 arc4.c \
28
29HEADERS += \
30 arc4.h \
31 ipodio.h \
32 ipodpatcher.h \
33 parttypes.h \
34
35DEFINES += RELEASE=1 _LARGEFILE64_SOURCE
36
37RC_FILE = ipodpatcher.rc
38
39macx {
40 LIBS += -framework CoreFoundation -framework IOKit
41}
42
43
44unix {
45 target.path = /usr/local/bin
46 INSTALLS += target
47}
diff --git a/utils/ipodpatcher/ipodpatcher.rc b/utils/ipodpatcher/ipodpatcher.rc
new file mode 100644
index 0000000000..e440b51271
--- /dev/null
+++ b/utils/ipodpatcher/ipodpatcher.rc
@@ -0,0 +1 @@
1 24 MOVEABLE PURE "ipodpatcher.manifest"
diff --git a/utils/ipodpatcher/main.c b/utils/ipodpatcher/main.c
new file mode 100644
index 0000000000..7b0a909178
--- /dev/null
+++ b/utils/ipodpatcher/main.c
@@ -0,0 +1,622 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006-2007 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdio.h>
23#include <unistd.h>
24#include <fcntl.h>
25#include <string.h>
26#include <stdlib.h>
27#include <inttypes.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30
31#include "ipodpatcher.h"
32#include "ipodio.h"
33
34#ifdef RELEASE
35#undef VERSION
36#define VERSION "5.0 with v4.0 bootloaders (v1.0 for 2nd Gen Nano)"
37#endif
38
39
40enum {
41 NONE,
42#ifdef WITH_BOOTOBJS
43 INSTALL,
44#endif
45 INTERACTIVE,
46 SHOW_INFO,
47 LIST_IMAGES,
48 DELETE_BOOTLOADER,
49 ADD_BOOTLOADER,
50 READ_FIRMWARE,
51 WRITE_FIRMWARE,
52 READ_AUPD,
53 WRITE_AUPD,
54 READ_PARTITION,
55 WRITE_PARTITION,
56 FORMAT_PARTITION,
57 DUMP_XML,
58 CONVERT_TO_FAT32
59};
60
61void print_macpod_warning(void)
62{
63 printf("[INFO] ************************************************************************\n");
64 printf("[INFO] *** WARNING FOR ROCKBOX USERS\n");
65 printf("[INFO] *** You must convert this ipod to FAT32 format (aka a \"winpod\")\n");
66 printf("[INFO] *** if you want to run Rockbox. Rockbox WILL NOT work on this ipod.\n");
67 printf("[INFO] *** See http://www.rockbox.org/wiki/IpodConversionToFAT32\n");
68 printf("[INFO] ************************************************************************\n");
69}
70
71void print_usage(void)
72{
73 fprintf(stderr,"Usage: ipodpatcher --scan\n");
74#ifdef __WIN32__
75 fprintf(stderr," or ipodpatcher [DISKNO] [action]\n");
76#else
77 fprintf(stderr," or ipodpatcher [device] [action]\n");
78#endif
79 fprintf(stderr,"\n");
80 fprintf(stderr,"Where [action] is one of the following options:\n");
81#ifdef WITH_BOOTOBJS
82 fprintf(stderr," --install\n");
83#endif
84 fprintf(stderr," -l, --list\n");
85 fprintf(stderr," -r, --read-partition bootpartition.bin\n");
86 fprintf(stderr," -w, --write-partition bootpartition.bin\n");
87 fprintf(stderr," -rf, --read-firmware filename.ipod[x]\n");
88 fprintf(stderr," -rfb, --read-firmware-bin filename.bin\n");
89 fprintf(stderr," -wf, --write-firmware filename.ipod[x]\n");
90 fprintf(stderr," -wfb, --write-firmware-bin filename.bin\n");
91#ifdef WITH_BOOTOBJS
92 fprintf(stderr," -we, --write-embedded\n");
93#endif
94 fprintf(stderr," -a, --add-bootloader filename.ipod[x]\n");
95 fprintf(stderr," -ab, --add-bootloader-bin filename.bin\n");
96 fprintf(stderr," -d, --delete-bootloader\n");
97 fprintf(stderr," -f, --format\n");
98 fprintf(stderr," -c, --convert\n");
99 fprintf(stderr," --read-aupd filename.bin\n");
100 fprintf(stderr," --write-aupd filename.bin\n");
101 fprintf(stderr," -x --dump-xml filename.xml\n");
102 fprintf(stderr,"\n");
103
104 fprintf(stderr,"The .ipodx extension is used for encrypted images for the 2nd Gen Nano.\n\n");
105
106#ifdef __WIN32__
107 fprintf(stderr,"DISKNO is the number (e.g. 2) Windows has assigned to your ipod's hard disk.\n");
108 fprintf(stderr,"The first hard disk in your computer (i.e. C:\\) will be disk 0, the next disk\n");
109 fprintf(stderr,"will be disk 1 etc. ipodpatcher will refuse to access a disk unless it\n");
110 fprintf(stderr,"can identify it as being an ipod.\n");
111 fprintf(stderr,"\n");
112#else
113#if defined(linux) || defined (__linux)
114 fprintf(stderr,"\"device\" is the device node (e.g. /dev/sda) assigned to your ipod.\n");
115#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
116 fprintf(stderr,"\"device\" is the device node (e.g. /dev/da1) assigned to your ipod.\n");
117#elif defined(__APPLE__) && defined(__MACH__)
118 fprintf(stderr,"\"device\" is the device node (e.g. /dev/disk1) assigned to your ipod.\n");
119#endif
120 fprintf(stderr,"ipodpatcher will refuse to access a disk unless it can identify it as being\n");
121 fprintf(stderr,"an ipod.\n");
122#endif
123}
124
125void display_partinfo(struct ipod_t* ipod)
126{
127 int i;
128 double sectors_per_MB = (1024.0*1024.0)/ipod->sector_size;
129
130 printf("[INFO] Part Start Sector End Sector Size (MB) Type\n");
131 for ( i = 0; i < 4; i++ ) {
132 if (ipod->pinfo[i].start != 0) {
133 printf("[INFO] %d %10ld %10ld %10.1f %s (0x%02x)\n",
134 i,
135 (long int)ipod->pinfo[i].start,
136 (long int)ipod->pinfo[i].start+ipod->pinfo[i].size-1,
137 ipod->pinfo[i].size/sectors_per_MB,
138 get_parttype(ipod->pinfo[i].type),
139 (int)ipod->pinfo[i].type);
140 }
141 }
142}
143
144
145int main(int argc, char* argv[])
146{
147 char yesno[4];
148 int i;
149 int n;
150 int infile, outfile;
151 unsigned int inputsize;
152 char* filename;
153 int action = SHOW_INFO;
154 int type;
155 struct ipod_t ipod;
156
157 fprintf(stderr,"ipodpatcher " VERSION "\n");
158 fprintf(stderr,"(C) Dave Chapman 2006-2009\n");
159 fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n");
160 fprintf(stderr,"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
161
162 if ((argc > 1) && ((strcmp(argv[1],"-h")==0) || (strcmp(argv[1],"--help")==0))) {
163 print_usage();
164 return IPOD_OK;
165 }
166
167 if (ipod_alloc_buffer(&ipod,BUFFER_SIZE) < 0) {
168 fprintf(stderr,"Failed to allocate memory buffer\n");
169 }
170
171 if ((argc > 1) && (strcmp(argv[1],"--scan")==0)) {
172 if (ipod_scan(&ipod) == 0)
173 fprintf(stderr,"[ERR] No ipods found.\n");
174 return IPOD_NOT_FOUND;
175 }
176
177 /* If the first parameter doesn't start with -, then we interpret it as a device */
178 if ((argc > 1) && (argv[1][0] != '-')) {
179 ipod.diskname[0]=0;
180#ifdef __WIN32__
181 snprintf(ipod.diskname,sizeof(ipod.diskname),"\\\\.\\PhysicalDrive%s",argv[1]);
182#else
183 strncpy(ipod.diskname,argv[1],sizeof(ipod.diskname));
184#endif
185 i = 2;
186 } else {
187 /* Autoscan for ipods */
188 n = ipod_scan(&ipod);
189 if (n==0) {
190 fprintf(stderr,"[ERR] No ipods found, aborting\n");
191 fprintf(stderr,"[ERR] Please connect your ipod and ensure it is in disk mode\n");
192#if defined(__APPLE__) && defined(__MACH__)
193 fprintf(stderr,"[ERR] Also ensure that itunes is closed, and that your ipod is not mounted.\n");
194#elif !defined(__WIN32__)
195 if (geteuid()!=0) {
196 fprintf(stderr,"[ERR] You may also need to run ipodpatcher as root.\n");
197 }
198#endif
199 fprintf(stderr,"[ERR] Please refer to the Rockbox manual if you continue to have problems.\n");
200 } else if (n > 1) {
201 fprintf(stderr,"[ERR] %d ipods found, aborting\n",n);
202 fprintf(stderr,"[ERR] Please connect only one ipod and re-run ipodpatcher.\n");
203 return IPOD_MULTIPLE_DEVICES;
204 } else if (n == 1 && ipod.macpod) {
205 return IPOD_WRONG_TYPE;
206 }
207
208 if (n != 1) {
209#ifdef WITH_BOOTOBJS
210 if (argc==1) {
211 printf("\nPress ENTER to exit ipodpatcher :");
212 fgets(yesno,4,stdin);
213 }
214#endif
215 return IPOD_NOT_FOUND;
216 }
217
218 i = 1;
219 }
220
221#ifdef WITH_BOOTOBJS
222 action = INTERACTIVE;
223#else
224 action = NONE;
225#endif
226
227 while (i < argc) {
228 if ((strcmp(argv[i],"-l")==0) || (strcmp(argv[i],"--list")==0)) {
229 action = LIST_IMAGES;
230 i++;
231#ifdef WITH_BOOTOBJS
232 } else if (strcmp(argv[i],"--install")==0) {
233 action = INSTALL;
234 i++;
235#endif
236 } else if ((strcmp(argv[i],"-d")==0) ||
237 (strcmp(argv[i],"--delete-bootloader")==0)) {
238 action = DELETE_BOOTLOADER;
239 i++;
240 } else if ((strcmp(argv[i],"-a")==0) ||
241 (strcmp(argv[i],"--add-bootloader")==0)) {
242 action = ADD_BOOTLOADER;
243 type = FILETYPE_DOT_IPOD;
244 i++;
245 if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; }
246 filename=argv[i];
247 i++;
248 } else if ((strcmp(argv[i],"-ab")==0) ||
249 (strcmp(argv[i],"--add-bootloader-bin")==0)) {
250 action = ADD_BOOTLOADER;
251 type = FILETYPE_DOT_BIN;
252 i++;
253 if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; }
254 filename=argv[i];
255 i++;
256 } else if ((strcmp(argv[i],"-rf")==0) ||
257 (strcmp(argv[i],"--read-firmware")==0)) {
258 action = READ_FIRMWARE;
259 type = FILETYPE_DOT_IPOD;
260 i++;
261 if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; }
262 filename=argv[i];
263 i++;
264 } else if ((strcmp(argv[i],"-rfb")==0) ||
265 (strcmp(argv[i],"--read-firmware-bin")==0)) {
266 action = READ_FIRMWARE;
267 type = FILETYPE_DOT_BIN;
268 i++;
269 if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; }
270 filename=argv[i];
271 i++;
272#ifdef WITH_BOOTOBJS
273 } else if ((strcmp(argv[i],"-we")==0) ||
274 (strcmp(argv[i],"--write-embedded")==0)) {
275 action = WRITE_FIRMWARE;
276 type = FILETYPE_INTERNAL;
277 filename="[embedded bootloader]"; /* Only displayed for user */
278 i++;
279#endif
280 } else if ((strcmp(argv[i],"-wf")==0) ||
281 (strcmp(argv[i],"--write-firmware")==0)) {
282 action = WRITE_FIRMWARE;
283 type = FILETYPE_DOT_IPOD;
284 i++;
285 if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; }
286 filename=argv[i];
287 i++;
288 } else if ((strcmp(argv[i],"-wfb")==0) ||
289 (strcmp(argv[i],"--write-firmware-bin")==0)) {
290 action = WRITE_FIRMWARE;
291 type = FILETYPE_DOT_BIN;
292 i++;
293 if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; }
294 filename=argv[i];
295 i++;
296 } else if ((strcmp(argv[i],"-r")==0) ||
297 (strcmp(argv[i],"--read-partition")==0)) {
298 action = READ_PARTITION;
299 i++;
300 if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; }
301 filename=argv[i];
302 i++;
303 } else if ((strcmp(argv[i],"-w")==0) ||
304 (strcmp(argv[i],"--write-partition")==0)) {
305 action = WRITE_PARTITION;
306 i++;
307 if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; }
308 filename=argv[i];
309 i++;
310 } else if ((strcmp(argv[i],"-v")==0) ||
311 (strcmp(argv[i],"--verbose")==0)) {
312 ipod_verbose++;
313 i++;
314 } else if ((strcmp(argv[i],"-f")==0) ||
315 (strcmp(argv[i],"--format")==0)) {
316 action = FORMAT_PARTITION;
317 i++;
318 } else if (strcmp(argv[i],"--read-aupd")==0) {
319 action = READ_AUPD;
320 i++;
321 if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; }
322 filename=argv[i];
323 i++;
324 } else if (strcmp(argv[i],"--write-aupd")==0) {
325 action = WRITE_AUPD;
326 i++;
327 if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; }
328 filename=argv[i];
329 i++;
330 } else if ((strcmp(argv[i],"-x")==0) ||
331 (strcmp(argv[i],"--dump-xml")==0)) {
332 action = DUMP_XML;
333 i++;
334 if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; }
335 filename=argv[i];
336 i++;
337 } else if ((strcmp(argv[i],"-c")==0) ||
338 (strcmp(argv[i],"--convert")==0)) {
339 action = CONVERT_TO_FAT32;
340 i++;
341 } else {
342 print_usage(); return IPOD_WRONG_ARGUMENTS;
343 }
344 }
345
346 if (ipod.diskname[0]==0) {
347 print_usage();
348 return 1;
349 }
350
351 if (ipod_open(&ipod, 0) < 0) {
352 return IPOD_ACCESS_DENIED;
353 }
354
355 fprintf(stderr,"[INFO] Reading partition table from %s\n",ipod.diskname);
356 fprintf(stderr,"[INFO] Sector size is %d bytes\n",ipod.sector_size);
357
358 if (read_partinfo(&ipod,0) < 0) {
359 return IPOD_PARTITION_ERROR;
360 }
361
362 display_partinfo(&ipod);
363
364 if (ipod.pinfo[0].start==0) {
365 fprintf(stderr,"[ERR] No partition 0 on disk:\n");
366 display_partinfo(&ipod);
367 return IPOD_PARTITION_ERROR;
368 }
369
370 read_directory(&ipod);
371
372 if (ipod.nimages <= 0) {
373 fprintf(stderr,"[ERR] Failed to read firmware directory - nimages=%d\n",ipod.nimages);
374 return IPOD_IMAGE_ERROR;
375 }
376
377 if (getmodel(&ipod,(ipod.ipod_directory[ipod.ososimage].vers>>8)) < 0) {
378 fprintf(stderr,"[ERR] Unknown version number in firmware (%08x)\n",
379 ipod.ipod_directory[ipod.ososimage].vers);
380 return IPOD_UNKNOWN_FW_VERSION;
381 }
382
383#ifdef __WIN32__
384 /* Windows requires the ipod in R/W mode for SCSI Inquiry */
385 if (ipod_reopen_rw(&ipod) < 0) {
386 return IPOD_CANNOT_REOPEN;
387 }
388#endif
389
390
391 /* Read the XML info, and if successful, look for the ramsize
392 (only available for some models - set to 0 if not known) */
393
394 ipod.ramsize = 0;
395
396 if (ipod_get_xmlinfo(&ipod) == 0) {
397 ipod_get_ramsize(&ipod);
398 }
399
400 printf("[INFO] Ipod model: %s ",ipod.modelstr);
401 if (ipod.ramsize > 0) { printf("(%dMB RAM) ",ipod.ramsize); }
402 printf("(\"%s\")\n",ipod.macpod ? "macpod" : "winpod");
403
404 if (ipod.macpod) {
405 print_macpod_warning();
406 }
407
408 if (action==LIST_IMAGES) {
409 list_images(&ipod);
410#ifdef WITH_BOOTOBJS
411 } else if (action==INTERACTIVE) {
412
413 printf("Enter i to install the Rockbox bootloader, u to uninstall\n or c to cancel and do nothing (i/u/c) :");
414
415 if (fgets(yesno,4,stdin)) {
416 if (yesno[0]=='i') {
417 if (ipod_reopen_rw(&ipod) < 0) {
418 return IPOD_CANNOT_REOPEN;
419 }
420
421 if (add_bootloader(&ipod, NULL, FILETYPE_INTERNAL)==0) {
422 fprintf(stderr,"[INFO] Bootloader installed successfully.\n");
423 } else {
424 fprintf(stderr,"[ERR] --install failed.\n");
425 }
426 } else if (yesno[0]=='u') {
427 if (ipod_reopen_rw(&ipod) < 0) {
428 return IPOD_CANNOT_REOPEN;
429 }
430
431 if (delete_bootloader(&ipod)==0) {
432 fprintf(stderr,"[INFO] Bootloader removed.\n");
433 } else {
434 fprintf(stderr,"[ERR] Bootloader removal failed.\n");
435 }
436 }
437 }
438#endif
439 } else if (action==DELETE_BOOTLOADER) {
440 if (ipod_reopen_rw(&ipod) < 0) {
441 return IPOD_CANNOT_REOPEN;
442 }
443
444 if (ipod.ipod_directory[0].entryOffset==0) {
445 fprintf(stderr,"[ERR] No bootloader detected.\n");
446 } else {
447 if (delete_bootloader(&ipod)==0) {
448 fprintf(stderr,"[INFO] Bootloader removed.\n");
449 } else {
450 fprintf(stderr,"[ERR] --delete-bootloader failed.\n");
451 }
452 }
453 } else if (action==ADD_BOOTLOADER) {
454 if (ipod_reopen_rw(&ipod) < 0) {
455 return IPOD_CANNOT_REOPEN;
456 }
457
458 if (add_bootloader(&ipod, filename, type)==0) {
459 fprintf(stderr,"[INFO] Bootloader %s written to device.\n",filename);
460 } else {
461 fprintf(stderr,"[ERR] --add-bootloader failed.\n");
462 }
463#ifdef WITH_BOOTOBJS
464 } else if (action==INSTALL) {
465 if (ipod_reopen_rw(&ipod) < 0) {
466 return IPOD_CANNOT_REOPEN;
467 }
468
469 if (add_bootloader(&ipod, NULL, FILETYPE_INTERNAL)==0) {
470 fprintf(stderr,"[INFO] Bootloader installed successfully.\n");
471 } else {
472 fprintf(stderr,"[ERR] --install failed.\n");
473 }
474#endif
475 } else if (action==WRITE_FIRMWARE) {
476 if (ipod_reopen_rw(&ipod) < 0) {
477 return IPOD_CANNOT_REOPEN;
478 }
479
480 if (write_firmware(&ipod, filename,type)==0) {
481 fprintf(stderr,"[INFO] Firmware %s written to device.\n",filename);
482 } else {
483 fprintf(stderr,"[ERR] --write-firmware failed.\n");
484 }
485 } else if (action==READ_FIRMWARE) {
486 if (read_firmware(&ipod, filename, type)==0) {
487 fprintf(stderr,"[INFO] Firmware read to file %s.\n",filename);
488 } else {
489 fprintf(stderr,"[ERR] --read-firmware failed.\n");
490 }
491 } else if (action==READ_AUPD) {
492 if (read_aupd(&ipod, filename)==0) {
493 fprintf(stderr,"[INFO] AUPD image read to file %s.\n",filename);
494 } else {
495 fprintf(stderr,"[ERR] --read-aupd failed.\n");
496 }
497 } else if (action==WRITE_AUPD) {
498 if (ipod_reopen_rw(&ipod) < 0) {
499 return IPOD_CANNOT_REOPEN;
500 }
501
502 if (write_aupd(&ipod, filename)==0) {
503 fprintf(stderr,"[INFO] AUPD image %s written to device.\n",filename);
504 } else {
505 fprintf(stderr,"[ERR] --write-aupd failed.\n");
506 }
507 } else if (action==DUMP_XML) {
508 if (ipod.xmlinfo == NULL) {
509 fprintf(stderr,"[ERR] No XML to write\n");
510 return IPOD_DUMP_FAILED;
511 }
512
513 outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IREAD|S_IWRITE);
514 if (outfile < 0) {
515 perror(filename);
516 return IPOD_OPEN_OUTFILE_FAILED;
517 }
518
519 if (write(outfile, ipod.xmlinfo, ipod.xmlinfo_len) < 0) {
520 fprintf(stderr,"[ERR] --dump-xml failed.\n");
521 } else {
522 fprintf(stderr,"[INFO] XML info written to %s.\n",filename);
523 }
524 close(outfile);
525 } else if (action==READ_PARTITION) {
526 outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IREAD|S_IWRITE);
527 if (outfile < 0) {
528 perror(filename);
529 return IPOD_OPEN_OUTFILE_FAILED;
530 }
531
532 if (read_partition(&ipod, outfile) < 0) {
533 fprintf(stderr,"[ERR] --read-partition failed.\n");
534 } else {
535 fprintf(stderr,"[INFO] Partition extracted to %s.\n",filename);
536 }
537 close(outfile);
538 } else if (action==WRITE_PARTITION) {
539 if (ipod_reopen_rw(&ipod) < 0) {
540 return IPOD_CANNOT_REOPEN;
541 }
542
543 infile = open(filename,O_RDONLY|O_BINARY);
544 if (infile < 0) {
545 perror(filename);
546 return IPOD_OPEN_INFILE_FAILED;
547 }
548
549 /* Check filesize is <= partition size */
550 inputsize=filesize(infile);
551 if (inputsize > 0) {
552 if (inputsize <= (ipod.pinfo[0].size*ipod.sector_size)) {
553 fprintf(stderr,"[INFO] Input file is %u bytes\n",inputsize);
554 if (write_partition(&ipod,infile) < 0) {
555 fprintf(stderr,"[ERR] --write-partition failed.\n");
556 } else {
557 fprintf(stderr,"[INFO] %s restored to partition\n",filename);
558 }
559 } else {
560 fprintf(stderr,"[ERR] File is too large for firmware partition, aborting.\n");
561 }
562 }
563
564 close(infile);
565 } else if (action==FORMAT_PARTITION) {
566 printf("WARNING!!! YOU ARE ABOUT TO USE AN EXPERIMENTAL FEATURE.\n");
567 printf("ALL DATA ON YOUR IPOD WILL BE ERASED.\n");
568 printf("Are you sure you want to format your ipod? (y/n):");
569
570 if (fgets(yesno,4,stdin)) {
571 if (yesno[0]=='y') {
572 if (ipod_reopen_rw(&ipod) < 0) {
573 return IPOD_CANNOT_REOPEN;
574 }
575
576 if (format_partition(&ipod,1) < 0) {
577 fprintf(stderr,"[ERR] Format failed.\n");
578 }
579 } else {
580 fprintf(stderr,"[INFO] Format cancelled.\n");
581 }
582 }
583 } else if (action==CONVERT_TO_FAT32) {
584 if (!ipod.macpod) {
585 printf("[ERR] Ipod is already FAT32, aborting\n");
586 } else {
587 printf("WARNING!!! YOU ARE ABOUT TO USE AN EXPERIMENTAL FEATURE.\n");
588 printf("ALL DATA ON YOUR IPOD WILL BE ERASED.\n");
589 printf("Are you sure you want to convert your ipod to FAT32? (y/n):");
590
591 if (fgets(yesno,4,stdin)) {
592 if (yesno[0]=='y') {
593 if (ipod_reopen_rw(&ipod) < 0) {
594 return IPOD_CANNOT_REOPEN;
595 }
596
597 if (write_dos_partition_table(&ipod) < 0) {
598 fprintf(stderr,"[ERR] Partition conversion failed.\n");
599 }
600
601 if (format_partition(&ipod,1) < 0) {
602 fprintf(stderr,"[ERR] Format failed.\n");
603 }
604 } else {
605 fprintf(stderr,"[INFO] Format cancelled.\n");
606 }
607 }
608 }
609 }
610
611 ipod_close(&ipod);
612
613#ifdef WITH_BOOTOBJS
614 if (action==INTERACTIVE) {
615 printf("Press ENTER to exit ipodpatcher :");
616 fgets(yesno,4,stdin);
617 }
618#endif
619
620 ipod_dealloc_buffer(&ipod);
621 return IPOD_OK;
622}
diff --git a/utils/ipodpatcher/parttypes.h b/utils/ipodpatcher/parttypes.h
new file mode 100644
index 0000000000..f8de303553
--- /dev/null
+++ b/utils/ipodpatcher/parttypes.h
@@ -0,0 +1,109 @@
1/* DOS partition types - taken from fdisk */
2
3struct parttype {
4 unsigned char type;
5 char *name;
6};
7
8struct parttype parttypes[] = {
9 {0x00, "Empty"},
10 {0x01, "FAT12"},
11 {0x02, "XENIX root"},
12 {0x03, "XENIX usr"},
13 {0x04, "FAT16 <32M"},
14 {0x05, "Extended"}, /* DOS 3.3+ extended partition */
15 {0x06, "FAT16"}, /* DOS 16-bit >=32M */
16 {0x07, "HPFS/NTFS"}, /* OS/2 IFS, eg, HPFS or NTFS or QNX */
17 {0x08, "AIX"}, /* AIX boot (AIX -- PS/2 port) or SplitDrive */
18 {0x09, "AIX bootable"}, /* AIX data or Coherent */
19 {0x0a, "OS/2 Boot Manager"},/* OS/2 Boot Manager */
20 {0x0b, "W95 FAT32"},
21 {0x0c, "W95 FAT32 (LBA)"},/* LBA really is `Extended Int 13h' */
22 {0x0e, "W95 FAT16 (LBA)"},
23 {0x0f, "W95 Ext'd (LBA)"},
24 {0x10, "OPUS"},
25 {0x11, "Hidden FAT12"},
26 {0x12, "Compaq diagnostics"},
27 {0x14, "Hidden FAT16 <32M"},
28 {0x16, "Hidden FAT16"},
29 {0x17, "Hidden HPFS/NTFS"},
30 {0x18, "AST SmartSleep"},
31 {0x1b, "Hidden W95 FAT32"},
32 {0x1c, "Hidden W95 FAT32 (LBA)"},
33 {0x1e, "Hidden W95 FAT16 (LBA)"},
34 {0x24, "NEC DOS"},
35 {0x39, "Plan 9"},
36 {0x3c, "PartitionMagic recovery"},
37 {0x40, "Venix 80286"},
38 {0x41, "PPC PReP Boot"},
39 {0x42, "SFS"},
40 {0x4d, "QNX4.x"},
41 {0x4e, "QNX4.x 2nd part"},
42 {0x4f, "QNX4.x 3rd part"},
43 {0x50, "OnTrack DM"},
44 {0x51, "OnTrack DM6 Aux1"}, /* (or Novell) */
45 {0x52, "CP/M"}, /* CP/M or Microport SysV/AT */
46 {0x53, "OnTrack DM6 Aux3"},
47 {0x54, "OnTrackDM6"},
48 {0x55, "EZ-Drive"},
49 {0x56, "Golden Bow"},
50 {0x5c, "Priam Edisk"},
51 {0x61, "SpeedStor"},
52 {0x63, "GNU HURD or SysV"}, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */
53 {0x64, "Novell Netware 286"},
54 {0x65, "Novell Netware 386"},
55 {0x70, "DiskSecure Multi-Boot"},
56 {0x75, "PC/IX"},
57 {0x80, "Old Minix"}, /* Minix 1.4a and earlier */
58 {0x81, "Minix / old Linux"},/* Minix 1.4b and later */
59 {0x82, "Linux swap / Solaris"},
60 {0x83, "Linux"},
61 {0x84, "OS/2 hidden C: drive"},
62 {0x85, "Linux extended"},
63 {0x86, "NTFS volume set"},
64 {0x87, "NTFS volume set"},
65 {0x88, "Linux plaintext"},
66 {0x8e, "Linux LVM"},
67 {0x93, "Amoeba"},
68 {0x94, "Amoeba BBT"}, /* (bad block table) */
69 {0x9f, "BSD/OS"}, /* BSDI */
70 {0xa0, "IBM Thinkpad hibernation"},
71 {0xa5, "FreeBSD"}, /* various BSD flavours */
72 {0xa6, "OpenBSD"},
73 {0xa7, "NeXTSTEP"},
74 {0xa8, "Darwin UFS"},
75 {0xa9, "NetBSD"},
76 {0xab, "Darwin boot"},
77 {0xb7, "BSDI fs"},
78 {0xb8, "BSDI swap"},
79 {0xbb, "Boot Wizard hidden"},
80 {0xbe, "Solaris boot"},
81 {0xbf, "Solaris"},
82 {0xc1, "DRDOS/sec (FAT-12)"},
83 {0xc4, "DRDOS/sec (FAT-16 < 32M)"},
84 {0xc6, "DRDOS/sec (FAT-16)"},
85 {0xc7, "Syrinx"},
86 {0xda, "Non-FS data"},
87 {0xdb, "CP/M / CTOS / ..."},/* CP/M or Concurrent CP/M or
88 Concurrent DOS or CTOS */
89 {0xde, "Dell Utility"}, /* Dell PowerEdge Server utilities */
90 {0xdf, "BootIt"}, /* BootIt EMBRM */
91 {0xe1, "DOS access"}, /* DOS access or SpeedStor 12-bit FAT
92 extended partition */
93 {0xe3, "DOS R/O"}, /* DOS R/O or SpeedStor */
94 {0xe4, "SpeedStor"}, /* SpeedStor 16-bit FAT extended
95 partition < 1024 cyl. */
96 {0xeb, "BeOS fs"},
97 {0xee, "EFI GPT"}, /* Intel EFI GUID Partition Table */
98 {0xef, "EFI (FAT-12/16/32)"},/* Intel EFI System Partition */
99 {0xf0, "Linux/PA-RISC boot"},/* Linux/PA-RISC boot loader */
100 {0xf1, "SpeedStor"},
101 {0xf4, "SpeedStor"}, /* SpeedStor large partition */
102 {0xf2, "DOS secondary"}, /* DOS 3.3+ secondary */
103 {0xfd, "Linux raid autodetect"},/* New (2.2.x) raid partition with
104 autodetect using persistent
105 superblock */
106 {0xfe, "LANstep"}, /* SpeedStor >1024 cyl. or LANstep */
107 {0xff, "BBT"}, /* Xenix Bad Block Table */
108 { 0, 0 }
109};
diff --git a/utils/jztool/Makefile b/utils/jztool/Makefile
new file mode 100644
index 0000000000..d1bbae578c
--- /dev/null
+++ b/utils/jztool/Makefile
@@ -0,0 +1,47 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7
8CFLAGS += -Wall -Wextra -Iinclude -I../../tools/ucl/include -I../../lib/microtar/src
9OUTPUT = jztool
10
11ifdef RELEASE
12CFLAGS += -Os -DNDEBUG
13else
14CFLAGS += -O0 -ggdb
15endif
16
17LIBSOURCES := src/buffer.c src/context.c src/device_info.c \
18 src/identify_file.c src/ucl_unpack.c src/usb.c src/x1000.c
19SOURCES := $(LIBSOURCES) jztool.c
20EXTRADEPS := libucl.a libmicrotar.a
21
22CPPDEFINES := $(shell echo foo | $(CROSS)$(CC) -dM -E -)
23
24ifeq ($(findstring WIN32,$(CPPDEFINES)),WIN32)
25# TODO: support Windows
26else
27ifeq ($(findstring APPLE,$(CPPDEFINES)),APPLE)
28# Mac, tested on x86 only -- may need to adjust paths if building on ARM.
29# paths should work with homebrew libusb.
30LIBUSB_CFLAGS ?= -I/usr/local/include/libusb-1.0
31ifdef STATIC
32LIBUSB_LDOPTS ?= /usr/local/lib/libusb-1.0.a -framework IOKit -framework CoreFoundation
33else
34LIBUSB_LDOPTS ?= -L/usr/local/lib -lusb-1.0
35endif
36else
37# Linux; note for static builds you need to build a copy of libusb without
38# udev support and specify the includes / libs manually
39LIBUSB_CFLAGS ?= `pkg-config --cflags libusb-1.0`
40LIBUSB_LDOPTS ?= `pkg-config --libs libusb-1.0`
41endif
42endif
43
44CFLAGS += $(LIBUSB_CFLAGS)
45LDOPTS += $(LIBUSB_LDOPTS)
46
47include ../libtools.make
diff --git a/utils/jztool/README.md b/utils/jztool/README.md
new file mode 100644
index 0000000000..72c630c6c3
--- /dev/null
+++ b/utils/jztool/README.md
@@ -0,0 +1,135 @@
1# jztool -- Ingenic device utility & bootloader installer
2
3The `jztool` utility can help install, backup, and restore the bootloader on
4Rockbox players based on a supported Ingenic SoC (currently only the X1000).
5
6## Running jztool
7
8### Getting a bootloader
9
10To use `jztool` you need to compile or download a bootloader for your player.
11It's recommended to use only official released bootloaders, since bootloaders
12compiled from Git are not tested and might be buggy.
13
14You can download released bootloaders from <https://download.rockbox.org/>.
15
16The bootloader file is named after the target: for example, the FiiO M3K
17bootloader is called `bootloader.m3k`. The FiiO M3K is used as an example
18here, but the instructions apply to all X1000-based players.
19
20Use `jztool --help` to find out the model name of your player.
21
22### Entering USB boot mode
23
24USB boot mode is a low-level mode provided by the CPU which allows a computer
25to load firmware onto the device. You need to put your player into this mode
26manually before using `jztool` (unfortunately, it can't be done automatically.)
27
28To connect the player in USB boot mode, follow these steps:
29
301. Ensure the player is fully powered off.
312. Plug one end of the USB cable into your player.
323. Hold down your player's USB boot key (see below).
334. Plug the other end of the USB cable into your computer.
345. Let go of the USB boot key.
35
36The USB boot key depends on your player:
37
38- FiiO M3K: Volume Down
39- Shanling Q1: Play
40- Eros Q: Menu
41
42### Linux/Mac
43
44Run the following command in a terminal. Note that on Linux, you will need to
45have root access to allow libusb to access the USB device.
46
47```sh
48# Linux / Mac
49# NOTE: root permissions are required on Linux to access the USB device
50# eg. with 'sudo' or 'su -c' depending on your distro.
51$ ./jztool fiiom3k load bootloader.m3k
52```
53
54### Windows
55
56To allow `jztool` access to your player in USB boot mode, you need to install
57the WinUSB driver. The recommended way to install it is using Zadig, which
58may be downloaded from its homepage <https://zadig.akeo.ie>. Please note
59this is 3rd party software not maintained or supported by Rockbox developers.
60(Zadig will require administrator access on the machine you are using.)
61
62When running Zadig you must select the WinUSB driver; the other driver options
63will not work properly with `jztool`. You will have to select the correct USB
64device in Zadig. All X1000-based players use the same USB ID while in USB boot
65mode, listed below. NOTE: the device name may show only as "X" and a hollow
66square in Zadig. The IDs will not change, so those are the most reliable way
67to confirm you have selected the correct device.
68
69```
70Name: Ingenic Semiconductor Co.,Ltd X1000
71USB ID: A108 1000
72```
73
74Assuming you installed the WinUSB driver successfully, open a command prompt
75in the folder containing `jztool`. Administrator access is not required for
76this step.
77
78Type the following command to load the Rockbox bootloader:
79
80```sh
81# Windows
82$ jztool.exe fiiom3k load bootloader.m3k
83```
84
85## Using the recovery menu
86
87If `jztool` runs successfully your player will display the Rockbox bootloader's
88recovery menu. If you want to permanently install Rockbox to your device, copy
89the bootloader file you downloaded to the root of your SD card, insert the SD
90card to your player, and choose "Install/update bootloader" from the menu.
91
92It is _highly_ recommended that you take a backup of your existing bootloader
93in case of any trouble -- choose "Backup bootloader" from the recovery menu.
94The backup file is called `PLAYER-boot.bin`, where `PLAYER` is the model name.
95(Example: `fiiom3k-boot.bin`.)
96
97You can restore the backup later by putting it on the root of your SD card and
98selecting "Restor bootloader" in the recovery menu.
99
100After installing the Rockbox bootloader, you can access the recovery menu by
101holding a key while booting:
102
103- FiiO M3K: Volume Up
104- Shanling Q1: Next (button on the lower left)
105- Eros Q: Volume Up
106
107### Known issues
108
109- When using the bootloader's USB mode, you may get stuck on "Waiting for USB"
110 even though the cable is already plugged in. If this occurs, unplug the USB
111 cable and plug it back in to trigger the connection.
112
113
114## TODO list
115
116### Add better documentation and logging
117
118There's only a bare minimum of documentation, and logging is sparse, not
119really enough to debug problems.
120
121Some of the error messages could be friendlier too.
122
123### Integration with the Rockbox utility
124
125Adding support to the Rockbox utility should be mostly boilerplate since the
126jztool library wraps all the troublesome details.
127
128Permissions are an issue on Linux because by default only root can access
129"raw" USB devices. If we want to package rbutil for distro we can install
130a udev rule to allow access to the specific USB IDs we need, eg. allowing
131users in the "wheel" group to access the device.
132
133On Windows and Mac, no special permissions are needed to access USB devices
134assuming the drivers are set up. (Zadig does require administrator access
135to run, but that's external to the Rockbox utility.)
diff --git a/utils/jztool/include/jztool.h b/utils/jztool/include/jztool.h
new file mode 100644
index 0000000000..9d3c08c5bc
--- /dev/null
+++ b/utils/jztool/include/jztool.h
@@ -0,0 +1,202 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef JZTOOL_H
23#define JZTOOL_H
24
25#include <stdint.h>
26#include <stddef.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32/******************************************************************************
33 * Types, enumerations, etc
34 */
35
36#define JZ_CPUINFO_BUFLEN 9
37
38typedef struct jz_context jz_context;
39typedef struct jz_usbdev jz_usbdev;
40typedef struct jz_device_info jz_device_info;
41typedef struct jz_cpu_info jz_cpu_info;
42typedef struct jz_buffer jz_buffer;
43
44typedef enum jz_error jz_error;
45typedef enum jz_identify_error jz_identify_error;
46typedef enum jz_log_level jz_log_level;
47typedef enum jz_device_type jz_device_type;
48typedef enum jz_cpu_type jz_cpu_type;
49
50typedef void(*jz_log_cb)(jz_log_level, const char*);
51
52enum jz_error {
53 JZ_SUCCESS = 0,
54 JZ_ERR_OUT_OF_MEMORY = -1,
55 JZ_ERR_OPEN_FILE = -2,
56 JZ_ERR_FILE_IO = -3,
57 JZ_ERR_USB = -4,
58 JZ_ERR_NO_DEVICE = -5,
59 JZ_ERR_BAD_FILE_FORMAT = -6,
60 JZ_ERR_FLASH_ERROR = -7,
61 JZ_ERR_OTHER = -99,
62};
63
64enum jz_identify_error {
65 JZ_IDERR_OTHER = -1,
66 JZ_IDERR_WRONG_SIZE = -2,
67 JZ_IDERR_BAD_HEADER = -3,
68 JZ_IDERR_BAD_CHECKSUM = -4,
69 JZ_IDERR_UNRECOGNIZED_MODEL = -5,
70};
71
72enum jz_log_level {
73 JZ_LOG_IGNORE = -1,
74 JZ_LOG_ERROR = 0,
75 JZ_LOG_WARNING = 1,
76 JZ_LOG_NOTICE = 2,
77 JZ_LOG_DETAIL = 3,
78 JZ_LOG_DEBUG = 4,
79};
80
81enum jz_device_type {
82 JZ_DEVICE_FIIOM3K,
83 JZ_DEVICE_SHANLINGQ1,
84 JZ_DEVICE_EROSQ,
85 JZ_NUM_DEVICES,
86};
87
88enum jz_cpu_type {
89 JZ_CPU_X1000,
90 JZ_NUM_CPUS,
91};
92
93struct jz_device_info {
94 /* internal device name and file extension */
95 const char* name;
96 const char* file_ext;
97
98 /* human-readable name */
99 const char* description;
100
101 /* device and CPU type */
102 jz_device_type device_type;
103 jz_cpu_type cpu_type;
104
105 /* USB IDs of the device in mass storage mode */
106 uint16_t vendor_id;
107 uint16_t product_id;
108};
109
110struct jz_cpu_info {
111 /* CPU info string, as reported by the boot ROM */
112 const char* info_str;
113
114 /* USB IDs of the boot ROM */
115 uint16_t vendor_id;
116 uint16_t product_id;
117
118 /* default addresses for running binaries */
119 uint32_t stage1_load_addr;
120 uint32_t stage1_exec_addr;
121 uint32_t stage2_load_addr;
122 uint32_t stage2_exec_addr;
123};
124
125struct jz_buffer {
126 size_t size;
127 uint8_t* data;
128};
129
130/******************************************************************************
131 * Library context and general functions
132 */
133
134jz_context* jz_context_create(void);
135void jz_context_destroy(jz_context* jz);
136
137void jz_context_set_user_data(jz_context* jz, void* ptr);
138void* jz_context_get_user_data(jz_context* jz);
139
140void jz_context_set_log_cb(jz_context* jz, jz_log_cb cb);
141void jz_context_set_log_level(jz_context* jz, jz_log_level lev);
142
143void jz_log(jz_context* jz, jz_log_level lev, const char* fmt, ...);
144void jz_log_cb_stderr(jz_log_level lev, const char* msg);
145
146void jz_sleepms(int ms);
147
148/******************************************************************************
149 * Device and file info
150 */
151
152const jz_device_info* jz_get_device_info(jz_device_type type);
153const jz_device_info* jz_get_device_info_named(const char* name);
154const jz_device_info* jz_get_device_info_indexed(int index);
155
156const jz_cpu_info* jz_get_cpu_info(jz_cpu_type type);
157const jz_cpu_info* jz_get_cpu_info_named(const char* info_str);
158
159int jz_identify_x1000_spl(const void* data, size_t len);
160int jz_identify_scramble_image(const void* data, size_t len);
161
162/******************************************************************************
163 * USB boot ROM protocol
164 */
165
166int jz_usb_open(jz_context* jz, jz_usbdev** devptr, uint16_t vend_id, uint16_t prod_id);
167void jz_usb_close(jz_usbdev* dev);
168
169int jz_usb_send(jz_usbdev* dev, uint32_t addr, size_t len, const void* data);
170int jz_usb_recv(jz_usbdev* dev, uint32_t addr, size_t len, void* data);
171int jz_usb_start1(jz_usbdev* dev, uint32_t addr);
172int jz_usb_start2(jz_usbdev* dev, uint32_t addr);
173int jz_usb_flush_caches(jz_usbdev* dev);
174int jz_usb_get_cpu_info(jz_usbdev* dev, char* buffer, size_t buflen);
175
176/******************************************************************************
177 * Rockbox loader (all functions are model-specific, see docs)
178 */
179
180int jz_x1000_boot(jz_usbdev* dev, jz_device_type type, const char* filename);
181
182/******************************************************************************
183 * Buffer API and other functions
184 */
185
186jz_buffer* jz_buffer_alloc(size_t size, const void* data);
187void jz_buffer_free(jz_buffer* buf);
188
189int jz_buffer_load(jz_buffer** buf, const char* filename);
190int jz_buffer_save(jz_buffer* buf, const char* filename);
191
192jz_buffer* jz_ucl_unpack(const uint8_t* src, uint32_t src_len, uint32_t* dst_len);
193
194/******************************************************************************
195 * END
196 */
197
198#ifdef __cplusplus
199}
200#endif
201
202#endif /* JZTOOL_H */
diff --git a/utils/jztool/jztool.c b/utils/jztool/jztool.c
new file mode 100644
index 0000000000..dcd78137b3
--- /dev/null
+++ b/utils/jztool/jztool.c
@@ -0,0 +1,212 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "jztool.h"
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <stdbool.h>
27
28jz_context* jz = NULL;
29jz_usbdev* usbdev = NULL;
30const jz_device_info* dev_info = NULL;
31const jz_cpu_info* cpu_info = NULL;
32
33void usage_x1000(void)
34{
35 printf(
36"Usage:\n"
37" jztool fiiom3k load <bootloader.m3k>\n"
38" jztool shanlingq1 load <bootloader.q1>\n"
39" jztool erosq load <bootloader.erosq>\n"
40"\n"
41"The 'load' command is used to boot the Rockbox bootloader in recovery\n"
42"mode, which allows you to install the Rockbox bootloader and backup or\n"
43"restore bootloader images. You need to connect your player in USB boot\n"
44"mode in order to use this tool.\n"
45"\n"
46"To connect the player in USB boot mode, follow these steps:\n"
47"\n"
48"1. Ensure the player is fully powered off.\n"
49"2. Plug one end of the USB cable into your player.\n"
50"3. Hold down your player's USB boot key (see below).\n"
51"4. Plug the other end of the USB cable into your computer.\n"
52"5. Let go of the USB boot key.\n"
53"\n"
54"USB boot keys:\n"
55"\n"
56" FiiO M3K - Volume Down\n"
57" Shanling Q1 - Play\n"
58" Eros Q - Menu\n"
59"\n"
60"Not all players give a visible indication that they are in USB boot mode.\n"
61"If you're having trouble connecting your player, try resetting it by\n"
62"holding the power button for 10 seconds, and try the above steps again.\n"
63"\n"
64"Note for Windows users: you need to install the WinUSB driver using a\n"
65"3rd-party tool such as Zadig <https://zadig.akeo.ie> before this tool\n"
66"can access your player in USB boot mode. You need to run Zadig while the\n"
67"player is plugged in and in USB boot mode. For more details check the\n"
68"jztool README.md file or visit <https://rockbox.org/wiki/IngenicX1000>.\n"
69"\n");
70
71 exit(4);
72}
73
74int cmdline_x1000(int argc, char** argv)
75{
76 if(argc < 2 || strcmp(argv[0], "load")) {
77 usage_x1000();
78 return 2;
79 }
80
81 int rc = jz_usb_open(jz, &usbdev, cpu_info->vendor_id, cpu_info->product_id);
82 if(rc < 0) {
83 jz_log(jz, JZ_LOG_ERROR, "Cannot open USB device: %d", rc);
84 return 1;
85 }
86
87 rc = jz_x1000_boot(usbdev, dev_info->device_type, argv[1]);
88 if(rc < 0) {
89 jz_log(jz, JZ_LOG_ERROR, "Boot failed: %d", rc);
90 return 1;
91 }
92
93 return 0;
94}
95
96void usage(void)
97{
98 printf("Usage:\n"
99 " jztool [global options] <device> <command> [command arguments]\n"
100 "\n"
101 "Global options:\n"
102 " -h, --help Display this help\n"
103 " -q, --quiet Don't log anything except errors\n"
104 " -v, --verbose Display detailed logging output\n\n");
105
106 printf("Supported devices:\n\n");
107 for(int i = 0; i < JZ_NUM_DEVICES; ++i) {
108 const jz_device_info* info = jz_get_device_info_indexed(i);
109 printf(" %s - %s\n", info->name, info->description);
110 }
111
112 printf("\n"
113 "For device-specific help run 'jztool DEVICE' without arguments,\n"
114 "eg. 'jztool fiiom3k' will display help for the FiiO M3K.\n");
115
116 exit(4);
117}
118
119void cleanup(void)
120{
121 if(usbdev)
122 jz_usb_close(usbdev);
123 if(jz)
124 jz_context_destroy(jz);
125}
126
127int main(int argc, char** argv)
128{
129 if(argc < 2)
130 usage();
131
132 /* Library initialization */
133 jz = jz_context_create();
134 if(!jz) {
135 fprintf(stderr, "ERROR: Can't create context");
136 return 1;
137 }
138
139 atexit(cleanup);
140 jz_context_set_log_cb(jz, jz_log_cb_stderr);
141 jz_context_set_log_level(jz, JZ_LOG_NOTICE);
142
143 /* Parse global options */
144 --argc, ++argv;
145 while(argc > 0 && argv[0][0] == '-') {
146 if(!strcmp(*argv, "-h") || !strcmp(*argv, "--help"))
147 usage();
148 else if(!strcmp(*argv, "-q") || !strcmp(*argv, "--quiet"))
149 jz_context_set_log_level(jz, JZ_LOG_ERROR);
150 else if(!strcmp(*argv, "-v") || !strcmp(*argv, "--verbose"))
151 jz_context_set_log_level(jz, JZ_LOG_DETAIL);
152 else if(!strcmp(*argv, "-l") || !strcmp(*argv, "--loglevel")) {
153 ++argv;
154 if(--argc == 0) {
155 jz_log(jz, JZ_LOG_ERROR, "Missing argument to option %s", *argv);
156 exit(2);
157 }
158
159 enum jz_log_level level;
160 if(!strcmp(*argv, "ignore"))
161 level = JZ_LOG_IGNORE;
162 else if(!strcmp(*argv, "error"))
163 level = JZ_LOG_ERROR;
164 else if(!strcmp(*argv, "warning"))
165 level = JZ_LOG_WARNING;
166 else if(!strcmp(*argv, "notice"))
167 level = JZ_LOG_NOTICE;
168 else if(!strcmp(*argv, "detail"))
169 level = JZ_LOG_DETAIL;
170 else if(!strcmp(*argv, "debug"))
171 level = JZ_LOG_DEBUG;
172 else {
173 jz_log(jz, JZ_LOG_ERROR, "Invalid log level '%s'", *argv);
174 exit(2);
175 }
176
177 jz_context_set_log_level(jz, level);
178 } else {
179 jz_log(jz, JZ_LOG_ERROR, "Invalid global option '%s'", *argv);
180 exit(2);
181 }
182
183 --argc, ++argv;
184 }
185
186 /* Read the device type */
187 if(argc == 0) {
188 jz_log(jz, JZ_LOG_ERROR, "No device specified (try jztool --help)");
189 exit(2);
190 }
191
192 dev_info = jz_get_device_info_named(*argv);
193 if(!dev_info) {
194 jz_log(jz, JZ_LOG_ERROR, "Unknown device '%s' (try jztool --help)", *argv);
195 exit(2);
196 }
197
198 cpu_info = jz_get_cpu_info(dev_info->cpu_type);
199
200 /* Dispatch to device handler */
201 --argc, ++argv;
202 switch(dev_info->device_type) {
203 case JZ_DEVICE_FIIOM3K:
204 case JZ_DEVICE_SHANLINGQ1:
205 case JZ_DEVICE_EROSQ:
206 return cmdline_x1000(argc, argv);
207
208 default:
209 jz_log(jz, JZ_LOG_ERROR, "INTERNAL ERROR: unhandled device type");
210 return 1;
211 }
212}
diff --git a/utils/jztool/src/buffer.c b/utils/jztool/src/buffer.c
new file mode 100644
index 0000000000..9e9c9ff5d1
--- /dev/null
+++ b/utils/jztool/src/buffer.c
@@ -0,0 +1,134 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "jztool.h"
23#include <stdlib.h>
24#include <string.h>
25#include <stdio.h>
26
27/** \brief Allocate a buffer, optionally providing its contents.
28 * \param size Number of bytes to allocate
29 * \param data Initial contents of the buffer, must be at least `size` bytes
30 * \return Pointer to buffer or NULL if out of memory.
31 * \note The buffer will not take ownership of the `data` pointer, instead it
32 * allocates a fresh buffer and copies the contents of `data` into it.
33 */
34jz_buffer* jz_buffer_alloc(size_t size, const void* data)
35{
36 jz_buffer* buf = malloc(sizeof(struct jz_buffer));
37 if(!buf)
38 return NULL;
39
40 buf->data = malloc(size);
41 if(!buf->data) {
42 free(buf);
43 return NULL;
44 }
45
46 if(data)
47 memcpy(buf->data, data, size);
48
49 buf->size = size;
50 return buf;
51}
52
53/** \brief Free a buffer
54 */
55void jz_buffer_free(jz_buffer* buf)
56{
57 if(buf) {
58 free(buf->data);
59 free(buf);
60 }
61}
62
63/** \brief Load a buffer from a file
64 * \param buf Returns loaded buffer on success, unmodified on error
65 * \param filename Path to the file
66 * \return either JZ_SUCCESS, or one of the following errors
67 * \retval JZ_ERR_OPEN_FILE file cannot be opened
68 * \retval JZ_ERR_OUT_OF_MEMORY cannot allocate buffer to hold file contents
69 * \retval JZ_ERR_FILE_IO problem reading file data
70 */
71int jz_buffer_load(jz_buffer** buf, const char* filename)
72{
73 FILE* f;
74 jz_buffer* b;
75 int rc;
76
77 f = fopen(filename, "rb");
78 if(!f)
79 return JZ_ERR_OPEN_FILE;
80
81 fseek(f, 0, SEEK_END);
82 int size = ftell(f);
83 fseek(f, 0, SEEK_SET);
84
85 b = jz_buffer_alloc(size, NULL);
86 if(!b) {
87 rc = JZ_ERR_OUT_OF_MEMORY;
88 goto err_fclose;
89 }
90
91 if(fread(b->data, size, 1, f) != 1) {
92 rc = JZ_ERR_FILE_IO;
93 goto err_free_buf;
94 }
95
96 rc = JZ_SUCCESS;
97 *buf = b;
98
99 err_fclose:
100 fclose(f);
101 return rc;
102
103 err_free_buf:
104 jz_buffer_free(b);
105 goto err_fclose;
106}
107
108/** \brief Save a buffer to a file
109 * \param buf Buffer to be written out
110 * \param filename Path to the file
111 * \return either JZ_SUCCESS, or one of the following errors
112 * \retval JZ_ERR_OPEN_FILE file cannot be opened
113 * \retval JZ_ERR_FILE_IO problem writing file data
114 */
115int jz_buffer_save(jz_buffer* buf, const char* filename)
116{
117 int rc;
118 FILE* f;
119
120 f = fopen(filename, "wb");
121 if(!f)
122 return JZ_ERR_OPEN_FILE;
123
124 if(fwrite(buf->data, buf->size, 1, f) != 1) {
125 rc = JZ_ERR_FILE_IO;
126 goto err_fclose;
127 }
128
129 rc = JZ_SUCCESS;
130
131 err_fclose:
132 fclose(f);
133 return rc;
134}
diff --git a/utils/jztool/src/context.c b/utils/jztool/src/context.c
new file mode 100644
index 0000000000..d269d1eece
--- /dev/null
+++ b/utils/jztool/src/context.c
@@ -0,0 +1,177 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "jztool_private.h"
23#include <string.h>
24#include <stdlib.h>
25#include <stddef.h>
26#include <stdarg.h>
27#include <stdio.h>
28#include <time.h>
29
30#ifdef WIN32
31# include <windows.h>
32#endif
33
34/** \brief Allocate a library context
35 * \returns New context or NULL if out of memory
36 */
37jz_context* jz_context_create(void)
38{
39 jz_context* jz = malloc(sizeof(struct jz_context));
40 if(!jz)
41 return NULL;
42
43 memset(jz, 0, sizeof(struct jz_context));
44 jz->log_level = JZ_LOG_ERROR;
45 return jz;
46}
47
48/** \brief Destroy the context and free its memory */
49void jz_context_destroy(jz_context* jz)
50{
51 if(jz->usb_ctx) {
52 jz_log(jz, JZ_LOG_ERROR, "BUG: USB was not cleaned up properly");
53 libusb_exit(jz->usb_ctx);
54 }
55
56 free(jz);
57}
58
59/** \brief Set a user data pointer. Useful for callbacks. */
60void jz_context_set_user_data(jz_context* jz, void* ptr)
61{
62 jz->user_data = ptr;
63}
64
65/** \brief Get the user data pointer */
66void* jz_context_get_user_data(jz_context* jz)
67{
68 return jz->user_data;
69}
70
71/** \brief Set the log message callback.
72 * \note By default, no message callback is set! No messages will be logged
73 * in this case, so ensure you set a callback if messages are desired.
74 */
75void jz_context_set_log_cb(jz_context* jz, jz_log_cb cb)
76{
77 jz->log_cb = cb;
78}
79
80/** \brief Set the log level.
81 *
82 * Messages of less importance than the set log level are not logged.
83 * The default log level is `JZ_LOG_WARNING`. The special log level
84 * `JZ_LOG_IGNORE` can be used to disable all logging temporarily.
85 *
86 * The `JZ_LOG_DEBUG` log level is extremely verbose and will log all calls,
87 * normally it's only useful for catching bugs.
88 */
89void jz_context_set_log_level(jz_context* jz, jz_log_level lev)
90{
91 jz->log_level = lev;
92}
93
94/** \brief Log an informational message.
95 * \param lev Log level for this message
96 * \param fmt `printf` style message format string
97 */
98void jz_log(jz_context* jz, jz_log_level lev, const char* fmt, ...)
99{
100 if(!jz->log_cb)
101 return;
102 if(lev == JZ_LOG_IGNORE)
103 return;
104 if(lev > jz->log_level)
105 return;
106
107 va_list ap;
108
109 va_start(ap, fmt);
110 int n = vsnprintf(NULL, 0, fmt, ap);
111 va_end(ap);
112
113 if(n < 0)
114 return;
115
116 char* buf = malloc(n + 1);
117 if(!buf)
118 return;
119
120 va_start(ap, fmt);
121 n = vsnprintf(buf, n + 1, fmt, ap);
122 va_end(ap);
123
124 if(n >= 0)
125 jz->log_cb(lev, buf);
126
127 free(buf);
128}
129
130/** \brief Log callback which writes messages to `stderr`.
131 */
132void jz_log_cb_stderr(jz_log_level lev, const char* msg)
133{
134 static const char* const tags[] =
135 {"ERROR", "WARNING", "NOTICE", "DETAIL", "DEBUG"};
136 fprintf(stderr, "[%7s] %s\n", tags[lev], msg);
137 fflush(stderr);
138}
139
140/** \brief Sleep for `ms` milliseconds.
141 */
142void jz_sleepms(int ms)
143{
144#ifdef WIN32
145 Sleep(ms);
146#else
147 struct timespec ts;
148 long ns = ms % 1000;
149 ts.tv_nsec = ns * 1000 * 1000;
150 ts.tv_sec = ms / 1000;
151 nanosleep(&ts, NULL);
152#endif
153}
154
155/** \brief Add reference to libusb context, allocating it if necessary */
156int jz_context_ref_libusb(jz_context* jz)
157{
158 if(jz->usb_ctxref == 0) {
159 int rc = libusb_init(&jz->usb_ctx);
160 if(rc < 0) {
161 jz_log(jz, JZ_LOG_ERROR, "libusb_init: %s", libusb_strerror(rc));
162 return JZ_ERR_USB;
163 }
164 }
165
166 jz->usb_ctxref += 1;
167 return JZ_SUCCESS;
168}
169
170/** \brief Remove reference to libusb context, freeing if it hits zero */
171void jz_context_unref_libusb(jz_context* jz)
172{
173 if(--jz->usb_ctxref == 0) {
174 libusb_exit(jz->usb_ctx);
175 jz->usb_ctx = NULL;
176 }
177}
diff --git a/utils/jztool/src/device_info.c b/utils/jztool/src/device_info.c
new file mode 100644
index 0000000000..cc431959ca
--- /dev/null
+++ b/utils/jztool/src/device_info.c
@@ -0,0 +1,109 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "jztool.h"
23#include <string.h>
24
25static const jz_device_info infotable[JZ_NUM_DEVICES] = {
26 [JZ_DEVICE_FIIOM3K] = {
27 .name = "fiiom3k",
28 .file_ext = "m3k",
29 .description = "FiiO M3K",
30 .device_type = JZ_DEVICE_FIIOM3K,
31 .cpu_type = JZ_CPU_X1000,
32 .vendor_id = 0x2972,
33 .product_id = 0x0003,
34 },
35 [JZ_DEVICE_SHANLINGQ1] = {
36 .name = "shanlingq1",
37 .file_ext = "q1",
38 .description = "Shanling Q1",
39 .device_type = JZ_DEVICE_SHANLINGQ1,
40 .cpu_type = JZ_CPU_X1000,
41 .vendor_id = 0x0525,
42 .product_id = 0xa4a5,
43 },
44 [JZ_DEVICE_EROSQ] = {
45 .name = "erosq",
46 .file_ext = "erosq",
47 .description = "AIGO Eros Q",
48 .device_type = JZ_DEVICE_EROSQ,
49 .cpu_type = JZ_CPU_X1000,
50 .vendor_id = 0xc502,
51 .product_id = 0x0023,
52 },
53};
54
55static const jz_cpu_info cputable[JZ_NUM_CPUS] = {
56 [JZ_CPU_X1000] = {
57 .info_str = "X1000_v1",
58 .vendor_id = 0xa108,
59 .product_id = 0x1000,
60 .stage1_load_addr = 0xf4001000,
61 .stage1_exec_addr = 0xf4001800,
62 .stage2_load_addr = 0x80004000,
63 .stage2_exec_addr = 0x80004000,
64 },
65};
66
67/** \brief Lookup info for a device by type, returns NULL if not found. */
68const jz_device_info* jz_get_device_info(jz_device_type type)
69{
70 return jz_get_device_info_indexed(type);
71}
72
73/** \brief Lookup info for a device by name, returns NULL if not found. */
74const jz_device_info* jz_get_device_info_named(const char* name)
75{
76 for(int i = 0; i < JZ_NUM_DEVICES; ++i)
77 if(!strcmp(infotable[i].name, name))
78 return &infotable[i];
79
80 return NULL;
81}
82
83/** \brief Get a device info entry by index, returns NULL if out of range. */
84const jz_device_info* jz_get_device_info_indexed(int index)
85{
86 if(index < JZ_NUM_DEVICES)
87 return &infotable[index];
88 else
89 return NULL;
90}
91
92/** \brief Lookup info for a CPU, returns NULL if not found. */
93const jz_cpu_info* jz_get_cpu_info(jz_cpu_type type)
94{
95 if(type < JZ_NUM_CPUS)
96 return &cputable[type];
97 else
98 return NULL;
99}
100
101/** \brief Lookup info for a CPU by info string, returns NULL if not found. */
102const jz_cpu_info* jz_get_cpu_info_named(const char* info_str)
103{
104 for(int i = 0; i < JZ_NUM_CPUS; ++i)
105 if(!strcmp(cputable[i].info_str, info_str))
106 return &cputable[i];
107
108 return NULL;
109}
diff --git a/utils/jztool/src/identify_file.c b/utils/jztool/src/identify_file.c
new file mode 100644
index 0000000000..e475d98a3b
--- /dev/null
+++ b/utils/jztool/src/identify_file.c
@@ -0,0 +1,170 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "jztool.h"
23#include <string.h>
24
25/* Following is copied from mkspl-x1000, basically */
26struct x1000_spl_header {
27 uint8_t magic[8];
28 uint8_t type;
29 uint8_t crc7;
30 uint8_t ppb;
31 uint8_t bpp;
32 uint32_t length;
33};
34
35static const uint8_t x1000_spl_header_magic[8] =
36 {0x06, 0x05, 0x04, 0x03, 0x02, 0x55, 0xaa, 0x55};
37
38static const size_t X1000_SPL_HEADER_SIZE = 2 * 1024;
39
40static uint8_t crc7(const uint8_t* buf, size_t len)
41{
42 /* table-based computation of CRC7 */
43 static const uint8_t t[256] = {
44 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
45 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
46 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26,
47 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
48 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d,
49 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
50 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14,
51 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
52 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b,
53 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
54 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42,
55 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
56 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69,
57 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
58 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70,
59 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
60 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e,
61 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
62 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67,
63 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
64 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
65 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
66 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55,
67 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
68 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a,
69 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
70 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03,
71 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
72 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28,
73 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
74 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31,
75 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79
76 };
77
78 uint8_t crc = 0;
79 while(len--)
80 crc = t[(crc << 1) ^ *buf++];
81 return crc;
82}
83
84/** \brief Identify a file as an SPL for X1000 CPUs
85 * \param data File data buffer
86 * \param len Length of file
87 * \return JZ_SUCCESS if file looks correct, or one of the following errors
88 * \retval JZ_IDERR_WRONG_SIZE file too small or size doesn't match header
89 * \retval JZ_IDERR_BAD_HEADER missing magic bytes from header
90 * \retval JZ_IDERR_BAD_CHECKSUM CRC7 mismatch
91 */
92int jz_identify_x1000_spl(const void* data, size_t len)
93{
94 /* Use <= check because a header-only file is not really valid,
95 * it should have at least one byte in it... */
96 if(len <= X1000_SPL_HEADER_SIZE)
97 return JZ_IDERR_WRONG_SIZE;
98
99 /* Look for header magic bytes */
100 const struct x1000_spl_header* header = (const struct x1000_spl_header*)data;
101 if(memcmp(header->magic, x1000_spl_header_magic, 8))
102 return JZ_IDERR_BAD_HEADER;
103
104 /* Length stored in the header should equal the length of the file */
105 if(header->length != len)
106 return JZ_IDERR_WRONG_SIZE;
107
108 /* Compute the CRC7 checksum; it only covers the SPL code */
109 const uint8_t* dat = (const uint8_t*)data;
110 uint8_t sum = crc7(&dat[X1000_SPL_HEADER_SIZE], len - X1000_SPL_HEADER_SIZE);
111 if(header->crc7 != sum)
112 return JZ_IDERR_BAD_CHECKSUM;
113
114 return JZ_SUCCESS;
115
116}
117
118static const struct scramble_model_info {
119 const char* name;
120 int model_num;
121 size_t offset_crc;
122 size_t offset_name;
123 size_t offset_data;
124} scramble_models[] = {
125 {"fiio", 114, 0, 4, 8},
126 {"shq1", 115, 0, 4, 8},
127 {"eros", 116, 0, 4, 8},
128 {NULL, 0, 0, 0, 0},
129};
130
131/** \brief Identify a file as a Rockbox `scramble` image
132 * \param data File data buffer
133 * \param len Length of file
134 * \return JZ_SUCCESS if file looks correct, or one of the following errors
135 * \retval JZ_IDERR_UNRECOGNIZED_MODEL unsupported/unknown model type
136 * \retval JZ_IDERR_BAD_CHECKSUM checksum mismatch
137 */
138int jz_identify_scramble_image(const void* data, size_t len)
139{
140 const uint8_t* dat;
141 const struct scramble_model_info* model_info;
142 uint32_t sum, file_sum;
143
144 dat = (const uint8_t*)data;
145 model_info = &scramble_models[0];
146
147 /* Look up the model number */
148 for(; model_info->name != NULL; ++model_info) {
149 if(model_info->offset_name + 4 > len)
150 continue;
151 if(!memcmp(&dat[model_info->offset_name], model_info->name, 4))
152 break;
153 }
154
155 if(model_info->name == NULL)
156 return JZ_IDERR_UNRECOGNIZED_MODEL;
157
158 /* Compute the checksum */
159 sum = model_info->model_num;
160 for(size_t i = model_info->offset_data; i < len; ++i)
161 sum += dat[i];
162
163 /* Compare with file's checksum, it's stored in big-endian form */
164 dat += model_info->offset_crc;
165 file_sum = (dat[0] << 24) | (dat[1] << 16) | (dat[2] << 8) | dat[3];
166 if(sum != file_sum)
167 return JZ_IDERR_BAD_CHECKSUM;
168
169 return JZ_SUCCESS;
170}
diff --git a/utils/jztool/src/jztool_private.h b/utils/jztool/src/jztool_private.h
new file mode 100644
index 0000000000..11299f21f9
--- /dev/null
+++ b/utils/jztool/src/jztool_private.h
@@ -0,0 +1,44 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef JZTOOL_PRIVATE_H
23#define JZTOOL_PRIVATE_H
24
25#include "jztool.h"
26#include <libusb.h>
27
28struct jz_context {
29 void* user_data;
30 jz_log_cb log_cb;
31 jz_log_level log_level;
32 libusb_context* usb_ctx;
33 int usb_ctxref;
34};
35
36struct jz_usbdev {
37 jz_context* jz;
38 libusb_device_handle* handle;
39};
40
41int jz_context_ref_libusb(jz_context* jz);
42void jz_context_unref_libusb(jz_context* jz);
43
44#endif /* JZTOOL_PRIVATE_H */
diff --git a/utils/jztool/src/ucl_unpack.c b/utils/jztool/src/ucl_unpack.c
new file mode 100644
index 0000000000..3b199c7008
--- /dev/null
+++ b/utils/jztool/src/ucl_unpack.c
@@ -0,0 +1,128 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "jztool.h"
23#include "ucl/ucl.h"
24
25static uint32_t xread32(const uint8_t* d)
26{
27 uint32_t r = 0;
28 r |= d[0] << 24;
29 r |= d[1] << 16;
30 r |= d[2] << 8;
31 r |= d[3] << 0;
32 return r;
33}
34
35/* adapted from firmware/common/ucl_decompress.c */
36jz_buffer* jz_ucl_unpack(const uint8_t* src, uint32_t src_len, uint32_t* dst_len)
37{
38 static const uint8_t magic[8] =
39 {0x00, 0xe9, 0x55, 0x43, 0x4c, 0xff, 0x01, 0x1a};
40
41 jz_buffer* buffer = NULL;
42
43 /* make sure there are enough bytes for the header */
44 if(src_len < 18)
45 goto error;
46
47 /* avoid memcmp for reasons of code size */
48 for(size_t i = 0; i < sizeof(magic); ++i)
49 if(src[i] != magic[i])
50 goto error;
51
52 /* read the other header fields */
53 /* uint32_t flags = xread32(&src[8]); */
54 uint8_t method = src[12];
55 /* uint8_t level = src[13]; */
56 uint32_t block_size = xread32(&src[14]);
57
58 /* check supported compression method */
59 if(method != 0x2e)
60 goto error;
61
62 /* validate */
63 if(block_size < 1024 || block_size > 8*1024*1024)
64 goto error;
65
66 src += 18;
67 src_len -= 18;
68
69 /* Calculate amount of space that we might need & allocate a buffer:
70 * - subtract 4 to account for end of file marker
71 * - each block is block_size bytes + 8 bytes of header
72 * - add one to nr_blocks to account for case where file size < block size
73 * - total size = max uncompressed size of block * nr_blocks
74 */
75 uint32_t nr_blocks = (src_len - 4) / (8 + block_size) + 1;
76 uint32_t max_size = nr_blocks * (block_size + block_size/8 + 256);
77 buffer = jz_buffer_alloc(max_size, NULL);
78 if(!buffer)
79 goto error;
80
81 /* perform the decompression */
82 uint32_t dst_ilen = buffer->size;
83 uint8_t* dst = buffer->data;
84 while(1) {
85 if(src_len < 4)
86 goto error;
87
88 uint32_t out_len = xread32(src); src += 4, src_len -= 4;
89 if(out_len == 0)
90 break;
91
92 if(src_len < 4)
93 goto error;
94
95 uint32_t in_len = xread32(src); src += 4, src_len -= 4;
96 if(in_len > block_size || out_len > block_size ||
97 in_len == 0 || in_len > out_len)
98 goto error;
99
100 if(src_len < in_len)
101 goto error;
102
103 if(in_len < out_len) {
104 uint32_t actual_out_len = dst_ilen;
105 int rc = ucl_nrv2e_decompress_safe_8(src, in_len, dst, &actual_out_len, NULL);
106 if(rc != UCL_E_OK)
107 goto error;
108 if(actual_out_len != out_len)
109 goto error;
110 } else {
111 for(size_t i = 0; i < in_len; ++i)
112 dst[i] = src[i];
113 }
114
115 src += in_len;
116 src_len -= in_len;
117 dst += out_len;
118 dst_ilen -= out_len;
119 }
120
121 /* subtract leftover number of bytes to get size of compressed output */
122 *dst_len = buffer->size - dst_ilen;
123 return buffer;
124
125 error:
126 jz_buffer_free(buffer);
127 return NULL;
128}
diff --git a/utils/jztool/src/usb.c b/utils/jztool/src/usb.c
new file mode 100644
index 0000000000..cfc3ba60cb
--- /dev/null
+++ b/utils/jztool/src/usb.c
@@ -0,0 +1,291 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "jztool_private.h"
23#include <stdlib.h>
24#include <stdbool.h>
25#include <string.h>
26
27#define VR_GET_CPU_INFO 0
28#define VR_SET_DATA_ADDRESS 1
29#define VR_SET_DATA_LENGTH 2
30#define VR_FLUSH_CACHES 3
31#define VR_PROGRAM_START1 4
32#define VR_PROGRAM_START2 5
33
34/** \brief Open a USB device
35 * \param jz Context
36 * \param devptr Returns pointer to the USB device upon success
37 * \param vend_id USB vendor ID
38 * \param prod_id USB product ID
39 * \return either JZ_SUCCESS if device was opened, or an error below
40 * \retval JZ_ERR_OUT_OF_MEMORY malloc failed
41 * \retval JZ_ERR_USB libusb error (details are logged)
42 * \retval JZ_ERR_NO_DEVICE can't unambiguously find the device
43 */
44int jz_usb_open(jz_context* jz, jz_usbdev** devptr, uint16_t vend_id, uint16_t prod_id)
45{
46 int rc;
47 jz_usbdev* dev = NULL;
48 libusb_device_handle* usb_handle = NULL;
49 libusb_device** dev_list = NULL;
50 ssize_t dev_index = -1, dev_count;
51
52 rc = jz_context_ref_libusb(jz);
53 if(rc < 0)
54 return rc;
55
56 dev = malloc(sizeof(struct jz_usbdev));
57 if(!dev) {
58 rc = JZ_ERR_OUT_OF_MEMORY;
59 goto error;
60 }
61
62 dev_count = libusb_get_device_list(jz->usb_ctx, &dev_list);
63 if(dev_count < 0) {
64 jz_log(jz, JZ_LOG_ERROR, "libusb_get_device_list: %s", libusb_strerror(dev_count));
65 rc = JZ_ERR_USB;
66 goto error;
67 }
68
69 for(ssize_t i = 0; i < dev_count; ++i) {
70 struct libusb_device_descriptor desc;
71 rc = libusb_get_device_descriptor(dev_list[i], &desc);
72 if(rc < 0) {
73 jz_log(jz, JZ_LOG_WARNING, "libusb_get_device_descriptor: %s",
74 libusb_strerror(rc));
75 continue;
76 }
77
78 if(desc.idVendor != vend_id || desc.idProduct != prod_id)
79 continue;
80
81 if(dev_index >= 0) {
82 /* not the best, but it is the safest thing */
83 jz_log(jz, JZ_LOG_ERROR, "Multiple devices match ID %04x:%04x",
84 (unsigned int)vend_id, (unsigned int)prod_id);
85 jz_log(jz, JZ_LOG_ERROR, "Please ensure only one player is plugged in, and try again");
86 rc = JZ_ERR_NO_DEVICE;
87 goto error;
88 }
89
90 dev_index = i;
91 }
92
93 if(dev_index < 0) {
94 jz_log(jz, JZ_LOG_ERROR, "No device with ID %04x:%04x found",
95 (unsigned int)vend_id, (unsigned int)prod_id);
96 rc = JZ_ERR_NO_DEVICE;
97 goto error;
98 }
99
100 rc = libusb_open(dev_list[dev_index], &usb_handle);
101 if(rc < 0) {
102 jz_log(jz, JZ_LOG_ERROR, "libusb_open: %s", libusb_strerror(rc));
103 rc = JZ_ERR_USB;
104 goto error;
105 }
106
107 rc = libusb_claim_interface(usb_handle, 0);
108 if(rc < 0) {
109 jz_log(jz, JZ_LOG_ERROR, "libusb_claim_interface: %s", libusb_strerror(rc));
110 rc = JZ_ERR_USB;
111 goto error;
112 }
113
114 jz_log(jz, JZ_LOG_DEBUG, "Opened device (%p, ID %04x:%04x)",
115 dev, (unsigned int)vend_id, (unsigned int)prod_id);
116 dev->jz = jz;
117 dev->handle = usb_handle;
118 *devptr = dev;
119 rc = JZ_SUCCESS;
120
121 exit:
122 if(dev_list)
123 libusb_free_device_list(dev_list, true);
124 return rc;
125
126 error:
127 if(dev)
128 free(dev);
129 if(usb_handle)
130 libusb_close(usb_handle);
131 jz_context_unref_libusb(jz);
132 goto exit;
133}
134
135/** \brief Close a USB device
136 * \param dev Device to close; memory will be freed automatically
137 */
138void jz_usb_close(jz_usbdev* dev)
139{
140 jz_log(dev->jz, JZ_LOG_DEBUG, "Closing device (%p)", dev);
141 libusb_release_interface(dev->handle, 0);
142 libusb_close(dev->handle);
143 jz_context_unref_libusb(dev->jz);
144 free(dev);
145}
146
147// Does an Ingenic-specific vendor request
148// Written with X1000 in mind but other Ingenic CPUs have the same commands
149static int jz_usb_vendor_req(jz_usbdev* dev, int req, uint32_t arg,
150 void* buffer, int buflen)
151{
152 int rc = libusb_control_transfer(dev->handle,
153 LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
154 req, arg >> 16, arg & 0xffff, buffer, buflen, 1000);
155
156 if(rc < 0) {
157 jz_log(dev->jz, JZ_LOG_ERROR, "libusb_control_transfer: %s", libusb_strerror(rc));
158 rc = JZ_ERR_USB;
159 } else {
160 static const char* req_names[] = {
161 "GET_CPU_INFO",
162 "SET_DATA_ADDRESS",
163 "SET_DATA_LENGTH",
164 "FLUSH_CACHES",
165 "PROGRAM_START1",
166 "PROGRAM_START2",
167 };
168
169 jz_log(dev->jz, JZ_LOG_DEBUG, "Issued %s %08lu",
170 req_names[req], (unsigned long)arg);
171 rc = JZ_SUCCESS;
172 }
173
174 return rc;
175}
176
177// Bulk transfer wrapper
178static int jz_usb_transfer(jz_usbdev* dev, bool write, size_t len, void* buf)
179{
180 int xfered = 0;
181 int ep = write ? LIBUSB_ENDPOINT_OUT|1 : LIBUSB_ENDPOINT_IN|1;
182 int rc = libusb_bulk_transfer(dev->handle, ep, buf, len, &xfered, 10000);
183
184 if(rc < 0) {
185 jz_log(dev->jz, JZ_LOG_ERROR, "libusb_bulk_transfer: %s", libusb_strerror(rc));
186 rc = JZ_ERR_USB;
187 } else if(xfered != (int)len) {
188 jz_log(dev->jz, JZ_LOG_ERROR, "libusb_bulk_transfer: incorrect amount of data transfered");
189 rc = JZ_ERR_USB;
190 } else {
191 jz_log(dev->jz, JZ_LOG_DEBUG, "Transferred %zu bytes %s",
192 len, write ? "to device" : "from device");
193 rc = JZ_SUCCESS;
194 }
195
196 return rc;
197}
198
199// Memory send/receive primitive, performs the necessary vendor requests
200// and then tranfers data using the bulk endpoint
201static int jz_usb_sendrecv(jz_usbdev* dev, bool write, uint32_t addr,
202 size_t len, void* data)
203{
204 int rc;
205 rc = jz_usb_vendor_req(dev, VR_SET_DATA_ADDRESS, addr, NULL, 0);
206 if(rc < 0)
207 return rc;
208
209 rc = jz_usb_vendor_req(dev, VR_SET_DATA_LENGTH, len, NULL, 0);
210 if(rc < 0)
211 return rc;
212
213 return jz_usb_transfer(dev, write, len, data);
214}
215
216/** \brief Write data to device memory
217 * \param dev USB device
218 * \param addr Address where data should be written
219 * \param len Length of the data, in bytes, should be positive
220 * \param data Data buffer
221 * \return either JZ_SUCCESS on success or a failure code
222 */
223int jz_usb_send(jz_usbdev* dev, uint32_t addr, size_t len, const void* data)
224{
225 return jz_usb_sendrecv(dev, true, addr, len, (void*)data);
226}
227
228/** \brief Read data to device memory
229 * \param dev USB device
230 * \param addr Address to read from
231 * \param len Length of the data, in bytes, should be positive
232 * \param data Data buffer
233 * \return either JZ_SUCCESS on success or a failure code
234 */
235int jz_usb_recv(jz_usbdev* dev, uint32_t addr, size_t len, void* data)
236{
237 return jz_usb_sendrecv(dev, false, addr, len, data);
238}
239
240/** \brief Execute stage1 program jumping to the specified address
241 * \param dev USB device
242 * \param addr Address to begin execution at
243 * \return either JZ_SUCCESS on success or a failure code
244 */
245int jz_usb_start1(jz_usbdev* dev, uint32_t addr)
246{
247 return jz_usb_vendor_req(dev, VR_PROGRAM_START1, addr, NULL, 0);
248}
249
250/** \brief Execute stage2 program jumping to the specified address
251 * \param dev USB device
252 * \param addr Address to begin execution at
253 * \return either JZ_SUCCESS on success or a failure code
254 */
255int jz_usb_start2(jz_usbdev* dev, uint32_t addr)
256{
257 return jz_usb_vendor_req(dev, VR_PROGRAM_START2, addr, NULL, 0);
258}
259
260/** \brief Ask device to flush CPU caches
261 * \param dev USB device
262 * \return either JZ_SUCCESS on success or a failure code
263 */
264int jz_usb_flush_caches(jz_usbdev* dev)
265{
266 return jz_usb_vendor_req(dev, VR_FLUSH_CACHES, 0, NULL, 0);
267}
268
269/** \brief Ask device for CPU info string
270 * \param dev USB device
271 * \param buffer Buffer to hold the info string
272 * \param buflen Size of the buffer, in bytes
273 * \return either JZ_SUCCESS on success or a failure code
274 *
275 * The buffer will always be null terminated, but to ensure the info string is
276 * not truncated the buffer needs to be at least `JZ_CPUINFO_BUFLEN` byes long.
277 */
278int jz_usb_get_cpu_info(jz_usbdev* dev, char* buffer, size_t buflen)
279{
280 char tmpbuf[JZ_CPUINFO_BUFLEN];
281 int rc = jz_usb_vendor_req(dev, VR_GET_CPU_INFO, 0, tmpbuf, 8);
282 if(rc != JZ_SUCCESS)
283 return rc;
284
285 if(buflen > 0) {
286 strncpy(buffer, tmpbuf, buflen);
287 buffer[buflen - 1] = 0;
288 }
289
290 return JZ_SUCCESS;
291}
diff --git a/utils/jztool/src/x1000.c b/utils/jztool/src/x1000.c
new file mode 100644
index 0000000000..f59727a2ca
--- /dev/null
+++ b/utils/jztool/src/x1000.c
@@ -0,0 +1,180 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "jztool.h"
23#include "jztool_private.h"
24#include "microtar-stdio.h"
25#include <stdbool.h>
26#include <string.h>
27
28/* TODO: these functions could be refactored to be CPU-agnostic */
29static int run_stage1(jz_usbdev* dev, jz_buffer* buf)
30{
31 int rc = jz_usb_send(dev, 0xf4001000, buf->size, buf->data);
32 if(rc < 0)
33 return rc;
34
35 return jz_usb_start1(dev, 0xf4001800);
36}
37
38static int run_stage2(jz_usbdev* dev, jz_buffer* buf)
39{
40 int rc = jz_usb_send(dev, 0x80004000, buf->size, buf->data);
41 if(rc < 0)
42 return rc;
43
44 rc = jz_usb_flush_caches(dev);
45 if(rc < 0)
46 return rc;
47
48 return jz_usb_start2(dev, 0x80004000);
49}
50
51static int get_file(jz_context* jz, mtar_t* tar, const char* file,
52 bool decompress, jz_buffer** buf)
53{
54 jz_buffer* buffer = NULL;
55 const mtar_header_t* h;
56 int rc;
57
58 rc = mtar_find(tar, file);
59 if(rc != MTAR_ESUCCESS) {
60 jz_log(jz, JZ_LOG_ERROR, "can't find %s in boot file, tar error %d", file, rc);
61 return JZ_ERR_BAD_FILE_FORMAT;
62 }
63
64 h = mtar_get_header(tar);
65 buffer = jz_buffer_alloc(h->size, NULL);
66 if(!buffer)
67 return JZ_ERR_OUT_OF_MEMORY;
68
69 rc = mtar_read_data(tar, buffer->data, buffer->size);
70 if(rc < 0 || (unsigned)rc != buffer->size) {
71 jz_buffer_free(buffer);
72 jz_log(jz, JZ_LOG_ERROR, "can't read %s in boot file, tar error %d", file, rc);
73 return JZ_ERR_BAD_FILE_FORMAT;
74 }
75
76 if(decompress) {
77 uint32_t dst_len;
78 jz_buffer* nbuf = jz_ucl_unpack(buffer->data, buffer->size, &dst_len);
79 jz_buffer_free(buffer);
80 if(!nbuf) {
81 jz_log(jz, JZ_LOG_ERROR, "error decompressing %s in boot file", file);
82 return JZ_ERR_BAD_FILE_FORMAT;
83 }
84
85 /* for simplicity just forget original size of buffer */
86 nbuf->size = dst_len;
87 buffer = nbuf;
88 }
89
90 *buf = buffer;
91 return JZ_SUCCESS;
92}
93
94static int show_version(jz_context* jz, jz_buffer* info_file)
95{
96 /* Extract the version string and log it for informational purposes */
97 char* boot_version = (char*)info_file->data;
98 char* endpos = memchr(boot_version, '\n', info_file->size);
99 if(!endpos) {
100 jz_log(jz, JZ_LOG_ERROR, "invalid metadata in boot file");
101 return JZ_ERR_BAD_FILE_FORMAT;
102 }
103
104 *endpos = 0;
105 jz_log(jz, JZ_LOG_NOTICE, "Rockbox bootloader version: %s", boot_version);
106 return JZ_SUCCESS;
107}
108
109/** \brief Load the Rockbox bootloader on an X1000 device
110 * \param dev USB device freshly returned by jz_usb_open()
111 * \param filename Path to the "bootloader.target" file
112 * \return either JZ_SUCCESS or an error code
113 */
114int jz_x1000_boot(jz_usbdev* dev, jz_device_type type, const char* filename)
115{
116 const jz_device_info* dev_info;
117 char spl_filename[32];
118 jz_buffer* spl = NULL, *bootloader = NULL, *info_file = NULL;
119 mtar_t tar;
120 int rc;
121
122 /* In retrospect using a model-dependent archive format was not a good
123 * idea, but it's not worth fixing just yet... */
124 dev_info = jz_get_device_info(type);
125 if(!dev_info)
126 return JZ_ERR_OTHER;
127 /* use of sprintf is safe since file_ext is short */
128 sprintf(spl_filename, "spl.%s", dev_info->file_ext);
129
130 /* Now open the archive */
131 rc = mtar_open(&tar, filename, "rb");
132 if(rc != MTAR_ESUCCESS) {
133 jz_log(dev->jz, JZ_LOG_ERROR, "cannot open file %s (tar error: %d)", filename, rc);
134 return JZ_ERR_OPEN_FILE;
135 }
136
137 /* Extract all necessary files */
138 rc = get_file(dev->jz, &tar, spl_filename, false, &spl);
139 if(rc != JZ_SUCCESS)
140 goto error;
141
142 rc = get_file(dev->jz, &tar, "bootloader.ucl", true, &bootloader);
143 if(rc != JZ_SUCCESS)
144 goto error;
145
146 rc = get_file(dev->jz, &tar, "bootloader-info.txt", false, &info_file);
147 if(rc != JZ_SUCCESS)
148 goto error;
149
150 /* Display the version string */
151 rc = show_version(dev->jz, info_file);
152 if(rc != JZ_SUCCESS)
153 goto error;
154
155 /* Stage1 boot of SPL to set up hardware */
156 rc = run_stage1(dev, spl);
157 if(rc != JZ_SUCCESS)
158 goto error;
159
160 /* Need a bit of time for SPL to handle init */
161 jz_sleepms(500);
162
163 /* Stage2 boot into the bootloader's recovery menu
164 * User has to take manual action from there */
165 rc = run_stage2(dev, bootloader);
166 if(rc != JZ_SUCCESS)
167 goto error;
168
169 rc = JZ_SUCCESS;
170
171 error:
172 if(spl)
173 jz_buffer_free(spl);
174 if(bootloader)
175 jz_buffer_free(bootloader);
176 if(info_file)
177 jz_buffer_free(info_file);
178 mtar_close(&tar);
179 return rc;
180}
diff --git a/utils/libtools.make b/utils/libtools.make
new file mode 100644
index 0000000000..3ab150e876
--- /dev/null
+++ b/utils/libtools.make
@@ -0,0 +1,183 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7
8# libtools.make
9#
10# Common Makefile for tools used by Rockbox Utility.
11# Provides rules for building as library, universal library (OS X) and
12# standalone binary.
13#
14# LIBSOURCES is a list of files to build the lib
15# SOURCES is a list of files to build for the main binary
16# EXTRADEPS is a list of make targets dependencies
17#
18ifndef V
19SILENT = @
20endif
21
22# Get directory this Makefile is in for relative paths.
23TOP := $(dir $(lastword $(MAKEFILE_LIST)))
24ifeq ($(OS),Windows_NT)
25SHELL = cmd.exe
26mkdir = if not exist $(subst /,\,$(1)) mkdir $(subst /,\,$(1))
27rm = if exist $(subst /,\,$(1)) del /q /s $(subst /,\,$(1))
28else
29mkdir = mkdir -p $(1)
30rm = rm -rf $(1)
31endif
32
33# overwrite for releases
34APPVERSION ?= $(shell $(TOP)/../tools/version.sh $(TOP)/..)
35GCCFLAGS += -DVERSION=\"$(APPVERSION)\"
36TARGET_DIR ?= $(abspath .)/
37
38CC := gcc
39CXX := g++
40# use either CC or CXX to link: this makes sure the compiler knows about its
41# internal dependencies. Use CXX if we have at least one c++ file, since we
42# then need to link the c++ standard library (which CXX does for us).
43ifeq ($(strip $(filter %.cpp,$(SOURCES) $(LIBSOURCES))),)
44LD := $(CC)
45else
46LD := $(CXX)
47endif
48CPPDEFINES := $(shell echo foo | $(CROSS)$(CC) -dM -E -)
49
50BINARY = $(OUTPUT)
51# when building a Windows binary add the correct file suffix
52ifeq ($(findstring CYGWIN,$(CPPDEFINES)),CYGWIN)
53BINARY = $(OUTPUT).exe
54GCCFLAGS += -mno-cygwin
55COMPILETARGET = cygwin
56else
57ifeq ($(findstring MINGW,$(CPPDEFINES)),MINGW)
58BINARY = $(OUTPUT).exe
59COMPILETARGET = mingw
60# use POSIX/C99 printf on windows
61GCCFLAGS += -D__USE_MINGW_ANSI_STDIO=1
62else
63ifeq ($(findstring APPLE,$(CPPDEFINES)),APPLE)
64COMPILETARGET = darwin
65LDOPTS += $(LDOPTS_OSX)
66else
67COMPILETARGET = posix
68endif
69endif
70endif
71$(info Compiler creates $(COMPILETARGET) binaries)
72
73# OS X specifics. Needs to consider cross compiling for Windows.
74ifeq ($(findstring APPLE,$(CPPDEFINES)),APPLE)
75# When building for 10.4+ we need to use gcc. Otherwise clang is used, so use
76# that to determine if we need to set arch and isysroot.
77ifeq ($(findstring __clang__,$(CPPDEFINES)),__clang__)
78GCCFLAGS += -mmacosx-version-min=10.5
79ifneq ($(ISYSROOT),)
80GCCFLAGS += -isysroot $(ISYSROOT)
81endif
82else
83# when building libs for OS X 10.4+ build for both i386 and ppc at the same time.
84# This creates fat objects, and ar can only create the archive but not operate
85# on it. As a result the ar call must NOT use the u (update) flag.
86ARCHFLAGS += -arch ppc -arch i386
87# building against SDK 10.4 is not compatible with gcc-4.2 (default on newer Xcode)
88# might need adjustment for older Xcode.
89CC = gcc-4.0
90GCCFLAGS += -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4
91endif
92endif
93
94BUILD_DIR ?= $(TARGET_DIR)build$(COMPILETARGET)
95OBJDIR = $(abspath $(BUILD_DIR))/
96
97all: $(BINARY)
98
99OBJS := $(addsuffix .o,$(addprefix $(OBJDIR),$(notdir $(SOURCES))))
100LIBOBJS := $(addsuffix .o,$(addprefix $(OBJDIR),$(notdir $(LIBSOURCES))))
101
102# create dependency files. Make sure to use the same prefix as with OBJS!
103$(foreach src,$(SOURCES) $(LIBSOURCES),$(eval $(addprefix $(OBJDIR),$(notdir $(src).o)): $(src)))
104$(foreach src,$(SOURCES) $(LIBSOURCES),$(eval $(addprefix $(OBJDIR),$(notdir $(src).d)): $(src)))
105DEPS = $(addprefix $(OBJDIR),$(addsuffix .d,$(notdir $(SOURCES) $(LIBSOURCES))))
106-include $(DEPS)
107
108# additional link dependencies for the standalone executable
109# extra dependencies: libucl
110LIBUCL = libucl.a
111$(LIBUCL): $(OBJDIR)$(LIBUCL)
112
113$(OBJDIR)$(LIBUCL):
114 $(SILENT)$(MAKE) -C $(TOP)/../tools/ucl/src TARGET_DIR=$(OBJDIR) CC=$(CC) $@
115
116LIBBZIP2 = libbz2.a
117$(LIBBZIP2): $(OBJDIR)$(LIBBZIP2)
118$(OBJDIR)$(LIBBZIP2):
119 $(SILENT)$(MAKE) -C $(TOP)/bzip2 TARGET_DIR=$(OBJDIR) CC=$(CC) $@
120
121LIBMICROTAR = libmicrotar.a
122$(LIBMICROTAR): $(OBJDIR)$(LIBMICROTAR)
123
124$(OBJDIR)$(LIBMICROTAR):
125 $(SILENT)$(MAKE) -C $(TOP)/../lib/microtar/src TARGET_DIR=$(OBJDIR) CC=$(CC) $@
126
127# building the standalone executable
128$(BINARY): $(OBJS) $(EXTRADEPS) $(addprefix $(OBJDIR),$(EXTRALIBOBJS)) $(TARGET_DIR)lib$(OUTPUT).a
129 $(info LD $@)
130 $(SILENT)$(call mkdir,$(dir $@))
131# EXTRADEPS need to be built into OBJDIR.
132 $(SILENT)$(CROSS)$(LD) $(ARCHFLAGS) $(LDFLAGS) -o $(BINARY) \
133 $(OBJS) $(addprefix $(OBJDIR),$(EXTRADEPS)) \
134 $(addprefix $(OBJDIR),$(EXTRALIBOBJS)) lib$(OUTPUT).a $(addprefix $(OBJDIR),$(EXTRADEPS)) $(LDOPTS)
135
136# common rules
137$(OBJDIR)%.c.o:
138 $(info CC $<)
139 $(SILENT)$(call mkdir,$(dir $@))
140 $(SILENT)$(CROSS)$(CC) $(ARCHFLAGS) $(GCCFLAGS) $(CFLAGS) -MMD -c -o $@ $<
141
142$(OBJDIR)%.cpp.o:
143 $(info CXX $<)
144 $(SILENT)$(call mkdir,$(dir $@))
145 $(SILENT)$(CROSS)$(CXX) $(ARCHFLAGS) $(GCCFLAGS) $(CXXFLAGS) -MMD -c -o $@ $<
146
147# lib rules
148lib$(OUTPUT).a: $(TARGET_DIR)lib$(OUTPUT).a
149lib$(OUTPUT): $(TARGET_DIR)lib$(OUTPUT).a
150
151$(TARGET_DIR)lib$(OUTPUT).a: $(LIBOBJS) \
152 $(addprefix $(OBJDIR),$(EXTRALIBOBJS))
153# rules to build a DLL. Only works for W32 as target (i.e. MinGW toolchain)
154dll: $(OUTPUT).dll
155$(OUTPUT).dll: $(TARGET_DIR)$(OUTPUT).dll
156$(TARGET_DIR)$(OUTPUT).dll: $(LIBOBJS) $(addprefix $(OBJDIR),$(EXTRALIBOBJS))
157 $(info DLL $(notdir $@))
158 $(SILENT)$(call mkdir,$(dir $@))
159 $(SILENT)$(CROSS)$(CC) $(ARCHFLAGS) $(GCCFLAGS) -shared -o $@ $^ \
160 -Wl,--output-def,$(TARGET_DIR)$(OUTPUT).def
161
162# create lib file from objects
163$(TARGET_DIR)lib$(OUTPUT).a: $(LIBOBJS) $(addprefix $(OBJDIR),$(EXTRALIBOBJS))
164 $(info AR $(notdir $@))
165 $(SILENT)$(call mkdir,$(dir $@))
166 $(SILENT)$(call rm,$@)
167 $(SILENT)$(CROSS)$(AR) rcs $@ $^
168
169clean:
170 $(call rm, $(OBJS) $(OUTPUT) $(TARGET_DIR)lib$(OUTPUT)*.a $(OUTPUT).dmg)
171 $(call rm, $(OUTPUT)-* i386 ppc $(OBJDIR))
172
173# extra tools
174BIN2C = $(TOP)/tools/bin2c
175$(BIN2C):
176 $(MAKE) -C $(TOP)/tools
177
178# OS X specifics
179$(OUTPUT).dmg: $(OUTPUT)
180 $(info DMG $@)
181 $(SILENT)$(call mkdir,"$(OUTPUT)-$(APPVERSION)")
182 $(SILENT)cp -p $(OUTPUT) "$(OUTPUT)-$(APPVERSION)"
183 $(SILENT)hdiutil create -srcfolder "$(OUTPUT)-$(APPVERSION)" $@
diff --git a/utils/mkamsboot/.gitignore b/utils/mkamsboot/.gitignore
new file mode 100644
index 0000000000..568b1d5a87
--- /dev/null
+++ b/utils/mkamsboot/.gitignore
@@ -0,0 +1,2 @@
1build/
2mkamsboot
diff --git a/utils/mkamsboot/Makefile b/utils/mkamsboot/Makefile
new file mode 100644
index 0000000000..7100bd9512
--- /dev/null
+++ b/utils/mkamsboot/Makefile
@@ -0,0 +1,31 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7
8# We use the UCL code available in the Rockbox tools/ directory
9CFLAGS += -I../../tools/ucl/include -Wall
10
11OUTPUT = mkamsboot
12LIBUCL = libucl.a
13
14# inputs
15LIBSOURCES := dualboot.c md5.c mkamsboot.c
16SOURCES := main.c
17# additional link dependencies for the standalone executable
18EXTRADEPS := $(LIBUCL)
19
20include ../libtools.make
21# explicit dependencies on dualboot.{c,h} and mkamsboot.h
22$(OBJDIR)mkamsboot.o: dualboot.h dualboot.c mkamsboot.c mkamsboot.h
23$(OBJDIR)main.o: dualboot.h dualboot.c main.c mkamsboot.h
24
25
26$(TARGET_DIR)$(OUTPUT).dll: EXTRALIBOBJS += $(TARGET_DIR)ucl.dll
27$(TARGET_DIR)$(OUTPUT).dll: $(TARGET_DIR)ucl.dll
28$(TARGET_DIR)ucl.dll:
29 $(SILENT)$(MAKE) -C ../../tools/ucl/src/ \
30 BUILD_DIR=$(BUILD_DIR) CC=$(CC) CROSS=$(CROSS) \
31 TARGET_DIR=$(TARGET_DIR)/ ucl.dll
diff --git a/utils/mkamsboot/README b/utils/mkamsboot/README
new file mode 100644
index 0000000000..8e3f202f38
--- /dev/null
+++ b/utils/mkamsboot/README
@@ -0,0 +1,67 @@
1mkamsboot
2---------
3
4A tool to inject a bootloader into a Sansa V2 (AMS) firmware file.
5
6
7Usage
8-----
9
10mkamsboot <firmware file> <boot file> <output file>
11
12<firmware file> is an original Sansa firmware file obtained from the Sansa
13 forums for example : http://forums.sandisk.com/sansa/?category.id=devices
14
15<boot file> is the code you want to execute (a rockbox bootloader), previously
16 scrambled with tools/scramble utility.
17
18<output file> is the resulting firmware file which you'll have to copy on your
19 Sansa player. See "Firmware filenames".
20
21
22Supported models
23----------------
24
25Sansa Clip : firmware version starting with "01."
26Sansa Clip+ : firmware version starting with "01."
27Sansa Clipv2: firmware version starting with "02."
28Sansa ClipZip: firmware version starting with "01."
29Sansa Fuze : firmware version starting with "01."
30Sansa Fuzev2: firmware version starting with "02."
31Sansa E200v2: firmware version starting with "03."
32Sansa C200v2: firmware version starting with "03."
33Sansa M200v4: firmware version starting with "4."
34
35
36Firmware filenames
37------------------
38
39For the firmware upgrade to happen, the firmware has to be named specially:
40
41clip v2 : m30pa.bin
42clip : m300a.bin
43clip+ : clppa.bin
44clip zip: clpza.bin
45fuze : fuzea.bin
46fuzev2 : fuzpa.bin
47e200v2 : e200pa.bin
48c200v2 : c200pa.bin
49m200v4 : m200a.bin
50
51
52Dual-Boot
53---------
54
55 The purpose of this program is to provide dual-boot between the original
56firmware and the new (rockbox) firmware.
57
58 By default the player will boot into the new firmware.
59
60 To boot into the Original Firmware, you need to press the Left key.
61 ***Note : on the Clip+ you can alternatively press the Home key.
62 ***Note : on the Clip Zip you can alternatively press the Vol- key.
63
64Hacking
65-------
66
67See comments in mkamsboot.c and dualboot/dualboot.S for more information.
diff --git a/utils/mkamsboot/dualboot.c b/utils/mkamsboot/dualboot.c
new file mode 100644
index 0000000000..d97ab0e95b
--- /dev/null
+++ b/utils/mkamsboot/dualboot.c
@@ -0,0 +1,152 @@
1/* Generated by bin2c */
2
3#include "dualboot.h"
4
5unsigned char nrv2e_d8[168] = {
6 0x0f, 0x18, 0x01, 0x24, 0x65, 0x42, 0xe4, 0x07, 0x05, 0x26, 0x36, 0x02, 0x0a, 0xe0, 0x00, 0x20,
7 0x00, 0x47, 0x04, 0x78, 0x64, 0x41, 0x01, 0x30, 0x24, 0x06, 0xf7, 0x46, 0x03, 0x78, 0x01, 0x30,
8 0x13, 0x70, 0x01, 0x32, 0x24, 0x19, 0xfe, 0x46, 0xf3, 0xd0, 0xf7, 0xd2, 0x01, 0x21, 0x04, 0xe0,
9 0x01, 0x39, 0x24, 0x19, 0xfe, 0x46, 0xec, 0xd0, 0x49, 0x41, 0x24, 0x19, 0xfe, 0x46, 0xe8, 0xd0,
10 0x49, 0x41, 0x24, 0x19, 0xfe, 0x46, 0xe4, 0xd0, 0xf2, 0xd3, 0xcb, 0x1e, 0x00, 0x21, 0x08, 0xd3,
11 0x1b, 0x02, 0x05, 0x78, 0x01, 0x30, 0x1d, 0x43, 0xed, 0x43, 0xd8, 0xd0, 0x6d, 0x10, 0x13, 0xd2,
12 0x03, 0xe0, 0x24, 0x19, 0xfe, 0x46, 0xd4, 0xd0, 0x0e, 0xd2, 0x01, 0x21, 0x24, 0x19, 0xfe, 0x46,
13 0xcf, 0xd0, 0x09, 0xd2, 0x24, 0x19, 0xfe, 0x46, 0xcb, 0xd0, 0x49, 0x41, 0x24, 0x19, 0xfe, 0x46,
14 0xc7, 0xd0, 0xf7, 0xd3, 0x04, 0x31, 0x04, 0xe0, 0x24, 0x19, 0xfe, 0x46, 0xc1, 0xd0, 0x49, 0x41,
15 0x02, 0x31, 0xee, 0x42, 0x00, 0xd2, 0x01, 0x31, 0x13, 0x78, 0x53, 0x5d, 0x13, 0x70, 0x01, 0x32,
16 0x01, 0x39, 0xfa, 0xd1, 0xbe, 0xe7, 0x00, 0x00
17};
18unsigned char dualboot_clip[196] = {
19 0x06, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
20 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
21 0x24, 0x00, 0x1f, 0xe5, 0x24, 0x10, 0x1f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 0x18, 0x30, 0x1f, 0xe5,
22 0x01, 0x40, 0x50, 0xe4, 0x01, 0x40, 0x43, 0xe4, 0x00, 0x00, 0x52, 0xe1, 0xfb, 0xff, 0xff, 0x1a,
23 0x2c, 0x30, 0x0f, 0xe5, 0x6c, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x18, 0x81, 0xe3,
24 0x00, 0x10, 0x80, 0xe5, 0x60, 0x00, 0x9f, 0xe5, 0x20, 0x10, 0xa0, 0xe3, 0x00, 0x14, 0x80, 0xe5,
25 0x80, 0x10, 0x80, 0xe5, 0x54, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x14, 0x80, 0xe5,
26 0x04, 0x10, 0x90, 0xe5, 0x00, 0x00, 0x51, 0xe3, 0x02, 0x00, 0x00, 0x1a, 0x70, 0x00, 0x1f, 0xe5,
27 0x70, 0x10, 0x1f, 0xe5, 0x01, 0x00, 0x00, 0xea, 0x84, 0x00, 0x1f, 0xe5, 0x84, 0x10, 0x1f, 0xe5,
28 0x7c, 0x30, 0x1f, 0xe5, 0x02, 0x50, 0x83, 0xe2, 0x01, 0x40, 0x43, 0xe0, 0x01, 0x20, 0x50, 0xe4,
29 0x01, 0x20, 0x43, 0xe4, 0x04, 0x00, 0x53, 0xe1, 0xfb, 0xff, 0xff, 0x1a, 0x01, 0x00, 0x83, 0xe2,
30 0x00, 0x20, 0xa0, 0xe3, 0x15, 0xff, 0x2f, 0xe1, 0x14, 0x00, 0x0f, 0xc8, 0x00, 0x00, 0x0d, 0xc8,
31 0x00, 0x00, 0x0c, 0xc8
32};
33unsigned char dualboot_e200v2[176] = {
34 0x06, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36 0x24, 0x00, 0x1f, 0xe5, 0x24, 0x10, 0x1f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 0x18, 0x30, 0x1f, 0xe5,
37 0x01, 0x40, 0x50, 0xe4, 0x01, 0x40, 0x43, 0xe4, 0x00, 0x00, 0x52, 0xe1, 0xfb, 0xff, 0xff, 0x1a,
38 0x2c, 0x30, 0x0f, 0xe5, 0x5c, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x18, 0x81, 0xe3,
39 0x00, 0x10, 0x80, 0xe5, 0x50, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x14, 0x80, 0xe5,
40 0x20, 0x10, 0x90, 0xe5, 0x00, 0x00, 0x51, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x60, 0x00, 0x1f, 0xe5,
41 0x60, 0x10, 0x1f, 0xe5, 0x01, 0x00, 0x00, 0xea, 0x74, 0x00, 0x1f, 0xe5, 0x74, 0x10, 0x1f, 0xe5,
42 0x6c, 0x30, 0x1f, 0xe5, 0x02, 0x50, 0x83, 0xe2, 0x01, 0x40, 0x43, 0xe0, 0x01, 0x20, 0x50, 0xe4,
43 0x01, 0x20, 0x43, 0xe4, 0x04, 0x00, 0x53, 0xe1, 0xfb, 0xff, 0xff, 0x1a, 0x01, 0x00, 0x83, 0xe2,
44 0x00, 0x20, 0xa0, 0xe3, 0x15, 0xff, 0x2f, 0xe1, 0x14, 0x00, 0x0f, 0xc8, 0x00, 0x00, 0x0d, 0xc8
45};
46unsigned char dualboot_c200v2[272] = {
47 0x06, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x24, 0x00, 0x1f, 0xe5, 0x24, 0x10, 0x1f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 0x18, 0x30, 0x1f, 0xe5,
50 0x01, 0x40, 0x50, 0xe4, 0x01, 0x40, 0x43, 0xe4, 0x00, 0x00, 0x52, 0xe1, 0xfb, 0xff, 0xff, 0x1a,
51 0x2c, 0x30, 0x0f, 0xe5, 0xa8, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x18, 0x81, 0xe3,
52 0x00, 0x10, 0x80, 0xe5, 0x9c, 0x00, 0x9f, 0xe5, 0x08, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x80, 0xe5,
53 0x94, 0x20, 0x9f, 0xe5, 0x0c, 0x10, 0xa0, 0xe3, 0x20, 0x14, 0x82, 0xe5, 0x8c, 0x20, 0x9f, 0xe5,
54 0xff, 0x10, 0xa0, 0xe3, 0x20, 0x14, 0x82, 0xe5, 0x84, 0x00, 0x9f, 0xe5, 0x91, 0x1a, 0xa0, 0xe3,
55 0x08, 0x10, 0x80, 0xe5, 0x7c, 0x10, 0x9f, 0xe5, 0x10, 0x10, 0x80, 0xe5, 0x0c, 0x10, 0x90, 0xe5,
56 0x01, 0x1b, 0x11, 0xe2, 0xfc, 0xff, 0xff, 0x0a, 0x6c, 0x10, 0x9f, 0xe5, 0x08, 0x10, 0x80, 0xe5,
57 0x0c, 0x10, 0x90, 0xe5, 0x01, 0x18, 0x11, 0xe2, 0xfc, 0xff, 0xff, 0x0a, 0xb4, 0x11, 0xd0, 0xe1,
58 0x04, 0x00, 0x11, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0xac, 0x00, 0x1f, 0xe5, 0xac, 0x10, 0x1f, 0xe5,
59 0x01, 0x00, 0x00, 0xea, 0xc0, 0x00, 0x1f, 0xe5, 0xc0, 0x10, 0x1f, 0xe5, 0xb8, 0x30, 0x1f, 0xe5,
60 0x02, 0x50, 0x83, 0xe2, 0x01, 0x40, 0x43, 0xe0, 0x01, 0x20, 0x50, 0xe4, 0x01, 0x20, 0x43, 0xe4,
61 0x04, 0x00, 0x53, 0xe1, 0xfb, 0xff, 0xff, 0x1a, 0x01, 0x00, 0x83, 0xe2, 0x00, 0x20, 0xa0, 0xe3,
62 0x15, 0xff, 0x2f, 0xe1, 0x14, 0x00, 0x0f, 0xc8, 0x38, 0x00, 0x0f, 0xc8, 0x00, 0x00, 0x0c, 0xc8,
63 0x00, 0x00, 0x0d, 0xc8, 0x00, 0x00, 0x12, 0xc8, 0xff, 0xf0, 0x00, 0x00, 0x1f, 0x90, 0x08, 0x00
64};
65unsigned char dualboot_m200v4[180] = {
66 0x06, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x24, 0x00, 0x1f, 0xe5, 0x24, 0x10, 0x1f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 0x18, 0x30, 0x1f, 0xe5,
69 0x01, 0x40, 0x50, 0xe4, 0x01, 0x40, 0x43, 0xe4, 0x00, 0x00, 0x52, 0xe1, 0xfb, 0xff, 0xff, 0x1a,
70 0x2c, 0x30, 0x0f, 0xe5, 0x60, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x18, 0x81, 0xe3,
71 0x00, 0x10, 0x80, 0xe5, 0x54, 0x00, 0x9f, 0xe5, 0x20, 0x10, 0xa0, 0xe3, 0x00, 0x14, 0x80, 0xe5,
72 0x80, 0x10, 0x80, 0xe5, 0x04, 0x20, 0x90, 0xe5, 0x00, 0x00, 0x52, 0xe3, 0x02, 0x00, 0x00, 0x1a,
73 0x64, 0x00, 0x1f, 0xe5, 0x64, 0x10, 0x1f, 0xe5, 0x01, 0x00, 0x00, 0xea, 0x78, 0x00, 0x1f, 0xe5,
74 0x78, 0x10, 0x1f, 0xe5, 0x70, 0x30, 0x1f, 0xe5, 0x02, 0x50, 0x83, 0xe2, 0x01, 0x40, 0x43, 0xe0,
75 0x01, 0x20, 0x50, 0xe4, 0x01, 0x20, 0x43, 0xe4, 0x04, 0x00, 0x53, 0xe1, 0xfb, 0xff, 0xff, 0x1a,
76 0x01, 0x00, 0x83, 0xe2, 0x00, 0x20, 0xa0, 0xe3, 0x15, 0xff, 0x2f, 0xe1, 0x14, 0x00, 0x0f, 0xc8,
77 0x00, 0x00, 0x0b, 0xc8
78};
79unsigned char dualboot_fuze[176] = {
80 0x06, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x24, 0x00, 0x1f, 0xe5, 0x24, 0x10, 0x1f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 0x18, 0x30, 0x1f, 0xe5,
83 0x01, 0x40, 0x50, 0xe4, 0x01, 0x40, 0x43, 0xe4, 0x00, 0x00, 0x52, 0xe1, 0xfb, 0xff, 0xff, 0x1a,
84 0x2c, 0x30, 0x0f, 0xe5, 0x5c, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x18, 0x81, 0xe3,
85 0x00, 0x10, 0x80, 0xe5, 0x50, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x14, 0x80, 0xe5,
86 0x20, 0x10, 0x90, 0xe5, 0x00, 0x00, 0x51, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x60, 0x00, 0x1f, 0xe5,
87 0x60, 0x10, 0x1f, 0xe5, 0x01, 0x00, 0x00, 0xea, 0x74, 0x00, 0x1f, 0xe5, 0x74, 0x10, 0x1f, 0xe5,
88 0x6c, 0x30, 0x1f, 0xe5, 0x02, 0x50, 0x83, 0xe2, 0x01, 0x40, 0x43, 0xe0, 0x01, 0x20, 0x50, 0xe4,
89 0x01, 0x20, 0x43, 0xe4, 0x04, 0x00, 0x53, 0xe1, 0xfb, 0xff, 0xff, 0x1a, 0x01, 0x00, 0x83, 0xe2,
90 0x00, 0x20, 0xa0, 0xe3, 0x15, 0xff, 0x2f, 0xe1, 0x14, 0x00, 0x0f, 0xc8, 0x00, 0x00, 0x0d, 0xc8
91};
92unsigned char dualboot_clipv2[240] = {
93 0x06, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x24, 0x00, 0x1f, 0xe5, 0x24, 0x10, 0x1f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 0x18, 0x30, 0x1f, 0xe5,
96 0x01, 0x40, 0x50, 0xe4, 0x01, 0x40, 0x43, 0xe4, 0x00, 0x00, 0x52, 0xe1, 0xfb, 0xff, 0xff, 0x1a,
97 0x2c, 0x30, 0x0f, 0xe5, 0x98, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x18, 0x81, 0xe3,
98 0x00, 0x10, 0x80, 0xe5, 0x8c, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x0c, 0x10, 0xc1, 0xe3,
99 0x00, 0x10, 0x80, 0xe5, 0x80, 0x00, 0x9f, 0xe5, 0x38, 0x10, 0xa0, 0xe3, 0x00, 0x14, 0x80, 0xe5,
100 0x08, 0x10, 0xa0, 0xe3, 0x20, 0x10, 0x80, 0xe5, 0x10, 0x10, 0xa0, 0xe3, 0x40, 0x10, 0x80, 0xe5,
101 0x20, 0x10, 0xa0, 0xe3, 0x80, 0x10, 0x80, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x40, 0x10, 0x80, 0xe5,
102 0x05, 0x10, 0xa0, 0xe3, 0x01, 0x10, 0x51, 0xe2, 0xfd, 0xff, 0xff, 0x1a, 0x04, 0x10, 0x90, 0xe5,
103 0x00, 0x00, 0x51, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x9c, 0x00, 0x1f, 0xe5, 0x9c, 0x10, 0x1f, 0xe5,
104 0x01, 0x00, 0x00, 0xea, 0xb0, 0x00, 0x1f, 0xe5, 0xb0, 0x10, 0x1f, 0xe5, 0xa8, 0x30, 0x1f, 0xe5,
105 0x02, 0x50, 0x83, 0xe2, 0x01, 0x40, 0x43, 0xe0, 0x01, 0x20, 0x50, 0xe4, 0x01, 0x20, 0x43, 0xe4,
106 0x04, 0x00, 0x53, 0xe1, 0xfb, 0xff, 0xff, 0x1a, 0x01, 0x00, 0x83, 0xe2, 0x00, 0x20, 0xa0, 0xe3,
107 0x15, 0xff, 0x2f, 0xe1, 0x14, 0x00, 0x0f, 0xc8, 0x0c, 0x00, 0x10, 0xc8, 0x00, 0x00, 0x0e, 0xc8
108};
109unsigned char dualboot_clipplus[184] = {
110 0x06, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0x24, 0x00, 0x1f, 0xe5, 0x24, 0x10, 0x1f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 0x18, 0x30, 0x1f, 0xe5,
113 0x01, 0x40, 0x50, 0xe4, 0x01, 0x40, 0x43, 0xe4, 0x00, 0x00, 0x52, 0xe1, 0xfb, 0xff, 0xff, 0x1a,
114 0x2c, 0x30, 0x0f, 0xe5, 0x60, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x18, 0x81, 0xe3,
115 0x00, 0x10, 0x80, 0xe5, 0x54, 0x00, 0x9f, 0xe5, 0x20, 0x10, 0x90, 0xe5, 0x50, 0x00, 0x9f, 0xe5,
116 0x08, 0x20, 0x90, 0xe5, 0x01, 0x20, 0x82, 0xe1, 0x00, 0x00, 0x52, 0xe3, 0x02, 0x00, 0x00, 0x1a,
117 0x64, 0x00, 0x1f, 0xe5, 0x64, 0x10, 0x1f, 0xe5, 0x01, 0x00, 0x00, 0xea, 0x78, 0x00, 0x1f, 0xe5,
118 0x78, 0x10, 0x1f, 0xe5, 0x70, 0x30, 0x1f, 0xe5, 0x02, 0x50, 0x83, 0xe2, 0x01, 0x40, 0x43, 0xe0,
119 0x01, 0x20, 0x50, 0xe4, 0x01, 0x20, 0x43, 0xe4, 0x04, 0x00, 0x53, 0xe1, 0xfb, 0xff, 0xff, 0x1a,
120 0x01, 0x00, 0x83, 0xe2, 0x00, 0x20, 0xa0, 0xe3, 0x15, 0xff, 0x2f, 0xe1, 0x14, 0x00, 0x0f, 0xc8,
121 0x00, 0x00, 0x0d, 0xc8, 0x00, 0x00, 0x0b, 0xc8
122};
123unsigned char dualboot_fuzev2[176] = {
124 0x06, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 0x24, 0x00, 0x1f, 0xe5, 0x24, 0x10, 0x1f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 0x18, 0x30, 0x1f, 0xe5,
127 0x01, 0x40, 0x50, 0xe4, 0x01, 0x40, 0x43, 0xe4, 0x00, 0x00, 0x52, 0xe1, 0xfb, 0xff, 0xff, 0x1a,
128 0x2c, 0x30, 0x0f, 0xe5, 0x5c, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x18, 0x81, 0xe3,
129 0x00, 0x10, 0x80, 0xe5, 0x50, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x14, 0x80, 0xe5,
130 0x20, 0x10, 0x90, 0xe5, 0x00, 0x00, 0x51, 0xe3, 0x02, 0x00, 0x00, 0x1a, 0x60, 0x00, 0x1f, 0xe5,
131 0x60, 0x10, 0x1f, 0xe5, 0x01, 0x00, 0x00, 0xea, 0x74, 0x00, 0x1f, 0xe5, 0x74, 0x10, 0x1f, 0xe5,
132 0x6c, 0x30, 0x1f, 0xe5, 0x02, 0x50, 0x83, 0xe2, 0x01, 0x40, 0x43, 0xe0, 0x01, 0x20, 0x50, 0xe4,
133 0x01, 0x20, 0x43, 0xe4, 0x04, 0x00, 0x53, 0xe1, 0xfb, 0xff, 0xff, 0x1a, 0x01, 0x00, 0x83, 0xe2,
134 0x00, 0x20, 0xa0, 0xe3, 0x15, 0xff, 0x2f, 0xe1, 0x14, 0x00, 0x0f, 0xc8, 0x00, 0x00, 0x0d, 0xc8
135};
136unsigned char dualboot_clipzip[232] = {
137 0x06, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 0x24, 0x00, 0x1f, 0xe5, 0x24, 0x10, 0x1f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 0x18, 0x30, 0x1f, 0xe5,
140 0x01, 0x40, 0x50, 0xe4, 0x01, 0x40, 0x43, 0xe4, 0x00, 0x00, 0x52, 0xe1, 0xfb, 0xff, 0xff, 0x1a,
141 0x2c, 0x30, 0x0f, 0xe5, 0x90, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x18, 0x81, 0xe3,
142 0x00, 0x10, 0x80, 0xe5, 0x84, 0x00, 0x9f, 0xe5, 0x00, 0x11, 0x90, 0xe5, 0x00, 0x00, 0x51, 0xe3,
143 0x11, 0x00, 0x00, 0x1a, 0x78, 0x00, 0x9f, 0xe5, 0x00, 0x14, 0x90, 0xe5, 0x06, 0x10, 0x81, 0xe3,
144 0x20, 0x10, 0xc1, 0xe3, 0x00, 0x14, 0x80, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x08, 0x10, 0x80, 0xe5,
145 0x04, 0x10, 0xa0, 0xe3, 0x10, 0x10, 0x80, 0xe5, 0x32, 0x10, 0xa0, 0xe3, 0x01, 0x10, 0x51, 0xe2,
146 0xfd, 0xff, 0xff, 0x1a, 0x80, 0x10, 0x90, 0xe5, 0x00, 0x00, 0x51, 0xe3, 0x02, 0x00, 0x00, 0x1a,
147 0x94, 0x00, 0x1f, 0xe5, 0x94, 0x10, 0x1f, 0xe5, 0x01, 0x00, 0x00, 0xea, 0xa8, 0x00, 0x1f, 0xe5,
148 0xa8, 0x10, 0x1f, 0xe5, 0xa0, 0x30, 0x1f, 0xe5, 0x02, 0x50, 0x83, 0xe2, 0x01, 0x40, 0x43, 0xe0,
149 0x01, 0x20, 0x50, 0xe4, 0x01, 0x20, 0x43, 0xe4, 0x04, 0x00, 0x53, 0xe1, 0xfb, 0xff, 0xff, 0x1a,
150 0x01, 0x00, 0x83, 0xe2, 0x00, 0x20, 0xa0, 0xe3, 0x15, 0xff, 0x2f, 0xe1, 0x14, 0x00, 0x0f, 0xc8,
151 0x00, 0x00, 0x0b, 0xc8, 0x00, 0x00, 0x0d, 0xc8
152};
diff --git a/utils/mkamsboot/dualboot.h b/utils/mkamsboot/dualboot.h
new file mode 100644
index 0000000000..774c35c119
--- /dev/null
+++ b/utils/mkamsboot/dualboot.h
@@ -0,0 +1,12 @@
1/* Generated by bin2c */
2
3extern unsigned char nrv2e_d8[168];
4extern unsigned char dualboot_clip[196];
5extern unsigned char dualboot_e200v2[176];
6extern unsigned char dualboot_c200v2[272];
7extern unsigned char dualboot_m200v4[180];
8extern unsigned char dualboot_fuze[176];
9extern unsigned char dualboot_clipv2[240];
10extern unsigned char dualboot_clipplus[184];
11extern unsigned char dualboot_fuzev2[176];
12extern unsigned char dualboot_clipzip[232];
diff --git a/utils/mkamsboot/dualboot/.gitignore b/utils/mkamsboot/dualboot/.gitignore
new file mode 100644
index 0000000000..a0ed5f4ee1
--- /dev/null
+++ b/utils/mkamsboot/dualboot/.gitignore
@@ -0,0 +1,3 @@
1*.arm-bin
2*.o
3bin2c
diff --git a/utils/mkamsboot/dualboot/Makefile b/utils/mkamsboot/dualboot/Makefile
new file mode 100644
index 0000000000..0aa1e3f7d9
--- /dev/null
+++ b/utils/mkamsboot/dualboot/Makefile
@@ -0,0 +1,61 @@
1CC=gcc
2CROSS_PREFIX?=arm-elf-eabi
3# Edit the following variables (plus copy/paste another set of rules) when
4# adding a new target. mkamsboot.c also needs to be edited to refer to these
5# new images.
6
7BOOTOBJS = nrv2e_d8.o dualboot_clip.o dualboot_e200v2.o dualboot_c200v2.o dualboot_m200v4.o dualboot_fuze.o dualboot_clipv2.o dualboot_clipplus.o dualboot_fuzev2.o dualboot_clipzip.o
8BOOTBINS = nrv2e_d8.arm-bin dualboot_clip.arm-bin dualboot_e200v2.arm-bin dualboot_c200v2.arm-bin dualboot_m200v4.arm-bin dualboot_fuze.arm-bin dualboot_clipv2.arm-bin dualboot_clipplus.arm-bin dualboot_fuzev2.arm-bin dualboot_clipzip.arm-bin
9
10all: ../dualboot.h ../dualboot.c
11
12# Dualboot bootloaders
13
14dualboot_clip.o: dualboot.S
15 $(CROSS_PREFIX)-$(CC) -DSANSA_CLIP -c -o dualboot_clip.o dualboot.S
16
17dualboot_fuze.o: dualboot.S
18 $(CROSS_PREFIX)-$(CC) -DSANSA_FUZE -c -o dualboot_fuze.o dualboot.S
19
20dualboot_e200v2.o: dualboot.S
21 $(CROSS_PREFIX)-$(CC) -DSANSA_E200V2 -c -o dualboot_e200v2.o dualboot.S
22
23dualboot_m200v4.o: dualboot.S
24 $(CROSS_PREFIX)-$(CC) -DSANSA_M200V4 -c -o dualboot_m200v4.o dualboot.S
25
26dualboot_c200v2.o: dualboot.S
27 $(CROSS_PREFIX)-$(CC) -DSANSA_C200V2 -c -o dualboot_c200v2.o dualboot.S
28
29dualboot_clipv2.o: dualboot.S
30 $(CROSS_PREFIX)-$(CC) -DSANSA_CLIPV2 -c -o dualboot_clipv2.o dualboot.S
31
32dualboot_clipplus.o: dualboot.S
33 $(CROSS_PREFIX)-$(CC) -DSANSA_CLIPPLUS -c -o dualboot_clipplus.o dualboot.S
34
35dualboot_fuzev2.o: dualboot.S
36 $(CROSS_PREFIX)-$(CC) -DSANSA_FUZEV2 -c -o dualboot_fuzev2.o dualboot.S
37
38dualboot_clipzip.o: dualboot.S
39 $(CROSS_PREFIX)-$(CC) -DSANSA_CLIPZIP -c -o dualboot_clipzip.o dualboot.S
40
41# Rules for the ucl unpack function
42nrv2e_d8.o: nrv2e_d8.S
43 $(CROSS_PREFIX)-$(CC) -DPURE_THUMB -c -o nrv2e_d8.o nrv2e_d8.S
44
45# Rules for the ARM code embedded in mkamsboot - assemble, link, then extract
46# the binary code and finally convert to .h for building in mkamsboot
47
48%.arm-elf: %.o
49 $(CROSS_PREFIX)-ld -e 0 -Ttext=0 -o $@ $<
50
51%.arm-bin: %.arm-elf
52 $(CROSS_PREFIX)-objcopy -O binary $< $@
53
54../dualboot.c ../dualboot.h: $(BOOTBINS) bin2c
55 ./bin2c ../dualboot $(BOOTBINS)
56
57bin2c: bin2c.c
58 $(CC) -o bin2c bin2c.c
59
60clean:
61 rm -f *~ bin2c $(BOOTBINS) $(BOOTOBJS)
diff --git a/utils/mkamsboot/dualboot/bin2c.c b/utils/mkamsboot/dualboot/bin2c.c
new file mode 100644
index 0000000000..b02af88a4d
--- /dev/null
+++ b/utils/mkamsboot/dualboot/bin2c.c
@@ -0,0 +1,140 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdio.h>
23#include <string.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <unistd.h>
27#include <fcntl.h>
28#include <stdlib.h>
29#include <libgen.h>
30
31#ifndef O_BINARY
32#define O_BINARY 0
33#endif
34
35static off_t filesize(int fd)
36{
37 struct stat buf;
38
39 fstat(fd,&buf);
40 return buf.st_size;
41}
42
43static void write_cfile(const unsigned char* buf, off_t len, FILE* fp, const char *name)
44{
45 int i;
46
47 fprintf(fp,"unsigned char %s[%ld] = {",name,len);
48
49 for (i=0;i<len;i++) {
50 if ((i % 16) == 0) {
51 fprintf(fp,"\n ");
52 }
53 if (i == (len-1)) {
54 fprintf(fp,"0x%02x",buf[i]);
55 } else if ((i % 16) == 15) {
56 fprintf(fp,"0x%02x,",buf[i]);
57 } else {
58 fprintf(fp,"0x%02x, ",buf[i]);
59 }
60 }
61 fprintf(fp,"\n};\n");
62}
63
64int main (int argc, char* argv[])
65{
66 char* cname;
67 int i;
68 FILE *cfile, *hfile;
69 char cfilename[256], hfilename[256];
70
71 if (argc < 3) {
72 fprintf(stderr,"Usage: bin2c cname file1 [file2 [file3 ...]]\n");
73 return 1;
74 }
75
76 cname=argv[1];
77
78 snprintf(cfilename,256,"%s.c",cname);
79 cfile = fopen(cfilename,"w+");
80 if (cfile == NULL) {
81 fprintf(stderr,"Couldn't open %s\n",cfilename);
82 return 2;
83 }
84
85 snprintf(hfilename,256,"%s.h",cname);
86 hfile = fopen(hfilename,"w+");
87 if (hfile == NULL) {
88 fprintf(stderr,"Couldn't open %s\n",hfilename);
89 fclose(cfile);
90 return 3;
91 }
92
93 fprintf(cfile,"/* Generated by bin2c */\n\n");
94 fprintf(cfile,"#include \"%s\"\n\n", basename(hfilename));
95 fprintf(hfile,"/* Generated by bin2c */\n\n");
96
97 for(i=0; i < argc - 2; i++) {
98 unsigned char* buf;
99 off_t len;
100 off_t orig_len;
101 char *ext;
102 char *array = argv[2+i];
103
104 int fd = open(array,O_RDONLY|O_BINARY);
105 if (fd < 0) {
106 fprintf(stderr,"Can not open %s\n",argv[2+i]);
107 fclose(cfile);
108 fclose(hfile);
109 return 4;
110 }
111
112 orig_len = filesize(fd);
113 /* pad to 32bit */
114 len = (orig_len + 3) & ~3;
115
116 buf = malloc(len);
117 if (read(fd,buf,orig_len) < orig_len) {
118 fprintf(stderr,"Short read, aborting\n");
119 return 5;
120 }
121
122 /* pad to 32bit with zeros */
123 if (len > orig_len)
124 memset(buf+orig_len, 0, len-orig_len);
125
126 /* remove file extension */
127 ext = strchr (array, '.');
128 if (ext != NULL)
129 *ext = '\0';
130 write_cfile (buf, len, cfile, array);
131 fprintf(hfile,"extern unsigned char %s[%ld];\n",array,len);
132
133 close(fd);
134 }
135
136 fclose(cfile);
137 fclose(hfile);
138
139 return 0;
140}
diff --git a/utils/mkamsboot/dualboot/dualboot.S b/utils/mkamsboot/dualboot/dualboot.S
new file mode 100644
index 0000000000..4e4dbe5505
--- /dev/null
+++ b/utils/mkamsboot/dualboot/dualboot.S
@@ -0,0 +1,307 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 Rafaël Carré
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22.text
23
24/* AS3525 hardware registers */
25.set GPIOA, 0xC80B0000
26.set GPIOB, 0xC80C0000
27.set GPIOC, 0xC80D0000
28.set GPIOD, 0xC80E0000
29.set CGU_PROC, 0xC80F0010
30.set CGU_PERI, 0xC80F0014
31.set CGU_DBOP, 0xC80F0038
32.set CCU_IO, 0xC810000C
33.set DBOP, 0xC8120000
34.set I2C_BASE, 0xC8070000
35.set I2C_DATA, 0x00
36.set I2C_SLAD0, 0x04
37.set I2C_CNTRL, 0x0c
38.set I2C_DACNT, 0x10
39.set I2C_CPSR0, 0x1c
40.set I2C_CPSR1, 0x20
41.set I2C_IMR, 0x24
42.set I2C_SR, 0x30
43.set I2C_SADDR, 0x44
44.set AS3514_I2C_ADDR, 0x46
45.set AS3514_IRQ_ENRD0, 0x25
46.set PCLK, 24000000
47.set I2C_CLK, 400000
48.set I2C_PRESCALER, ((PCLK + I2C_CLK -1) / I2C_CLK)
49.set I2C_PRESCALER_LOW, (I2C_PRESCALER & 0xff)
50.set I2C_PRESCALER_HIGH, (I2C_PRESCALER >> 8)
51#if I2C_PRESCALER_HIGH > 3
52#error i2c prescaler too big!
53#endif
54
55 b start @ skip our data
56
57/* These values are filled in by mkamsboot - don't move them from offset 0x4 */
58
59uclunpack_end: .word 0 /* End of the ucl_unpack function */
60uclunpack_size: .word 0 /* Size in bytes of the ucl_unpack function */
61
62ucl_of_end: .word 0 /* End of the ucl-compressed OF image */
63ucl_of_size: .word 0 /* Size in bytes of the compressed OF image */
64
65ucl_rb_end: .word 0 /* End of the ucl-compressed RB image */
66ucl_rb_size: .word 0 /* Size in bytes of the compressed RB image */
67
68ucl_dest: .word 0 /* End of our destination buffer (end of memory) */
69
70start:
71 /* First copy the UCL unpack function to the end of RAM */
72 ldr r0, uclunpack_end /* Source */
73 ldr r1, uclunpack_size /* Source length */
74 sub r2, r0, r1 /* Source start - 1*/
75
76 ldr r3, ucl_dest /* Destination end */
77
78uclcopy:
79 ldrb r4, [r0], #-1
80 strb r4, [r3], #-1
81 cmp r2, r0
82 bne uclcopy
83
84 /* store the new destination buffer */
85 str r3, ucl_dest
86
87 /* enable gpio clock */
88 ldr r0, =CGU_PERI
89 ldr r1, [r0]
90 orr r1, r1, #(1<<16)
91 str r1, [r0]
92
93 /* Here are model specific tests for dual boot (test left button) */
94
95#ifdef SANSA_CLIP
96.set row, (1<<5) /* enable output on C5 */
97.set col, (1<<0) /* read keyscan column B0 */
98
99 ldr r0, =GPIOC
100 mov r1, #row
101 str r1, [r0, #0x400]
102 str r1, [r0, #(4*row)]
103
104 ldr r0, =GPIOB
105 mov r1, #0
106 str r1, [r0, #0x400]
107 ldr r1, [r0, #(4*col)]
108
109 cmp r1, #0
110 bne boot_of
111#elif defined(SANSA_CLIPV2)
112.set row, (1<<4) /* enable output on D4 */
113.set col, (1<<0) /* read keyscan column D0 */
114
115 ldr r0, =CCU_IO
116 ldr r1, [r0]
117 bic r1, r1, #(3<<2) @ XPD works as general purpose IO
118 str r1, [r0]
119
120 ldr r0, =GPIOD
121 mov r1, #((1<<5)|(1<<4)|(1<<3)) /* all rows as output */
122 str r1, [r0, #0x400]
123
124 /* all rows high */
125 mov r1, #(1<<3)
126 str r1, [r0, #(4*(1<<3))]
127 mov r1, #(1<<4)
128 str r1, [r0, #(4*(1<<4))]
129 mov r1, #(1<<5)
130 str r1, [r0, #(4*(1<<5))]
131
132 mov r1, #0 /* button row low */
133 str r1, [r0, #(4*row)]
134
135 mov r1, #5 /* small delay */
1361: subs r1, r1, #1
137 bne 1b
138
139 ldr r1, [r0, #(4*col)]
140
141 cmp r1, #0
142 beq boot_of
143#elif defined(SANSA_E200V2) || defined(SANSA_FUZE)
144 ldr r0, =GPIOC
145 mov r1, #0
146 str r1, [r0, #0x400]
147 ldr r1, [r0, #0x20] /* read pin C3 */
148
149 cmp r1, #0 /* C3 = #0 means button pressed */
150 beq boot_of
151
152#elif defined(SANSA_FUZEV2)
153 ldr r0, =GPIOC
154 mov r1, #0
155 str r1, [r0, #0x400]
156 ldr r1, [r0, #0x20] /* read pin C3 */
157
158 cmp r1, #0 /* C3 != #0 means button pressed */
159 bne boot_of
160
161#elif defined(SANSA_CLIPPLUS)
162 @ read pins
163 ldr r0, =GPIOC
164 ldr r1, [r0, #4*(1<<3)] @ read pin C3 "|<<"
165
166 ldr r0, =GPIOA
167 ldr r2, [r0, #4*(1<<1)] @ read pin A1 "Home"
168
169 orr r2, r2, r1 @ c3 || A1
170
171 cmp r2, #0 @ test input from pins
172 bne boot_of @ branch directly to OF if either pin high
173
174#elif defined(SANSA_CLIPZIP)
175 @ read pins
176 ldr r0, =GPIOA
177 ldr r1, [r0, #4*(1<<6)] @ read GPIO A6 "vol-"
178
179 cmp r1, #0 @ test input from pins
180 bne boot_of @ branch directly to OF if either pin high
181
182 ldr r0, =GPIOC
183
184 ldr r1, [r0, #0x400]
185 orr r1, r1, #((1<<1)|(1<<2)) @ output
186 bic r1, r1, #(1<<5) @ input
187 str r1, [r0, #0x400]
188
189 mov r1, #0
190 str r1, [r0, #4*(1<<1)] @ zero C1
191 mov r1, #(1<<2)
192 str r1, [r0, #4*(1<<2)] @ set C2
193
194 mov r1, #50 /* small delay */
1951: subs r1, r1, #1
196 bne 1b
197
198 ldr r1, [r0, #4*(1<<5)] @ read C5 = left
199
200 cmp r1, #0
201 bne boot_of
202
203#elif defined(SANSA_C200V2)
204.set BUTTON_LEFT, (1<< 2)
205.set BUTTON_DOWN, (1<< 3)
206.set BUTTON_SELECT, (1<< 4)
207.set BUTTON_UP, (1<< 5)
208.set BUTTON_RIGHT, (1<< 6)
209.set BUTTON_HOLD, (1<<12)
210
211 ldr r0, =CGU_DBOP
212 mov r1, #(1<<3) @ DBOP freq = PCLK, clock enabled
213 str r1, [r0]
214
215 @ AFSEL needs to be set for this to work
216 ldr r2, =GPIOB
217 mov r1, #0xc
218 str r1, [r2, #0x420] @ GPIOB_AFSEL
219 ldr r2, =GPIOC
220 mov r1, #0xff
221 str r1, [r2, #0x420] @ GPIOC_AFSEL
222
223 ldr r0, =DBOP
224 @ TIMPOL doesn't matter here since we don't need
225 @ the control signals.
226
227 @ 16 bit data width
228 @ enable write
229 @ tri-state output
230 ldr r1, =0x00091000
231 str r1, [r0, #8] @ DBOP_CTRL
232
233 ldr r1, =0xf0ff @ precharge
234 str r1, [r0, #0x10] @ DBOP_DOUT
235
2362: ldr r1, [r0, #0xc] @ DOBP_STAT
237 ands r1, r1, #(1<<10)
238 beq 2b @ make sure fifo is empty
239
240 @ 16 bit data width
241 @ start read
242 @ tri-state output
243 @ strobe time 31
244 ldr r1, =0x0008901f
245 str r1, [r0, #8] @ DBOP_CTRL
246
2473: ldr r1, [r0, #0xc] @ DOBP_STAT
248 ands r1, r1, #(1<<16)
249 beq 3b @ wait for valid data
250
251 ldrh r1, [r0, #0x14] @ DBOP_DIN
252
253 tst r1, #BUTTON_LEFT @ boot of?
254 beq boot_of
255#elif defined(SANSA_M200V4)
256.set row, (1<<5) /* enable output on A5 */
257.set col, (1<<0) /* read keyscan column A0 */
258
259 ldr r0, =GPIOA
260 mov r1, #row
261 str r1, [r0, #0x400]
262 str r1, [r0, #(4*row)]
263
264 ldr r2, [r0, #(4*col)]
265
266 /* check value read (1 means button pressed) */
267 cmp r2, #0
268 bne boot_of
269#else
270 #error No target-specific key check defined!
271#endif
272
273 /* The dualboot button was not held, so we boot rockbox */
274 ldr r0, ucl_rb_end /* Address of compressed image */
275 ldr r1, ucl_rb_size /* Compressed size */
276 b decompress
277
278boot_of:
279 ldr r0, ucl_of_end /* Address of compressed image */
280 ldr r1, ucl_of_size /* Compressed size */
281
282
283decompress:
284 /* At this point: */
285 /* r0 = source_end for UCL image to copy */
286 /* r1 = size of UCL image to copy */
287
288 ldr r3, ucl_dest
289 add r5, r3, #2 /* r5 is entry point of copy of uclunpack */
290 /* function, plus one (for thumb mode */
291
292 sub r4, r3, r1 /* r4 := destination_start - 1 */
293
294fw_copy:
295 ldrb r2, [r0], #-1
296 strb r2, [r3], #-1
297 cmp r3, r4 /* Stop when we reached dest_start-1 */
298 bne fw_copy
299
300 /* Call the ucl decompress function, which will branch to 0x0 */
301 /* on completion */
302 add r0, r3, #1 /* r0 := Start of compressed image */
303 /* r1 already contains compressed size */
304 mov r2, #0 /* r2 := Destination for unpacking */
305 bx r5 /* Branch to uclunpack, switching to thumb */
306
307 /* never reached : uclunpack will branch to the reset vector (0x0) */
diff --git a/utils/mkamsboot/dualboot/nrv2e_d8.S b/utils/mkamsboot/dualboot/nrv2e_d8.S
new file mode 100644
index 0000000000..d24fb94b2a
--- /dev/null
+++ b/utils/mkamsboot/dualboot/nrv2e_d8.S
@@ -0,0 +1,198 @@
1/* arm_nrv2e_d8.S -- ARM decompressor for NRV2E
2
3 This file is part of the UPX executable compressor.
4
5 Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer
6 Copyright (C) 1996-2008 Laszlo Molnar
7 Copyright (C) 2000-2008 John F. Reiser
8 All Rights Reserved.
9
10 UPX and the UCL library are free software; you can redistribute them
11 and/or modify them under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2 of
13 the License, or (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; see the file COPYING.
22 If not, write to the Free Software Foundation, Inc.,
23 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25 Markus F.X.J. Oberhumer Laszlo Molnar
26 <markus@oberhumer.com> <ml1050@users.sourceforge.net>
27
28 John F. Reiser
29 <jreiser@users.sourceforge.net>
30*/
31#define SAFE 0 /* 1 for src+dst bounds checking: cost 40 bytes */
32
33#define src r0
34#define len r1 /* overlaps 'cnt' */
35#define dst r2
36#define tmp r3
37#define bits r4
38#define off r5
39#define wrnk r6 /* 0x500 M2_MAX_OFFSET before "wrinkle" */
40#define srclim r7
41#if 1==SAFE /*{*/
42#define dstlim r12
43#endif /*}*/
44
45#define cnt r1 /* overlaps 'len' while reading an offset */
46
47#if 1==SAFE /*{*/
48#define CHECK_SRC cmp src,srclim; bhs bad_src_n2e
49#define CHECK_DST cmp dst,dstlim; bhs bad_dst_n2e
50#else /*}{*/
51#define CHECK_SRC /*empty*/
52#define CHECK_DST /*empty*/
53#endif /*}*/
54
55#if 0 /*{ DEBUG only: check newly-decompressed against original dst */
56#define CHECK_BYTE \
57 push {wrnk}; \
58 ldrb wrnk,[dst]; \
59 cmp wrnk,tmp; beq 0f; bkpt; \
600: pop {wrnk}
61#else /*}{*/
62#define CHECK_BYTE /*empty*/
63#endif /*}*/
64
65/* "mov lr,pc; bxx ..." implements conditional subroutine call
66 *
67 * NOTE: the lsb will not be set, so you MUST NOT use 'bx lr' to return,
68 * else the T bit will be cleared and processor will go in ARM state */
69#define GETBIT add bits,bits; mov lr,pc; beq get1_n2e
70
71#define getnextb(reg) GETBIT; adc reg,reg
72#define jnextb0 GETBIT; bcc
73#define jnextb1 GETBIT; bcs
74
75#ifndef PURE_THUMB
76ucl_nrv2e_decompress_8: .globl ucl_nrv2e_decompress_8 @ ARM mode
77 .type ucl_nrv2e_decompress_8, %function
78/* error = (*)(char const *src, int len_src, char *dst, int *plen_dst)
79 Actual decompressed length is stored through plen_dst.
80 For SAFE mode: at call, *plen_dst must be allowed length of output buffer.
81*/
82 adr r12,1+.thumb_nrv2e_d8; bx r12 @ enter THUMB mode
83#endif
84 .code 16 @ THUMB mode
85 .thumb_func
86
87.thumb_nrv2e_d8:
88#if 0
89 push {r2,r3, r4,r5,r6,r7, lr}
90#define sp_DST0 0 /* stack offset of original dst */
91#endif
92 add srclim,len,src @ srclim= eof_src;
93#if 1==SAFE /*{*/
94 ldr tmp,[r3] @ len_dst
95 add tmp,dst
96 mov dstlim,tmp
97#endif /*}*/
98 mov bits,#1; neg off,bits @ off= -1 initial condition
99 lsl bits,#31 @ 1<<31: refill next time
100 mov wrnk,#5
101 lsl wrnk,#8 @ 0x500 @ nrv2e M2_MAX_OFFSET
102 b top_n2e
103
104#if 1==SAFE /*{*/
105bad_dst_n2e: # return value will be 2
106 add src,srclim,#1
107bad_src_n2e: # return value will be 1
108 add src,#1
109#endif /*}*/
110eof_n2e:
111#if 0
112 pop {r3,r4} @ r3= orig_dst; r4= plen_dst
113 sub src,srclim @ 0 if actual src length equals expected length
114 sub dst,r3 @ actual dst length
115 str dst,[r4]
116 pop {r4,r5,r6,r7 /*,pc*/}
117 pop {r1}; bx r1 @ "pop {,pc}" fails return to ARM mode on ARMv4T
118#else
119 mov r0, #0
120 bx r0 /* Branch to 0x0, switch to ARM mode */
121#endif
122
123get1_n2e: @ In: Carry set [from adding 0x80000000 (1<<31) to itself]
124 ldrb bits,[src] @ zero-extend next byte
125 adc bits,bits @ double and insert CarryIn as low bit
126 CHECK_SRC
127 add src,#1
128 lsl bits,#24 @ move to top byte, and set CarryOut from old bit 8
129 /* NOTE: the following instruction will not work on ARMv7+, because
130 * it will update the T bit and return into ARM state */
131 mov pc,lr @ return, stay in current (THUMB) mode
132
133lit_n2e:
134 CHECK_SRC; ldrb tmp,[src]; add src,#1
135 CHECK_BYTE
136 CHECK_DST; strb tmp,[dst]; add dst,#1
137top_n2e:
138 jnextb1 lit_n2e
139 mov cnt,#1; b getoff_n2e
140
141off_n2e:
142 sub cnt,#1
143 getnextb(cnt)
144getoff_n2e:
145 getnextb(cnt)
146 jnextb0 off_n2e
147
148 sub tmp,cnt,#3 @ set Carry
149 mov len,#0 @ Carry unaffected
150 blo offprev_n2e @ cnt was 2; tests Carry only
151 lsl tmp,#8
152 CHECK_SRC; ldrb off,[src]; add src,#1 @ low 7+1 bits
153 orr off,tmp
154 mvn off,off; beq eof_n2e @ off= ~off
155 asr off,#1; bcs lenlast_n2e
156 b lenmore_n2e
157
158offprev_n2e:
159 jnextb1 lenlast_n2e
160lenmore_n2e:
161 mov len,#1
162 jnextb1 lenlast_n2e
163len_n2e:
164 getnextb(len)
165 jnextb0 len_n2e
166 add len,#6-2
167 b gotlen_n2e
168
169lenlast_n2e:
170 getnextb(len) @ 0,1,2,3
171 add len,#2
172gotlen_n2e: @ 'cmn': add the inputs, set condition codes, discard the sum
173 cmn wrnk,off; bcs near_n2e @ within M2_MAX_OFFSET
174 add len,#1 @ too far away, so minimum match length is 3
175near_n2e:
176#if 1==SAFE /*{*/
177 ldr tmp,[sp,#sp_DST0]
178 sub tmp,dst
179 sub tmp,off; bhi bad_dst_n2e @ reaching back too far
180
181 add tmp,dst,cnt
182 cmp tmp,dstlim; bhi bad_dst_n2e @ too much output
183#endif /*}*/
184 ldrb tmp,[dst] @ force cacheline allocate
185copy_n2e:
186 ldrb tmp,[dst,off]
187 CHECK_BYTE
188 strb tmp,[dst]; add dst,#1
189 sub len,#1; bne copy_n2e
190 b top_n2e
191
192#ifndef PURE_THUMB
193 .size ucl_nrv2e_decompress_8, .-ucl_nrv2e_decompress_8
194#endif
195
196/*
197vi:ts=8:et:nowrap
198 */
diff --git a/utils/mkamsboot/main.c b/utils/mkamsboot/main.c
new file mode 100644
index 0000000000..cf40811ace
--- /dev/null
+++ b/utils/mkamsboot/main.c
@@ -0,0 +1,174 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * mkamsboot - a tool for merging bootloader code into an Sansa V2
11 * (AMS) firmware file
12 *
13 * Copyright (C) 2008 Dave Chapman
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <stdint.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <fcntl.h>
31#include <unistd.h>
32#include <string.h>
33
34#include <ucl/ucl.h>
35
36#include "mkamsboot.h"
37
38/* Header for ARM code binaries */
39#include "dualboot.h"
40
41/* Win32 compatibility */
42#ifndef O_BINARY
43#define O_BINARY 0
44#endif
45
46/* standalone executable */
47int main(int argc, char* argv[])
48{
49 char *infile, *bootfile, *outfile;
50 int fdout;
51 off_t len;
52 uint32_t n;
53 unsigned char* buf;
54 int firmware_size;
55 int bootloader_size;
56 unsigned char* of_packed;
57 int of_packedsize;
58 unsigned char* rb_packed;
59 int rb_packedsize;
60 int patchable;
61 int totalsize;
62 int model;
63 char errstr[200];
64 struct md5sums sum;
65 char md5sum[33]; /* 32 digits + \0 */
66
67 sum.md5 = md5sum;
68
69/* VERSION comes frome the Makefile */
70 fprintf(stderr,
71"mkamsboot Version " VERSION "\n"
72"This is free software; see the source for copying conditions. There is NO\n"
73"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
74"\n");
75
76 if(argc != 4) {
77 printf("Usage: mkamsboot <firmware file> <boot file> <output file>\n");
78 return 1;
79 }
80
81 infile = argv[1];
82 bootfile = argv[2];
83 outfile = argv[3];
84
85 /* Load bootloader file */
86 rb_packed = load_rockbox_file(bootfile, &model, &bootloader_size,
87 &rb_packedsize, errstr, sizeof(errstr));
88 if (rb_packed == NULL) {
89 fprintf(stderr, "%s", errstr);
90 fprintf(stderr, "[ERR] Could not load %s\n", bootfile);
91 return 1;
92 }
93
94 /* Load original firmware file */
95 buf = load_of_file(infile, model, &len, &sum,
96 &firmware_size, &of_packed, &of_packedsize, errstr, sizeof(errstr));
97
98 if (buf == NULL) {
99 free(rb_packed);
100 fprintf(stderr, "%s", errstr);
101 fprintf(stderr, "[ERR] Could not load %s\n", infile);
102 return 1;
103 }
104
105 fprintf(stderr, "[INFO] Original firmware MD5 checksum match\n");
106 fprintf(stderr, "[INFO] Model: Sansa %s v%d - Firmware version: %s\n",
107 ams_identity[sum.model].model_name,
108 ams_identity[sum.model].hw_revision, sum.version);
109
110
111 printf("[INFO] Firmware patching has begun !\n\n");
112
113 fprintf(stderr, "[INFO] Original firmware size: %8d bytes\n",
114 firmware_size);
115 fprintf(stderr, "[INFO] Packed OF size: %8d bytes\n",
116 of_packedsize);
117 fprintf(stderr, "[INFO] Bootloader size: %8d bytes\n",
118 bootloader_size);
119 fprintf(stderr, "[INFO] Packed bootloader size: %8d bytes\n",
120 rb_packedsize);
121 fprintf(stderr, "[INFO] Dual-boot function size: %8d bytes\n",
122 ams_identity[sum.model].bootloader_size);
123 fprintf(stderr, "[INFO] UCL unpack function size: %8zu bytes\n",
124 sizeof(nrv2e_d8));
125 fprintf(stderr, "[INFO] Original firmware version: %8u bytes\n",
126 0x200);
127
128 patchable = check_sizes(sum.model, rb_packedsize, bootloader_size,
129 of_packedsize, firmware_size, &totalsize, errstr, sizeof(errstr));
130
131 fprintf(stderr, "[INFO] Total size of new image: %8d bytes\n", totalsize);
132
133 if (!patchable) {
134 fprintf(stderr, "%s", errstr);
135 free(buf);
136 free(of_packed);
137 free(rb_packed);
138 return 1;
139 }
140
141 patch_firmware(sum.model, ams_identity[sum.model].fw_revision,
142 firmware_size, buf, len, of_packed, of_packedsize, rb_packed,
143 rb_packedsize);
144
145 /* Write the new firmware */
146 fdout = open(outfile, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0666);
147
148 if (fdout < 0) {
149 fprintf(stderr, "[ERR] Could not open %s for writing\n", outfile);
150 free(buf);
151 free(of_packed);
152 free(rb_packed);
153 return 1;
154 }
155
156 n = write(fdout, buf, len);
157
158 if (n != (unsigned)len) {
159 fprintf(stderr, "[ERR] Could not write firmware file\n");
160 free(buf);
161 free(of_packed);
162 free(rb_packed);
163 return 1;
164 }
165
166 close(fdout);
167 free(buf);
168 free(of_packed);
169 free(rb_packed);
170 fprintf(stderr, "\n[INFO] Patching succeeded!\n");
171
172 return 0;
173}
174
diff --git a/utils/mkamsboot/md5.c b/utils/mkamsboot/md5.c
new file mode 100644
index 0000000000..530d8df15a
--- /dev/null
+++ b/utils/mkamsboot/md5.c
@@ -0,0 +1,246 @@
1/*
2 * RFC 1321 compliant MD5 implementation
3 *
4 * Copyright (C) 2001-2003 Christophe Devine
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <string.h>
22
23#include "md5.h"
24
25#define GET_UINT32(n,b,i) \
26{ \
27 (n) = ( (uint32) (b)[(i) ] ) \
28 | ( (uint32) (b)[(i) + 1] << 8 ) \
29 | ( (uint32) (b)[(i) + 2] << 16 ) \
30 | ( (uint32) (b)[(i) + 3] << 24 ); \
31}
32
33#define PUT_UINT32(n,b,i) \
34{ \
35 (b)[(i) ] = (uint8) ( (n) ); \
36 (b)[(i) + 1] = (uint8) ( (n) >> 8 ); \
37 (b)[(i) + 2] = (uint8) ( (n) >> 16 ); \
38 (b)[(i) + 3] = (uint8) ( (n) >> 24 ); \
39}
40
41void md5_starts( md5_context *ctx )
42{
43 ctx->total[0] = 0;
44 ctx->total[1] = 0;
45
46 ctx->state[0] = 0x67452301;
47 ctx->state[1] = 0xEFCDAB89;
48 ctx->state[2] = 0x98BADCFE;
49 ctx->state[3] = 0x10325476;
50}
51
52void md5_process( md5_context *ctx, uint8 data[64] )
53{
54 uint32 X[16], A, B, C, D;
55
56 GET_UINT32( X[0], data, 0 );
57 GET_UINT32( X[1], data, 4 );
58 GET_UINT32( X[2], data, 8 );
59 GET_UINT32( X[3], data, 12 );
60 GET_UINT32( X[4], data, 16 );
61 GET_UINT32( X[5], data, 20 );
62 GET_UINT32( X[6], data, 24 );
63 GET_UINT32( X[7], data, 28 );
64 GET_UINT32( X[8], data, 32 );
65 GET_UINT32( X[9], data, 36 );
66 GET_UINT32( X[10], data, 40 );
67 GET_UINT32( X[11], data, 44 );
68 GET_UINT32( X[12], data, 48 );
69 GET_UINT32( X[13], data, 52 );
70 GET_UINT32( X[14], data, 56 );
71 GET_UINT32( X[15], data, 60 );
72
73#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
74
75#define P(a,b,c,d,k,s,t) \
76{ \
77 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
78}
79
80 A = ctx->state[0];
81 B = ctx->state[1];
82 C = ctx->state[2];
83 D = ctx->state[3];
84
85#define F(x,y,z) (z ^ (x & (y ^ z)))
86
87 P( A, B, C, D, 0, 7, 0xD76AA478 );
88 P( D, A, B, C, 1, 12, 0xE8C7B756 );
89 P( C, D, A, B, 2, 17, 0x242070DB );
90 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
91 P( A, B, C, D, 4, 7, 0xF57C0FAF );
92 P( D, A, B, C, 5, 12, 0x4787C62A );
93 P( C, D, A, B, 6, 17, 0xA8304613 );
94 P( B, C, D, A, 7, 22, 0xFD469501 );
95 P( A, B, C, D, 8, 7, 0x698098D8 );
96 P( D, A, B, C, 9, 12, 0x8B44F7AF );
97 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
98 P( B, C, D, A, 11, 22, 0x895CD7BE );
99 P( A, B, C, D, 12, 7, 0x6B901122 );
100 P( D, A, B, C, 13, 12, 0xFD987193 );
101 P( C, D, A, B, 14, 17, 0xA679438E );
102 P( B, C, D, A, 15, 22, 0x49B40821 );
103
104#undef F
105
106#define F(x,y,z) (y ^ (z & (x ^ y)))
107
108 P( A, B, C, D, 1, 5, 0xF61E2562 );
109 P( D, A, B, C, 6, 9, 0xC040B340 );
110 P( C, D, A, B, 11, 14, 0x265E5A51 );
111 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
112 P( A, B, C, D, 5, 5, 0xD62F105D );
113 P( D, A, B, C, 10, 9, 0x02441453 );
114 P( C, D, A, B, 15, 14, 0xD8A1E681 );
115 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
116 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
117 P( D, A, B, C, 14, 9, 0xC33707D6 );
118 P( C, D, A, B, 3, 14, 0xF4D50D87 );
119 P( B, C, D, A, 8, 20, 0x455A14ED );
120 P( A, B, C, D, 13, 5, 0xA9E3E905 );
121 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
122 P( C, D, A, B, 7, 14, 0x676F02D9 );
123 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
124
125#undef F
126
127#define F(x,y,z) (x ^ y ^ z)
128
129 P( A, B, C, D, 5, 4, 0xFFFA3942 );
130 P( D, A, B, C, 8, 11, 0x8771F681 );
131 P( C, D, A, B, 11, 16, 0x6D9D6122 );
132 P( B, C, D, A, 14, 23, 0xFDE5380C );
133 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
134 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
135 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
136 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
137 P( A, B, C, D, 13, 4, 0x289B7EC6 );
138 P( D, A, B, C, 0, 11, 0xEAA127FA );
139 P( C, D, A, B, 3, 16, 0xD4EF3085 );
140 P( B, C, D, A, 6, 23, 0x04881D05 );
141 P( A, B, C, D, 9, 4, 0xD9D4D039 );
142 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
143 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
144 P( B, C, D, A, 2, 23, 0xC4AC5665 );
145
146#undef F
147
148#define F(x,y,z) (y ^ (x | ~z))
149
150 P( A, B, C, D, 0, 6, 0xF4292244 );
151 P( D, A, B, C, 7, 10, 0x432AFF97 );
152 P( C, D, A, B, 14, 15, 0xAB9423A7 );
153 P( B, C, D, A, 5, 21, 0xFC93A039 );
154 P( A, B, C, D, 12, 6, 0x655B59C3 );
155 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
156 P( C, D, A, B, 10, 15, 0xFFEFF47D );
157 P( B, C, D, A, 1, 21, 0x85845DD1 );
158 P( A, B, C, D, 8, 6, 0x6FA87E4F );
159 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
160 P( C, D, A, B, 6, 15, 0xA3014314 );
161 P( B, C, D, A, 13, 21, 0x4E0811A1 );
162 P( A, B, C, D, 4, 6, 0xF7537E82 );
163 P( D, A, B, C, 11, 10, 0xBD3AF235 );
164 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
165 P( B, C, D, A, 9, 21, 0xEB86D391 );
166
167#undef F
168
169 ctx->state[0] += A;
170 ctx->state[1] += B;
171 ctx->state[2] += C;
172 ctx->state[3] += D;
173}
174
175void md5_update( md5_context *ctx, uint8 *input, uint32 length )
176{
177 uint32 left, fill;
178
179 if( ! length ) return;
180
181 left = ctx->total[0] & 0x3F;
182 fill = 64 - left;
183
184 ctx->total[0] += length;
185 ctx->total[0] &= 0xFFFFFFFF;
186
187 if( ctx->total[0] < length )
188 ctx->total[1]++;
189
190 if( left && length >= fill )
191 {
192 memcpy( (void *) (ctx->buffer + left),
193 (void *) input, fill );
194 md5_process( ctx, ctx->buffer );
195 length -= fill;
196 input += fill;
197 left = 0;
198 }
199
200 while( length >= 64 )
201 {
202 md5_process( ctx, input );
203 length -= 64;
204 input += 64;
205 }
206
207 if( length )
208 {
209 memcpy( (void *) (ctx->buffer + left),
210 (void *) input, length );
211 }
212}
213
214static uint8 md5_padding[64] =
215{
216 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
217 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
218 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
219 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
220};
221
222void md5_finish( md5_context *ctx, uint8 digest[16] )
223{
224 uint32 last, padn;
225 uint32 high, low;
226 uint8 msglen[8];
227
228 high = ( ctx->total[0] >> 29 )
229 | ( ctx->total[1] << 3 );
230 low = ( ctx->total[0] << 3 );
231
232 PUT_UINT32( low, msglen, 0 );
233 PUT_UINT32( high, msglen, 4 );
234
235 last = ctx->total[0] & 0x3F;
236 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
237
238 md5_update( ctx, md5_padding, padn );
239 md5_update( ctx, msglen, 8 );
240
241 PUT_UINT32( ctx->state[0], digest, 0 );
242 PUT_UINT32( ctx->state[1], digest, 4 );
243 PUT_UINT32( ctx->state[2], digest, 8 );
244 PUT_UINT32( ctx->state[3], digest, 12 );
245}
246
diff --git a/utils/mkamsboot/md5.h b/utils/mkamsboot/md5.h
new file mode 100644
index 0000000000..71fa395548
--- /dev/null
+++ b/utils/mkamsboot/md5.h
@@ -0,0 +1,25 @@
1#ifndef _MD5_H
2#define _MD5_H
3
4#ifndef uint8
5#define uint8 unsigned char
6#endif
7
8#ifndef uint32
9#define uint32 unsigned long int
10#endif
11
12typedef struct
13{
14 uint32 total[2];
15 uint32 state[4];
16 uint8 buffer[64];
17}
18md5_context;
19
20void md5_starts( md5_context *ctx );
21void md5_update( md5_context *ctx, uint8 *input, uint32 length );
22void md5_finish( md5_context *ctx, uint8 digest[16] );
23
24#endif /* md5.h */
25
diff --git a/utils/mkamsboot/mkamsboot.c b/utils/mkamsboot/mkamsboot.c
new file mode 100644
index 0000000000..09eb15ee43
--- /dev/null
+++ b/utils/mkamsboot/mkamsboot.c
@@ -0,0 +1,595 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * mkamsboot.c - a tool for merging bootloader code into an Sansa V2
11 * (AMS) firmware file
12 *
13 * Copyright (C) 2008 Dave Chapman
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25/*
26
27Insert a Rockbox bootloader into a Sansa AMS original firmware file.
28
29Layout of a Sansa AMS original firmware file:
30
31 ---------------------- 0x0
32| HEADER |
33|----------------------| 0x400
34| FIRMWARE BLOCK | (contains the OF version on some fuzev2 firmwares
35|----------------------| 0x600
36| FIRMWARE BLOCK |
37|----------------------| 0x400 + firmware block size
38| LIBRARIES/DATA |
39 ---------------------- END
40
41We replace the main firmware block while preserving the potential OF version
42(bytes 0x600..0x400+firmware_size) as follows:
43
44
45 ---------------------- 0x0
46| |
47| Dual-boot code |
48| |
49|----------------------|
50| EMPTY SPACE |
51|----------------------|
52| |
53| compressed RB image |
54| |
55|----------------------|
56| |
57| compressed OF image |
58| |
59|----------------------|
60| UCL unpack function |
61 ----------------------
62
63This entire block fits into the space previously occupied by the main
64firmware block - the space saved by compressing the OF image is used
65to store the compressed version of the Rockbox bootloader.
66
67On version 1 firmwares, the OF image is typically about 120KB, which allows
68us to store a Rockbox bootloader with an uncompressed size of about 60KB-70KB.
69Version 2 firmwares are bigger and are stored in SDRAM (instead of IRAM).
70In both cases, the RAM we are using is mapped at offset 0x0.
71
72mkamsboot then corrects the checksums and writes a new legal firmware
73file which can be installed on the device.
74
75When the Sansa device boots, this firmware block is loaded to RAM at
76address 0x0 and executed.
77
78Firstly, the dual-boot code will copy the UCL unpack function to the
79end of RAM.
80
81Then, depending on the detection of the dual-boot keypress, either the
82OF image or the Rockbox image is copied to the end of RAM (just before
83the ucl unpack function) and uncompressed to the start of RAM.
84
85Finally, the ucl unpack function branches to address 0x0, passing
86execution to the uncompressed firmware.
87
88
89*/
90
91#include <stdio.h>
92#include <stdlib.h>
93#include <stdint.h>
94#include <sys/types.h>
95#include <sys/stat.h>
96#include <fcntl.h>
97#include <unistd.h>
98#include <string.h>
99
100#include <ucl/ucl.h>
101
102#include "mkamsboot.h"
103
104#include "md5.h"
105
106/* Header for ARM code binaries */
107#include "dualboot.h"
108
109/* Win32 compatibility */
110#ifndef O_BINARY
111#define O_BINARY 0
112#endif
113
114/* fw_revision: version 2 is used in Clipv2, Clip+ and Fuzev2 firmwares */
115/* hw_revision: 4 for m200, 2 for e200/c200, 1 or 2 for fuze/clip, 1 for clip+ */
116const struct ams_models ams_identity[] = {
117 [MODEL_C200V2] = { 2, 1, "c200", dualboot_c200v2, sizeof(dualboot_c200v2), "c2v2", 44 },
118 [MODEL_CLIPPLUS]= { 1, 2, "Clip+", dualboot_clipplus, sizeof(dualboot_clipplus), "cli+", 66 },
119 [MODEL_CLIPV2] = { 2, 2, "Clip", dualboot_clipv2, sizeof(dualboot_clipv2), "clv2", 60 },
120 [MODEL_CLIP] = { 1, 1, "Clip", dualboot_clip, sizeof(dualboot_clip), "clip", 40 },
121 [MODEL_E200V2] = { 2, 1, "e200", dualboot_e200v2, sizeof(dualboot_e200v2), "e2v2", 41 },
122 [MODEL_FUZEV2] = { 2, 2, "Fuze", dualboot_fuzev2, sizeof(dualboot_fuzev2), "fuz2", 68 },
123 [MODEL_FUZE] = { 1, 1, "Fuze", dualboot_fuze, sizeof(dualboot_fuze), "fuze", 43 },
124 [MODEL_M200V4] = { 4, 1, "m200", dualboot_m200v4, sizeof(dualboot_m200v4), "m2v4", 42 },
125 [MODEL_CLIPZIP] = { 1, 2, "ClipZip", dualboot_clipzip, sizeof(dualboot_clipzip), "clzp", 79 },
126};
127
128
129/* Checksums of unmodified original firmwares - for safety, and device
130 detection */
131static struct md5sums sansasums[] = {
132 /* NOTE: Different regional versions of the firmware normally only
133 differ in the filename - the md5sums are identical */
134
135 /* model version md5 */
136 { MODEL_E200V2, "3.01.11", "e622ca8cb6df423f54b8b39628a1f0a3" },
137 { MODEL_E200V2, "3.01.14", "2c1d0383fc3584b2cc83ba8cc2243af6" },
138 { MODEL_E200V2, "3.01.16", "12563ad71b25a1034cf2092d1e0218c4" },
139
140 { MODEL_FUZE, "1.01.11", "cac8ffa03c599330ac02c4d41de66166" },
141 { MODEL_FUZE, "1.01.15", "df0e2c1612727f722c19a3c764cff7f2" },
142 { MODEL_FUZE, "1.01.22", "5aff5486fe8dd64239cc71eac470af98" },
143 { MODEL_FUZE, "1.02.26", "7c632c479461c48c8833baed74eb5e4f" },
144 { MODEL_FUZE, "1.02.28", "5b34260f6470e75f702a9c6825471752" },
145 { MODEL_FUZE, "1.02.31", "66d01b37462a5ef7ccc6ad37188b4235" },
146
147 { MODEL_C200V2, "3.02.05", "b6378ebd720b0ade3fad4dc7ab61c1a5" },
148
149 { MODEL_M200V4, "4.00.45", "82e3194310d1514e3bbcd06e84c4add3" },
150 { MODEL_M200V4, "4.01.08-A", "fc9dd6116001b3e6a150b898f1b091f0" },
151 { MODEL_M200V4, "4.01.08-E", "d3fb7d8ec8624ee65bc99f8dab0e2369" },
152
153 { MODEL_CLIP, "1.01.17", "12caad785d506219d73f538772afd99e" },
154 { MODEL_CLIP, "1.01.18", "d720b266bd5afa38a198986ef0508a45" },
155 { MODEL_CLIP, "1.01.20", "236d8f75189f468462c03f6d292cf2ac" },
156 { MODEL_CLIP, "1.01.29", "c12711342169c66e209540cd1f27cd26" },
157 { MODEL_CLIP, "1.01.30", "f2974d47c536549c9d8259170f1dbe4d" },
158 { MODEL_CLIP, "1.01.32", "d835d12342500732ffb9c4ee54abec15" },
159 { MODEL_CLIP, "1.01.35", "b4d0edb3b8f2a4e8eee0a344f7f8e480" },
160
161 { MODEL_CLIPV2, "2.01.16", "c57fb3fcbe07c2c9b360f060938f80cb" },
162 { MODEL_CLIPV2, "2.01.32", "0ad3723e52022509089d938d0fbbf8c5" },
163 { MODEL_CLIPV2, "2.01.35", "a3cbbd22b9508d7f8a9a1a39acc342c2" },
164
165 { MODEL_CLIPPLUS, "01.02.09", "656d38114774c2001dc18e6726df3c5d" },
166 { MODEL_CLIPPLUS, "01.02.13", "5f89872b79ef440b0e5ee3a7a44328b2" },
167 { MODEL_CLIPPLUS, "01.02.15", "680a4f521e790ad25b93b1b16f3a207d" },
168 { MODEL_CLIPPLUS, "01.02.16", "055a53de1dfb09f6cb71c504ad48bd13" },
169 { MODEL_CLIPPLUS, "01.02.18", "80b547244438b113e2a55ff0305f12c0" },
170
171 { MODEL_FUZEV2, "2.01.17", "8b85fb05bf645d08a4c8c3e344ec9ebe" },
172 { MODEL_FUZEV2, "2.02.26", "d4f6f85c3e4a8ea8f2e5acc421641801" },
173 { MODEL_FUZEV2, "2.03.31", "74fb197ccd51707388f3b233402186a6" },
174 { MODEL_FUZEV2, "2.03.33", "1599cc73d02ea7fe53fe2d4379c24b66" },
175
176 { MODEL_CLIPZIP, "1.01.12", "45adea0873326b5af34f096e5c402f78" },
177 { MODEL_CLIPZIP, "1.01.15", "f62af954334cd9ba1a87a7fa58ec6074" },
178 { MODEL_CLIPZIP, "1.01.17", "27bcb343d6950f35dc261629e22ba60c" },
179 { MODEL_CLIPZIP, "1.01.18", "ef16aa9e02b49885ebede5aa149502e8" },
180 { MODEL_CLIPZIP, "1.01.20", "d88c8977cc6a952d3f51ece105869d97" },
181 { MODEL_CLIPZIP, "1.01.21", "92c814d6e3250189706a36d2b49b6152" },
182};
183
184#define NUM_MD5S (sizeof(sansasums)/sizeof(sansasums[0]))
185
186static unsigned int model_memory_size(int model)
187{
188 /* The OF boots with IRAM (320kB) mapped at 0x0 */
189
190 if(model == MODEL_CLIPV2)
191 {
192 /* The decompressed Clipv2 OF is around 380kB.
193 * Let's use the full IRAM (1MB on AMSv2)
194 */
195 return 1 << 20;
196 }
197 else
198 {
199 /* The IRAM is 320kB on AMSv1, and 320 will be enough on Fuzev1/Clip+ */
200 return 320 << 10;
201 }
202}
203
204int firmware_revision(int model)
205{
206 return ams_identity[model].fw_revision;
207}
208
209static off_t filesize(int fd)
210{
211 struct stat buf;
212
213 if (fstat(fd, &buf) < 0) {
214 perror("[ERR] Checking filesize of input file");
215 return -1;
216 } else {
217 return(buf.st_size);
218 }
219}
220
221static uint32_t get_uint32le(unsigned char* p)
222{
223 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
224}
225
226static uint32_t get_uint32be(unsigned char* p)
227{
228 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
229}
230
231static void put_uint32le(unsigned char* p, uint32_t x)
232{
233 p[0] = x & 0xff;
234 p[1] = (x >> 8) & 0xff;
235 p[2] = (x >> 16) & 0xff;
236 p[3] = (x >> 24) & 0xff;
237}
238
239void calc_MD5(unsigned char* buf, int len, char *md5str)
240{
241 int i;
242 md5_context ctx;
243 unsigned char md5sum[16];
244
245 md5_starts(&ctx);
246 md5_update(&ctx, buf, len);
247 md5_finish(&ctx, md5sum);
248
249 for (i = 0; i < 16; ++i)
250 sprintf(md5str + 2*i, "%02x", md5sum[i]);
251}
252
253/* Calculate a simple checksum used in Sansa Original Firmwares */
254static uint32_t calc_checksum(unsigned char* buf, uint32_t n)
255{
256 uint32_t sum = 0;
257 uint32_t i;
258
259 for (i=0;i<n;i+=4)
260 sum += get_uint32le(buf + i);
261
262 return sum;
263}
264
265/* Compress using nrv2e algorithm : Thumb decompressor fits in 168 bytes ! */
266static unsigned char* uclpack(unsigned char* inbuf, int insize, int* outsize)
267{
268 int maxsize;
269 unsigned char* outbuf;
270 int r;
271
272 /* The following formula comes from the UCL documentation */
273 maxsize = insize + (insize / 8) + 256;
274
275 /* Allocate some memory for the output buffer */
276 outbuf = malloc(maxsize);
277
278 if (outbuf == NULL)
279 return NULL;
280
281 r = ucl_nrv2e_99_compress(
282 (const ucl_bytep) inbuf,
283 (ucl_uint) insize,
284 (ucl_bytep) outbuf,
285 (ucl_uintp) outsize,
286 0, 10, NULL, NULL);
287
288 if (r != UCL_E_OK || *outsize > maxsize) {
289 /* this should NEVER happen, and implies memory corruption */
290 fprintf(stderr, "internal error - compression failed: %d\n", r);
291 free(outbuf);
292 return NULL;
293 }
294
295 return outbuf;
296}
297
298#define ERROR(format, ...) \
299 do { \
300 snprintf(errstr, errstrsize, format, __VA_ARGS__); \
301 goto error; \
302 } while(0)
303
304/* Loads a Sansa AMS Original Firmware file into memory */
305unsigned char* load_of_file(
306 char* filename, int model, off_t* bufsize, struct md5sums *sum,
307 int* firmware_size, unsigned char** of_packed,
308 int* of_packedsize, char* errstr, int errstrsize)
309{
310 int fd;
311 unsigned char* buf =NULL;
312 off_t n;
313 unsigned int i=0;
314 uint32_t checksum;
315 unsigned int last_word;
316
317 fd = open(filename, O_RDONLY|O_BINARY);
318 if (fd < 0)
319 ERROR("[ERR] Could not open %s for reading\n", filename);
320
321 *bufsize = filesize(fd);
322
323 buf = malloc(*bufsize);
324 if (buf == NULL)
325 ERROR("[ERR] Could not allocate memory for %s\n", filename);
326
327 n = read(fd, buf, *bufsize);
328
329 if (n != *bufsize)
330 ERROR("[ERR] Could not read file %s\n", filename);
331
332 /* check the file */
333
334 /* Calculate MD5 checksum of OF */
335 calc_MD5(buf, *bufsize, sum->md5);
336
337 while ((i < NUM_MD5S) && (strcmp(sansasums[i].md5, sum->md5) != 0))
338 i++;
339
340 if (i < NUM_MD5S) {
341 *sum = sansasums[i];
342 if(sum->model != model) {
343 ERROR("[ERR] OF File provided is %sv%d version %s, not for %sv%d\n",
344 ams_identity[sum->model].model_name, ams_identity[sum->model].hw_revision,
345 sum->version, ams_identity[model].model_name, ams_identity[model].hw_revision
346 );
347 }
348 } else {
349 /* OF unknown, give a list of tested versions for the requested model */
350
351 char tested_versions[100];
352 tested_versions[0] = '\0';
353
354 for (i = 0; i < NUM_MD5S ; i++)
355 if (sansasums[i].model == model) {
356 if (tested_versions[0] != '\0') {
357 strncat(tested_versions, ", ",
358 sizeof(tested_versions) - strlen(tested_versions) - 1);
359 }
360 strncat(tested_versions, sansasums[i].version,
361 sizeof(tested_versions) - strlen(tested_versions) - 1);
362 }
363
364 ERROR("[ERR] Original firmware unknown, please try another version."
365 " Tested %sv%d versions are: %s\n",
366 ams_identity[model].model_name, ams_identity[model].hw_revision, tested_versions);
367 }
368
369 /* TODO: Do some more sanity checks on the OF image. Some images (like
370 m200v4) dont have a checksum at the end, only padding (0xdeadbeef). */
371 last_word = *bufsize - 4;
372 checksum = get_uint32le(buf + last_word);
373 if (checksum != 0xefbeadde && checksum != calc_checksum(buf, last_word))
374 ERROR("%s", "[ERR] Whole file checksum failed\n");
375
376 if (ams_identity[sum->model].bootloader == NULL)
377 ERROR("[ERR] Unsupported model - \"%s\"\n", ams_identity[sum->model].model_name);
378
379 /* Get the firmware size */
380 if (ams_identity[sum->model].fw_revision == 1)
381 *firmware_size = get_uint32le(&buf[0x0c]);
382 else if (ams_identity[sum->model].fw_revision == 2)
383 *firmware_size = get_uint32le(&buf[0x10]);
384
385 /* Compress the original firmware image */
386 *of_packed = uclpack(buf + 0x400, *firmware_size, of_packedsize);
387 if (*of_packed == NULL)
388 ERROR("[ERR] Could not compress %s\n", filename);
389
390 return buf;
391
392error:
393 free(buf);
394 return NULL;
395}
396
397/* Loads a rockbox bootloader file into memory */
398unsigned char* load_rockbox_file(
399 char* filename, int *model, int* bufsize, int* rb_packedsize,
400 char* errstr, int errstrsize)
401{
402 int fd;
403 unsigned char* buf = NULL;
404 unsigned char* packed = NULL;
405 unsigned char header[8];
406 uint32_t sum;
407 off_t n;
408 int i;
409
410 fd = open(filename, O_RDONLY|O_BINARY);
411 if (fd < 0)
412 ERROR("[ERR] Could not open %s for reading\n", filename);
413
414 /* Read Rockbox header */
415 n = read(fd, header, sizeof(header));
416 if (n != sizeof(header))
417 ERROR("[ERR] Could not read file %s\n", filename);
418
419 for(*model = 0; *model < NUM_MODELS; (*model)++)
420 if (memcmp(ams_identity[*model].rb_model_name, header + 4, 4) == 0)
421 break;
422
423 if(*model == NUM_MODELS)
424 ERROR("[ERR] Model name \"%4.4s\" unknown. Is this really a rockbox bootloader?\n", header + 4);
425
426 *bufsize = filesize(fd) - sizeof(header);
427
428 buf = malloc(*bufsize);
429 if (buf == NULL)
430 ERROR("[ERR] Could not allocate memory for %s\n", filename);
431
432 n = read(fd, buf, *bufsize);
433
434 if (n != *bufsize)
435 ERROR("[ERR] Could not read file %s\n", filename);
436
437 /* Check checksum */
438 sum = ams_identity[*model].rb_model_num;
439 for (i = 0; i < *bufsize; i++) {
440 /* add 8 unsigned bits but keep a 32 bit sum */
441 sum += buf[i];
442 }
443
444 if (sum != get_uint32be(header))
445 ERROR("[ERR] Checksum mismatch in %s\n", filename);
446
447 packed = uclpack(buf, *bufsize, rb_packedsize);
448 if(packed == NULL)
449 ERROR("[ERR] Could not compress %s\n", filename);
450
451 free(buf);
452 return packed;
453
454error:
455 free(buf);
456 return NULL;
457}
458
459#undef ERROR
460
461/* Patches a Sansa AMS Original Firmware file */
462void patch_firmware(
463 int model, int fw_revision, int firmware_size, unsigned char* buf,
464 int len, unsigned char* of_packed, int of_packedsize,
465 unsigned char* rb_packed, int rb_packedsize)
466{
467 unsigned char *p;
468 uint32_t sum, filesum;
469 uint32_t ucl_dest;
470 unsigned int i;
471
472 /* Zero the original firmware area - not needed, but helps debugging */
473 memset(buf + 0x600, 0, firmware_size);
474
475 /* Insert dual-boot bootloader at offset 0x200, we preserve the OF
476 * version string located between 0x0 and 0x200 */
477 memcpy(buf + 0x600, ams_identity[model].bootloader, ams_identity[model].bootloader_size);
478
479 /* Insert vectors, they won't overwrite the OF version string */
480 static const uint32_t goto_start = 0xe3a0fc02; // mov pc, #0x200
481 static const uint32_t infinite_loop = 0xeafffffe; // 1: b 1b
482 /* ALL vectors: infinite loop */
483 for (i=0; i < 8; i++)
484 put_uint32le(buf + 0x400 + 4*i, infinite_loop);
485 /* Now change only the interesting vectors */
486 /* Reset/SWI vectors: branch to our dualboot code at 0x200 */
487 put_uint32le(buf + 0x400 + 4*0, goto_start); // Reset
488 put_uint32le(buf + 0x400 + 4*2, goto_start); // SWI
489
490 /* We are filling the firmware buffer backwards from the end */
491 p = buf + 0x400 + firmware_size;
492
493 /* 1 - UCL unpack function */
494 p -= sizeof(nrv2e_d8);
495 memcpy(p, nrv2e_d8, sizeof(nrv2e_d8));
496
497 /* 2 - Compressed copy of original firmware */
498 p -= of_packedsize;
499 memcpy(p, of_packed, of_packedsize);
500
501 /* 3 - Compressed copy of Rockbox bootloader */
502 p -= rb_packedsize;
503 memcpy(p, rb_packed, rb_packedsize);
504
505 /* Write the locations of the various images to the variables at the
506 start of the dualboot image - we save the location of the last byte
507 in each image, along with the size in bytes */
508
509 /* UCL unpack function */
510 put_uint32le(&buf[0x604], firmware_size - 1);
511 put_uint32le(&buf[0x608], sizeof(nrv2e_d8));
512
513 /* Compressed original firmware image */
514 put_uint32le(&buf[0x60c], firmware_size - sizeof(nrv2e_d8) - 1);
515 put_uint32le(&buf[0x610], of_packedsize);
516
517 /* Compressed Rockbox image */
518 put_uint32le(&buf[0x614], firmware_size - sizeof(nrv2e_d8) - of_packedsize
519 - 1);
520 put_uint32le(&buf[0x618], rb_packedsize);
521
522 ucl_dest = model_memory_size(model) - 1; /* last byte of memory */
523 put_uint32le(&buf[0x61c], ucl_dest);
524
525 /* Update the firmware block checksum */
526 sum = calc_checksum(buf + 0x400, firmware_size);
527
528 if (fw_revision == 1) {
529 put_uint32le(&buf[0x04], sum);
530 put_uint32le(&buf[0x204], sum);
531 } else if (fw_revision == 2) {
532 put_uint32le(&buf[0x08], sum);
533 put_uint32le(&buf[0x208], sum);
534
535 /* Update the header checksums */
536 put_uint32le(&buf[0x1fc], calc_checksum(buf, 0x1fc));
537 put_uint32le(&buf[0x3fc], calc_checksum(buf + 0x200, 0x1fc));
538 }
539
540 /* Update the whole-file checksum */
541 filesum = 0;
542 for (i=0;i < (unsigned)len - 4; i+=4)
543 filesum += get_uint32le(&buf[i]);
544
545 put_uint32le(buf + len - 4, filesum);
546}
547
548/* returns != 0 if the firmware can be safely patched */
549int check_sizes(int model, int rb_packed_size, int rb_unpacked_size,
550 int of_packed_size, int of_unpacked_size, int *total_size,
551 char *errstr, int errstrsize)
552{
553 /* XXX: we keep the first 0x200 bytes block unmodified, we just replace
554 * the ARM vectors */
555 unsigned int packed_size = ams_identity[model].bootloader_size + sizeof(nrv2e_d8) +
556 of_packed_size + rb_packed_size + 0x200;
557
558 /* how much memory is available */
559 unsigned int memory_size = model_memory_size(model);
560
561 /* the memory used when unpacking the OF */
562 unsigned int ram_of = sizeof(nrv2e_d8) + of_packed_size + of_unpacked_size;
563
564 /* the memory used when unpacking the bootloader */
565 unsigned int ram_rb = sizeof(nrv2e_d8) + rb_packed_size + rb_unpacked_size;
566
567 *total_size = packed_size;
568
569#define ERROR(format, ...) \
570 do { \
571 snprintf(errstr, errstrsize, format, __VA_ARGS__); \
572 return 0; \
573 } while(0)
574
575 /* will packed data fit in the OF file ? */
576 if(packed_size > of_unpacked_size)
577 ERROR(
578 "[ERR] Packed data (%d bytes) doesn't fit in the firmware "
579 "(%d bytes)\n", packed_size, of_unpacked_size
580 );
581
582 else if(ram_rb > memory_size)
583 ERROR("[ERR] Rockbox can't be unpacked at runtime, needs %d bytes "
584 "of memory and only %d available\n", ram_rb, memory_size
585 );
586
587 else if(ram_of > memory_size)
588 ERROR("[ERR] OF can't be unpacked at runtime, needs %d bytes "
589 "of memory and only %d available\n", ram_of, memory_size
590 );
591
592 return 1;
593
594#undef ERROR
595}
diff --git a/utils/mkamsboot/mkamsboot.h b/utils/mkamsboot/mkamsboot.h
new file mode 100644
index 0000000000..263fe9e9c1
--- /dev/null
+++ b/utils/mkamsboot/mkamsboot.h
@@ -0,0 +1,195 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * mkamsboot.h - a tool for merging bootloader code into an Sansa V2
11 * (AMS) firmware file
12 *
13 * Copyright (C) 2008 Dave Chapman
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#ifndef MKAMSBOOT_H
26#define MKAMSBOOT_H
27
28#include <stdint.h>
29#include <sys/types.h>
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35/* Supported models */
36enum {
37 MODEL_UNKNOWN = -1,
38 MODEL_FUZE = 0,
39 MODEL_CLIP,
40 MODEL_CLIPV2,
41 MODEL_E200V2,
42 MODEL_M200V4,
43 MODEL_C200V2,
44 MODEL_CLIPPLUS,
45 MODEL_FUZEV2,
46 MODEL_CLIPZIP,
47 /* new models go here */
48
49 NUM_MODELS
50};
51
52
53/* Holds info about the OF */
54struct md5sums {
55 int model;
56 char *version;
57 char *md5;
58};
59
60struct ams_models {
61 unsigned short hw_revision;
62 unsigned short fw_revision;
63 /* Descriptive name of this model */
64 const char* model_name;
65 /* Dualboot functions for this model */
66 const unsigned char* bootloader;
67 /* Size of dualboot functions for this model */
68 int bootloader_size;
69 /* Model name used in the Rockbox header in ".sansa" files - these match the
70 -add parameter to the "scramble" tool */
71 const char* rb_model_name;
72 /* Model number used to initialise the checksum in the Rockbox header in
73 ".sansa" files - these are the same as MODEL_NUMBER in config-target.h */
74 const int rb_model_num;
75};
76extern const struct ams_models ams_identity[];
77
78/* load_rockbox_file()
79 *
80 * Loads a rockbox bootloader file into memory
81 *
82 * ARGUMENTS
83 *
84 * filename : bootloader file to load
85 * model : will be set to this bootloader's model
86 * bootloader_size : set to the uncompressed bootloader size
87 * rb_packed_size : set to the size of compressed bootloader
88 * errstr : provided buffer to store an eventual error
89 * errstrsize : size of provided error buffer
90 *
91 * RETURN VALUE
92 * pointer to allocated memory containing the content of compressed bootloader
93 * or NULL in case of error (errstr will hold a description of the error)
94 */
95
96unsigned char* load_rockbox_file(
97 char* filename, int *model, int* bootloader_size, int* rb_packedsize,
98 char* errstr, int errstrsize);
99
100
101/* load_of_file()
102 *
103 * Loads a Sansa AMS Original Firmware file into memory
104 *
105 * ARGUMENTS
106 *
107 * filename : firmware file to load
108 * model : desired player's model
109 * bufsize : set to firmware file size
110 * md5sum : set to file md5sum, must be at least 33 bytes long
111 * firmware_size : set to firmware block's size
112 * of_packed : pointer to allocated memory containing the compressed
113 * original firmware block
114 * of_packedsize : size of compressed original firmware block
115 * errstr : provided buffer to store an eventual error
116 * errstrsize : size of provided error buffer
117 *
118 * RETURN VALUE
119 * pointer to allocated memory containing the content of Original Firmware
120 * or NULL in case of error (errstr will hold a description of the error)
121 */
122
123unsigned char* load_of_file(
124 char* filename, int model, off_t* bufsize, struct md5sums *sum,
125 int* firmware_size, unsigned char** of_packed,
126 int* of_packedsize, char* errstr, int errstrsize);
127
128
129/* patch_firmware()
130 *
131 * Patches a Sansa AMS Original Firmware file
132 *
133 * ARGUMENTS
134 *
135 * model : firmware model (MODEL_XXX)
136 * fw_version : firmware format version (1 or 2)
137 * firmware_size : size of uncompressed original firmware block
138 * buf : pointer to original firmware file
139 * len : size of original firmware file
140 * of_packed : pointer to compressed original firmware block
141 * of_packedsize : size of compressed original firmware block
142 * rb_packed : pointer to compressed rockbox bootloader
143 * rb_packed_size : size of compressed rockbox bootloader
144 */
145
146void patch_firmware(
147 int model, int fw_version, int firmware_size, unsigned char* buf,
148 int len, unsigned char* of_packed, int of_packedsize,
149 unsigned char* rb_packed, int rb_packedsize);
150
151
152/* check_sizes()
153 *
154 * Verify if the given bootloader can be embedded in the OF file, while still
155 * allowing both the bootloader and the OF to be unpacked at runtime
156 *
157 * ARGUMENTS
158 *
159 * model : firmware model (MODEL_XXX)
160 * rb_packed_size : size of compressed rockbox bootloader
161 * rb_unpacked_size : size of compressed rockbox bootloader
162 * of_packed_size : size of compressed original firmware block
163 * of_unpacked_size : size of compressed original firmware block
164 * total_size : will contain the size of useful data that would be
165 * written to the firmware block, even in case of an
166 * error
167 * errstr : provided buffer to store an eventual error
168 * errstrsize : size of provided error buffer
169 *
170 * RETURN VALUE
171 * 0 if the conditions aren't met, 1 if we can go and patch the firmware
172*/
173
174int check_sizes(int model, int rb_packed_size, int rb_unpacked_size,
175 int of_packed_size, int of_unpacked_size, int *total_size,
176 char *errstr, int errstrsize);
177
178/* firmware_revision()
179 *
180 * returns the firmware revision for a particular model
181 *
182 * ARGUMENTS
183 *
184 * model : firmware model (MODEL_XXX)
185 *
186 * RETURN VALUE
187 * firmware version
188*/
189int firmware_revision(int model);
190
191#ifdef __cplusplus
192};
193#endif
194
195#endif
diff --git a/utils/mkimxboot/Makefile b/utils/mkimxboot/Makefile
new file mode 100644
index 0000000000..966423159a
--- /dev/null
+++ b/utils/mkimxboot/Makefile
@@ -0,0 +1,46 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7
8# We use the SB code available in the Rockbox utils/sbtools directory
9
10IMXTOOLS_DIR=../../utils/imxtools/sbtools/
11
12COMPILEFLAGS := -Wall -g -O3 -I$(IMXTOOLS_DIR)
13
14# std=gnu99 is required by MinGW on Windows (c99 is sufficient for Linux / MXE)
15CFLAGS += -std=gnu99 $(COMPILEFLAGS)
16
17TOMCRYPT_DIR := ../../utils/tomcrypt
18
19CFLAGS += -I$(TOMCRYPT_DIR)/src/headers
20LDOPTS += -lpthread $(TOMCRYPT_DIR)/librbtomcrypt.a
21
22OUTPUT = mkimxboot
23
24# inputs for lib
25IMXTOOLS_SOURCES = misc.c sb.c crypto.c crc.c elf.c
26LIBSOURCES := dualboot.c mkimxboot.c md5.c \
27 $(addprefix $(IMXTOOLS_DIR),$(IMXTOOLS_SOURCES))
28
29# for now build tomcrypt as part of the lib.
30LIBSOURCES += $(addprefix $(TOMCRYPT_DIR),$(TOMCRYPT_SOURCES))
31
32# inputs for binary only
33SOURCES := $(LIBSOURCES) main.c
34# dependencies for binary
35EXTRADEPS :=
36
37include ../libtools.make
38
39# explicit dependencies on dualboot.{c,h} and mkimxboot.h
40$(OBJDIR)mkimxboot.o: dualboot.h dualboot.c mkimxboot.c mkimxboot.h
41$(OBJDIR)main.o: dualboot.h dualboot.c main.c mkimxboot.h
42$(BINARY): librbtomcrypt.a
43
44librbtomcrypt.a:
45 $(MAKE) -C ../../utils/tomcrypt
46
diff --git a/utils/mkimxboot/dualboot.c b/utils/mkimxboot/dualboot.c
new file mode 100644
index 0000000000..dd43a63d2d
--- /dev/null
+++ b/utils/mkimxboot/dualboot.c
@@ -0,0 +1,293 @@
1/* Generated by bin2c */
2
3#include "dualboot.h"
4
5unsigned char dualboot_fuzeplus[728] = {
6 0x10, 0x40, 0x2d, 0xe9, 0x30, 0x00, 0x00, 0xeb, 0x10, 0x80, 0xbd, 0xe8, 0x40, 0x30, 0x9f, 0xe5,
7 0xb0, 0x30, 0x93, 0xe5, 0x03, 0x18, 0xa0, 0xe1, 0x21, 0x18, 0xa0, 0xe1, 0x34, 0x20, 0x9f, 0xe5,
8 0x02, 0x00, 0x51, 0xe1, 0x08, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x50, 0xe3, 0x01, 0x38, 0x03, 0x02,
9 0x23, 0x08, 0xa0, 0x01, 0x1e, 0xff, 0x2f, 0x01, 0x01, 0x00, 0x50, 0xe3, 0x02, 0x00, 0x00, 0x1a,
10 0x06, 0x38, 0x03, 0xe2, 0xa3, 0x08, 0xa0, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
11 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xc0, 0x05, 0x80, 0x52, 0x42, 0x00, 0x00, 0x04, 0x40, 0x2d, 0xe5,
12 0x5c, 0x20, 0x9f, 0xe5, 0xb0, 0x30, 0x92, 0xe5, 0x03, 0x48, 0xa0, 0xe1, 0x24, 0x48, 0xa0, 0xe1,
13 0x50, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x54, 0xe1, 0x02, 0x30, 0xa0, 0x11, 0x00, 0x00, 0x50, 0xe3,
14 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x09, 0x00, 0x00, 0x1a, 0x04, 0x00, 0x00, 0xea,
15 0x01, 0x38, 0xc3, 0xe3, 0x01, 0x18, 0xa0, 0xe1, 0x01, 0x18, 0x01, 0xe2, 0x01, 0x30, 0x83, 0xe1,
16 0x03, 0x00, 0x00, 0xea, 0x06, 0x38, 0xc3, 0xe3, 0x81, 0x18, 0xa0, 0xe1, 0x06, 0x18, 0x01, 0xe2,
17 0x01, 0x30, 0x83, 0xe1, 0x08, 0x20, 0x9f, 0xe5, 0xb0, 0x30, 0x82, 0xe5, 0x10, 0x00, 0xbd, 0xe8,
18 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xc0, 0x05, 0x80, 0x52, 0x42, 0x00, 0x00, 0x70, 0x40, 0x2d, 0xe9,
19 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x60, 0xa0, 0xe1, 0xd8, 0x31, 0x9f, 0xe5, 0x03, 0x00, 0x50, 0xe1,
20 0x34, 0x00, 0x00, 0x1a, 0xd0, 0x31, 0x9f, 0xe5, 0x02, 0x21, 0xa0, 0xe3, 0x08, 0x20, 0x83, 0xe5,
21 0x03, 0x21, 0x82, 0xe2, 0x08, 0x20, 0x83, 0xe5, 0xd0, 0x20, 0x93, 0xe5, 0xff, 0x24, 0xc2, 0xe3,
22 0x02, 0x21, 0x82, 0xe3, 0xd0, 0x20, 0x83, 0xe5, 0xd0, 0x20, 0x93, 0xe5, 0x0f, 0x28, 0xc2, 0xe3,
23 0x01, 0x28, 0x82, 0xe3, 0xd0, 0x20, 0x83, 0xe5, 0xd0, 0x20, 0x93, 0xe5, 0x7f, 0x2e, 0xc2, 0xe3,
24 0x0f, 0x20, 0xc2, 0xe3, 0xc8, 0x20, 0x82, 0xe3, 0xd0, 0x20, 0x83, 0xe5, 0x01, 0x26, 0xa0, 0xe3,
25 0xd4, 0x20, 0x83, 0xe5, 0x34, 0x21, 0x83, 0xe5, 0x30, 0x11, 0x93, 0xe5, 0x03, 0x18, 0xc1, 0xe3,
26 0x02, 0x18, 0x81, 0xe3, 0x30, 0x11, 0x83, 0xe5, 0x03, 0x39, 0x43, 0xe2, 0x30, 0x10, 0x93, 0xe5,
27 0x0f, 0x1c, 0xc1, 0xe3, 0x01, 0x1c, 0x81, 0xe3, 0x30, 0x10, 0x83, 0xe5, 0x30, 0x10, 0x93, 0xe5,
28 0x3f, 0x10, 0xc1, 0xe3, 0x10, 0x10, 0x81, 0xe3, 0x30, 0x10, 0x83, 0xe5, 0x01, 0x18, 0xa0, 0xe3,
29 0x38, 0x10, 0x83, 0xe5, 0x80, 0x10, 0x93, 0xe5, 0x02, 0x15, 0x81, 0xe3, 0x80, 0x10, 0x83, 0xe5,
30 0x18, 0x20, 0x83, 0xe5, 0x10, 0x20, 0x93, 0xe5, 0x3f, 0x2a, 0xc2, 0xe3, 0x01, 0x28, 0x82, 0xe3,
31 0x10, 0x20, 0x83, 0xe5, 0x01, 0x39, 0x43, 0xe2, 0x00, 0x10, 0xa0, 0xe3, 0x20, 0x20, 0x93, 0xe5,
32 0x01, 0x2a, 0x82, 0xe3, 0x20, 0x20, 0x83, 0xe5, 0x90, 0x1f, 0x07, 0xee, 0x00, 0x00, 0xa0, 0xe1,
33 0x00, 0x00, 0xa0, 0xe1, 0xf8, 0xff, 0xff, 0xea, 0x00, 0x00, 0xa0, 0xe3, 0x01, 0x10, 0xa0, 0xe3,
34 0xa5, 0xff, 0xff, 0xeb, 0x01, 0x00, 0xa0, 0xe3, 0x8f, 0xff, 0xff, 0xeb, 0x00, 0x50, 0xa0, 0xe1,
35 0x01, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0x9f, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x55, 0xe3,
36 0x25, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x55, 0xe3, 0x04, 0x00, 0x00, 0x1a, 0x01, 0x27, 0xa0, 0xe3,
37 0xc8, 0x30, 0x9f, 0xe5, 0x78, 0x20, 0x83, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 0x70, 0x80, 0xbd, 0xe8,
38 0xbc, 0x30, 0x9f, 0xe5, 0xc0, 0x30, 0x93, 0xe5, 0x3f, 0x34, 0x03, 0xe2, 0x23, 0x3c, 0xa0, 0xe1,
39 0x20, 0x00, 0x13, 0xe3, 0x01, 0x30, 0xa0, 0x13, 0x02, 0x00, 0x00, 0x1a, 0x10, 0x00, 0x13, 0xe3,
40 0x02, 0x30, 0xa0, 0x13, 0x00, 0x30, 0xa0, 0x03, 0x98, 0x20, 0x9f, 0xe5, 0x10, 0x26, 0x92, 0xe5,
41 0x01, 0x01, 0x12, 0xe3, 0x10, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x53, 0xe3, 0x10, 0x00, 0x00, 0x1a,
42 0x03, 0x20, 0xa0, 0xe1, 0x78, 0x00, 0x9f, 0xe5, 0x7c, 0x10, 0x9f, 0xe5, 0xc0, 0xc0, 0x90, 0xe5,
43 0x03, 0xc6, 0x0c, 0xe2, 0x01, 0x06, 0x5c, 0xe3, 0x01, 0x20, 0x82, 0x02, 0x01, 0x30, 0x83, 0xe2,
44 0x01, 0x00, 0x53, 0xe1, 0xf8, 0xff, 0xff, 0x1a, 0x60, 0x30, 0x9f, 0xe5, 0x03, 0x00, 0x52, 0xe1,
45 0x03, 0x00, 0x00, 0xca, 0x05, 0x00, 0x00, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x00, 0x00, 0xa0, 0xe3,
46 0x70, 0x80, 0xbd, 0xe8, 0x00, 0x40, 0x86, 0xe5, 0x01, 0x00, 0xa0, 0xe3, 0x70, 0x80, 0xbd, 0xe8,
47 0x30, 0x30, 0x9f, 0xe5, 0x03, 0x27, 0xa0, 0xe3, 0x04, 0x21, 0x83, 0xe5, 0x02, 0x2c, 0xa0, 0xe3,
48 0x00, 0x27, 0x83, 0xe5, 0x00, 0x25, 0x83, 0xe5, 0x24, 0x20, 0x9f, 0xe5, 0x0b, 0x39, 0x83, 0xe2,
49 0x00, 0x21, 0x83, 0xe5, 0xef, 0xff, 0xff, 0xea, 0x63, 0x68, 0x72, 0x67, 0x00, 0x00, 0x05, 0x80,
50 0x00, 0xc0, 0x05, 0x80, 0x00, 0x40, 0x04, 0x80, 0x00, 0x80, 0x01, 0x80, 0x70, 0x64, 0x08, 0x00,
51 0x7f, 0x1a, 0x06, 0x00, 0x01, 0x00, 0xff, 0xff
52};
53unsigned char dualboot_zenxfi2[608] = {
54 0x10, 0x40, 0x2d, 0xe9, 0x30, 0x00, 0x00, 0xeb, 0x10, 0x80, 0xbd, 0xe8, 0x40, 0x30, 0x9f, 0xe5,
55 0xb0, 0x30, 0x93, 0xe5, 0x03, 0x18, 0xa0, 0xe1, 0x21, 0x18, 0xa0, 0xe1, 0x34, 0x20, 0x9f, 0xe5,
56 0x02, 0x00, 0x51, 0xe1, 0x08, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x50, 0xe3, 0x01, 0x38, 0x03, 0x02,
57 0x23, 0x08, 0xa0, 0x01, 0x1e, 0xff, 0x2f, 0x01, 0x01, 0x00, 0x50, 0xe3, 0x02, 0x00, 0x00, 0x1a,
58 0x06, 0x38, 0x03, 0xe2, 0xa3, 0x08, 0xa0, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
59 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xc0, 0x05, 0x80, 0x52, 0x42, 0x00, 0x00, 0x04, 0x40, 0x2d, 0xe5,
60 0x5c, 0x20, 0x9f, 0xe5, 0xb0, 0x30, 0x92, 0xe5, 0x03, 0x48, 0xa0, 0xe1, 0x24, 0x48, 0xa0, 0xe1,
61 0x50, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x54, 0xe1, 0x02, 0x30, 0xa0, 0x11, 0x00, 0x00, 0x50, 0xe3,
62 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x09, 0x00, 0x00, 0x1a, 0x04, 0x00, 0x00, 0xea,
63 0x01, 0x38, 0xc3, 0xe3, 0x01, 0x18, 0xa0, 0xe1, 0x01, 0x18, 0x01, 0xe2, 0x01, 0x30, 0x83, 0xe1,
64 0x03, 0x00, 0x00, 0xea, 0x06, 0x38, 0xc3, 0xe3, 0x81, 0x18, 0xa0, 0xe1, 0x06, 0x18, 0x01, 0xe2,
65 0x01, 0x30, 0x83, 0xe1, 0x08, 0x20, 0x9f, 0xe5, 0xb0, 0x30, 0x82, 0xe5, 0x10, 0x00, 0xbd, 0xe8,
66 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xc0, 0x05, 0x80, 0x52, 0x42, 0x00, 0x00, 0x70, 0x40, 0x2d, 0xe9,
67 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x60, 0xa0, 0xe1, 0x6c, 0x31, 0x9f, 0xe5, 0x03, 0x00, 0x50, 0xe1,
68 0x34, 0x00, 0x00, 0x1a, 0x64, 0x31, 0x9f, 0xe5, 0x02, 0x21, 0xa0, 0xe3, 0x08, 0x20, 0x83, 0xe5,
69 0x03, 0x21, 0x82, 0xe2, 0x08, 0x20, 0x83, 0xe5, 0xd0, 0x20, 0x93, 0xe5, 0xff, 0x24, 0xc2, 0xe3,
70 0x02, 0x21, 0x82, 0xe3, 0xd0, 0x20, 0x83, 0xe5, 0xd0, 0x20, 0x93, 0xe5, 0x0f, 0x28, 0xc2, 0xe3,
71 0x01, 0x28, 0x82, 0xe3, 0xd0, 0x20, 0x83, 0xe5, 0xd0, 0x20, 0x93, 0xe5, 0x7f, 0x2e, 0xc2, 0xe3,
72 0x0f, 0x20, 0xc2, 0xe3, 0xc8, 0x20, 0x82, 0xe3, 0xd0, 0x20, 0x83, 0xe5, 0x01, 0x26, 0xa0, 0xe3,
73 0xd4, 0x20, 0x83, 0xe5, 0x34, 0x21, 0x83, 0xe5, 0x30, 0x11, 0x93, 0xe5, 0x03, 0x18, 0xc1, 0xe3,
74 0x02, 0x18, 0x81, 0xe3, 0x30, 0x11, 0x83, 0xe5, 0x03, 0x39, 0x43, 0xe2, 0x30, 0x10, 0x93, 0xe5,
75 0x0f, 0x1c, 0xc1, 0xe3, 0x01, 0x1c, 0x81, 0xe3, 0x30, 0x10, 0x83, 0xe5, 0x30, 0x10, 0x93, 0xe5,
76 0x3f, 0x10, 0xc1, 0xe3, 0x10, 0x10, 0x81, 0xe3, 0x30, 0x10, 0x83, 0xe5, 0x01, 0x18, 0xa0, 0xe3,
77 0x38, 0x10, 0x83, 0xe5, 0x80, 0x10, 0x93, 0xe5, 0x02, 0x15, 0x81, 0xe3, 0x80, 0x10, 0x83, 0xe5,
78 0x18, 0x20, 0x83, 0xe5, 0x10, 0x20, 0x93, 0xe5, 0x3f, 0x2a, 0xc2, 0xe3, 0x01, 0x28, 0x82, 0xe3,
79 0x10, 0x20, 0x83, 0xe5, 0x01, 0x39, 0x43, 0xe2, 0x00, 0x10, 0xa0, 0xe3, 0x20, 0x20, 0x93, 0xe5,
80 0x01, 0x2a, 0x82, 0xe3, 0x20, 0x20, 0x83, 0xe5, 0x90, 0x1f, 0x07, 0xee, 0x00, 0x00, 0xa0, 0xe1,
81 0x00, 0x00, 0xa0, 0xe1, 0xf8, 0xff, 0xff, 0xea, 0x00, 0x00, 0xa0, 0xe3, 0x01, 0x10, 0xa0, 0xe3,
82 0xa5, 0xff, 0xff, 0xeb, 0x01, 0x00, 0xa0, 0xe3, 0x8f, 0xff, 0xff, 0xeb, 0x00, 0x50, 0xa0, 0xe1,
83 0x01, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0x9f, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x55, 0xe3,
84 0x17, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x55, 0xe3, 0x04, 0x00, 0x00, 0x1a, 0x01, 0x27, 0xa0, 0xe3,
85 0x5c, 0x30, 0x9f, 0xe5, 0x78, 0x20, 0x83, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 0x70, 0x80, 0xbd, 0xe8,
86 0x50, 0x30, 0x9f, 0xe5, 0xc0, 0x30, 0x93, 0xe5, 0x02, 0x02, 0x13, 0xe3, 0x04, 0x00, 0x00, 0x1a,
87 0x44, 0x30, 0x9f, 0xe5, 0x00, 0x36, 0x93, 0xe5, 0x01, 0x09, 0x13, 0xe3, 0x08, 0x00, 0x00, 0x0a,
88 0x04, 0x00, 0x00, 0xea, 0x2c, 0x30, 0x9f, 0xe5, 0xc0, 0x30, 0x93, 0xe5, 0x03, 0x36, 0x03, 0xe2,
89 0x01, 0x06, 0x53, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x40, 0x86, 0xe5, 0x01, 0x00, 0xa0, 0xe3,
90 0x70, 0x80, 0xbd, 0xe8, 0x00, 0x00, 0xa0, 0xe3, 0x70, 0x80, 0xbd, 0xe8, 0x63, 0x68, 0x72, 0x67,
91 0x00, 0x00, 0x05, 0x80, 0x00, 0xc0, 0x05, 0x80, 0x00, 0x40, 0x04, 0x80, 0x00, 0x80, 0x01, 0x80
92};
93unsigned char dualboot_zenxfi3[572] = {
94 0x10, 0x40, 0x2d, 0xe9, 0x30, 0x00, 0x00, 0xeb, 0x10, 0x80, 0xbd, 0xe8, 0x40, 0x30, 0x9f, 0xe5,
95 0xb0, 0x30, 0x93, 0xe5, 0x03, 0x18, 0xa0, 0xe1, 0x21, 0x18, 0xa0, 0xe1, 0x34, 0x20, 0x9f, 0xe5,
96 0x02, 0x00, 0x51, 0xe1, 0x08, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x50, 0xe3, 0x01, 0x38, 0x03, 0x02,
97 0x23, 0x08, 0xa0, 0x01, 0x1e, 0xff, 0x2f, 0x01, 0x01, 0x00, 0x50, 0xe3, 0x02, 0x00, 0x00, 0x1a,
98 0x06, 0x38, 0x03, 0xe2, 0xa3, 0x08, 0xa0, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
99 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xc0, 0x05, 0x80, 0x52, 0x42, 0x00, 0x00, 0x04, 0x40, 0x2d, 0xe5,
100 0x5c, 0x20, 0x9f, 0xe5, 0xb0, 0x30, 0x92, 0xe5, 0x03, 0x48, 0xa0, 0xe1, 0x24, 0x48, 0xa0, 0xe1,
101 0x50, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x54, 0xe1, 0x02, 0x30, 0xa0, 0x11, 0x00, 0x00, 0x50, 0xe3,
102 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x09, 0x00, 0x00, 0x1a, 0x04, 0x00, 0x00, 0xea,
103 0x01, 0x38, 0xc3, 0xe3, 0x01, 0x18, 0xa0, 0xe1, 0x01, 0x18, 0x01, 0xe2, 0x01, 0x30, 0x83, 0xe1,
104 0x03, 0x00, 0x00, 0xea, 0x06, 0x38, 0xc3, 0xe3, 0x81, 0x18, 0xa0, 0xe1, 0x06, 0x18, 0x01, 0xe2,
105 0x01, 0x30, 0x83, 0xe1, 0x08, 0x20, 0x9f, 0xe5, 0xb0, 0x30, 0x82, 0xe5, 0x10, 0x00, 0xbd, 0xe8,
106 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xc0, 0x05, 0x80, 0x52, 0x42, 0x00, 0x00, 0x70, 0x40, 0x2d, 0xe9,
107 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x60, 0xa0, 0xe1, 0x48, 0x31, 0x9f, 0xe5, 0x03, 0x00, 0x50, 0xe1,
108 0x34, 0x00, 0x00, 0x1a, 0x40, 0x31, 0x9f, 0xe5, 0x02, 0x21, 0xa0, 0xe3, 0x08, 0x20, 0x83, 0xe5,
109 0x03, 0x21, 0x82, 0xe2, 0x08, 0x20, 0x83, 0xe5, 0xd0, 0x20, 0x93, 0xe5, 0xff, 0x24, 0xc2, 0xe3,
110 0x02, 0x21, 0x82, 0xe3, 0xd0, 0x20, 0x83, 0xe5, 0xd0, 0x20, 0x93, 0xe5, 0x0f, 0x28, 0xc2, 0xe3,
111 0x01, 0x28, 0x82, 0xe3, 0xd0, 0x20, 0x83, 0xe5, 0xd0, 0x20, 0x93, 0xe5, 0x7f, 0x2e, 0xc2, 0xe3,
112 0x0f, 0x20, 0xc2, 0xe3, 0xc8, 0x20, 0x82, 0xe3, 0xd0, 0x20, 0x83, 0xe5, 0x01, 0x26, 0xa0, 0xe3,
113 0xd4, 0x20, 0x83, 0xe5, 0x34, 0x21, 0x83, 0xe5, 0x30, 0x11, 0x93, 0xe5, 0x03, 0x18, 0xc1, 0xe3,
114 0x02, 0x18, 0x81, 0xe3, 0x30, 0x11, 0x83, 0xe5, 0x03, 0x39, 0x43, 0xe2, 0x30, 0x10, 0x93, 0xe5,
115 0x0f, 0x1c, 0xc1, 0xe3, 0x01, 0x1c, 0x81, 0xe3, 0x30, 0x10, 0x83, 0xe5, 0x30, 0x10, 0x93, 0xe5,
116 0x3f, 0x10, 0xc1, 0xe3, 0x10, 0x10, 0x81, 0xe3, 0x30, 0x10, 0x83, 0xe5, 0x01, 0x18, 0xa0, 0xe3,
117 0x38, 0x10, 0x83, 0xe5, 0x80, 0x10, 0x93, 0xe5, 0x02, 0x15, 0x81, 0xe3, 0x80, 0x10, 0x83, 0xe5,
118 0x18, 0x20, 0x83, 0xe5, 0x10, 0x20, 0x93, 0xe5, 0x3f, 0x2a, 0xc2, 0xe3, 0x01, 0x28, 0x82, 0xe3,
119 0x10, 0x20, 0x83, 0xe5, 0x01, 0x39, 0x43, 0xe2, 0x00, 0x10, 0xa0, 0xe3, 0x20, 0x20, 0x93, 0xe5,
120 0x01, 0x2a, 0x82, 0xe3, 0x20, 0x20, 0x83, 0xe5, 0x90, 0x1f, 0x07, 0xee, 0x00, 0x00, 0xa0, 0xe1,
121 0x00, 0x00, 0xa0, 0xe1, 0xf8, 0xff, 0xff, 0xea, 0x00, 0x00, 0xa0, 0xe3, 0x01, 0x10, 0xa0, 0xe3,
122 0xa5, 0xff, 0xff, 0xeb, 0x01, 0x00, 0xa0, 0xe3, 0x8f, 0xff, 0xff, 0xeb, 0x00, 0x50, 0xa0, 0xe1,
123 0x01, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0x9f, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x55, 0xe3,
124 0x0e, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x55, 0xe3, 0x04, 0x00, 0x00, 0x1a, 0x01, 0x27, 0xa0, 0xe3,
125 0x38, 0x30, 0x9f, 0xe5, 0x78, 0x20, 0x83, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 0x70, 0x80, 0xbd, 0xe8,
126 0x2c, 0x30, 0x9f, 0xe5, 0xc0, 0x30, 0x93, 0xe5, 0x28, 0x30, 0x9f, 0xe5, 0x20, 0x36, 0x93, 0xe5,
127 0x80, 0x00, 0x13, 0xe3, 0x00, 0x40, 0x86, 0x15, 0x01, 0x00, 0xa0, 0x13, 0x70, 0x80, 0xbd, 0x18,
128 0x00, 0x00, 0xa0, 0xe3, 0x70, 0x80, 0xbd, 0xe8, 0x63, 0x68, 0x72, 0x67, 0x00, 0x00, 0x05, 0x80,
129 0x00, 0xc0, 0x05, 0x80, 0x00, 0x40, 0x04, 0x80, 0x00, 0x80, 0x01, 0x80
130};
131unsigned char dualboot_nwze370[896] = {
132 0x10, 0x40, 0x2d, 0xe9, 0x48, 0x00, 0x00, 0xeb, 0x10, 0x80, 0xbd, 0xe8, 0x40, 0x30, 0x9f, 0xe5,
133 0xb0, 0x30, 0x93, 0xe5, 0x03, 0x18, 0xa0, 0xe1, 0x21, 0x18, 0xa0, 0xe1, 0x34, 0x20, 0x9f, 0xe5,
134 0x02, 0x00, 0x51, 0xe1, 0x08, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x50, 0xe3, 0x01, 0x38, 0x03, 0x02,
135 0x23, 0x08, 0xa0, 0x01, 0x1e, 0xff, 0x2f, 0x01, 0x01, 0x00, 0x50, 0xe3, 0x02, 0x00, 0x00, 0x1a,
136 0x06, 0x38, 0x03, 0xe2, 0xa3, 0x08, 0xa0, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
137 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xc0, 0x05, 0x80, 0x52, 0x42, 0x00, 0x00, 0x04, 0x40, 0x2d, 0xe5,
138 0x5c, 0x20, 0x9f, 0xe5, 0xb0, 0x30, 0x92, 0xe5, 0x03, 0x48, 0xa0, 0xe1, 0x24, 0x48, 0xa0, 0xe1,
139 0x50, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x54, 0xe1, 0x02, 0x30, 0xa0, 0x11, 0x00, 0x00, 0x50, 0xe3,
140 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x09, 0x00, 0x00, 0x1a, 0x04, 0x00, 0x00, 0xea,
141 0x01, 0x38, 0xc3, 0xe3, 0x01, 0x18, 0xa0, 0xe1, 0x01, 0x18, 0x01, 0xe2, 0x01, 0x30, 0x83, 0xe1,
142 0x03, 0x00, 0x00, 0xea, 0x06, 0x38, 0xc3, 0xe3, 0x81, 0x18, 0xa0, 0xe1, 0x06, 0x18, 0x01, 0xe2,
143 0x01, 0x30, 0x83, 0xe1, 0x08, 0x20, 0x9f, 0xe5, 0xb0, 0x30, 0x82, 0xe5, 0x10, 0x00, 0xbd, 0xe8,
144 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xc0, 0x05, 0x80, 0x52, 0x42, 0x00, 0x00, 0x54, 0x30, 0x9f, 0xe5,
145 0x01, 0x20, 0xa0, 0xe3, 0x18, 0x20, 0x83, 0xe5, 0x04, 0x20, 0x83, 0xe5, 0x03, 0x20, 0xa0, 0xe1,
146 0x10, 0x30, 0x92, 0xe5, 0x01, 0x00, 0x13, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x34, 0x30, 0x9f, 0xe5,
147 0x50, 0x00, 0x93, 0xe5, 0xff, 0x04, 0xc0, 0xe3, 0x3f, 0x07, 0xc0, 0xe3, 0x41, 0x3e, 0x40, 0xe2,
148 0x0a, 0x30, 0x43, 0xe2, 0x63, 0x00, 0x53, 0xe3, 0x02, 0x00, 0xa0, 0x93, 0x1e, 0xff, 0x2f, 0x91,
149 0x16, 0x0d, 0x40, 0xe2, 0x0c, 0x00, 0x40, 0xe2, 0x63, 0x00, 0x50, 0xe3, 0x00, 0x00, 0xa0, 0x83,
150 0x01, 0x00, 0xa0, 0x93, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x05, 0x80, 0xf0, 0x41, 0x2d, 0xe9,
151 0x00, 0x60, 0xa0, 0xe1, 0x01, 0x70, 0xa0, 0xe1, 0x28, 0x32, 0x9f, 0xe5, 0x03, 0x00, 0x50, 0xe1,
152 0x34, 0x00, 0x00, 0x1a, 0x20, 0x32, 0x9f, 0xe5, 0x02, 0x21, 0xa0, 0xe3, 0x08, 0x20, 0x83, 0xe5,
153 0x03, 0x21, 0x82, 0xe2, 0x08, 0x20, 0x83, 0xe5, 0xd0, 0x20, 0x93, 0xe5, 0xff, 0x24, 0xc2, 0xe3,
154 0x02, 0x21, 0x82, 0xe3, 0xd0, 0x20, 0x83, 0xe5, 0xd0, 0x20, 0x93, 0xe5, 0x0f, 0x28, 0xc2, 0xe3,
155 0x01, 0x28, 0x82, 0xe3, 0xd0, 0x20, 0x83, 0xe5, 0xd0, 0x20, 0x93, 0xe5, 0x7f, 0x2e, 0xc2, 0xe3,
156 0x0f, 0x20, 0xc2, 0xe3, 0xc8, 0x20, 0x82, 0xe3, 0xd0, 0x20, 0x83, 0xe5, 0x01, 0x26, 0xa0, 0xe3,
157 0xd4, 0x20, 0x83, 0xe5, 0x34, 0x21, 0x83, 0xe5, 0x30, 0x11, 0x93, 0xe5, 0x03, 0x18, 0xc1, 0xe3,
158 0x02, 0x18, 0x81, 0xe3, 0x30, 0x11, 0x83, 0xe5, 0x03, 0x39, 0x43, 0xe2, 0x30, 0x10, 0x93, 0xe5,
159 0x0f, 0x1c, 0xc1, 0xe3, 0x01, 0x1c, 0x81, 0xe3, 0x30, 0x10, 0x83, 0xe5, 0x30, 0x10, 0x93, 0xe5,
160 0x3f, 0x10, 0xc1, 0xe3, 0x10, 0x10, 0x81, 0xe3, 0x30, 0x10, 0x83, 0xe5, 0x01, 0x18, 0xa0, 0xe3,
161 0x38, 0x10, 0x83, 0xe5, 0x80, 0x10, 0x93, 0xe5, 0x02, 0x15, 0x81, 0xe3, 0x80, 0x10, 0x83, 0xe5,
162 0x18, 0x20, 0x83, 0xe5, 0x10, 0x20, 0x93, 0xe5, 0x3f, 0x2a, 0xc2, 0xe3, 0x01, 0x28, 0x82, 0xe3,
163 0x10, 0x20, 0x83, 0xe5, 0x01, 0x39, 0x43, 0xe2, 0x00, 0x10, 0xa0, 0xe3, 0x20, 0x20, 0x93, 0xe5,
164 0x01, 0x2a, 0x82, 0xe3, 0x20, 0x20, 0x83, 0xe5, 0x90, 0x1f, 0x07, 0xee, 0x00, 0x00, 0xa0, 0xe1,
165 0x00, 0x00, 0xa0, 0xe1, 0xf8, 0xff, 0xff, 0xea, 0x00, 0x00, 0xa0, 0xe3, 0x01, 0x10, 0xa0, 0xe3,
166 0x8d, 0xff, 0xff, 0xeb, 0x01, 0x00, 0xa0, 0xe3, 0x77, 0xff, 0xff, 0xeb, 0x00, 0x40, 0xa0, 0xe1,
167 0x01, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0x87, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x54, 0xe3,
168 0x31, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x54, 0xe3, 0x04, 0x00, 0x00, 0x1a, 0x01, 0x27, 0xa0, 0xe3,
169 0x18, 0x31, 0x9f, 0xe5, 0x78, 0x20, 0x83, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 0xf0, 0x81, 0xbd, 0xe8,
170 0x0c, 0x31, 0x9f, 0xe5, 0xc0, 0x30, 0x93, 0xe5, 0x3f, 0x34, 0x03, 0xe2, 0x23, 0x3c, 0xa0, 0xe1,
171 0x20, 0x00, 0x13, 0xe3, 0x01, 0x00, 0x00, 0x1a, 0x10, 0x00, 0x13, 0xe3, 0x24, 0x00, 0x00, 0x0a,
172 0xe4, 0x30, 0x9f, 0xe5, 0x02, 0x21, 0xa0, 0xe3, 0x08, 0x20, 0x83, 0xe5, 0x03, 0x21, 0x82, 0xe2,
173 0x08, 0x20, 0x83, 0xe5, 0x3f, 0x21, 0x82, 0xe2, 0x48, 0x21, 0x83, 0xe5, 0x00, 0x20, 0xa0, 0xe3,
174 0x44, 0x21, 0x83, 0xe5, 0x3f, 0x24, 0x82, 0xe2, 0x58, 0x20, 0x83, 0xe5, 0xc2, 0x24, 0x82, 0xe2,
175 0x24, 0x20, 0x83, 0xe5, 0x84, 0xff, 0xff, 0xeb, 0x00, 0x40, 0x50, 0xe2, 0x06, 0x00, 0x00, 0x1a,
176 0x0a, 0x00, 0x00, 0xea, 0x80, 0xff, 0xff, 0xeb, 0x00, 0x00, 0x54, 0xe1, 0x0a, 0x00, 0x00, 0x1a,
177 0xc0, 0x30, 0x98, 0xe5, 0x03, 0x00, 0x55, 0xe1, 0xf9, 0xff, 0xff, 0x8a, 0x01, 0x00, 0x54, 0xe3,
178 0x02, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x54, 0xe3, 0x03, 0x00, 0x00, 0x1a, 0x06, 0x00, 0x00, 0xea,
179 0x00, 0x60, 0x87, 0xe5, 0x01, 0x00, 0xa0, 0xe3, 0xf0, 0x81, 0xbd, 0xe8, 0x74, 0x20, 0x9f, 0xe5,
180 0x6c, 0x30, 0x9f, 0xe5, 0x00, 0x21, 0x83, 0xe5, 0xfe, 0xff, 0xff, 0xea, 0x00, 0x00, 0xa0, 0xe3,
181 0xf0, 0x81, 0xbd, 0xe8, 0x50, 0x30, 0x9f, 0xe5, 0x02, 0x21, 0xa0, 0xe3, 0x08, 0x20, 0x83, 0xe5,
182 0x03, 0x21, 0x82, 0xe2, 0x08, 0x20, 0x83, 0xe5, 0x3f, 0x21, 0x82, 0xe2, 0x48, 0x21, 0x83, 0xe5,
183 0x00, 0x20, 0xa0, 0xe3, 0x44, 0x21, 0x83, 0xe5, 0x3f, 0x24, 0x82, 0xe2, 0x58, 0x20, 0x83, 0xe5,
184 0xc2, 0x24, 0x82, 0xe2, 0x24, 0x20, 0x83, 0xe5, 0x5f, 0xff, 0xff, 0xeb, 0x00, 0x40, 0xa0, 0xe1,
185 0x24, 0x30, 0x9f, 0xe5, 0xc0, 0x50, 0x93, 0xe5, 0x3d, 0x59, 0x85, 0xe2, 0x09, 0x5d, 0x85, 0xe2,
186 0x03, 0x80, 0xa0, 0xe1, 0xd9, 0xff, 0xff, 0xea, 0x63, 0x68, 0x72, 0x67, 0x00, 0x00, 0x05, 0x80,
187 0x00, 0xc0, 0x05, 0x80, 0x00, 0x40, 0x04, 0x80, 0x01, 0x00, 0xff, 0xff, 0x00, 0xc0, 0x01, 0x80
188};
189unsigned char dualboot_nwze360[944] = {
190 0x10, 0x40, 0x2d, 0xe9, 0x4e, 0x00, 0x00, 0xeb, 0x10, 0x80, 0xbd, 0xe8, 0x40, 0x30, 0x9f, 0xe5,
191 0xb0, 0x30, 0x93, 0xe5, 0x03, 0x18, 0xa0, 0xe1, 0x21, 0x18, 0xa0, 0xe1, 0x34, 0x20, 0x9f, 0xe5,
192 0x02, 0x00, 0x51, 0xe1, 0x08, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x50, 0xe3, 0x01, 0x38, 0x03, 0x02,
193 0x23, 0x08, 0xa0, 0x01, 0x1e, 0xff, 0x2f, 0x01, 0x01, 0x00, 0x50, 0xe3, 0x02, 0x00, 0x00, 0x1a,
194 0x06, 0x38, 0x03, 0xe2, 0xa3, 0x08, 0xa0, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
195 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xc0, 0x05, 0x80, 0x52, 0x42, 0x00, 0x00, 0x04, 0x40, 0x2d, 0xe5,
196 0x5c, 0x20, 0x9f, 0xe5, 0xb0, 0x30, 0x92, 0xe5, 0x03, 0x48, 0xa0, 0xe1, 0x24, 0x48, 0xa0, 0xe1,
197 0x50, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x54, 0xe1, 0x02, 0x30, 0xa0, 0x11, 0x00, 0x00, 0x50, 0xe3,
198 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x09, 0x00, 0x00, 0x1a, 0x04, 0x00, 0x00, 0xea,
199 0x01, 0x38, 0xc3, 0xe3, 0x01, 0x18, 0xa0, 0xe1, 0x01, 0x18, 0x01, 0xe2, 0x01, 0x30, 0x83, 0xe1,
200 0x03, 0x00, 0x00, 0xea, 0x06, 0x38, 0xc3, 0xe3, 0x81, 0x18, 0xa0, 0xe1, 0x06, 0x18, 0x01, 0xe2,
201 0x01, 0x30, 0x83, 0xe1, 0x08, 0x20, 0x9f, 0xe5, 0xb0, 0x30, 0x82, 0xe5, 0x10, 0x00, 0xbd, 0xe8,
202 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xc0, 0x05, 0x80, 0x52, 0x42, 0x00, 0x00, 0x68, 0x30, 0x9f, 0xe5,
203 0x01, 0x20, 0xa0, 0xe3, 0x18, 0x20, 0x83, 0xe5, 0x04, 0x20, 0x83, 0xe5, 0x03, 0x20, 0xa0, 0xe1,
204 0x10, 0x30, 0x92, 0xe5, 0x01, 0x00, 0x13, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x48, 0x30, 0x9f, 0xe5,
205 0x50, 0x30, 0x93, 0xe5, 0x44, 0x20, 0x9f, 0xe5, 0x00, 0x26, 0x92, 0xe5, 0x02, 0x0c, 0x12, 0xe3,
206 0x00, 0x00, 0xa0, 0x03, 0x1e, 0xff, 0x2f, 0x01, 0xff, 0x34, 0xc3, 0xe3, 0x3f, 0x37, 0xc3, 0xe3,
207 0x41, 0x2e, 0x43, 0xe2, 0x0a, 0x20, 0x42, 0xe2, 0x63, 0x00, 0x52, 0xe3, 0x02, 0x00, 0xa0, 0x93,
208 0x1e, 0xff, 0x2f, 0x91, 0x16, 0x3d, 0x43, 0xe2, 0x0c, 0x30, 0x43, 0xe2, 0x63, 0x00, 0x53, 0xe3,
209 0x00, 0x00, 0xa0, 0x83, 0x01, 0x00, 0xa0, 0x93, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x05, 0x80,
210 0x00, 0x80, 0x01, 0x80, 0xf0, 0x41, 0x2d, 0xe9, 0x00, 0x60, 0xa0, 0xe1, 0x01, 0x70, 0xa0, 0xe1,
211 0x40, 0x32, 0x9f, 0xe5, 0x03, 0x00, 0x50, 0xe1, 0x34, 0x00, 0x00, 0x1a, 0x38, 0x32, 0x9f, 0xe5,
212 0x02, 0x21, 0xa0, 0xe3, 0x08, 0x20, 0x83, 0xe5, 0x03, 0x21, 0x82, 0xe2, 0x08, 0x20, 0x83, 0xe5,
213 0xd0, 0x20, 0x93, 0xe5, 0xff, 0x24, 0xc2, 0xe3, 0x02, 0x21, 0x82, 0xe3, 0xd0, 0x20, 0x83, 0xe5,
214 0xd0, 0x20, 0x93, 0xe5, 0x0f, 0x28, 0xc2, 0xe3, 0x01, 0x28, 0x82, 0xe3, 0xd0, 0x20, 0x83, 0xe5,
215 0xd0, 0x20, 0x93, 0xe5, 0x7f, 0x2e, 0xc2, 0xe3, 0x0f, 0x20, 0xc2, 0xe3, 0xc8, 0x20, 0x82, 0xe3,
216 0xd0, 0x20, 0x83, 0xe5, 0x01, 0x26, 0xa0, 0xe3, 0xd4, 0x20, 0x83, 0xe5, 0x34, 0x21, 0x83, 0xe5,
217 0x30, 0x11, 0x93, 0xe5, 0x03, 0x18, 0xc1, 0xe3, 0x02, 0x18, 0x81, 0xe3, 0x30, 0x11, 0x83, 0xe5,
218 0x03, 0x39, 0x43, 0xe2, 0x30, 0x10, 0x93, 0xe5, 0x0f, 0x1c, 0xc1, 0xe3, 0x01, 0x1c, 0x81, 0xe3,
219 0x30, 0x10, 0x83, 0xe5, 0x30, 0x10, 0x93, 0xe5, 0x3f, 0x10, 0xc1, 0xe3, 0x10, 0x10, 0x81, 0xe3,
220 0x30, 0x10, 0x83, 0xe5, 0x01, 0x18, 0xa0, 0xe3, 0x38, 0x10, 0x83, 0xe5, 0x80, 0x10, 0x93, 0xe5,
221 0x02, 0x15, 0x81, 0xe3, 0x80, 0x10, 0x83, 0xe5, 0x18, 0x20, 0x83, 0xe5, 0x10, 0x20, 0x93, 0xe5,
222 0x3f, 0x2a, 0xc2, 0xe3, 0x01, 0x28, 0x82, 0xe3, 0x10, 0x20, 0x83, 0xe5, 0x01, 0x39, 0x43, 0xe2,
223 0x00, 0x10, 0xa0, 0xe3, 0x20, 0x20, 0x93, 0xe5, 0x01, 0x2a, 0x82, 0xe3, 0x20, 0x20, 0x83, 0xe5,
224 0x90, 0x1f, 0x07, 0xee, 0x00, 0x00, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe1, 0xf8, 0xff, 0xff, 0xea,
225 0x00, 0x00, 0xa0, 0xe3, 0x01, 0x10, 0xa0, 0xe3, 0x87, 0xff, 0xff, 0xeb, 0x01, 0x00, 0xa0, 0xe3,
226 0x71, 0xff, 0xff, 0xeb, 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
227 0x81, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x54, 0xe3, 0x34, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x54, 0xe3,
228 0x04, 0x00, 0x00, 0x1a, 0x01, 0x27, 0xa0, 0xe3, 0x30, 0x31, 0x9f, 0xe5, 0x78, 0x20, 0x83, 0xe5,
229 0x00, 0x00, 0xa0, 0xe3, 0xf0, 0x81, 0xbd, 0xe8, 0x24, 0x31, 0x9f, 0xe5, 0xc0, 0x30, 0x93, 0xe5,
230 0x3f, 0x34, 0x03, 0xe2, 0x23, 0x3c, 0xa0, 0xe1, 0x20, 0x00, 0x13, 0xe3, 0x01, 0x00, 0x00, 0x1a,
231 0x10, 0x00, 0x13, 0xe3, 0x27, 0x00, 0x00, 0x0a, 0xfc, 0x30, 0x9f, 0xe5, 0x02, 0x21, 0xa0, 0xe3,
232 0x08, 0x20, 0x83, 0xe5, 0x03, 0x21, 0x82, 0xe2, 0x08, 0x20, 0x83, 0xe5, 0x3f, 0x21, 0x82, 0xe2,
233 0x48, 0x21, 0x83, 0xe5, 0x00, 0x20, 0xa0, 0xe3, 0x44, 0x21, 0x83, 0xe5, 0x3f, 0x24, 0x82, 0xe2,
234 0x58, 0x20, 0x83, 0xe5, 0xc2, 0x24, 0x82, 0xe2, 0x24, 0x20, 0x83, 0xe5, 0x02, 0x2c, 0xa0, 0xe3,
235 0x0e, 0x39, 0x43, 0xe2, 0x04, 0x24, 0x83, 0xe5, 0x7b, 0xff, 0xff, 0xeb, 0x00, 0x40, 0x50, 0xe2,
236 0x06, 0x00, 0x00, 0x1a, 0x0a, 0x00, 0x00, 0xea, 0x77, 0xff, 0xff, 0xeb, 0x00, 0x00, 0x54, 0xe1,
237 0x0a, 0x00, 0x00, 0x1a, 0xc0, 0x30, 0x98, 0xe5, 0x03, 0x00, 0x55, 0xe1, 0xf9, 0xff, 0xff, 0x8a,
238 0x01, 0x00, 0x54, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x54, 0xe3, 0x03, 0x00, 0x00, 0x1a,
239 0x06, 0x00, 0x00, 0xea, 0x00, 0x60, 0x87, 0xe5, 0x01, 0x00, 0xa0, 0xe3, 0xf0, 0x81, 0xbd, 0xe8,
240 0x80, 0x20, 0x9f, 0xe5, 0x78, 0x30, 0x9f, 0xe5, 0x00, 0x21, 0x83, 0xe5, 0xfe, 0xff, 0xff, 0xea,
241 0x00, 0x00, 0xa0, 0xe3, 0xf0, 0x81, 0xbd, 0xe8, 0x5c, 0x30, 0x9f, 0xe5, 0x02, 0x21, 0xa0, 0xe3,
242 0x08, 0x20, 0x83, 0xe5, 0x03, 0x21, 0x82, 0xe2, 0x08, 0x20, 0x83, 0xe5, 0x3f, 0x21, 0x82, 0xe2,
243 0x48, 0x21, 0x83, 0xe5, 0x00, 0x20, 0xa0, 0xe3, 0x44, 0x21, 0x83, 0xe5, 0x3f, 0x24, 0x82, 0xe2,
244 0x58, 0x20, 0x83, 0xe5, 0xc2, 0x24, 0x82, 0xe2, 0x24, 0x20, 0x83, 0xe5, 0x02, 0x2c, 0xa0, 0xe3,
245 0x0e, 0x39, 0x43, 0xe2, 0x04, 0x24, 0x83, 0xe5, 0x53, 0xff, 0xff, 0xeb, 0x00, 0x40, 0xa0, 0xe1,
246 0x24, 0x30, 0x9f, 0xe5, 0xc0, 0x50, 0x93, 0xe5, 0x3d, 0x59, 0x85, 0xe2, 0x09, 0x5d, 0x85, 0xe2,
247 0x03, 0x80, 0xa0, 0xe1, 0xd6, 0xff, 0xff, 0xea, 0x63, 0x68, 0x72, 0x67, 0x00, 0x00, 0x05, 0x80,
248 0x00, 0xc0, 0x05, 0x80, 0x00, 0x40, 0x04, 0x80, 0x01, 0x00, 0xff, 0xff, 0x00, 0xc0, 0x01, 0x80
249};
250unsigned char dualboot_zenxfistyle[660] = {
251 0x10, 0x40, 0x2d, 0xe9, 0x30, 0x00, 0x00, 0xeb, 0x10, 0x80, 0xbd, 0xe8, 0x40, 0x30, 0x9f, 0xe5,
252 0xb0, 0x30, 0x93, 0xe5, 0x03, 0x18, 0xa0, 0xe1, 0x21, 0x18, 0xa0, 0xe1, 0x34, 0x20, 0x9f, 0xe5,
253 0x02, 0x00, 0x51, 0xe1, 0x08, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x50, 0xe3, 0x01, 0x38, 0x03, 0x02,
254 0x23, 0x08, 0xa0, 0x01, 0x1e, 0xff, 0x2f, 0x01, 0x01, 0x00, 0x50, 0xe3, 0x02, 0x00, 0x00, 0x1a,
255 0x06, 0x38, 0x03, 0xe2, 0xa3, 0x08, 0xa0, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
256 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xc0, 0x05, 0x80, 0x52, 0x42, 0x00, 0x00, 0x04, 0x40, 0x2d, 0xe5,
257 0x5c, 0x20, 0x9f, 0xe5, 0xb0, 0x30, 0x92, 0xe5, 0x03, 0x48, 0xa0, 0xe1, 0x24, 0x48, 0xa0, 0xe1,
258 0x50, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x54, 0xe1, 0x02, 0x30, 0xa0, 0x11, 0x00, 0x00, 0x50, 0xe3,
259 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x09, 0x00, 0x00, 0x1a, 0x04, 0x00, 0x00, 0xea,
260 0x01, 0x38, 0xc3, 0xe3, 0x01, 0x18, 0xa0, 0xe1, 0x01, 0x18, 0x01, 0xe2, 0x01, 0x30, 0x83, 0xe1,
261 0x03, 0x00, 0x00, 0xea, 0x06, 0x38, 0xc3, 0xe3, 0x81, 0x18, 0xa0, 0xe1, 0x06, 0x18, 0x01, 0xe2,
262 0x01, 0x30, 0x83, 0xe1, 0x08, 0x20, 0x9f, 0xe5, 0xb0, 0x30, 0x82, 0xe5, 0x10, 0x00, 0xbd, 0xe8,
263 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xc0, 0x05, 0x80, 0x52, 0x42, 0x00, 0x00, 0x70, 0x40, 0x2d, 0xe9,
264 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x60, 0xa0, 0xe1, 0xa4, 0x31, 0x9f, 0xe5, 0x03, 0x00, 0x50, 0xe1,
265 0x34, 0x00, 0x00, 0x1a, 0x9c, 0x31, 0x9f, 0xe5, 0x02, 0x21, 0xa0, 0xe3, 0x08, 0x20, 0x83, 0xe5,
266 0x03, 0x21, 0x82, 0xe2, 0x08, 0x20, 0x83, 0xe5, 0xd0, 0x20, 0x93, 0xe5, 0xff, 0x24, 0xc2, 0xe3,
267 0x02, 0x21, 0x82, 0xe3, 0xd0, 0x20, 0x83, 0xe5, 0xd0, 0x20, 0x93, 0xe5, 0x0f, 0x28, 0xc2, 0xe3,
268 0x01, 0x28, 0x82, 0xe3, 0xd0, 0x20, 0x83, 0xe5, 0xd0, 0x20, 0x93, 0xe5, 0x7f, 0x2e, 0xc2, 0xe3,
269 0x0f, 0x20, 0xc2, 0xe3, 0xc8, 0x20, 0x82, 0xe3, 0xd0, 0x20, 0x83, 0xe5, 0x01, 0x26, 0xa0, 0xe3,
270 0xd4, 0x20, 0x83, 0xe5, 0x34, 0x21, 0x83, 0xe5, 0x30, 0x11, 0x93, 0xe5, 0x03, 0x18, 0xc1, 0xe3,
271 0x02, 0x18, 0x81, 0xe3, 0x30, 0x11, 0x83, 0xe5, 0x03, 0x39, 0x43, 0xe2, 0x30, 0x10, 0x93, 0xe5,
272 0x0f, 0x1c, 0xc1, 0xe3, 0x01, 0x1c, 0x81, 0xe3, 0x30, 0x10, 0x83, 0xe5, 0x30, 0x10, 0x93, 0xe5,
273 0x3f, 0x10, 0xc1, 0xe3, 0x10, 0x10, 0x81, 0xe3, 0x30, 0x10, 0x83, 0xe5, 0x01, 0x18, 0xa0, 0xe3,
274 0x38, 0x10, 0x83, 0xe5, 0x80, 0x10, 0x93, 0xe5, 0x02, 0x15, 0x81, 0xe3, 0x80, 0x10, 0x83, 0xe5,
275 0x18, 0x20, 0x83, 0xe5, 0x10, 0x20, 0x93, 0xe5, 0x3f, 0x2a, 0xc2, 0xe3, 0x01, 0x28, 0x82, 0xe3,
276 0x10, 0x20, 0x83, 0xe5, 0x01, 0x39, 0x43, 0xe2, 0x00, 0x10, 0xa0, 0xe3, 0x20, 0x20, 0x93, 0xe5,
277 0x01, 0x2a, 0x82, 0xe3, 0x20, 0x20, 0x83, 0xe5, 0x90, 0x1f, 0x07, 0xee, 0x00, 0x00, 0xa0, 0xe1,
278 0x00, 0x00, 0xa0, 0xe1, 0xf8, 0xff, 0xff, 0xea, 0x00, 0x00, 0xa0, 0xe3, 0x01, 0x10, 0xa0, 0xe3,
279 0xa5, 0xff, 0xff, 0xeb, 0x01, 0x00, 0xa0, 0xe3, 0x8f, 0xff, 0xff, 0xeb, 0x00, 0x50, 0xa0, 0xe1,
280 0x01, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0x9f, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x55, 0xe3,
281 0x25, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x55, 0xe3, 0x04, 0x00, 0x00, 0x1a, 0x01, 0x27, 0xa0, 0xe3,
282 0x94, 0x30, 0x9f, 0xe5, 0x78, 0x20, 0x83, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 0x70, 0x80, 0xbd, 0xe8,
283 0x88, 0x30, 0x9f, 0xe5, 0xc0, 0x30, 0x93, 0xe5, 0x78, 0x30, 0x9f, 0xe5, 0x02, 0x21, 0xa0, 0xe3,
284 0x08, 0x20, 0x83, 0xe5, 0x03, 0x21, 0x82, 0xe2, 0x08, 0x20, 0x83, 0xe5, 0x0f, 0x2c, 0xa0, 0xe3,
285 0x48, 0x21, 0x83, 0xe5, 0x0d, 0x2c, 0x42, 0xe2, 0x44, 0x21, 0x83, 0xe5, 0x3f, 0x24, 0xa0, 0xe3,
286 0x78, 0x20, 0x83, 0xe5, 0xc5, 0x24, 0x82, 0xe2, 0x24, 0x20, 0x83, 0xe5, 0x04, 0x20, 0xa0, 0xe3,
287 0x18, 0x20, 0x83, 0xe5, 0x04, 0x20, 0x83, 0xe5, 0x10, 0x20, 0x93, 0xe5, 0x04, 0x00, 0x12, 0xe3,
288 0xfc, 0xff, 0xff, 0x0a, 0x2c, 0x30, 0x9f, 0xe5, 0x70, 0x30, 0x93, 0xe5, 0xff, 0x34, 0xc3, 0xe3,
289 0x3f, 0x37, 0xc3, 0xe3, 0xcb, 0x3f, 0x43, 0xe2, 0x03, 0x30, 0x43, 0xe2, 0x63, 0x00, 0x53, 0xe3,
290 0x00, 0x40, 0x86, 0x85, 0x01, 0x00, 0xa0, 0x83, 0x70, 0x80, 0xbd, 0x88, 0x00, 0x00, 0xa0, 0xe3,
291 0x70, 0x80, 0xbd, 0xe8, 0x63, 0x68, 0x72, 0x67, 0x00, 0x00, 0x05, 0x80, 0x00, 0xc0, 0x05, 0x80,
292 0x00, 0x40, 0x04, 0x80
293};
diff --git a/utils/mkimxboot/dualboot.h b/utils/mkimxboot/dualboot.h
new file mode 100644
index 0000000000..fbce031d56
--- /dev/null
+++ b/utils/mkimxboot/dualboot.h
@@ -0,0 +1,8 @@
1/* Generated by bin2c */
2
3extern unsigned char dualboot_fuzeplus[728];
4extern unsigned char dualboot_zenxfi2[608];
5extern unsigned char dualboot_zenxfi3[572];
6extern unsigned char dualboot_nwze370[896];
7extern unsigned char dualboot_nwze360[944];
8extern unsigned char dualboot_zenxfistyle[660];
diff --git a/utils/mkimxboot/dualboot/Makefile b/utils/mkimxboot/dualboot/Makefile
new file mode 100644
index 0000000000..b80233226a
--- /dev/null
+++ b/utils/mkimxboot/dualboot/Makefile
@@ -0,0 +1,48 @@
1CC=gcc
2LD=ld
3OC=objcopy
4PREFIX?=arm-elf-eabi-
5IMX233_PATH=../../../firmware/target/arm/imx233
6CFLAGS=-mcpu=arm926ej-s -std=gnu99 -I. -I$(IMX233_PATH) -nostdlib -ffreestanding -fomit-frame-pointer -O
7# Edit the following variables when adding a new target.
8# mkimxboot.c also needs to be edited to refer to these
9# To add a new target x you need to:
10# 1) add x to the list in TARGETS
11# 2) create a variable named OPT_x of the form:
12# OPT_x=target specific defines
13TARGETS=fuzeplus zenxfi2 zenxfi3 nwze370 nwze360 zenxfistyle
14OPT_fuzeplus=-DSANSA_FUZEPLUS -DIMX233_SUBTARGET=3780
15OPT_zenxfi2=-DCREATIVE_ZENXFI2 -DIMX233_SUBTARGET=3780
16OPT_zenxfi3=-DCREATIVE_ZENXFI3 -DIMX233_SUBTARGET=3780
17OPT_nwze370=-DSONY_NWZE370 -DIMX233_SUBTARGET=3780
18OPT_nwze360=-DSONY_NWZE360 -DIMX233_SUBTARGET=3780
19OPT_zenxfistyle=-DCREATIVE_ZENXFISTYLE -DIMX233_SUBTARGET=3780
20
21BOOTOBJS=$(patsubst %, dualboot_%.o, $(TARGETS))
22BOOTBINS=$(patsubst %, dualboot_%.arm-bin, $(TARGETS))
23BOOTELFS=$(patsubst %, dualboot_%.arm-elf, $(TARGETS))
24
25all: ../dualboot.h ../dualboot.c $(BOOTELFS)
26
27# Dualboot bootloaders
28
29dualboot_%.o: dualboot.c
30 $(PREFIX)$(CC) $(CFLAGS) $(OPT_$(@:dualboot_%.o=%)) -c -o $@ $^
31
32dualboot_%.arm-elf: dualboot_%.o
33 $(PREFIX)$(LD) $(LDFLAGS) -Tdualboot.lds -o $@ $<
34
35# Rules for the ARM code embedded in mkamsboot - assemble, link, then extract
36# the binary code and finally convert to .h for building in mkamsboot
37
38%.arm-bin: %.arm-elf
39 $(PREFIX)$(OC) -O binary $< $@
40
41../dualboot.c ../dualboot.h: $(BOOTBINS) bin2c
42 ./bin2c ../dualboot $(BOOTBINS)
43
44bin2c: bin2c.c
45 $(CC) -o bin2c bin2c.c
46
47clean:
48 rm -f *~ bin2c $(BOOTBINS) $(BOOTOBJS) $(BOOTELFS)
diff --git a/utils/mkimxboot/dualboot/bin2c.c b/utils/mkimxboot/dualboot/bin2c.c
new file mode 100644
index 0000000000..b02af88a4d
--- /dev/null
+++ b/utils/mkimxboot/dualboot/bin2c.c
@@ -0,0 +1,140 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdio.h>
23#include <string.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <unistd.h>
27#include <fcntl.h>
28#include <stdlib.h>
29#include <libgen.h>
30
31#ifndef O_BINARY
32#define O_BINARY 0
33#endif
34
35static off_t filesize(int fd)
36{
37 struct stat buf;
38
39 fstat(fd,&buf);
40 return buf.st_size;
41}
42
43static void write_cfile(const unsigned char* buf, off_t len, FILE* fp, const char *name)
44{
45 int i;
46
47 fprintf(fp,"unsigned char %s[%ld] = {",name,len);
48
49 for (i=0;i<len;i++) {
50 if ((i % 16) == 0) {
51 fprintf(fp,"\n ");
52 }
53 if (i == (len-1)) {
54 fprintf(fp,"0x%02x",buf[i]);
55 } else if ((i % 16) == 15) {
56 fprintf(fp,"0x%02x,",buf[i]);
57 } else {
58 fprintf(fp,"0x%02x, ",buf[i]);
59 }
60 }
61 fprintf(fp,"\n};\n");
62}
63
64int main (int argc, char* argv[])
65{
66 char* cname;
67 int i;
68 FILE *cfile, *hfile;
69 char cfilename[256], hfilename[256];
70
71 if (argc < 3) {
72 fprintf(stderr,"Usage: bin2c cname file1 [file2 [file3 ...]]\n");
73 return 1;
74 }
75
76 cname=argv[1];
77
78 snprintf(cfilename,256,"%s.c",cname);
79 cfile = fopen(cfilename,"w+");
80 if (cfile == NULL) {
81 fprintf(stderr,"Couldn't open %s\n",cfilename);
82 return 2;
83 }
84
85 snprintf(hfilename,256,"%s.h",cname);
86 hfile = fopen(hfilename,"w+");
87 if (hfile == NULL) {
88 fprintf(stderr,"Couldn't open %s\n",hfilename);
89 fclose(cfile);
90 return 3;
91 }
92
93 fprintf(cfile,"/* Generated by bin2c */\n\n");
94 fprintf(cfile,"#include \"%s\"\n\n", basename(hfilename));
95 fprintf(hfile,"/* Generated by bin2c */\n\n");
96
97 for(i=0; i < argc - 2; i++) {
98 unsigned char* buf;
99 off_t len;
100 off_t orig_len;
101 char *ext;
102 char *array = argv[2+i];
103
104 int fd = open(array,O_RDONLY|O_BINARY);
105 if (fd < 0) {
106 fprintf(stderr,"Can not open %s\n",argv[2+i]);
107 fclose(cfile);
108 fclose(hfile);
109 return 4;
110 }
111
112 orig_len = filesize(fd);
113 /* pad to 32bit */
114 len = (orig_len + 3) & ~3;
115
116 buf = malloc(len);
117 if (read(fd,buf,orig_len) < orig_len) {
118 fprintf(stderr,"Short read, aborting\n");
119 return 5;
120 }
121
122 /* pad to 32bit with zeros */
123 if (len > orig_len)
124 memset(buf+orig_len, 0, len-orig_len);
125
126 /* remove file extension */
127 ext = strchr (array, '.');
128 if (ext != NULL)
129 *ext = '\0';
130 write_cfile (buf, len, cfile, array);
131 fprintf(hfile,"extern unsigned char %s[%ld];\n",array,len);
132
133 close(fd);
134 }
135
136 fclose(cfile);
137 fclose(hfile);
138
139 return 0;
140}
diff --git a/utils/mkimxboot/dualboot/config.h b/utils/mkimxboot/dualboot/config.h
new file mode 100644
index 0000000000..e9ea8d4a35
--- /dev/null
+++ b/utils/mkimxboot/dualboot/config.h
@@ -0,0 +1,26 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2013 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22/** mostly empty, used by register files and dualboot */
23#define COMPILE_DUALBOOT_STUB
24
25/* obviously we have the dualboot stub! */
26#define HAVE_DUALBOOT_STUB
diff --git a/utils/mkimxboot/dualboot/dualboot.c b/utils/mkimxboot/dualboot/dualboot.c
new file mode 100644
index 0000000000..77b816bf76
--- /dev/null
+++ b/utils/mkimxboot/dualboot/dualboot.c
@@ -0,0 +1,323 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2013 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "regs/pinctrl.h"
22#include "regs/power.h"
23#include "regs/lradc.h"
24#include "regs/digctl.h"
25#include "regs/clkctrl.h"
26
27#define BOOT_ROM_CONTINUE 0 /* continue boot */
28#define BOOT_ROM_SECTION 1 /* switch to new section *result_id */
29
30#define BOOT_ARG_CHARGE ('c' | 'h' << 8 | 'r' << 16 | 'g' << 24)
31/** additional defines */
32#define BP_LRADC_CTRL4_LRADCxSELECT(x) (4 * (x))
33#define BM_LRADC_CTRL4_LRADCxSELECT(x) (0xf << (4 * (x)))
34
35typedef unsigned long uint32_t;
36
37/* we include the dualboot rtc code directly */
38#include "dualboot-imx233.h"
39#include "dualboot-imx233.c"
40
41// target specific boot context
42enum context_t
43{
44 CONTEXT_NORMAL, /* normal boot */
45 CONTEXT_USB, /* USB plugged boot */
46 CONTEXT_RTC, /* RTC wake up boot */
47};
48// target specific boot decision
49enum boot_t
50{
51 BOOT_STOP, /* power down */
52 BOOT_ROCK, /* boot to Rockbox */
53 BOOT_OF, /* boot to OF */
54};
55
56/**
57 * Helper functions
58 */
59
60static inline int __attribute__((always_inline)) read_gpio(int bank, int pin)
61{
62 return (HW_PINCTRL_DINn(bank) >> pin) & 1;
63}
64
65static inline int __attribute__((always_inline)) read_pswitch(void)
66{
67#if IMX233_SUBTARGET >= 3700
68 return BF_RD(POWER_STS, PSWITCH);
69#else
70 return BF_RD(DIGCTL_STATUS, PSWITCH);
71#endif
72}
73
74/* only works for channels <=7, always divide by 2, never accumulates */
75static inline void __attribute__((always_inline)) setup_lradc(int src)
76{
77 BF_CLR(LRADC_CTRL0, SFTRST);
78 BF_CLR(LRADC_CTRL0, CLKGATE);
79#if IMX233_SUBTARGET >= 3700
80 HW_LRADC_CTRL4_CLR = BM_LRADC_CTRL4_LRADCxSELECT(src);
81 HW_LRADC_CTRL4_SET = src << BP_LRADC_CTRL4_LRADCxSELECT(src);
82#endif
83 HW_LRADC_CHn_CLR(src) = BM_OR(LRADC_CHn, NUM_SAMPLES, ACCUMULATE);
84 BF_WR(LRADC_CTRL2_SET, DIVIDE_BY_TWO(1 << src));
85}
86
87#define BP_LRADC_CTRL1_LRADCx_IRQ(x) (x)
88#define BM_LRADC_CTRL1_LRADCx_IRQ(x) (1 << (x))
89
90static inline int __attribute__((always_inline)) read_lradc(int src)
91{
92 BF_CLR(LRADC_CTRL1, LRADCx_IRQ(src));
93 BF_WR(LRADC_CTRL0_SET, SCHEDULE(1 << src));
94 while(!BF_RD(LRADC_CTRL1, LRADCx_IRQ(src)));
95 return BF_RD(LRADC_CHn(src), VALUE);
96}
97
98static inline void __attribute__((noreturn)) power_down()
99{
100#ifdef SANSA_FUZEPLUS
101 /* B0P09: this pin seems to be important to shutdown the hardware properly */
102 HW_PINCTRL_MUXSELn_SET(0) = 3 << 18;
103 HW_PINCTRL_DOEn(0) = 1 << 9;
104 HW_PINCTRL_DOUTn(0) = 1 << 9;
105#endif
106 /* power down */
107 HW_POWER_RESET = BM_OR(POWER_RESET, UNLOCK, PWD);
108 while(1);
109}
110
111/**
112 * Boot decision functions
113 */
114
115#if defined(SANSA_FUZEPLUS)
116static enum boot_t boot_decision(enum context_t context)
117{
118 /* if volume down is hold, boot to OF */
119 if(!read_gpio(1, 30))
120 return BOOT_OF;
121 /* on normal boot, make sure power button is hold long enough */
122 if(context == CONTEXT_NORMAL)
123 {
124 // monitor PSWITCH
125 int count = 0;
126 for(int i = 0; i < 550000; i++)
127 if(read_pswitch() == 1)
128 count++;
129 if(count < 400000)
130 return BOOT_STOP;
131 }
132 return BOOT_ROCK;
133}
134#elif defined(CREATIVE_ZENXFI2)
135static int boot_decision(int context)
136{
137 /* We are lacking buttons on the Zen X-Fi2 because on USB, the select button
138 * enters recovery mode ! So we can only use power but power is used to power up
139 * on normal boots and then select is free ! Thus use a non-uniform scheme:
140 * - normal boot/RTC:
141 * - no key: Rockbox
142 * - select: OF
143 * - USB boot:
144 * - no key: Rockbox
145 * - power: OF
146 */
147 if(context == CONTEXT_USB)
148 return read_pswitch() == 1 ? BOOT_OF : BOOT_ROCK;
149 else
150 return !read_gpio(0, 14) ? BOOT_OF : BOOT_ROCK;
151}
152#elif defined(CREATIVE_ZENXFI3)
153static int boot_decision(int context)
154{
155 /* if volume down is hold, boot to OF */
156 return !read_gpio(2, 7) ? BOOT_OF : BOOT_ROCK;
157}
158#elif defined(SONY_NWZE360) || defined(SONY_NWZE370)
159static int local_decision(void)
160{
161 /* read keys and pswitch */
162 int val = read_lradc(0);
163 /* if hold is on, power off
164 * if back is pressed, boot to OF
165 * if play is pressed, boot RB
166 * otherwise power off */
167#ifdef SONY_NWZE360
168 if(read_gpio(0, 9) == 0)
169 return BOOT_STOP;
170#endif
171 if(val >= 1050 && val < 1150)
172 return BOOT_OF;
173 if(val >= 1420 && val < 1520)
174 return BOOT_ROCK;
175 return BOOT_STOP;
176}
177
178static int boot_decision(int context)
179{
180 setup_lradc(0); // setup LRADC channel 0 to read keys
181#ifdef SONY_NWZE360
182 HW_PINCTRL_PULLn_SET(0) = 1 << 9; // enable pullup on hold key (B0P09)
183#endif
184 /* make a decision */
185 int decision = local_decision();
186 /* in USB or alarm context, stick to it */
187 if(context == CONTEXT_USB || context == CONTEXT_RTC)
188 {
189 /* never power down so replace power off decision by rockbox */
190 return decision == BOOT_STOP ? BOOT_ROCK : decision;
191 }
192 /* otherwise start a 1 second timeout. Any decision change
193 * will result in power down */
194 uint32_t tmo = HW_DIGCTL_MICROSECONDS + 1000000;
195 while(HW_DIGCTL_MICROSECONDS < tmo)
196 {
197 int new_dec = local_decision();
198 if(new_dec != decision)
199 return BOOT_STOP;
200 }
201 return decision;
202}
203#elif defined(CREATIVE_ZENXFISTYLE)
204static int boot_decision(int context)
205{
206 setup_lradc(2); // setup LRADC channel 2 to read keys
207 /* make a decision */
208 int val = read_lradc(2);
209 /* boot to OF if left is hold
210 * NOTE: VDDIO is set to 3.1V initially and the resistor ladder is wired to
211 * VDDIO so these values are not the same as in the main binary which is
212 * calibrated for VDDIO=3.3V */
213 if(val >= 815 && val < 915)
214 return BOOT_OF;
215 return BOOT_ROCK;
216}
217#else
218#warning You should define a target specific boot decision function
219static int boot_decision(int context)
220{
221 return BOOT_ROCK;
222}
223#endif
224
225/**
226 * Context functions
227 */
228static inline enum context_t get_context(void)
229{
230#if IMX233_SUBTARGET >= 3780
231 /* On the imx233 it's easy because we know the power up source */
232 unsigned pwrup_src = BF_RD(POWER_STS, PWRUP_SOURCE);
233 if(pwrup_src & (1 << 5))
234 return CONTEXT_USB;
235 else if(pwrup_src & (1 << 4))
236 return CONTEXT_RTC;
237 else
238 return CONTEXT_NORMAL;
239#else
240 /* On the other targets, we need to poke a few more registers */
241#endif
242}
243
244/**
245 * Charging function
246 */
247static inline void do_charge(void)
248{
249 BF_CLR(LRADC_CTRL0, SFTRST);
250 BF_CLR(LRADC_CTRL0, CLKGATE);
251 BF_WR(LRADC_DELAYn(0), TRIGGER_LRADCS(0x80));
252 BF_WR(LRADC_DELAYn(0), TRIGGER_DELAYS(0x1));
253 BF_WR(LRADC_DELAYn(0), DELAY(200));
254 BF_SET(LRADC_DELAYn(0), KICK);
255 BF_SET(LRADC_CONVERSION, AUTOMATIC);
256 BF_WR(LRADC_CONVERSION, SCALE_FACTOR_V(LI_ION));
257 BF_WR(POWER_CHARGE, STOP_ILIMIT(1));
258 BF_WR(POWER_CHARGE, BATTCHRG_I(0x10));
259 BF_CLR(POWER_CHARGE, PWD_BATTCHRG);
260#if IMX233_SUBTARGET >= 3780
261 BF_WR(POWER_DCDC4P2, ENABLE_4P2(1));
262 BF_CLR(POWER_5VCTRL, PWD_CHARGE_4P2);
263 BF_WR(POWER_5VCTRL, CHARGE_4P2_ILIMIT(0x10));
264#endif
265 while(1)
266 {
267 BF_WR(CLKCTRL_CPU, INTERRUPT_WAIT(1));
268 asm volatile (
269 "mcr p15, 0, %0, c7, c0, 4 \n" /* Wait for interrupt */
270 "nop\n" /* Datasheet unclear: "The lr sent to handler points here after RTI"*/
271 "nop\n"
272 : : "r"(0)
273 );
274 }
275}
276
277static void set_updater_bits(void)
278{
279 /* The OF will continue to updater if we clear 18 of PERSISTENT1.
280 * See dualboot-imx233.c in firmware/ for more explanation */
281 HW_RTC_PERSISTENT1_CLR = 1 << 18;
282}
283
284int main(uint32_t arg, uint32_t *result_id)
285{
286 if(arg == BOOT_ARG_CHARGE)
287 do_charge();
288 /* tell rockbox that we can handle boot mode */
289 imx233_dualboot_set_field(DUALBOOT_CAP_BOOT, 1);
290 /* if we were asked to boot in a special mode, do so */
291 unsigned boot_mode = imx233_dualboot_get_field(DUALBOOT_BOOT);
292 /* clear boot mode to avoid any loop */
293 imx233_dualboot_set_field(DUALBOOT_BOOT, IMX233_BOOT_NORMAL);
294 switch(boot_mode)
295 {
296 case IMX233_BOOT_UPDATER:
297 set_updater_bits();
298 /* fallthrough */
299 case IMX233_BOOT_OF:
300 /* continue booting */
301 return BOOT_ROM_CONTINUE;
302 case IMX233_BOOT_NORMAL:
303 default:
304 break;
305 }
306 /* normal boot */
307 switch(boot_decision(get_context()))
308 {
309 case BOOT_ROCK:
310 *result_id = arg;
311 return BOOT_ROM_SECTION;
312 case BOOT_OF:
313 return BOOT_ROM_CONTINUE;
314 case BOOT_STOP:
315 default:
316 power_down();
317 }
318}
319
320int __attribute__((section(".start"))) start(uint32_t arg, uint32_t *result_id)
321{
322 return main(arg, result_id);
323}
diff --git a/utils/mkimxboot/dualboot/dualboot.lds b/utils/mkimxboot/dualboot/dualboot.lds
new file mode 100644
index 0000000000..09739aee15
--- /dev/null
+++ b/utils/mkimxboot/dualboot/dualboot.lds
@@ -0,0 +1,17 @@
1ENTRY(start)
2OUTPUT_FORMAT(elf32-littlearm)
3OUTPUT_ARCH(arm)
4
5MEMORY
6{
7 OCRAM : ORIGIN = 0, LENGTH = 0x8000
8}
9
10SECTIONS
11{
12 .text 0 :
13 {
14 *(.start*)
15 *(.text*)
16 } > OCRAM
17}
diff --git a/utils/mkimxboot/main.c b/utils/mkimxboot/main.c
new file mode 100644
index 0000000000..5b8cceb044
--- /dev/null
+++ b/utils/mkimxboot/main.c
@@ -0,0 +1,289 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <getopt.h>
23#include <stdlib.h>
24#include <stdio.h>
25#include <string.h>
26#include "mkimxboot.h"
27
28struct imx_variant_t
29{
30 const char *name;
31 enum imx_firmware_variant_t variant;
32};
33
34static struct imx_variant_t imx_variants[] =
35{
36 { "default", VARIANT_DEFAULT },
37 { "zenxfi2-recovery", VARIANT_ZENXFI2_RECOVERY },
38 { "zenxfi2-nand", VARIANT_ZENXFI2_NAND },
39 { "zenxfi2-sd", VARIANT_ZENXFI2_SD },
40 { "zenxfistyle-recovery", VARIANT_ZENXFISTYLE_RECOVERY },
41 { "zenstyle-recovery", VARIANT_ZENSTYLE_RECOVERY },
42};
43
44#define NR_VARIANTS sizeof(imx_variants) / sizeof(imx_variants[0])
45
46struct model_t
47{
48 const char *name;
49 enum imx_model_t model;
50};
51
52struct model_t imx_models[] =
53{
54 { "unknown", MODEL_UNKNOWN },
55 { "fuzeplus", MODEL_FUZEPLUS },
56 { "zenxfi2", MODEL_ZENXFI2 },
57 { "zenxfi3", MODEL_ZENXFI3 },
58 { "zenxfistyle", MODEL_ZENXFISTYLE },
59 { "zenstyle", MODEL_ZENSTYLE },
60 { "nwze370", MODEL_NWZE370 },
61 { "nwze360", MODEL_NWZE360 },
62};
63
64#define NR_MODELS sizeof(imx_models) / sizeof(imx_models[0])
65
66static void usage(void)
67{
68 printf("Usage: mkimxboot [options | file]...\n");
69 printf("Options:\n");
70 printf(" -?/--help Display this message\n");
71 printf(" -o <file> Set output file\n");
72 printf(" -i <file> Set input file\n");
73 printf(" -b <file> Set boot file\n");
74 printf(" -d/--debug Enable debug output\n");
75 printf(" -t <type> Set type (dualboot, singleboot, recovery, origfw, charge)\n");
76 printf(" -v <v> Set variant\n");
77 printf(" -x Dump device informations\n");
78 printf(" -p <ver> Force product and component version\n");
79 printf(" -5 <type> Compute <type> MD5 sum of the input file\n");
80 printf(" -m <model> Specify model (useful for soft MD5 sum)\n");
81 printf("Supported variants: (default is standard)\n");
82 printf(" ");
83 for(size_t i = 0; i < NR_VARIANTS; i++)
84 {
85 if(i != 0)
86 printf(", ");
87 printf("%s", imx_variants[i].name);
88 }
89 printf("\n");
90 printf("Supported models: (default is unknown)\n");
91 for(size_t i = 0; i < NR_MODELS; i++)
92 {
93 if(i != 0)
94 printf(", ");
95 printf("%s", imx_models[i].name);
96 }
97 printf("\n");
98 printf("By default a dualboot image is built\n");
99 printf("This tools supports the following format for the boot file:\n");
100 printf("- rockbox scramble format\n");
101 printf("- elf format\n");
102 printf("Additional checks will be performed on rockbox scramble format to\n");
103 printf("ensure soundness of operation.\n");
104 printf("There are two types of MD5 sums: 'full' or 'soft'.\n");
105 printf("- full MD5 sum applies to the whole file\n");
106 printf("- soft MD5 sum for SB files accounts for relevant parts only\n");
107 exit(1);
108}
109
110static int print_md5(const char *file, const char *type)
111{
112 uint8_t md5sum[16];
113 enum imx_error_t err;
114 if(strcmp(type, "full") == 0)
115 err = compute_md5sum(file, md5sum);
116 else if(strcmp(type, "soft") == 0)
117 err = compute_soft_md5sum(file, md5sum);
118 else
119 {
120 printf("Invalid md5sum type '%s'\n", type);
121 return 1;
122 }
123 if(err != IMX_SUCCESS)
124 {
125 printf("There was an error when computing the MD5 sum: %d\n", err);
126 return 2;
127 }
128 printf("%s MD5 sum: ", type);
129 for(int i = 0; i < 16; i++)
130 printf("%02x", md5sum[i]);
131 printf("\n");
132 return 0;
133}
134
135int main(int argc, char *argv[])
136{
137 char *infile = NULL;
138 char *outfile = NULL;
139 char *bootfile = NULL;
140 enum imx_firmware_variant_t variant = VARIANT_DEFAULT;
141 enum imx_output_type_t type = IMX_DUALBOOT;
142 enum imx_model_t model = MODEL_UNKNOWN;
143 bool debug = false;
144 const char *md5type = NULL;
145 const char *force_version = NULL;
146
147 if(argc == 1)
148 usage();
149
150 while(1)
151 {
152 static struct option long_options[] =
153 {
154 {"help", no_argument, 0, 'h'},
155 {"in-file", no_argument, 0, 'i'},
156 {"out-file", required_argument, 0, 'o'},
157 {"boot-file", required_argument, 0, 'b'},
158 {"debug", no_argument, 0, 'd'},
159 {"type", required_argument, 0, 't'},
160 {"variant", required_argument, 0, 'v'},
161 {"dev-info", no_argument, 0, 'x'},
162 {"model", required_argument, 0, 'm'},
163 {"md5", required_argument, 0, '5'},
164 {0, 0, 0, 0}
165 };
166
167 int c = getopt_long(argc, argv, "hdi:o:b:t:v:xp:m:5:", long_options, NULL);
168 if(c == -1)
169 break;
170 switch(c)
171 {
172 case 'd':
173 debug = true;
174 break;
175 case 'h':
176 usage();
177 break;
178 case 'o':
179 outfile = optarg;
180 break;
181 case 'i':
182 infile = optarg;
183 break;
184 case 'b':
185 bootfile = optarg;
186 break;
187 case 't':
188 if(strcmp(optarg, "dualboot") == 0)
189 type = IMX_DUALBOOT;
190 else if(strcmp(optarg, "singleboot") == 0)
191 type = IMX_SINGLEBOOT;
192 else if(strcmp(optarg, "recovery") == 0)
193 type = IMX_RECOVERY;
194 else if(strcmp(optarg, "charge") == 0)
195 type = IMX_CHARGE;
196 else if(strcmp(optarg, "origfw") == 0)
197 type = IMX_ORIG_FW;
198 else
199 {
200 printf("Invalid boot type '%s'\n", optarg);
201 return 1;
202 }
203 break;
204 case 'v':
205 {
206 for(size_t i = 0; i < NR_VARIANTS; i++)
207 {
208 if(strcmp(optarg, imx_variants[i].name) == 0)
209 {
210 variant = imx_variants[i].variant;
211 goto Lok;
212 }
213 }
214 printf("Invalid variant '%s'\n", optarg);
215 return 1;
216
217 Lok:
218 break;
219 }
220 case 'x':
221 dump_imx_dev_info("");
222 printf("variant mapping:\n");
223 for(int i = 0; i < sizeof(imx_variants) / sizeof(imx_variants[0]); i++)
224 printf(" %s -> variant=%d\n", imx_variants[i].name, imx_variants[i].variant);
225 break;
226 case 'p':
227 force_version = optarg;
228 break;
229 case '5':
230 md5type = optarg;
231 break;
232 case 'm':
233 if(model != MODEL_UNKNOWN)
234 {
235 printf("You cannot specify two models\n");
236 return 1;
237 }
238 for(int i = 0; i < NR_MODELS; i++)
239 if(strcmp(optarg, imx_models[i].name) == 0)
240 {
241 model = imx_models[i].model;
242 break;
243 }
244 if(model == MODEL_UNKNOWN)
245 printf("Unknown model '%s'\n", optarg);
246 break;
247 default:
248 abort();
249 }
250 }
251
252 if(!infile)
253 {
254 printf("You must specify an input file\n");
255 return 1;
256 }
257
258 if(md5type)
259 return print_md5(infile, md5type);
260
261 if(!outfile)
262 {
263 printf("You must specify an output file\n");
264 return 1;
265 }
266
267 if(!bootfile && type != IMX_ORIG_FW)
268 {
269 printf("You must specify an boot file\n");
270 return 1;
271 }
272
273 if(optind != argc)
274 {
275 printf("Extra arguments on command line\n");
276 return 1;
277 }
278
279 struct imx_option_t opt;
280 memset(&opt, 0, sizeof(opt));
281 opt.debug = debug;
282 opt.output = type;
283 opt.fw_variant = variant;
284 opt.force_version = force_version;
285 opt.model = model;
286 enum imx_error_t err = mkimxboot(infile, bootfile, outfile, opt);
287 printf("Result: %d (%s)\n", err, imx_error_to_string(err));
288 return 0;
289}
diff --git a/utils/mkimxboot/md5.c b/utils/mkimxboot/md5.c
new file mode 100644
index 0000000000..530d8df15a
--- /dev/null
+++ b/utils/mkimxboot/md5.c
@@ -0,0 +1,246 @@
1/*
2 * RFC 1321 compliant MD5 implementation
3 *
4 * Copyright (C) 2001-2003 Christophe Devine
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <string.h>
22
23#include "md5.h"
24
25#define GET_UINT32(n,b,i) \
26{ \
27 (n) = ( (uint32) (b)[(i) ] ) \
28 | ( (uint32) (b)[(i) + 1] << 8 ) \
29 | ( (uint32) (b)[(i) + 2] << 16 ) \
30 | ( (uint32) (b)[(i) + 3] << 24 ); \
31}
32
33#define PUT_UINT32(n,b,i) \
34{ \
35 (b)[(i) ] = (uint8) ( (n) ); \
36 (b)[(i) + 1] = (uint8) ( (n) >> 8 ); \
37 (b)[(i) + 2] = (uint8) ( (n) >> 16 ); \
38 (b)[(i) + 3] = (uint8) ( (n) >> 24 ); \
39}
40
41void md5_starts( md5_context *ctx )
42{
43 ctx->total[0] = 0;
44 ctx->total[1] = 0;
45
46 ctx->state[0] = 0x67452301;
47 ctx->state[1] = 0xEFCDAB89;
48 ctx->state[2] = 0x98BADCFE;
49 ctx->state[3] = 0x10325476;
50}
51
52void md5_process( md5_context *ctx, uint8 data[64] )
53{
54 uint32 X[16], A, B, C, D;
55
56 GET_UINT32( X[0], data, 0 );
57 GET_UINT32( X[1], data, 4 );
58 GET_UINT32( X[2], data, 8 );
59 GET_UINT32( X[3], data, 12 );
60 GET_UINT32( X[4], data, 16 );
61 GET_UINT32( X[5], data, 20 );
62 GET_UINT32( X[6], data, 24 );
63 GET_UINT32( X[7], data, 28 );
64 GET_UINT32( X[8], data, 32 );
65 GET_UINT32( X[9], data, 36 );
66 GET_UINT32( X[10], data, 40 );
67 GET_UINT32( X[11], data, 44 );
68 GET_UINT32( X[12], data, 48 );
69 GET_UINT32( X[13], data, 52 );
70 GET_UINT32( X[14], data, 56 );
71 GET_UINT32( X[15], data, 60 );
72
73#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
74
75#define P(a,b,c,d,k,s,t) \
76{ \
77 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
78}
79
80 A = ctx->state[0];
81 B = ctx->state[1];
82 C = ctx->state[2];
83 D = ctx->state[3];
84
85#define F(x,y,z) (z ^ (x & (y ^ z)))
86
87 P( A, B, C, D, 0, 7, 0xD76AA478 );
88 P( D, A, B, C, 1, 12, 0xE8C7B756 );
89 P( C, D, A, B, 2, 17, 0x242070DB );
90 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
91 P( A, B, C, D, 4, 7, 0xF57C0FAF );
92 P( D, A, B, C, 5, 12, 0x4787C62A );
93 P( C, D, A, B, 6, 17, 0xA8304613 );
94 P( B, C, D, A, 7, 22, 0xFD469501 );
95 P( A, B, C, D, 8, 7, 0x698098D8 );
96 P( D, A, B, C, 9, 12, 0x8B44F7AF );
97 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
98 P( B, C, D, A, 11, 22, 0x895CD7BE );
99 P( A, B, C, D, 12, 7, 0x6B901122 );
100 P( D, A, B, C, 13, 12, 0xFD987193 );
101 P( C, D, A, B, 14, 17, 0xA679438E );
102 P( B, C, D, A, 15, 22, 0x49B40821 );
103
104#undef F
105
106#define F(x,y,z) (y ^ (z & (x ^ y)))
107
108 P( A, B, C, D, 1, 5, 0xF61E2562 );
109 P( D, A, B, C, 6, 9, 0xC040B340 );
110 P( C, D, A, B, 11, 14, 0x265E5A51 );
111 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
112 P( A, B, C, D, 5, 5, 0xD62F105D );
113 P( D, A, B, C, 10, 9, 0x02441453 );
114 P( C, D, A, B, 15, 14, 0xD8A1E681 );
115 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
116 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
117 P( D, A, B, C, 14, 9, 0xC33707D6 );
118 P( C, D, A, B, 3, 14, 0xF4D50D87 );
119 P( B, C, D, A, 8, 20, 0x455A14ED );
120 P( A, B, C, D, 13, 5, 0xA9E3E905 );
121 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
122 P( C, D, A, B, 7, 14, 0x676F02D9 );
123 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
124
125#undef F
126
127#define F(x,y,z) (x ^ y ^ z)
128
129 P( A, B, C, D, 5, 4, 0xFFFA3942 );
130 P( D, A, B, C, 8, 11, 0x8771F681 );
131 P( C, D, A, B, 11, 16, 0x6D9D6122 );
132 P( B, C, D, A, 14, 23, 0xFDE5380C );
133 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
134 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
135 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
136 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
137 P( A, B, C, D, 13, 4, 0x289B7EC6 );
138 P( D, A, B, C, 0, 11, 0xEAA127FA );
139 P( C, D, A, B, 3, 16, 0xD4EF3085 );
140 P( B, C, D, A, 6, 23, 0x04881D05 );
141 P( A, B, C, D, 9, 4, 0xD9D4D039 );
142 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
143 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
144 P( B, C, D, A, 2, 23, 0xC4AC5665 );
145
146#undef F
147
148#define F(x,y,z) (y ^ (x | ~z))
149
150 P( A, B, C, D, 0, 6, 0xF4292244 );
151 P( D, A, B, C, 7, 10, 0x432AFF97 );
152 P( C, D, A, B, 14, 15, 0xAB9423A7 );
153 P( B, C, D, A, 5, 21, 0xFC93A039 );
154 P( A, B, C, D, 12, 6, 0x655B59C3 );
155 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
156 P( C, D, A, B, 10, 15, 0xFFEFF47D );
157 P( B, C, D, A, 1, 21, 0x85845DD1 );
158 P( A, B, C, D, 8, 6, 0x6FA87E4F );
159 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
160 P( C, D, A, B, 6, 15, 0xA3014314 );
161 P( B, C, D, A, 13, 21, 0x4E0811A1 );
162 P( A, B, C, D, 4, 6, 0xF7537E82 );
163 P( D, A, B, C, 11, 10, 0xBD3AF235 );
164 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
165 P( B, C, D, A, 9, 21, 0xEB86D391 );
166
167#undef F
168
169 ctx->state[0] += A;
170 ctx->state[1] += B;
171 ctx->state[2] += C;
172 ctx->state[3] += D;
173}
174
175void md5_update( md5_context *ctx, uint8 *input, uint32 length )
176{
177 uint32 left, fill;
178
179 if( ! length ) return;
180
181 left = ctx->total[0] & 0x3F;
182 fill = 64 - left;
183
184 ctx->total[0] += length;
185 ctx->total[0] &= 0xFFFFFFFF;
186
187 if( ctx->total[0] < length )
188 ctx->total[1]++;
189
190 if( left && length >= fill )
191 {
192 memcpy( (void *) (ctx->buffer + left),
193 (void *) input, fill );
194 md5_process( ctx, ctx->buffer );
195 length -= fill;
196 input += fill;
197 left = 0;
198 }
199
200 while( length >= 64 )
201 {
202 md5_process( ctx, input );
203 length -= 64;
204 input += 64;
205 }
206
207 if( length )
208 {
209 memcpy( (void *) (ctx->buffer + left),
210 (void *) input, length );
211 }
212}
213
214static uint8 md5_padding[64] =
215{
216 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
217 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
218 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
219 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
220};
221
222void md5_finish( md5_context *ctx, uint8 digest[16] )
223{
224 uint32 last, padn;
225 uint32 high, low;
226 uint8 msglen[8];
227
228 high = ( ctx->total[0] >> 29 )
229 | ( ctx->total[1] << 3 );
230 low = ( ctx->total[0] << 3 );
231
232 PUT_UINT32( low, msglen, 0 );
233 PUT_UINT32( high, msglen, 4 );
234
235 last = ctx->total[0] & 0x3F;
236 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
237
238 md5_update( ctx, md5_padding, padn );
239 md5_update( ctx, msglen, 8 );
240
241 PUT_UINT32( ctx->state[0], digest, 0 );
242 PUT_UINT32( ctx->state[1], digest, 4 );
243 PUT_UINT32( ctx->state[2], digest, 8 );
244 PUT_UINT32( ctx->state[3], digest, 12 );
245}
246
diff --git a/utils/mkimxboot/md5.h b/utils/mkimxboot/md5.h
new file mode 100644
index 0000000000..71fa395548
--- /dev/null
+++ b/utils/mkimxboot/md5.h
@@ -0,0 +1,25 @@
1#ifndef _MD5_H
2#define _MD5_H
3
4#ifndef uint8
5#define uint8 unsigned char
6#endif
7
8#ifndef uint32
9#define uint32 unsigned long int
10#endif
11
12typedef struct
13{
14 uint32 total[2];
15 uint32 state[4];
16 uint8 buffer[64];
17}
18md5_context;
19
20void md5_starts( md5_context *ctx );
21void md5_update( md5_context *ctx, uint8 *input, uint32 length );
22void md5_finish( md5_context *ctx, uint8 digest[16] );
23
24#endif /* md5.h */
25
diff --git a/utils/mkimxboot/mkimxboot.c b/utils/mkimxboot/mkimxboot.c
new file mode 100644
index 0000000000..0483b5aeee
--- /dev/null
+++ b/utils/mkimxboot/mkimxboot.c
@@ -0,0 +1,1123 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <stdio.h>
22#include <stdlib.h>
23#include <stdarg.h>
24#include <string.h>
25#include <ctype.h>
26#include "mkimxboot.h"
27#include "sb.h"
28#include "dualboot.h"
29#include "md5.h"
30#include "elf.h"
31
32/* abstract structure to represent a Rockbox firmware. It can be a scrambled file
33 * or an ELF file or whatever. */
34struct rb_fw_t
35{
36 int nr_insts;
37 struct sb_inst_t *insts;
38 int entry_idx;
39};
40
41/* A firmware upgrade can contains several variants like recovery image, or
42 * images for different models */
43struct imx_fw_variant_desc_t
44{
45 /* Offset within file */
46 size_t offset;
47 /* Total size of the firmware */
48 size_t size;
49};
50
51/* Map a MD5 sum of the whole file to a model and describe the variants in it */
52struct imx_md5sum_t
53{
54 /* Device model */
55 enum imx_model_t model;
56 /* md5sum of the file */
57 char *md5sum;
58 /* Version string */
59 const char *version;
60 /* Variant descriptions */
61 struct imx_fw_variant_desc_t fw_variants[VARIANT_COUNT];
62};
63
64/* Describe how to produce a bootloader image for a specific model */
65struct imx_model_desc_t
66{
67 /* Descriptive name of this model */
68 const char *model_name;
69 /* Dualboot code for this model */
70 const unsigned char *dualboot;
71 /* Size of dualboot functions for this model */
72 int dualboot_size;
73 /* Model name used in the Rockbox header in ".sansa" files - these match the
74 -add parameter to the "scramble" tool */
75 const char *rb_model_name;
76 /* Model number used to initialise the checksum in the Rockbox header in
77 ".sansa" files - these are the same as MODEL_NUMBER in config-target.h */
78 const int rb_model_num;
79 /* Array of NULL-terminated keys */
80 struct crypto_key_t **keys;
81 /* Dualboot load address */
82 uint32_t dualboot_addr;
83 /* Bootloader load address */
84 uint32_t bootloader_addr;
85};
86
87/* Friendly names for variants */
88static const char *imx_fw_variant[] =
89{
90 [VARIANT_DEFAULT] = "default",
91 [VARIANT_ZENXFI2_RECOVERY] = "ZEN X-Fi2 Recovery",
92 [VARIANT_ZENXFI2_NAND] = "ZEN X-Fi2 NAND",
93 [VARIANT_ZENXFI2_SD] = "ZEN X-Fi2 eMMC/SD",
94 [VARIANT_ZENXFISTYLE_RECOVERY] = "ZEN X-Fi Style Recovery",
95 [VARIANT_ZENSTYLE_RECOVERY] = "ZEN Style 100/300 Recovery",
96};
97
98/* List of known MD5 sums for firmware upgrades */
99static const struct imx_md5sum_t imx_sums[] =
100{
101 /** Fuze+ */
102 {
103 /* Version 2.38.6 */
104 MODEL_FUZEPLUS, "c3e27620a877dc6b200b97dcb3e0ecc7", "2.38.6",
105 { [VARIANT_DEFAULT] = { 0, 34652624 } }
106 },
107 /** Zen X-Fi2 */
108 {
109 /* Version 1.23.01 */
110 MODEL_ZENXFI2, "e37e2c24abdff8e624d0a29f79157850", "1.23.01",
111 {
112 [VARIANT_ZENXFI2_RECOVERY] = { 602128, 684192},
113 [VARIANT_ZENXFI2_NAND] = { 1286320, 42406608 },
114 [VARIANT_ZENXFI2_SD] = { 43692928, 42304208 }
115 }
116 },
117 {
118 /* Version 1.23.01e */
119 MODEL_ZENXFI2, "2beff2168212d332f13cfc36ca46989d", "1.23.01e",
120 {
121 [VARIANT_ZENXFI2_RECOVERY] = { 0x93010, 684192},
122 [VARIANT_ZENXFI2_NAND] = { 0x13a0b0, 42410704 },
123 [VARIANT_ZENXFI2_SD] = { 0x29ac380, 42304208 }
124 }
125 },
126 /** Zen X-Fi3 */
127 {
128 /* Version 1.00.15e */
129 MODEL_ZENXFI3, "658a24eeef5f7186ca731085d8822a87", "1.00.15e",
130 { [VARIANT_DEFAULT] = {0, 18110576} }
131 },
132 {
133 /* Version 1.00.22e */
134 MODEL_ZENXFI3, "a5114cd45ea4554ec221f51a71083862", "1.00.22e",
135 { [VARIANT_DEFAULT] = {0, 18110576} }
136 },
137 {
138 /* Version 1.00.25 */
139 MODEL_ZENXFI3, "a41a3a78f86a4ac2879d194c6d528059", "1.00.25",
140 { [VARIANT_DEFAULT] = {0, 18110576 } }
141 },
142 {
143 /* Version 1.00.25e */
144 MODEL_ZENXFI3, "c180f57e2b2d62620f87a1d853f349ff", "1.00.25e",
145 { [VARIANT_DEFAULT] = {0, 18110576 } }
146 },
147 /** Zen X-Fi Style */
148 {
149 /* Version 1.03.04e */
150 MODEL_ZENXFISTYLE, "32a731b7f714e9f99a95991003759c98", "1.03.04",
151 {
152 [VARIANT_DEFAULT] = {842960, 29876944},
153 [VARIANT_ZENXFISTYLE_RECOVERY] = {610272, 232688},
154 }
155 },
156 {
157 /* Version 1.03.04e */
158 MODEL_ZENXFISTYLE, "2c7ee52d9984d85dd39aa49b3331e66c", "1.03.04e",
159 {
160 [VARIANT_DEFAULT] = {842960, 29876944},
161 [VARIANT_ZENXFISTYLE_RECOVERY] = {610272, 232688},
162 }
163 },
164 {
165 /* Version 1.03.04e */
166 MODEL_ZENSTYLE, "dbebec8fe666412061d9740ff68605dd", "1.03.04e",
167 {
168 [VARIANT_DEFAULT] = {758848, 6641344},
169 [VARIANT_ZENSTYLE_RECOVERY] = {610272, 148576},
170 }
171 },
172 /** Sony NWZ-E370 */
173 {
174 /* Version 1.00.00 */
175 MODEL_NWZE370, "a615fdb70b3e1bfb0355a5bc2bf237ab", "1.00.00",
176 { [VARIANT_DEFAULT] = {0, 16056320 } }
177 },
178 {
179 /* Version 1.00.01 */
180 MODEL_NWZE370, "ee83f3c6026cbcc07097867f06fd585f", "1.00.01",
181 { [VARIANT_DEFAULT] = {0, 16515072 } }
182 },
183 /** Sony NWZ-E360 */
184 {
185 /* Version 1.00.00 */
186 MODEL_NWZE360, "d0047f8a87d456a0032297b3c802a1ff", "1.00.00",
187 { [VARIANT_DEFAULT] = {0, 20652032 } }
188 },
189 /** Sony NWZ-E380 */
190 {
191 /* Version 1.00.00 */
192 MODEL_NWZE370, "412f8ccd453195c0bebcc1fd8376322f", "1.00.00",
193 { [VARIANT_DEFAULT] = {0, 16429056 } }
194 },
195 {
196 /* Version 1.00.200 */
197 MODEL_NWZE370, "75cfa51078261c547717e11a4676f1af", "1.00.200",
198 { [VARIANT_DEFAULT] = {0, 16429056 } }
199 }
200};
201
202static struct crypto_key_t zero_key =
203{
204 .method = CRYPTO_KEY,
205 .u.key = {0}
206};
207
208static struct crypto_key_t *list_zero_key[] = { &zero_key, NULL };
209static struct crypto_key_t *list_all_keys[] = { &zero_key, NULL };
210
211static const struct imx_model_desc_t imx_models[] =
212{
213 [MODEL_FUZEPLUS] = {"Fuze+", dualboot_fuzeplus, sizeof(dualboot_fuzeplus),
214 "fuz+", 72, list_zero_key, 0, 0x40000000 },
215 [MODEL_ZENXFI2] = {"Zen X-Fi2", dualboot_zenxfi2, sizeof(dualboot_zenxfi2),
216 "zxf2", 82, list_zero_key, 0, 0x40000000 },
217 [MODEL_ZENXFI3] = {"Zen X-Fi3", dualboot_zenxfi3, sizeof(dualboot_zenxfi3),
218 "zxf3", 83, list_zero_key, 0, 0x40000000 },
219 [MODEL_ZENXFISTYLE] = {"Zen X-Fi Style", dualboot_zenxfistyle, sizeof(dualboot_zenxfistyle),
220 "zxfs", 94, list_zero_key, 0, 0x40000000 },
221 [MODEL_ZENSTYLE] = {"Zen Style 100/300", NULL, 0, "", -1, list_zero_key, 0, 0x40000000 },
222 [MODEL_NWZE370] = {"NWZ-E370", dualboot_nwze370, sizeof(dualboot_nwze370),
223 "e370", 88, list_zero_key, 0, 0x40000000 },
224 [MODEL_NWZE360] = {"NWZ-E360", dualboot_nwze360, sizeof(dualboot_nwze360),
225 "e360", 89, list_zero_key, 0, 0x40000000 },
226};
227
228#define NR_IMX_SUMS (sizeof(imx_sums) / sizeof(imx_sums[0]))
229#define NR_IMX_MODELS (sizeof(imx_models) / sizeof(imx_models[0]))
230
231#define MAGIC_ROCK 0x726f636b /* 'rock' */
232#define MAGIC_RECOVERY 0xfee1dead
233#define MAGIC_NORMAL 0xcafebabe
234#define MAGIC_CHARGE 0x67726863 /* 'chrg' */
235
236const char *imx_error_to_string(enum imx_error_t err)
237{
238 switch(err)
239 {
240 case IMX_SUCCESS: return "success";
241 case IMX_ERROR: return "error";
242 case IMX_OPEN_ERROR: return "open error";
243 case IMX_READ_ERROR: return "read error";
244 case IMX_NO_MATCH: return "no match";
245 case IMX_BOOT_INVALID: return "invalid";
246 case IMX_BOOT_MISMATCH: return "mismatch";
247 case IMX_BOOT_CHECKSUM_ERROR: return "checksum error";
248 case IMX_DONT_KNOW_HOW_TO_PATCH: return "don't know how to patch";
249 case IMX_VARIANT_MISMATCH: return "variant mismatch";
250 case IMX_WRITE_ERROR: return "write error";
251 case IMX_FIRST_SB_ERROR: return "sb error";
252 case IMX_MODEL_MISMATCH: return "model mismatch";
253 default: return "unknown error";
254 }
255}
256
257static void add_key_list(struct crypto_key_t **list)
258{
259 while(*list != NULL)
260 add_keys(*list++, 1);
261}
262
263static int rb_fw_get_sb_inst_count(struct rb_fw_t *fw)
264{
265 return fw->nr_insts;
266}
267
268/* fill sb instruction for the firmware, fill fill rb_fw_get_sb_inst_count() instructions */
269static void rb_fw_fill_sb(struct rb_fw_t *fw, struct sb_inst_t *inst,
270 uint32_t entry_arg)
271{
272 memcpy(inst, fw->insts, fw->nr_insts * sizeof(struct sb_inst_t));
273 /* copy data if needed */
274 for(int i = 0; i < fw->nr_insts; i++)
275 if(fw->insts[i].inst == SB_INST_LOAD)
276 fw->insts[i].data = memdup(fw->insts[i].data, fw->insts[i].size);
277 /* replace call argument of the entry point */
278 inst[fw->entry_idx].argument = entry_arg;
279}
280
281static enum imx_error_t patch_std_zero_host_play(int jump_before,
282 struct imx_option_t opt, struct sb_file_t *sb_file, struct rb_fw_t boot_fw)
283{
284 /* We assume the file has three boot sections: ____, host, play and one
285 * resource section rsrc.
286 *
287 * Dual Boot:
288 * ----------
289 * We patch the file by inserting the dualboot code before the <jump_before>th
290 * call in the ____ section. We give it as argument the section name 'rock'
291 * and add a section called 'rock' after rsrc which contains the bootloader.
292 *
293 * Single Boot & Recovery:
294 * -----------------------
295 * We patch the file by inserting the bootloader code after the <jump_before>th
296 * call in the ____ section and get rid of everything else. In recovery mode,
297 * we give 0xfee1dead as argument */
298
299 /* used to manipulate entries */
300 int nr_boot_inst = rb_fw_get_sb_inst_count(&boot_fw);
301
302 /* first locate the good instruction */
303 struct sb_section_t *sec = &sb_file->sections[0];
304 int jump_idx = 0;
305 while(jump_idx < sec->nr_insts && jump_before > 0)
306 if(sec->insts[jump_idx++].inst == SB_INST_CALL)
307 jump_before--;
308 if(jump_idx == sec->nr_insts)
309 {
310 printf("[ERR] Cannot locate call in section ____\n");
311 return IMX_DONT_KNOW_HOW_TO_PATCH;
312 }
313
314 if(opt.output == IMX_DUALBOOT)
315 {
316 /* create a new instruction array with a hole for two instructions */
317 struct sb_inst_t *new_insts = xmalloc(sizeof(struct sb_inst_t) * (sec->nr_insts + 2));
318 memcpy(new_insts, sec->insts, sizeof(struct sb_inst_t) * jump_idx);
319 memcpy(new_insts + jump_idx + 2, sec->insts + jump_idx,
320 sizeof(struct sb_inst_t) * (sec->nr_insts - jump_idx));
321 /* first instruction is be a load */
322 struct sb_inst_t *load = &new_insts[jump_idx];
323 memset(load, 0, sizeof(struct sb_inst_t));
324 load->inst = SB_INST_LOAD;
325 load->size = imx_models[opt.model].dualboot_size;
326 load->addr = imx_models[opt.model].dualboot_addr;
327 /* duplicate memory because it will be free'd */
328 load->data = memdup(imx_models[opt.model].dualboot,
329 imx_models[opt.model].dualboot_size);
330 /* second instruction is a call */
331 struct sb_inst_t *call = &new_insts[jump_idx + 1];
332 memset(call, 0, sizeof(struct sb_inst_t));
333 call->inst = SB_INST_CALL;
334 call->addr = imx_models[opt.model].dualboot_addr;
335 call->argument = MAGIC_ROCK;
336 /* free old instruction array */
337 free(sec->insts);
338 sec->insts = new_insts;
339 sec->nr_insts += 2;
340
341 /* create a new section */
342 struct sb_section_t rock_sec;
343 memset(&rock_sec, 0, sizeof(rock_sec));
344 /* section can have any number of instructions */
345 rock_sec.identifier = MAGIC_ROCK;
346 rock_sec.alignment = BLOCK_SIZE;
347 rock_sec.nr_insts = nr_boot_inst;
348 rock_sec.insts = xmalloc(nr_boot_inst * sizeof(struct sb_inst_t));
349 rb_fw_fill_sb(&boot_fw, rock_sec.insts, MAGIC_NORMAL);
350
351 sb_file->sections = augment_array(sb_file->sections,
352 sizeof(struct sb_section_t), sb_file->nr_sections,
353 &rock_sec, 1);
354 sb_file->nr_sections++;
355
356 return IMX_SUCCESS;
357 }
358 else if(opt.output == IMX_SINGLEBOOT || opt.output == IMX_RECOVERY)
359 {
360 bool recovery = (opt.output == IMX_RECOVERY);
361 /* remove everything after the call and add instructions for firmware */
362 struct sb_inst_t *new_insts = xmalloc(sizeof(struct sb_inst_t) * (jump_idx + nr_boot_inst));
363 memcpy(new_insts, sec->insts, sizeof(struct sb_inst_t) * jump_idx);
364 for(int i = jump_idx; i < sec->nr_insts; i++)
365 sb_free_instruction(sec->insts[i]);
366 rb_fw_fill_sb(&boot_fw, &new_insts[jump_idx], recovery ? MAGIC_RECOVERY : MAGIC_NORMAL);
367
368 free(sec->insts);
369 sec->insts = new_insts;
370 sec->nr_insts = jump_idx + nr_boot_inst;
371 /* remove all other sections */
372 for(int i = 1; i < sb_file->nr_sections; i++)
373 sb_free_section(sb_file->sections[i]);
374 struct sb_section_t *new_sec = xmalloc(sizeof(struct sb_section_t));
375 memcpy(new_sec, &sb_file->sections[0], sizeof(struct sb_section_t));
376 free(sb_file->sections);
377 sb_file->sections = new_sec;
378 sb_file->nr_sections = 1;
379
380 return IMX_SUCCESS;
381 }
382 else if(opt.output == IMX_CHARGE)
383 {
384 /* throw away everything except the dualboot stub with a special argument */
385 struct sb_inst_t *new_insts = xmalloc(sizeof(struct sb_inst_t) * 2);
386 /* first instruction is be a load */
387 struct sb_inst_t *load = &new_insts[0];
388 memset(load, 0, sizeof(struct sb_inst_t));
389 load->inst = SB_INST_LOAD;
390 load->size = imx_models[opt.model].dualboot_size;
391 load->addr = imx_models[opt.model].dualboot_addr;
392 /* duplicate memory because it will be free'd */
393 load->data = memdup(imx_models[opt.model].dualboot,
394 imx_models[opt.model].dualboot_size);
395 /* second instruction is a call */
396 struct sb_inst_t *call = &new_insts[1];
397 memset(call, 0, sizeof(struct sb_inst_t));
398 call->inst = SB_INST_CALL;
399 call->addr = imx_models[opt.model].dualboot_addr;
400 call->argument = MAGIC_CHARGE;
401 /* free old instruction array */
402 free(sec->insts);
403 sec->insts = new_insts;
404 sec->nr_insts = 2;
405 /* remove all other sections */
406 for(int i = 1; i < sb_file->nr_sections; i++)
407 sb_free_section(sb_file->sections[i]);
408 struct sb_section_t *new_sec = xmalloc(sizeof(struct sb_section_t));
409 memcpy(new_sec, &sb_file->sections[0], sizeof(struct sb_section_t));
410 free(sb_file->sections);
411 sb_file->sections = new_sec;
412 sb_file->nr_sections = 1;
413
414 return IMX_SUCCESS;
415 }
416 else
417 {
418 printf("[ERR] Bad output type !\n");
419 return IMX_DONT_KNOW_HOW_TO_PATCH;
420 }
421}
422
423static enum imx_error_t parse_subversion(const char *s, const char *end, uint16_t *ver)
424{
425 int len = (end == NULL) ? strlen(s) : end - s;
426 if(len > 4)
427 {
428 printf("[ERR] Bad subversion override '%s' (too long)\n", s);
429 return IMX_ERROR;
430 }
431 *ver = 0;
432 for(int i = 0; i < len; i++)
433 {
434 if(!isdigit(s[i]))
435 {
436 printf("[ERR] Bad subversion override '%s' (not a digit)\n", s);
437 return IMX_ERROR;
438 }
439 *ver = *ver << 4 | (s[i] - '0');
440 }
441 return IMX_SUCCESS;
442}
443
444static enum imx_error_t parse_version(const char *s, struct sb_version_t *ver)
445{
446 const char *dot1 = strchr(s, '.');
447 if(dot1 == NULL)
448 {
449 printf("[ERR] Bad version override '%s' (missing dot)\n", s);
450 return IMX_ERROR;
451 }
452 const char *dot2 = strchr(dot1 + 1, '.');
453 if(dot2 == NULL)
454 {
455 printf("[ERR] Bad version override '%s' (missing second dot)\n", s);
456 return IMX_ERROR;
457 }
458 enum imx_error_t ret = parse_subversion(s, dot1, &ver->major);
459 if(ret != IMX_SUCCESS) return ret;
460 ret = parse_subversion(dot1 + 1, dot2, &ver->minor);
461 if(ret != IMX_SUCCESS) return ret;
462 ret = parse_subversion(dot2 + 1, NULL, &ver->revision);
463 if(ret != IMX_SUCCESS) return ret;
464 return IMX_SUCCESS;
465}
466
467static enum imx_error_t patch_firmware(struct imx_option_t opt,
468 struct sb_file_t *sb_file, struct rb_fw_t boot_fw)
469{
470 if(opt.force_version)
471 {
472 enum imx_error_t err = parse_version(opt.force_version, &sb_file->product_ver);
473 if(err != IMX_SUCCESS)
474 return err;
475 err = parse_version(opt.force_version, &sb_file->component_ver);
476 if(err != IMX_SUCCESS)
477 return err;
478 }
479 switch(opt.model)
480 {
481 case MODEL_FUZEPLUS:
482 /* The Fuze+ uses the standard ____, host, play sections, patch after third
483 * call in ____ section */
484 return patch_std_zero_host_play(3, opt, sb_file, boot_fw);
485 case MODEL_ZENXFI3:
486 /* The ZEN X-Fi3 uses the standard ____, hSst, pSay sections, patch after third
487 * call in ____ section. Although sections names use the S variant, they are standard. */
488 return patch_std_zero_host_play(3, opt, sb_file, boot_fw);
489 case MODEL_NWZE360:
490 case MODEL_NWZE370:
491 /* The NWZ-E360/E370 uses the standard ____, host, play sections, patch after first
492 * call in ____ section. */
493 return patch_std_zero_host_play(1, opt, sb_file, boot_fw);
494 case MODEL_ZENXFI2:
495 /* The ZEN X-Fi2 has two types of firmware: recovery and normal.
496 * Normal uses the standard ___, host, play sections and recovery only ____ */
497 switch(opt.fw_variant)
498 {
499 case VARIANT_ZENXFI2_RECOVERY:
500 case VARIANT_ZENXFI2_NAND:
501 case VARIANT_ZENXFI2_SD:
502 return patch_std_zero_host_play(1, opt, sb_file, boot_fw);
503 default:
504 return IMX_DONT_KNOW_HOW_TO_PATCH;
505 }
506 break;
507 case MODEL_ZENXFISTYLE:
508 /* The ZEN X-Fi Style uses the standard ____, host, play sections, patch after first
509 * call in ____ section. */
510 return patch_std_zero_host_play(1, opt, sb_file, boot_fw);
511 default:
512 return IMX_DONT_KNOW_HOW_TO_PATCH;
513 }
514}
515
516static enum imx_error_t unpatch_std_zero_host_play(int jump_before,
517 struct imx_option_t opt, struct sb_file_t *sb_file)
518{
519 /* find rockbox section */
520 int rb_sec = -1;
521 for(int i = 0; i < sb_file->nr_sections; i++)
522 if(sb_file->sections[i].identifier == MAGIC_ROCK)
523 rb_sec = i;
524 if(rb_sec == -1)
525 {
526 printf("[ERR][INTERNAL] Cannot find rockbox section\n");
527 return IMX_ERROR;
528 }
529 /** 1) remove rockbox section */
530 /* free rockbox section */
531 sb_free_section(sb_file->sections[rb_sec]);
532 /* create a new array of sections */
533 sb_file->nr_sections--;
534 struct sb_section_t *new_sec = xmalloc(sb_file->nr_sections * sizeof(struct sb_section_t));
535 /* copy all sections exception rockbox */
536 memcpy(new_sec, sb_file->sections, rb_sec * sizeof(struct sb_section_t));
537 memcpy(new_sec + rb_sec, sb_file->sections + rb_sec + 1,
538 (sb_file->nr_sections - rb_sec) * sizeof(struct sb_section_t));
539 /* free old array and replace it */
540 free(sb_file->sections);
541 sb_file->sections = new_sec;
542
543 /** 2) remove patch instructions in boot section */
544 struct sb_section_t *sec = &sb_file->sections[0];
545 int jump_idx = 0;
546 while(jump_idx < sec->nr_insts && jump_before > 0)
547 if(sec->insts[jump_idx++].inst == SB_INST_CALL)
548 jump_before--;
549 if(jump_idx == sec->nr_insts)
550 {
551 printf("[ERR] Cannot locate call in section ____\n");
552 return IMX_DONT_KNOW_HOW_TO_PATCH;
553 }
554 /* free two instructions */
555 sb_free_instruction(sec->insts[jump_idx]);
556 sb_free_instruction(sec->insts[jump_idx + 1]);
557 /* create a new array of instructions */
558 sec->nr_insts -= 2;
559 struct sb_inst_t *new_inst = xmalloc(sec->nr_insts * sizeof(struct sb_inst_t));
560 /* copy all instructions except the two patch to remove */
561 memcpy(new_inst, sec->insts, jump_idx * sizeof(struct sb_inst_t));
562 memcpy(new_inst + jump_idx, sec->insts + jump_idx + 2,
563 (sec->nr_insts - jump_idx) * sizeof(struct sb_inst_t));
564 /* free old array and replace it */
565 free(sec->insts);
566 sec->insts = new_inst;
567
568 return IMX_SUCCESS;
569}
570
571static enum imx_error_t unpatch_firmware(struct imx_option_t opt,
572 struct sb_file_t *sb_file)
573{
574 /* keep consistent with patch_firmware */
575 switch(opt.model)
576 {
577 case MODEL_FUZEPLUS:
578 /* The Fuze+ uses the standard ____, host, play sections, patch after third
579 * call in ____ section */
580 return unpatch_std_zero_host_play(3, opt, sb_file);
581 case MODEL_ZENXFI3:
582 /* The ZEN X-Fi3 uses the standard ____, hSst, pSay sections, patch after third
583 * call in ____ section. Although sections names use the S variant, they are standard. */
584 return unpatch_std_zero_host_play(3, opt, sb_file);
585 case MODEL_NWZE360:
586 case MODEL_NWZE370:
587 /* The NWZ-E360/E370 uses the standard ____, host, play sections, patch after first
588 * call in ____ section. */
589 return unpatch_std_zero_host_play(1, opt, sb_file);
590 case MODEL_ZENXFI2:
591 /* The ZEN X-Fi2 has two types of firmware: recovery and normal.
592 * Normal uses the standard ___, host, play sections and recovery only ____ */
593 switch(opt.fw_variant)
594 {
595 case VARIANT_ZENXFI2_RECOVERY:
596 case VARIANT_ZENXFI2_NAND:
597 case VARIANT_ZENXFI2_SD:
598 return unpatch_std_zero_host_play(1, opt, sb_file);
599 default:
600 return IMX_DONT_KNOW_HOW_TO_PATCH;
601 }
602 break;
603 case MODEL_ZENXFISTYLE:
604 /* The ZEN X-Fi Style uses the standard ____, host, play sections, patch after first
605 * call in ____ section. */
606 return unpatch_std_zero_host_play(1, opt, sb_file);
607 default:
608 return IMX_DONT_KNOW_HOW_TO_PATCH;
609 }
610}
611
612static uint32_t get_uint32be(unsigned char *p)
613{
614 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
615}
616
617void dump_imx_dev_info(const char *prefix)
618{
619 printf("%smkimxboot models:\n", prefix);
620 for(int i = 0; i < NR_IMX_MODELS; i++)
621 {
622 printf("%s %s: idx=%d rb_model=%s rb_num=%d\n", prefix,
623 imx_models[i].model_name, i, imx_models[i].rb_model_name,
624 imx_models[i].rb_model_num);
625 }
626 printf("%smkimxboot variants:\n", prefix);
627 for(int i = 0; i < VARIANT_COUNT; i++)
628 {
629 printf("%s %d: %s\n", prefix, i, imx_fw_variant[i]);
630 }
631 printf("%smkimxboot mapping:\n", prefix);
632 for(int i = 0; i < NR_IMX_SUMS; i++)
633 {
634 printf("%s md5sum=%s -> idx=%d, ver=%s\n", prefix, imx_sums[i].md5sum,
635 imx_sums[i].model, imx_sums[i].version);
636 for(int j = 0; j < VARIANT_COUNT; j++)
637 if(imx_sums[i].fw_variants[j].size)
638 printf("%s variant=%d -> offset=%#x size=%#x\n", prefix,
639 j, (unsigned)imx_sums[i].fw_variants[j].offset,
640 (unsigned)imx_sums[i].fw_variants[j].size);
641 }
642}
643
644/* find an entry into imx_sums which matches the MD5 sum of a file */
645static enum imx_error_t find_model_by_md5sum(uint8_t file_md5sum[16], int *md5_idx)
646{
647 int i = 0;
648 while(i < NR_IMX_SUMS)
649 {
650 uint8_t md5[20];
651 if(strlen(imx_sums[i].md5sum) != 32)
652 {
653 printf("[INFO] Invalid MD5 sum in imx_sums\n");
654 return IMX_ERROR;
655 }
656 for(int j = 0; j < 16; j++)
657 {
658 uint8_t a, b;
659 if(convxdigit(imx_sums[i].md5sum[2 * j], &a) || convxdigit(imx_sums[i].md5sum[2 * j + 1], &b))
660 {
661 printf("[ERR][INTERNAL] Bad checksum format: %s\n", imx_sums[i].md5sum);
662 return IMX_ERROR;
663 }
664 md5[j] = (a << 4) | b;
665 }
666 if(memcmp(file_md5sum, md5, 16) == 0)
667 break;
668 i++;
669 }
670 if(i == NR_IMX_SUMS)
671 {
672 printf("[WARN] MD5 sum doesn't match any known file\n");
673 return IMX_NO_MATCH;
674 }
675 *md5_idx = i;
676 return IMX_SUCCESS;
677}
678
679/* read a file to a buffer */
680static enum imx_error_t read_file(const char *file, void **buffer, size_t *size)
681{
682 FILE *f = fopen(file, "rb");
683 if(f == NULL)
684 {
685 printf("[ERR] Cannot open file '%s' for reading: %m\n", file);
686 return IMX_OPEN_ERROR;
687 }
688 fseek(f, 0, SEEK_END);
689 *size = ftell(f);
690 fseek(f, 0, SEEK_SET);
691 *buffer = xmalloc(*size);
692 if(fread(*buffer, *size, 1, f) != 1)
693 {
694 free(*buffer);
695 fclose(f);
696 printf("[ERR] Cannot read file '%s': %m\n", file);
697 return IMX_READ_ERROR;
698 }
699 fclose(f);
700 return IMX_SUCCESS;
701}
702
703/* write a file from a buffer */
704static enum imx_error_t write_file(const char *file, void *buffer, size_t size)
705{
706 FILE *f = fopen(file, "wb");
707 if(f == NULL)
708 {
709 printf("[ERR] Cannot open file '%s' for writing: %m\n", file);
710 return IMX_OPEN_ERROR;
711 }
712 if(fwrite(buffer, size, 1, f) != 1)
713 {
714 fclose(f);
715 printf("[ERR] Cannot write file '%s': %m\n", file);
716 return IMX_WRITE_ERROR;
717 }
718 fclose(f);
719 return IMX_SUCCESS;
720}
721
722/* compute MD5 sum of a buffer */
723static enum imx_error_t compute_md5sum_buf(void *buf, size_t sz, uint8_t file_md5sum[16])
724{
725 md5_context ctx;
726 md5_starts(&ctx);
727 md5_update(&ctx, buf, sz);
728 md5_finish(&ctx, file_md5sum);
729 return IMX_SUCCESS;
730}
731
732/* compute MD5 sum of a buffer */
733static enum imx_error_t compute_soft_md5sum_buf(struct sb_file_t *sb, uint8_t file_md5sum[16])
734{
735 md5_context ctx;
736 md5_starts(&ctx);
737#define hash(obj) \
738 md5_update(&ctx, (void *)&obj, sizeof(obj))
739 /* various header fiels */
740 hash(sb->timestamp);
741 hash(sb->drive_tag);
742 hash(sb->drive_tag);
743 hash(sb->first_boot_sec_id);
744 hash(sb->flags);
745 hash(sb->product_ver);
746 hash(sb->component_ver);
747
748 for(int i = 0; i < sb->nr_sections; i++)
749 {
750 struct sb_section_t *sec = &sb->sections[i];
751 hash(sec->identifier);
752 uint32_t flags = sec->other_flags;
753 if(!sec->is_data)
754 flags |= SECTION_BOOTABLE;
755 if(sec->is_cleartext)
756 flags |= SECTION_CLEARTEXT;
757 hash(flags);
758
759 for(int j = 0; j < sec->nr_insts; j++)
760 {
761 struct sb_inst_t *inst = &sec->insts[j];
762 switch(inst->inst)
763 {
764 case SB_INST_NOP:
765 /* ignore them totally because they are used for padding */
766 break;
767 case SB_INST_LOAD:
768 hash(inst->inst);
769 hash(inst->addr);
770 md5_update(&ctx, inst->data, inst->size);
771 break;
772 case SB_INST_FILL:
773 hash(inst->inst);
774 hash(inst->addr);
775 hash(inst->pattern);
776 break;
777 case SB_INST_JUMP:
778 case SB_INST_CALL:
779 hash(inst->inst);
780 hash(inst->addr);
781 hash(inst->argument);
782 break;
783 case SB_INST_MODE:
784 hash(inst->inst);
785 hash(inst->argument);
786 break;
787 case SB_INST_DATA:
788 md5_update(&ctx, inst->data, inst->size);
789 break;
790 default:
791 printf("[ERR][INTERNAL] Unexpected instruction %d\n", inst->inst);
792 return IMX_ERROR;
793 }
794 }
795 }
796#undef hash
797 md5_finish(&ctx, file_md5sum);
798 return IMX_SUCCESS;
799}
800
801/* compute MD5 of a file */
802enum imx_error_t compute_md5sum(const char *file, uint8_t file_md5sum[16])
803{
804 void *buf;
805 size_t sz;
806 enum imx_error_t err = read_file(file, &buf, &sz);
807 if(err != IMX_SUCCESS)
808 return err;
809 compute_md5sum_buf(buf, sz, file_md5sum);
810 free(buf);
811 return IMX_SUCCESS;
812}
813
814/* compute soft MD5 of a file */
815enum imx_error_t compute_soft_md5sum(const char *file, uint8_t soft_md5sum[16])
816{
817 clear_keys();
818 add_key_list(list_all_keys);
819 /* read file */
820 enum sb_error_t err;
821 struct sb_file_t *sb = sb_read_file(file, false, NULL, generic_std_printf, &err);
822 if(sb == NULL)
823 {
824 printf("[ERR] Cannot load SB file: %d\n", err);
825 return err;
826 }
827 /* compute sum */
828 err = compute_soft_md5sum_buf(sb, soft_md5sum);
829 /* release file */
830 sb_free(sb);
831 return err;
832}
833
834/* Load a rockbox firwmare from a buffer. Data is copied. Assume firmware is
835 * using our scramble format. */
836static enum imx_error_t rb_fw_load_buf_scramble(struct rb_fw_t *fw, uint8_t *buf,
837 size_t sz, enum imx_model_t model)
838{
839 if(sz < 8)
840 {
841 printf("[ERR] Bootloader file is too small to be valid\n");
842 return IMX_BOOT_INVALID;
843 }
844 /* check model name */
845 uint8_t *name = buf + 4;
846 if(memcmp(name, imx_models[model].rb_model_name, 4) != 0)
847 {
848 printf("[ERR] Bootloader model doesn't match found model for input file\n");
849 return IMX_BOOT_MISMATCH;
850 }
851 /* check checksum */
852 uint32_t sum = imx_models[model].rb_model_num;
853 for(int i = 8; i < sz; i++)
854 sum += buf[i];
855 if(sum != get_uint32be(buf))
856 {
857 printf("[ERR] Bootloader checksum mismatch\n");
858 return IMX_BOOT_CHECKSUM_ERROR;
859 }
860 /* two instructions: load and jump */
861 fw->nr_insts = 2;
862 fw->entry_idx = 1;
863 fw->insts = xmalloc(fw->nr_insts * sizeof(struct sb_inst_t));
864 memset(fw->insts, 0, fw->nr_insts * sizeof(struct sb_inst_t));
865 fw->insts[0].inst = SB_INST_LOAD;
866 fw->insts[0].addr = imx_models[model].bootloader_addr;
867 fw->insts[0].size = sz - 8;
868 fw->insts[0].data = memdup(buf + 8, sz - 8);
869 fw->insts[1].inst = SB_INST_JUMP;
870 fw->insts[1].addr = imx_models[model].bootloader_addr;
871 return IMX_SUCCESS;
872}
873
874struct elf_user_t
875{
876 void *buf;
877 size_t sz;
878};
879
880static bool elf_read(void *user, uint32_t addr, void *buf, size_t count)
881{
882 struct elf_user_t *u = user;
883 if(addr + count <= u->sz)
884 {
885 memcpy(buf, u->buf + addr, count);
886 return true;
887 }
888 else
889 return false;
890}
891
892/* Load a rockbox firwmare from a buffer. Data is copied. Assume firmware is
893 * using ELF format. */
894static enum imx_error_t rb_fw_load_buf_elf(struct rb_fw_t *fw, uint8_t *buf,
895 size_t sz, enum imx_model_t model)
896{
897 struct elf_params_t elf;
898 struct elf_user_t user;
899 user.buf = buf;
900 user.sz = sz;
901 elf_init(&elf);
902 if(!elf_read_file(&elf, elf_read, generic_std_printf, &user))
903 {
904 elf_release(&elf);
905 printf("[ERR] Error parsing ELF file\n");
906 return IMX_BOOT_INVALID;
907 }
908 fw->nr_insts = elf_get_nr_sections(&elf) + 1;
909 fw->insts = xmalloc(fw->nr_insts * sizeof(struct sb_inst_t));
910 fw->entry_idx = fw->nr_insts - 1;
911 memset(fw->insts, 0, fw->nr_insts * sizeof(struct sb_inst_t));
912 struct elf_section_t *sec = elf.first_section;
913 for(int i = 0; sec; i++, sec = sec->next)
914 {
915 fw->insts[i].addr = elf_translate_virtual_address(&elf, sec->addr);
916 fw->insts[i].size = sec->size;
917 if(sec->type == EST_LOAD)
918 {
919 fw->insts[i].inst = SB_INST_LOAD;
920 fw->insts[i].data = memdup(sec->section, sec->size);
921 }
922 else if(sec->type == EST_FILL)
923 {
924 fw->insts[i].inst = SB_INST_FILL;
925 fw->insts[i].pattern = sec->pattern;
926 }
927 else
928 {
929 printf("[WARN] Warning parsing ELF file: unsupported section type mapped to NOP!\n");
930 fw->insts[i].inst = SB_INST_NOP;
931 }
932 }
933 fw->insts[fw->nr_insts - 1].inst = SB_INST_JUMP;
934 if(!elf_get_start_addr(&elf, &fw->insts[fw->nr_insts - 1].addr))
935 {
936 elf_release(&elf);
937 printf("[ERROR] Error parsing ELF file: it has no entry point!\n");
938 return IMX_BOOT_INVALID;
939 }
940 elf_release(&elf);
941 return IMX_SUCCESS;
942}
943
944/* Load a rockbox firwmare from a buffer. Data is copied. */
945static enum imx_error_t rb_fw_load_buf(struct rb_fw_t *fw, uint8_t *buf,
946 size_t sz, enum imx_model_t model)
947{
948 /* detect file format */
949 if(sz >= 4 && buf[0] == 0x7f && memcmp(buf + 1, "ELF", 3) == 0)
950 return rb_fw_load_buf_elf(fw, buf, sz, model);
951 else
952 return rb_fw_load_buf_scramble(fw, buf, sz, model);
953}
954
955/* load a rockbox firmware from a file. */
956static enum imx_error_t rb_fw_load(struct rb_fw_t *fw, const char *file,
957 enum imx_model_t model)
958{
959 void *buf;
960 size_t sz;
961 int ret = read_file(file, &buf, &sz);
962 if(ret == IMX_SUCCESS)
963 {
964 ret = rb_fw_load_buf(fw, buf, sz, model);
965 free(buf);
966 }
967 return ret;
968}
969
970/* free rockbox firmware */
971static void rb_fw_free(struct rb_fw_t *fw)
972{
973 for(int i = 0; i < fw->nr_insts; i++)
974 sb_free_instruction(fw->insts[i]);
975 free(fw->insts);
976 memset(fw, 0, sizeof(struct rb_fw_t));
977}
978
979static bool contains_rockbox_bootloader(struct sb_file_t *sb_file)
980{
981 for(int i = 0; i < sb_file->nr_sections; i++)
982 if(sb_file->sections[i].identifier == MAGIC_ROCK)
983 return true;
984 return false;
985}
986
987/* modify sb_file to produce requested boot image */
988static enum imx_error_t make_boot(struct sb_file_t *sb_file, const char *bootfile,
989 struct imx_option_t opt)
990{
991 /* things went smoothly, we have a SB image but it may not be suitable as an
992 * input image: if it contains a rockbox bootloader, we need to remove it */
993 if(contains_rockbox_bootloader(sb_file))
994 {
995 printf("[INFO] SB file contains a Rockbox bootloader, trying to remove it...\n");
996 enum imx_error_t ret = unpatch_firmware(opt, sb_file);
997 if(ret != IMX_SUCCESS)
998 return ret;
999 }
1000 /* if asked to produce OF, don't do anything more */
1001 if(opt.output == IMX_ORIG_FW)
1002 return IMX_SUCCESS;
1003 /* load rockbox file */
1004 struct rb_fw_t boot_fw;
1005 enum imx_error_t ret = rb_fw_load(&boot_fw, bootfile, opt.model);
1006 if(ret != IMX_SUCCESS)
1007 return ret;
1008 /* produce file */
1009 ret = patch_firmware(opt, sb_file, boot_fw);
1010 rb_fw_free(&boot_fw);
1011 return ret;
1012}
1013
1014enum imx_error_t mkimxboot(const char *infile, const char *bootfile,
1015 const char *outfile, struct imx_option_t opt)
1016{
1017 /* sanity check */
1018 if(opt.fw_variant >= VARIANT_COUNT || opt.model >= MODEL_COUNT)
1019 return IMX_ERROR;
1020 /* dump tables */
1021 dump_imx_dev_info("[INFO] ");
1022 /* load file */
1023 void *buf;
1024 size_t offset = 0, size = 0;
1025 enum imx_error_t ret = read_file(infile, &buf, &size);
1026 if(ret != IMX_SUCCESS)
1027 return ret;
1028 /* compute MD5 sum of the file */
1029 uint8_t file_md5sum[16];
1030 compute_md5sum_buf(buf, size, file_md5sum);
1031 printf("[INFO] MD5 sum of the file: ");
1032 for(int i = 0; i < 16; i++)
1033 printf("%02x", file_md5sum[i]);
1034 printf("\n");
1035 /* find model */
1036 int md5_idx;
1037 ret = find_model_by_md5sum(file_md5sum, &md5_idx);
1038 /* is this a known firmware upgrade ? */
1039 if(ret == IMX_SUCCESS)
1040 {
1041 enum imx_model_t model = imx_sums[md5_idx].model;
1042 printf("[INFO] File is for model %d (%s, version %s)\n", model,
1043 imx_models[model].model_name, imx_sums[md5_idx].version);
1044 /* check the model is the expected one */
1045 if(opt.model == MODEL_UNKNOWN)
1046 opt.model = model;
1047 else if(opt.model != model)
1048 {
1049 printf("[ERR] Model mismatch, was expecting model %d (%s)\n",
1050 opt.model, imx_models[opt.model].model_name);
1051 free(buf);
1052 return IMX_MODEL_MISMATCH;
1053 }
1054 /* use database values */
1055 offset = imx_sums[md5_idx].fw_variants[opt.fw_variant].offset;
1056 size = imx_sums[md5_idx].fw_variants[opt.fw_variant].size;
1057 if(size == 0)
1058 {
1059 printf("[ERR] Input file does not contain variant '%s'\n", imx_fw_variant[opt.fw_variant]);
1060 free(buf);
1061 return IMX_VARIANT_MISMATCH;
1062 }
1063 /* special case: if we need to produce the OF, just bypass read/write of
1064 * the SB file and output this chunk of the file. This is faster and it
1065 * also avoids modifying the OF by reconstructing it */
1066 if(opt.output == IMX_ORIG_FW)
1067 {
1068 printf("[INFO] Extracting original firmware...\n");
1069 ret = write_file(outfile, buf + offset, size);
1070 free(buf);
1071 return ret;
1072 }
1073 }
1074 else
1075 {
1076 printf("[INFO] File doesn't have a known MD5 sum, assuming it's a SB image...\n");
1077 /* image didn't match, so we expect the file to be a raw SB image, either
1078 * produced by mkimxboot when uninstalling bootloader or after installing RB,
1079 * so load all known keys and go on */
1080
1081 /* To be more user friendly, give a nice error message if we detect
1082 * the file is not a SB file */
1083 if(guess_sb_version(infile) == SB_VERSION_UNK)
1084 {
1085 printf("[ERR] Your firmware doesn't look like a SB file\n");
1086 printf("[ERR] This is probably a firmware upgrade\n");
1087 printf("[ERR] Unfortunately, this tool doesn't know about it yet\n");
1088 printf("[ERR] Please report to the developers to add it\n");
1089 free(buf);
1090 return IMX_ERROR;
1091 }
1092 }
1093 /* to proceed further, we need to know the model */
1094 if(opt.model == MODEL_UNKNOWN)
1095 {
1096 printf("[ERR] Cannot do processing of soft image without knowing the model\n");
1097 free(buf);
1098 return IMX_MODEL_MISMATCH;
1099 }
1100 /* load image */
1101 g_debug = opt.debug;
1102 clear_keys();
1103 add_key_list(imx_models[opt.model].keys);
1104 enum sb_error_t err;
1105 struct sb_file_t *sb_file = sb_read_memory(buf + offset, size, false, NULL, generic_std_printf, &err);
1106 if(sb_file == NULL)
1107 {
1108 printf("[ERR] Cannot open firmware as SB file: %d\n", err);
1109 free(buf);
1110 return IMX_FIRST_SB_ERROR + err;
1111 }
1112 /* modify image */
1113 ret = make_boot(sb_file, bootfile, opt);
1114 if(ret == IMX_SUCCESS)
1115 {
1116 /* write image */
1117 ret = sb_write_file(sb_file, outfile, NULL, generic_std_printf);
1118 }
1119 /* cleanup */
1120 sb_free(sb_file);
1121 free(buf);
1122 return ret;
1123}
diff --git a/utils/mkimxboot/mkimxboot.h b/utils/mkimxboot/mkimxboot.h
new file mode 100644
index 0000000000..6bf0415e9c
--- /dev/null
+++ b/utils/mkimxboot/mkimxboot.h
@@ -0,0 +1,116 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef MKIMXBOOT_H
23#define MKIMXBOOT_H
24
25#include <stdbool.h>
26#include <stdint.h>
27#include <sys/types.h>
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33enum imx_error_t
34{
35 IMX_SUCCESS = 0,
36 IMX_ERROR = -1,
37 IMX_OPEN_ERROR = -2,
38 IMX_READ_ERROR = -3,
39 IMX_NO_MATCH = -4,
40 IMX_BOOT_INVALID = -5,
41 IMX_BOOT_MISMATCH = -6,
42 IMX_BOOT_CHECKSUM_ERROR = -7,
43 IMX_DONT_KNOW_HOW_TO_PATCH = -8,
44 IMX_VARIANT_MISMATCH = -9,
45 IMX_WRITE_ERROR = -10,
46 IMX_FIRST_SB_ERROR = -11,
47 IMX_MODEL_MISMATCH = -12,
48};
49
50enum imx_output_type_t
51{
52 IMX_DUALBOOT = 0,
53 IMX_RECOVERY,
54 IMX_SINGLEBOOT,
55 IMX_CHARGE,
56 IMX_ORIG_FW,
57};
58
59/* Supported models */
60enum imx_model_t
61{
62 MODEL_UNKNOWN = 0,
63 MODEL_FUZEPLUS,
64 MODEL_ZENXFI2,
65 MODEL_ZENXFI3,
66 MODEL_ZENXFISTYLE,
67 MODEL_ZENSTYLE, /* Style 100 and Style 300 */
68 MODEL_NWZE370,
69 MODEL_NWZE360,
70 /* Last */
71 MODEL_COUNT
72};
73
74/* Supported firmware variants */
75enum imx_firmware_variant_t
76{
77 VARIANT_DEFAULT = 0,
78 /* For the Creative ZEN X-Fi2 */
79 VARIANT_ZENXFI2_NAND,
80 VARIANT_ZENXFI2_SD,
81 VARIANT_ZENXFI2_RECOVERY,
82 /* For the Creative X-Fi Style */
83 VARIANT_ZENXFISTYLE_RECOVERY,
84 /* For the Creative Zen Style 100/300 */
85 VARIANT_ZENSTYLE_RECOVERY,
86 /* Last */
87 VARIANT_COUNT
88};
89
90struct imx_option_t
91{
92 bool debug;
93 enum imx_model_t model;
94 enum imx_output_type_t output;
95 enum imx_firmware_variant_t fw_variant;
96 const char *force_version; // set to NULL to ignore
97};
98
99/* Print internal information to stdout about device database */
100void dump_imx_dev_info(const char *prefix);
101/* Build a SB image from an input firmware and a bootloader, input firmware
102 * can either be a firmware update or another SB file produced by this tool */
103enum imx_error_t mkimxboot(const char *infile, const char *bootfile,
104 const char *outfile, struct imx_option_t opt);
105/* Compute MD5 sum of an entire file */
106enum imx_error_t compute_md5sum(const char *file, uint8_t file_md5sum[16]);
107/* Compute "soft" MD5 sum of a SB file */
108enum imx_error_t compute_soft_md5sum(const char *file, uint8_t soft_md5sum[16]);
109/* Translate error */
110const char *imx_error_to_string(enum imx_error_t err);
111
112#ifdef __cplusplus
113}
114#endif
115#endif
116
diff --git a/utils/mkmpioboot/Makefile b/utils/mkmpioboot/Makefile
new file mode 100644
index 0000000000..8aa2d37028
--- /dev/null
+++ b/utils/mkmpioboot/Makefile
@@ -0,0 +1,23 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7
8TARGET_DIR ?= $(shell pwd)/
9# We use the UCL code available in the Rockbox tools/ directory
10CFLAGS += -I../../tools/ucl/include -Wall
11
12OUTPUT = mkmpioboot
13
14# inputs
15LIBSOURCES = mkmpioboot.c
16SOURCES = main.c
17EXTRADEPS = $(LIBUCL)
18
19include ../libtools.make
20
21# explicit dependencies
22$(OBJDIR)mkmpioboot.o: mkmpioboot.c mkmpioboot.h
23
diff --git a/utils/mkmpioboot/main.c b/utils/mkmpioboot/main.c
new file mode 100644
index 0000000000..9861cba261
--- /dev/null
+++ b/utils/mkmpioboot/main.c
@@ -0,0 +1,55 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2010 by Marcin Bukat
11 *
12 * code taken mostly from mkboot.c
13 * Copyright (C) 2005 by Linus Nielsen Feltzing
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#include <stdio.h>
26#include <stdlib.h>
27#include "mkmpioboot.h"
28
29static void usage(void)
30{
31 printf("usage: mkmpioboot <firmware file> <boot file> <output file>\n");
32 exit(1);
33}
34
35int main(int argc, char *argv[])
36{
37 char *infile, *bootfile, *outfile;
38 int origin = 0xe0000; /* MPIO HD200 bootloader address */
39
40 fprintf(stderr,
41"mkmpioboot Version " VERSION "\n"
42"This is free software; see the source for copying conditions. There is NO\n"
43"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
44"\n");
45
46 if(argc < 3) {
47 usage();
48 }
49
50 infile = argv[1];
51 bootfile = argv[2];
52 outfile = argv[3];
53
54 return mkmpioboot(infile, bootfile, outfile, origin);
55}
diff --git a/utils/mkmpioboot/mkmpioboot.c b/utils/mkmpioboot/mkmpioboot.c
new file mode 100644
index 0000000000..ea619ed2f2
--- /dev/null
+++ b/utils/mkmpioboot/mkmpioboot.c
@@ -0,0 +1,243 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2010 by Marcin Bukat
11 *
12 * code taken mostly from mkboot.c
13 * Copyright (C) 2005 by Linus Nielsen Feltzing
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include "mkmpioboot.h"
28
29#define OF_FIRMWARE_LEN 0x100000 /* size of the OF file */
30#define MPIO_STRING_OFFSET 0xfffe0 /* offset of the version string in OF */
31#define BOOTLOADER_MAX_SIZE 0x1f800 /* free space size */
32
33struct mpio_model {
34 /* Descriptive name of this model */
35 const char* model_name;
36 /* Model name used in the Rockbox header in ".mpio" files - these match the
37 -add parameter to the "scramble" tool */
38 const char* rb_model_name;
39 /* Model number used to initialise the checksum in the Rockbox header in
40 ".mpio" files - these are the same as MODEL_NUMBER in config-target.h */
41 const int rb_model_num;
42 /* Strings which indentifies OF version */
43 const char* of_model_string;
44};
45
46static const struct mpio_model mpio_models[] = {
47 [MODEL_HD200] =
48 { "MPIO HD200", "hd20", 69, "HD200 HDD Audio Ver113005" },
49 [MODEL_HD300] =
50 { "MPIO HD300", "hd30", 70, "HD300 HDD Audio Ver113006" },
51};
52
53
54/* MPIO HD200 and HD300 firmware is plain binary image
55 * 4 bytes of initial SP (loaded on reset)
56 * 4 bytes of initial PC (loaded on reset)
57 * binary image with entry point 0x00000008
58 *
59 * We put our bootloader code at 0x000e0000
60 * and patch reset vector to jump directly
61 * into our code on reset
62 */
63
64static unsigned char image[OF_FIRMWARE_LEN];
65
66static unsigned int get_uint32be(unsigned char* p)
67{
68 return ((p[0] << 24) | (p[1] << 16) | (p[2]<<8) | p[3]);
69}
70
71static long checksum(unsigned char* buf, int model, unsigned long length)
72{
73 unsigned long chksum = model;
74 unsigned long i;
75
76 if(buf == NULL)
77 return -1;
78
79 for (i = 0; i < length; i++)
80 {
81 chksum += *buf++;
82 }
83
84return chksum;
85}
86
87int mkmpioboot(const char* infile, const char* bootfile, const char* outfile, int origin)
88{
89 FILE *f;
90 int i;
91 int len;
92 int model_index;
93 unsigned long file_checksum;
94 unsigned char header[8];
95
96 memset(image, 0xff, sizeof(image));
97
98 /* First, read the mpio original firmware into the image */
99 f = fopen(infile, "rb");
100 if(!f)
101 {
102 fprintf(stderr, "[ERR] Can not open %s file for reading\n", infile);
103 return -1;
104 }
105
106 i = fread(image, 1, OF_FIRMWARE_LEN, f);
107 if(i < OF_FIRMWARE_LEN)
108 {
109 fprintf(stderr, "[ERR] %s file read error\n", infile);
110 fclose(f);
111 return -2;
112 }
113
114 fclose(f);
115
116 /* Now check if we have OF file loaded based on presence
117 * of the version string in firmware
118 */
119
120 for(model_index = 0; model_index < NUM_MODELS; model_index++)
121 if (strcmp(mpio_models[model_index].of_model_string,
122 (char*)(image + MPIO_STRING_OFFSET)) == 0)
123 break;
124
125 if(model_index == NUM_MODELS)
126 {
127 fprintf(stderr, "[ERR] Unknown MPIO original firmware version\n");
128 return -3;
129 }
130
131 fprintf(stderr, "[INFO] Loading original firmware file for %s\n",
132 mpio_models[model_index].model_name);
133
134 /* Now, read the boot loader into the image */
135 f = fopen(bootfile, "rb");
136 if(!f)
137 {
138 fprintf(stderr, "[ERR] Can not open %s file for reading\n", bootfile);
139 return -4;
140 }
141
142 fprintf(stderr, "[INFO] Loading Rockbox bootloader file\n");
143
144 /* get bootloader size
145 * excluding header
146 */
147 fseek(f, 0, SEEK_END);
148 len = ftell(f) - 8;
149
150 if (len > BOOTLOADER_MAX_SIZE)
151 {
152 fprintf(stderr, "[ERR] Bootloader doesn't fit in firmware file.\n");
153 fprintf(stderr, "[ERR] This bootloader is %d bytes long\n", len);
154 fprintf(stderr, "[ERR] and maximum allowed size is %d bytes\n",
155 BOOTLOADER_MAX_SIZE);
156 return -5;
157 }
158
159 /* Now check if the place we want to put
160 * our bootloader is free
161 */
162 for(i=0;i<len;i++)
163 {
164 if (image[origin+i] != 0)
165 {
166 fprintf(stderr, "[ERR] Place for bootloader in OF file not empty\n");
167 return -6;
168 }
169 }
170
171 fseek(f, 0, SEEK_SET);
172
173 /* get bootloader header*/
174 fread(header,1,8,f);
175
176 if ( memcmp(header + 4, mpio_models[model_index].rb_model_name, 4) != 0 )
177 {
178 fprintf(stderr, "[ERR] Original firmware and rockbox bootloader mismatch!\n");
179 fprintf(stderr, "[ERR] Double check that you have bootloader for %s\n",
180 mpio_models[model_index].model_name);
181 return -7;
182 }
183
184 /* omit header */
185 fseek(f, 8, SEEK_SET);
186
187 i = fread(image + origin, 1, len, f);
188 if(i < len)
189 {
190 fprintf(stderr, "[ERR] %s file read error\n", bootfile);
191 fclose(f);
192 return -8;
193 }
194
195 fclose(f);
196
197 /* calculate checksum and compare with data
198 * from header
199 */
200 file_checksum = checksum(image + origin, mpio_models[model_index].rb_model_num, len);
201
202 if ( file_checksum != get_uint32be(header) )
203 {
204 fprintf(stderr,"[ERR] Bootloader checksum error\n");
205 return -9;
206 }
207
208 f = fopen(outfile, "wb");
209 if(!f)
210 {
211 fprintf(stderr, "[ERR] Can not open %s file for writing\n" ,outfile);
212 return -10;
213 }
214
215 fprintf(stderr, "[INFO] Patching reset vector\n");
216
217 /* Patch the stack pointer address */
218 image[0] = image[origin + 0];
219 image[1] = image[origin + 1];
220 image[2] = image[origin + 2];
221 image[3] = image[origin + 3];
222
223 /* Patch the reset vector to start the boot loader */
224 image[4] = image[origin + 4];
225 image[5] = image[origin + 5];
226 image[6] = image[origin + 6];
227 image[7] = image[origin + 7];
228
229 i = fwrite(image, 1, OF_FIRMWARE_LEN, f);
230 if(i < OF_FIRMWARE_LEN)
231 {
232 fprintf(stderr,"[ERR] %s file write error\n", outfile);
233 fclose(f);
234 return -11;
235 }
236
237 fprintf(stderr,"[INFO] Wrote 0x%x bytes in %s\n", OF_FIRMWARE_LEN, outfile);
238 fprintf(stderr,"[INFO] Patching succeeded!\n");
239
240 fclose(f);
241
242 return 0;
243}
diff --git a/utils/mkmpioboot/mkmpioboot.h b/utils/mkmpioboot/mkmpioboot.h
new file mode 100644
index 0000000000..4828ac953e
--- /dev/null
+++ b/utils/mkmpioboot/mkmpioboot.h
@@ -0,0 +1,46 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2010 by Marcin Bukat
11 * code based mainly on mkboot.h
12 * Copyright (C) 2008 by Dominik Riebeling
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24#ifndef MKMPIOBOOT_H
25#define MKMPIOBOOT_H
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/* Supported models */
32enum {
33 MODEL_UNKNOWN = -1,
34 MODEL_HD200 = 0,
35 MODEL_HD300,
36
37 NUM_MODELS
38};
39
40int mkmpioboot(const char* infile, const char* bootfile, const char* outfile, int origin);
41
42#ifdef __cplusplus
43}
44#endif
45#endif
46
diff --git a/utils/mknwzboot/Makefile b/utils/mknwzboot/Makefile
new file mode 100644
index 0000000000..3cbb2ef9dd
--- /dev/null
+++ b/utils/mknwzboot/Makefile
@@ -0,0 +1,52 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7
8# We use the SB code available in the Rockbox utils/sbtools directory
9UPGTOOLS_DIR=../../utils/nwztools/upgtools/
10CFLAGS += -I$(UPGTOOLS_DIR) -Wall
11# std=gnu99 is required by MinGW on Windows (c99 is sufficient for Linux / MXE)
12CFLAGS += -std=gnu99 -g -O3
13# dependencies
14# FIXME make it work for windows and maybe embed crypto++
15
16# Location to pkg-config binary.
17PKGCONFIG := pkg-config
18
19# Distros could use different names for the crypto library. We try a list
20# of candidate names, only one of them should be the valid one.
21LIBCRYPTO_NAMES = libcryptopp libcrypto++ cryptopp crypto++
22
23$(foreach l,$(LIBCRYPTO_NAMES),\
24 $(eval LDOPTS += $(shell $(PKGCONFIG) --silence-errors --libs $(l))))
25$(foreach l,$(LIBCRYPTO_NAMES),\
26 $(eval CFLAGS += $(shell $(PKGCONFIG) --silence-errors --cflags $(l))))
27$(foreach l,$(LIBCRYPTO_NAMES),\
28 $(eval CXXFLAGS += $(shell $(PKGCONFIG) --silence-errors --cflags $(l))))
29LDOPTS += -lpthread
30
31OUTPUT = mknwzboot
32
33# inputs for lib
34UPGTOOLS_SOURCES = misc.c upg.c fwp.c mg.cpp md5.cpp
35LIBSOURCES := mknwzboot.c install_script.c uninstall_script.c \
36 $(addprefix $(UPGTOOLS_DIR),$(UPGTOOLS_SOURCES))
37# inputs for binary only
38SOURCES := $(LIBSOURCES) main.c
39# dependencies for binary
40EXTRADEPS :=
41
42include ../libtools.make
43
44install_script.c install_script.h: install_script.sh $(BIN2C)
45 $(BIN2C) install_script.sh install_script
46
47uninstall_script.c uninstall_script.h: uninstall_script.sh $(BIN2C)
48 $(BIN2C) uninstall_script.sh uninstall_script
49
50# explicit dependencies on install_script.{c,h} and mknwzboot.h
51$(OBJDIR)mknwzboot.o: install_script.h install_script.c uninstall_script.h uninstall_script.c mknwzboot.h
52$(OBJDIR)main.o: main.c mknwzboot.h
diff --git a/utils/mknwzboot/install_script.sh b/utils/mknwzboot/install_script.sh
new file mode 100644
index 0000000000..76bd12c4d5
--- /dev/null
+++ b/utils/mknwzboot/install_script.sh
@@ -0,0 +1,157 @@
1#!/bin/sh
2
3# NOTE: busybox is using ash, a very posix and very pedantic shell, make sure
4# you test your scripts with
5# busybox sh -n <script>
6# and if you really, really don't want to download busybox to try it, then go
7# ahead and brick your device
8
9# The updater script on the NWZ has a major bug/feature:
10# it does NOT clear the update flag if the update scrit fails
11# thus causing a update/reboot loop and a bricked device
12# always clear to make sure we don't end up being screwed
13nvpflag fup 0xFFFFFFFF
14
15# go to /tmp
16cd /tmp
17
18# get content partition path
19CONTENTS="/contents"
20CONTENTS_PART=`mount | grep contents | awk '{ print $1 }'`
21
22# print a message to the screen and also on the standard output
23# lcdprint x,y msg
24lcdprint ()
25{
26 echo $2
27 lcdmsg -f /usr/local/bin/font_08x12.bmp -l $1 "$2"
28}
29
30# clear screen
31lcdmsg -c ""
32lcdprint 0,3 "Contents partition:\n$CONTENTS_PART"
33
34# We need to remount the contents partition in read-write mode be able to
35# write something on it
36lcdprint 0,6 "Remount $CONTENTS rw"
37mount -o remount,rw $CONTENTS_PART $CONTENTS
38if [ "$?" != 0 ]; then
39 lcdprint 0,15 "ERROR: remount failed"
40 sleep 3
41 exit 0
42fi
43
44# redirect all output to a log file
45exec > "$CONTENTS/install_dualboot_log.txt" 2>&1
46
47# import constants
48. /install_script/constant.txt
49_UPDATE_FN_=`nvpstr ufn`
50ROOTFS_TMP_DIR=/tmp/rootfs
51SPIDERAPP_PATH=$ROOTFS_TMP_DIR/usr/local/bin/SpiderApp
52
53# mount root partition
54lcdprint 0,7 "Mount root filesystem"
55mkdir $ROOTFS_TMP_DIR
56if [ "$?" != 0 ]; then
57 lcdprint 0,15 "ERROR: mkdir failed"
58 sleep 3
59 exit 0
60fi
61
62# If there is an ext4 mounter, try it. Otherwise or on failure, try ext3 and
63# then ext2.
64# NOTE some platforms probably use an mtd and this might need some fixing
65if [ -e /usr/local/bin/icx_mount.ext4 ]; then
66 /usr/local/bin/icx_mount.ext4 $COMMON_ROOTFS_PARTITION $ROOTFS_TMP_DIR
67else
68 false
69fi
70if [ "$?" != 0 ]; then
71 mount -t ext3 $COMMON_ROOTFS_PARTITION $ROOTFS_TMP_DIR
72fi
73if [ "$?" != 0 ]; then
74 mount -t ext2 $COMMON_ROOTFS_PARTITION $ROOTFS_TMP_DIR
75fi
76if [ "$?" != 0 ]; then
77 lcdprint 0,15 "ERROR: mount failed"
78 sleep 3
79 exit 0
80fi
81
82# rename the previous main application unless there is already a copy
83lcdprint 0,8 "Backup OF"
84if [ ! -e $SPIDERAPP_PATH.of ]; then
85 mv $SPIDERAPP_PATH $SPIDERAPP_PATH.of
86fi
87
88# extract our payload: the second file in the upgrade is a tar file
89# the files in the archive have paths of the form ./absolute/path and we extract
90# it at the rootfs mount it, so it can create/overwrite any file
91#
92# we need a small trick here: we want to pipe directly the output of the decryption
93# tool to tar, to avoid using space in /tmp/ or on the user partition
94lcdprint 0,9 "Install rockbox"
95FIFO_FILE=/tmp/rb.fifo
96mkfifo $FIFO_FILE
97if [ "$?" != 0 ]; then
98 umount "$ROOTFS_TMP_DIR"
99 lcdprint 0,15 "ERROR: cannot create fifo"
100 sleep 3
101 exit 0
102fi
103fwpchk -f /contents/$_UPDATE_FN_.UPG -c -1 $FIFO_FILE &
104#tar -tvf $FIFO_FILE
105tar -C $ROOTFS_TMP_DIR -xvf $FIFO_FILE
106if [ "$?" != 0 ]; then
107 umount "$ROOTFS_TMP_DIR"
108 lcdprint 0,15 "ERROR: extraction failed"
109 sleep 3
110 exit 0
111fi
112# wait for fwpchk
113wait
114if [ "$?" != 0 ]; then
115 umount "$ROOTFS_TMP_DIR"
116 lcdprint 0,15 "ERROR: no file to extract"
117 sleep 3
118 exit 0
119fi
120
121# create a symlink from /.rockbox to /contents/.rockbox (see dualboot code
122# for why)
123lcdprint 0,10 "Create rockbox symlink"
124rm -f "$ROOTFS_TMP_DIR/.rockbox"
125ln -s "$CONTENTS/.rockbox" "$ROOTFS_TMP_DIR/.rockbox"
126if [ "$?" != 0 ]; then
127 umount "$ROOTFS_TMP_DIR"
128 lcdprint 0,15 "ERROR: cannot create rockbox symlink"
129 sleep 3
130 exit 0
131fi
132
133# unmount root partition
134lcdprint 0,11 "Unmount root filesystem"
135sync
136if [ "$?" != 0 ]; then
137 umount "$ROOTFS_TMP_DIR"
138 lcdprint 0,15 "ERROR: sync failed"
139 sleep 3
140 exit 0
141fi
142
143umount $ROOTFS_TMP_DIR
144if [ "$?" != 0 ]; then
145 lcdprint 0,15 "ERROR: umount failed"
146 sleep 3
147 exit 0
148fi
149
150# Success screen
151lcdprint 0,15 "Rebooting in 3 seconds."
152sleep 3
153sync
154
155echo "Installation successful"
156# finish
157exit 0
diff --git a/utils/mknwzboot/main.c b/utils/mknwzboot/main.c
new file mode 100644
index 0000000000..491a18043b
--- /dev/null
+++ b/utils/mknwzboot/main.c
@@ -0,0 +1,126 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <getopt.h>
23#include <stdlib.h>
24#include <stdio.h>
25#include <string.h>
26#include "mknwzboot.h"
27
28static void usage(void)
29{
30 printf("Usage: mknwzboot [options | file]...\n");
31 printf("Options:\n");
32 printf(" -h/--help Display this message\n");
33 printf(" -o <file> Set output file\n");
34 printf(" -b <file> Set boot file\n");
35 printf(" -d/--debug Enable debug output\n");
36 printf(" -x Dump device informations\n");
37 printf(" -u Create uninstall update\n");
38 printf(" -m <model> Specify model\n");
39 exit(1);
40}
41
42int main(int argc, char *argv[])
43{
44 char *outfile = NULL;
45 char *bootfile = NULL;
46 bool debug = false;
47 bool install = true;
48 const char *model = NULL;
49
50 if(argc == 1)
51 usage();
52
53 while(1)
54 {
55 static struct option long_options[] =
56 {
57 {"help", no_argument, 0, 'h'},
58 {"out-file", required_argument, 0, 'o'},
59 {"boot-file", required_argument, 0, 'b'},
60 {"debug", no_argument, 0, 'd'},
61 {"dev-info", no_argument, 0, 'x'},
62 {"uninstall", no_argument, 0, 'u'},
63 {"model", required_argument, 0, 'm'},
64 {0, 0, 0, 0}
65 };
66
67 int c = getopt_long(argc, argv, "ho:b:dxum:", long_options, NULL);
68 if(c == -1)
69 break;
70 switch(c)
71 {
72 case 'd':
73 debug = true;
74 break;
75 case 'h':
76 usage();
77 break;
78 case 'o':
79 outfile = optarg;
80 break;
81 case 'b':
82 bootfile = optarg;
83 break;
84 case 'x':
85 dump_nwz_dev_info("");
86 return 0;
87 case 'u':
88 install = false;
89 break;
90 case 'm':
91 model = optarg;
92 break;
93 default:
94 abort();
95 }
96 }
97
98 if(!outfile)
99 {
100 printf("You must specify an output file\n");
101 return 1;
102 }
103 if(install && !bootfile)
104 {
105 printf("You must specify a boot file for installation\n");
106 return 1;
107 }
108 if(!install && !model)
109 {
110 printf("You must provide a model for uninstallation\n");
111 return 1;
112 }
113 if(optind != argc)
114 {
115 printf("Extra arguments on command line\n");
116 return 1;
117 }
118
119 int err;
120 if(install)
121 err = mknwzboot(bootfile, outfile, debug);
122 else
123 err = mknwzboot_uninst(model, outfile, debug);
124 printf("Result: %d\n", err);
125 return err;
126}
diff --git a/utils/mknwzboot/mknwzboot.c b/utils/mknwzboot/mknwzboot.c
new file mode 100644
index 0000000000..22885674d8
--- /dev/null
+++ b/utils/mknwzboot/mknwzboot.c
@@ -0,0 +1,294 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <stdio.h>
22#include <stdlib.h>
23#include <stdarg.h>
24#include <string.h>
25#include <ctype.h>
26#include "mknwzboot.h"
27#include "upg.h"
28
29#include "install_script.h"
30#include "uninstall_script.h"
31
32struct nwz_model_desc_t
33{
34 /* Descriptive name of this model */
35 const char *model_name;
36 /* Model name used in the Rockbox header in ".sansa" files - these match the
37 -add parameter to the "scramble" tool */
38 const char *rb_model_name;
39 /* Model number used to initialise the checksum in the Rockbox header in
40 ".sansa" files - these are the same as MODEL_NUMBER in config-target.h */
41 const int rb_model_num;
42 /* Codename used in upgtool */
43 const char *codename;
44};
45
46static const struct nwz_model_desc_t nwz_models[] =
47{
48 { "Sony NWZ-E350 Series", "e350", 109, "nwz-e350" },
49 { "Sony NWZ-E450 Series", "e450", 100, "nwz-e450" },
50 { "Sony NWZ-E460 Series", "e460", 101, "nwz-e460" },
51 { "Sony NWZ-E470 Series", "e470", 103, "nwz-e470" },
52 { "Sony NWZ-E580 Series", "e580", 102, "nwz-e580" },
53 { "Sony NWZ-A10 Series", "a10", 104, "nwz-a10" },
54 { "Sony NW-A20 Series", "a20", 106, "nw-a20" },
55 { "Sony NWZ-A860 Series", "a860", 107, "nwz-a860" },
56 { "Sony NWZ-S750 Series", "s750", 108, "nwz-s750" },
57};
58
59#define NR_NWZ_MODELS (sizeof(nwz_models) / sizeof(nwz_models[0]))
60
61void dump_nwz_dev_info(const char *prefix)
62{
63 printf("%smknwzboot models:\n", prefix);
64 for(int i = 0; i < NR_NWZ_MODELS; i++)
65 {
66 printf("%s %s: rb_model=%s rb_num=%d codename=%s\n", prefix,
67 nwz_models[i].model_name, nwz_models[i].rb_model_name,
68 nwz_models[i].rb_model_num, nwz_models[i].codename);
69 }
70}
71
72/* read a file to a buffer */
73static void *read_file(const char *file, size_t *size)
74{
75 FILE *f = fopen(file, "rb");
76 if(f == NULL)
77 {
78 printf("[ERR] Cannot open file '%s' for reading: %m\n", file);
79 return NULL;
80 }
81 fseek(f, 0, SEEK_END);
82 *size = ftell(f);
83 fseek(f, 0, SEEK_SET);
84 void *buffer = malloc(*size);
85 if(fread(buffer, *size, 1, f) != 1)
86 {
87 free(buffer);
88 fclose(f);
89 printf("[ERR] Cannot read file '%s': %m\n", file);
90 return NULL;
91 }
92 fclose(f);
93 return buffer;
94}
95
96/* write a file from a buffer */
97static bool write_file(const char *file, void *buffer, size_t size)
98{
99 FILE *f = fopen(file, "wb");
100 if(f == NULL)
101 {
102 printf("[ERR] Cannot open file '%s' for writing: %m\n", file);
103 return false;
104 }
105 if(fwrite(buffer, size, 1, f) != 1)
106 {
107 fclose(f);
108 printf("[ERR] Cannot write file '%s': %m\n", file);
109 return false;
110 }
111 fclose(f);
112 return true;
113}
114
115static unsigned int be2int(unsigned char* buf)
116{
117 return ((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]);
118}
119
120static int find_model(uint8_t *boot, size_t boot_size)
121{
122 if(boot_size < 8)
123 {
124 printf("[ERR] Boot file is too small to be valid\n");
125 return -1;
126 }
127 /* find model by comparing magic scramble value */
128 int model = 0;
129 for(; model < NR_NWZ_MODELS; model++)
130 if(memcmp(boot + 4, nwz_models[model].rb_model_name, 4) == 0)
131 break;
132 if(model == NR_NWZ_MODELS)
133 {
134 printf("[ERR] This player is not supported: %.4s\n", boot + 4);
135 return -1;
136 }
137 printf("[INFO] Bootloader file for %s\n", nwz_models[model].model_name);
138 /* verify checksum */
139 uint32_t sum = nwz_models[model].rb_model_num;
140 for(int i = 8; i < boot_size; i++)
141 sum += boot[i];
142 if(sum != be2int(boot))
143 {
144 printf("[ERR] Checksum mismatch\n");
145 return -1;
146 }
147 return model;
148}
149
150static int find_model2(const char *model_str)
151{
152 /* since it can be confusing for the user, we accept both rbmodel and codename */
153 /* find model by comparing magic scramble value */
154 int model = 0;
155 for(; model < NR_NWZ_MODELS; model++)
156 if(strcmp(nwz_models[model].rb_model_name, model_str) == 0 ||
157 strcmp(nwz_models[model].codename, model_str) == 0)
158 break;
159 if(model == NR_NWZ_MODELS)
160 {
161 printf("[ERR] Unknown model: %s\n", model_str);
162 return -1;
163 }
164 printf("[INFO] Bootloader file for %s\n", nwz_models[model].model_name);
165 return model;
166}
167
168static bool get_model_keysig(int model, char key[NWZ_KEY_SIZE], char sig[NWZ_SIG_SIZE])
169{
170 const char *codename = nwz_models[model].codename;
171 for(int i = 0; g_model_list[i].model; i++)
172 if(strcmp(g_model_list[i].model, codename) == 0)
173 {
174 if(decrypt_keysig(g_model_list[i].kas, key, sig) == 0)
175 return true;
176 printf("[ERR] Cannot decrypt kas '%s'\n", g_model_list[i].kas);
177 return false;
178 }
179 printf("[ERR] Codename '%s' matches to entry in upg database\n", codename);
180 return false;
181}
182
183void nwz_printf(void *u, bool err, color_t c, const char *f, ...)
184{
185 (void)err;
186 (void)c;
187 bool *debug = u;
188 va_list args;
189 va_start(args, f);
190 if(err || *debug)
191 vprintf(f, args);
192 va_end(args);
193}
194
195static void *memdup(void *data, size_t size)
196{
197 void *buf = malloc(size);
198 memcpy(buf, data, size);
199 return buf;
200}
201
202int mknwzboot(const char *bootfile, const char *outfile, bool debug)
203{
204 size_t boot_size;
205 uint8_t *boot = read_file(bootfile, &boot_size);
206 if(boot == NULL)
207 {
208 printf("[ERR] Cannot open boot file\n");
209 return 1;
210 }
211 /* check that it is a valid scrambled file */
212 int model = find_model(boot, boot_size);
213 if(model < 0)
214 {
215 free(boot);
216 printf("[ERR] Invalid boot file\n");
217 return 2;
218 }
219 /* find keys */
220 char key[NWZ_KEY_SIZE];
221 char sig[NWZ_SIG_SIZE];
222 if(!get_model_keysig(model, key, sig))
223 {
224 printf("[ERR][INTERNAL] Cannot get keys for model\n");
225 return 3;
226 }
227 /* create the upg file */
228 struct upg_file_t *upg = upg_new();
229 /* first file is the install script: we have to copy data because upg_free()
230 * will free it */
231 upg_append(upg, memdup(install_script, LEN_install_script), LEN_install_script);
232 /* second file is the bootloader content (expected to be a tar file): we have
233 * to copy data because upg_free() will free it */
234 upg_append(upg, memdup(boot + 8, boot_size - 8), boot_size - 8);
235 free(boot);
236 /* write file to buffer */
237 size_t upg_size;
238 void *upg_buf = upg_write_memory(upg, key, sig, &upg_size, &debug, nwz_printf);
239 upg_free(upg);
240 if(upg_buf == NULL)
241 {
242 printf("[ERR] Cannot create UPG file\n");
243 return 4;
244 }
245 if(!write_file(outfile, upg_buf, upg_size))
246 {
247 free(upg_buf);
248 printf("[ERR] Cannpt write UPG file\n");
249 return 5;
250 }
251 free(upg_buf);
252 return 0;
253}
254
255int mknwzboot_uninst(const char *model_string, const char *outfile, bool debug)
256{
257 /* check that it is a valid scrambled file */
258 int model = find_model2(model_string);
259 if(model < 0)
260 {
261 printf("[ERR] Invalid model\n");
262 return 2;
263 }
264 /* find keys */
265 char key[NWZ_KEY_SIZE];
266 char sig[NWZ_SIG_SIZE];
267 if(!get_model_keysig(model, key, sig))
268 {
269 printf("[ERR][INTERNAL] Cannot get keys for model\n");
270 return 3;
271 }
272 /* create the upg file */
273 struct upg_file_t *upg = upg_new();
274 /* first file is the uninstall script: we have to copy data because upg_free()
275 * will free it */
276 upg_append(upg, memdup(uninstall_script, LEN_uninstall_script), LEN_uninstall_script);
277 /* write file to buffer */
278 size_t upg_size;
279 void *upg_buf = upg_write_memory(upg, key, sig, &upg_size, &debug, nwz_printf);
280 upg_free(upg);
281 if(upg_buf == NULL)
282 {
283 printf("[ERR] Cannot create UPG file\n");
284 return 4;
285 }
286 if(!write_file(outfile, upg_buf, upg_size))
287 {
288 free(upg_buf);
289 printf("[ERR] Cannpt write UPG file\n");
290 return 5;
291 }
292 free(upg_buf);
293 return 0;
294}
diff --git a/utils/mknwzboot/mknwzboot.h b/utils/mknwzboot/mknwzboot.h
new file mode 100644
index 0000000000..31f2c6355e
--- /dev/null
+++ b/utils/mknwzboot/mknwzboot.h
@@ -0,0 +1,42 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef MKIMXBOOT_H
23#define MKIMXBOOT_H
24
25#include <stdbool.h>
26#include <stdint.h>
27#include <sys/types.h>
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33void dump_nwz_dev_info(const char *prefix);
34/* return 0 on success */
35int mknwzboot(const char *bootfile, const char *outfile, bool debug);
36int mknwzboot_uninst(const char *model, const char *outfile, bool debug);
37
38#ifdef __cplusplus
39}
40#endif
41#endif
42
diff --git a/utils/mknwzboot/uninstall_script.sh b/utils/mknwzboot/uninstall_script.sh
new file mode 100644
index 0000000000..0e409c63cd
--- /dev/null
+++ b/utils/mknwzboot/uninstall_script.sh
@@ -0,0 +1,122 @@
1#!/bin/sh
2
3# NOTE: busybox is using ash, a very posix and very pedantic shell, make sure
4# you test your scripts with
5# busybox sh -n <script>
6# and if you really, really don't want to download busybox to try it, then go
7# ahead and brick your device
8
9# The updater script on the NWZ has a major bug/feature:
10# it does NOT clear the update flag if the update scrit fails
11# thus causing a update/reboot loop and a bricked device
12# always clear to make sure we don't end up being screwed
13nvpflag fup 0xFFFFFFFF
14
15# go to /tmp
16cd /tmp
17
18# get content partition path
19CONTENTS="/contents"
20CONTENTS_PART=`mount | grep contents | awk '{ print $1 }'`
21
22# print a message to the screen and also on the standard output
23# lcdprint x,y msg
24lcdprint ()
25{
26 echo $2
27 lcdmsg -f /usr/local/bin/font_08x12.bmp -l $1 "$2"
28}
29
30# clear screen
31lcdmsg -c ""
32lcdprint 0,3 "Contents partition:\n$CONTENTS_PART"
33
34# We need to remount the contents partition in read-write mode be able to
35# write something on it
36lcdprint 0,6 "Remount $CONTENTS rw"
37mount -o remount,rw $CONTENTS_PART $CONTENTS
38if [ "$?" != 0 ]; then
39 lcdprint 0,15 "ERROR: remount failed"
40 sleep 3
41 exit 0
42fi
43
44# redirect all output to a log file
45exec > "$CONTENTS/uninstall_dualboot_log.txt" 2>&1
46
47# import constants
48. /install_script/constant.txt
49ROOTFS_TMP_DIR=/tmp/rootfs
50SPIDERAPP_PATH=$ROOTFS_TMP_DIR/usr/local/bin/SpiderApp
51
52# mount root partition
53lcdprint 0,7 "Mount root filesystem"
54mkdir $ROOTFS_TMP_DIR
55if [ "$?" != 0 ]; then
56 lcdprint 0,15 "ERROR: mkdir failed"
57 sleep 3
58 exit 0
59fi
60
61# If there is an ext4 mounter, try it. Otherwise or on failure, try ext3 and
62# then ext2.
63# NOTE some platforms probably use an mtd and this might need some fixing
64if [ -e /usr/local/bin/icx_mount.ext4 ]; then
65 /usr/local/bin/icx_mount.ext4 $COMMON_ROOTFS_PARTITION $ROOTFS_TMP_DIR
66else
67 false
68fi
69if [ "$?" != 0 ]; then
70 mount -t ext3 $COMMON_ROOTFS_PARTITION $ROOTFS_TMP_DIR
71fi
72if [ "$?" != 0 ]; then
73 mount -t ext2 $COMMON_ROOTFS_PARTITION $ROOTFS_TMP_DIR
74fi
75if [ "$?" != 0 ]; then
76 lcdprint 0,15 "ERROR: mount failed"
77 sleep 3
78 exit 0
79fi
80
81# the installer renames the OF to $SPIDERAPP_PATH.of so if it does not exists
82# print an error
83lcdprint 0,8 "Restore OF"
84if [ ! -e $SPIDERAPP_PATH.of ]; then
85 lcdprint 0,15 "ERROR: cannot find OF"
86 lcdprint 0,16 "ERROR: is Rockbox installed?"
87 sleep 3
88 exit 0
89fi
90# restore the OF
91mv $SPIDERAPP_PATH.of $SPIDERAPP_PATH
92if [ "$?" != 0 ]; then
93 lcdprint 0,15 "ERROR: restore failed"
94 sleep 3
95 exit 0
96fi
97
98# unmount root partition
99lcdprint 0,11 "Unmount root filesystem"
100sync
101if [ "$?" != 0 ]; then
102 umount "$ROOTFS_TMP_DIR"
103 lcdprint 0,15 "ERROR: sync failed"
104 sleep 3
105 exit 0
106fi
107
108umount $ROOTFS_TMP_DIR
109if [ "$?" != 0 ]; then
110 lcdprint 0,15 "ERROR: umount failed"
111 sleep 3
112 exit 0
113fi
114
115# Success screen
116lcdprint 0,15 "Rebooting in 3 seconds."
117sleep 3
118sync
119
120echo "Uninstallation successful"
121# finish
122exit 0
diff --git a/utils/mkrk27boot/Makefile b/utils/mkrk27boot/Makefile
new file mode 100644
index 0000000000..cbb7231f66
--- /dev/null
+++ b/utils/mkrk27boot/Makefile
@@ -0,0 +1,39 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10FIRMWARE = ../../firmware/
11
12DRIVERS = $(FIRMWARE)drivers/
13EXPORT = $(FIRMWARE)export/
14
15BUILDDATE=$(shell date -u +'-DYEAR=%Y -DMONTH=%m -DDAY=%d')
16INCLUDE = -I$(EXPORT) -I$(FIRMWARE)include -I$(FIRMWARE)target/hosted -I$(FIRMWARE)target/hosted/sdl
17DEFINES = -DTEST_FAT -DDISK_WRITE -DHAVE_FAT16SUPPORT -D__PCTOOL__
18
19CFLAGS = -Wall -g -std=gnu99 -Wno-pointer-sign $(DEFINES) -I. $(INCLUDE)
20SIM_FLAGS = $(CFLAGS) $(BUILDDATE) -I$(FIRMWARE)/libc/include
21
22OUTPUT = mkrk27boot
23
24# inputs
25LIBSOURCES := $(DRIVERS)fat.c $(FIRMWARE)libc/ctype.c $(FIRMWARE)libc/strtok.c \
26 $(FIRMWARE)libc/errno.c $(FIRMWARE)common/strlcpy.c $(FIRMWARE)common/unicode.c \
27 $(FIRMWARE)common/file.c $(FIRMWARE)common/dir_uncached.c $(FIRMWARE)common/disk.c ata-sim.c mkrk27boot.c
28
29SOURCES := $(LIBSOURCES) main.c
30
31include ../libtools.make
32
33SIMOBJS = $(addprefix $(OBJDIR),fat.o ctype.o strtok.o errno.o disk.o dir_uncached.o file.o unicode.o strlcpy.o)
34
35$(SIMOBJS):
36 @echo CC $<
37 $(SILENT)mkdir -p $(dir $@)
38 $(SILENT)$(CROSS)$(CC) $(SIM_FLAGS) -c -o $@ $<
39
diff --git a/utils/mkrk27boot/ata-sim.c b/utils/mkrk27boot/ata-sim.c
new file mode 100644
index 0000000000..129c4b36a9
--- /dev/null
+++ b/utils/mkrk27boot/ata-sim.c
@@ -0,0 +1,122 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2012 by Andrew Ryabinin
11 *
12 * major portion of code is taken from firmware/test/fat/ata-sim.c
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <stdarg.h>
28#include "debug.h"
29#include "dir.h"
30
31#define BLOCK_SIZE 512
32
33static FILE* file;
34
35extern char *img_filename;
36
37void mutex_init(struct mutex* l) {}
38void mutex_lock(struct mutex* l) {}
39void mutex_unlock(struct mutex* l) {}
40
41void panicf( char *fmt, ...) {
42 va_list ap;
43 va_start( ap, fmt );
44 fprintf(stderr,"***PANIC*** ");
45 vfprintf(stderr, fmt, ap );
46 va_end( ap );
47 exit(1);
48}
49
50void debugf(const char *fmt, ...) {
51 va_list ap;
52 va_start( ap, fmt );
53 fprintf(stderr,"DEBUGF: ");
54 vfprintf( stderr, fmt, ap );
55 va_end( ap );
56}
57
58void ldebugf(const char* file, int line, const char *fmt, ...) {
59 va_list ap;
60 va_start( ap, fmt );
61 fprintf( stderr, "%s:%d ", file, line );
62 vfprintf( stderr, fmt, ap );
63 va_end( ap );
64}
65
66int storage_read_sectors(unsigned long start, int count, void* buf)
67{
68 if ( count > 1 )
69 DEBUGF("[Reading %d blocks: 0x%lx to 0x%lx]\n",
70 count, start, start+count-1);
71 else
72 DEBUGF("[Reading block 0x%lx]\n", start);
73
74 if(fseek(file,start*BLOCK_SIZE,SEEK_SET)) {
75 perror("fseek");
76 return -1;
77 }
78 if(!fread(buf,BLOCK_SIZE,count,file)) {
79 DEBUGF("ata_write_sectors(0x%lx, 0x%x, %p)\n", start, count, buf );
80 perror("fread");
81 panicf("Disk error\n");
82 }
83 return 0;
84}
85
86int storage_write_sectors(unsigned long start, int count, void* buf)
87{
88 if ( count > 1 )
89 DEBUGF("[Writing %d blocks: 0x%lx to 0x%lx]\n",
90 count, start, start+count-1);
91 else
92 DEBUGF("[Writing block 0x%lx]\n", start);
93
94 if (start == 0)
95 panicf("Writing on sector 0!\n");
96
97 if(fseek(file,start*BLOCK_SIZE,SEEK_SET)) {
98 perror("fseek");
99 return -1;
100 }
101 if(!fwrite(buf,BLOCK_SIZE,count,file)) {
102 DEBUGF("ata_write_sectors(0x%lx, 0x%x, %p)\n", start, count, buf );
103 perror("fwrite");
104 panicf("Disk error\n");
105 }
106 return 0;
107}
108
109int ata_init(void)
110{
111 file=fopen(img_filename,"rb+");
112 if(!file) {
113 fprintf(stderr, "read_disk() - Could not find \"%s\"\n",img_filename);
114 return -1;
115 }
116 return 0;
117}
118
119void ata_exit(void)
120{
121 fclose(file);
122}
diff --git a/utils/mkrk27boot/autoconf.h b/utils/mkrk27boot/autoconf.h
new file mode 100644
index 0000000000..a4907d4599
--- /dev/null
+++ b/utils/mkrk27boot/autoconf.h
@@ -0,0 +1,37 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2012 by Andrew Ryabinin
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __BUILD_AUTOCONF_H
22#define __BUILD_AUTOCONF_H
23
24/* assume little endian for now */
25#define ROCKBOX_LITTLE_ENDIAN 1
26
27#define ROCKBOX_DIR "../../"
28
29/* Rename rockbox API functions which may conflict with system's functions.
30 This will allow to link libmkrk27boot with rbutil safely. */
31#define read(x,y,z) mkrk27_read(x,y,z)
32#define write(x,y,z) mkrk27_write(x,y,z)
33
34/* This should resolve confilict with ipodpatcher's filesize function. */
35#define filesize(x) mkrk27_filesize(x)
36
37#endif
diff --git a/utils/mkrk27boot/main.c b/utils/mkrk27boot/main.c
new file mode 100644
index 0000000000..5ba69b5a98
--- /dev/null
+++ b/utils/mkrk27boot/main.c
@@ -0,0 +1,55 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2012 by Andrew Ryabinin
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include<stdio.h>
23#include "mkrk27boot.h"
24
25
26int main(int argc, char **argv)
27{
28 char* img_file = NULL;
29 char* rkw_file = NULL;
30 char* out_img_file = NULL;
31 char* out_rkw_file = NULL;
32
33 if (argc == 4) {
34 img_file = argv[1];
35 rkw_file = argv[2];
36 out_img_file = argv[3];
37 out_rkw_file = "BASE.RKW";
38 } else if (argc == 5) {
39 img_file = argv[1];
40 rkw_file = argv[2];
41 out_img_file = argv[3];
42 out_rkw_file = argv[4];
43 } else {
44 fprintf(stdout, "\tusage: mkrk27boot <img file> <rkw file> <output img file> [<output rkw file>]\n");
45 fprintf(stdout, "\tIf output rkw file is not specified, the default is to put rkw file to BASE.RKW\n");
46 return -1;
47 }
48 if (mkrk27_patch(img_file, rkw_file, out_img_file, out_rkw_file)) {
49 fprintf(stdout, "%s\n", mkrk27_get_error());
50 return -1;
51 }
52 fprintf(stdout, "Success!\n");
53 return 0;
54}
55
diff --git a/utils/mkrk27boot/mkrk27boot.c b/utils/mkrk27boot/mkrk27boot.c
new file mode 100644
index 0000000000..0ecdf93506
--- /dev/null
+++ b/utils/mkrk27boot/mkrk27boot.c
@@ -0,0 +1,281 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2012 by Andrew Ryabinin
11 *
12 * based on firmware/test/fat/main.c
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <stdarg.h>
28#include <time.h>
29#include <errno.h>
30#include "disk.h"
31#include "dir.h"
32#include "file.h"
33#include "ata.h"
34#include "storage.h"
35#include "mkrk27boot.h"
36
37
38const char *img_filename;
39static char mkrk27_error_msg[256];
40
41static void mkrk27_set_error(const char *msg, ...) {
42 va_list ap;
43 va_start(ap, msg);
44 snprintf(mkrk27_error_msg, sizeof(mkrk27_error_msg), msg, ap);
45 va_end(ap);
46 return;
47}
48
49
50
51/* Extracts in_file from FAT image to out_file */
52static int extract_file(const char *in_file, const char* out_file) {
53 char buf[81920];
54 int nread;
55
56 int fd = open(in_file, O_RDONLY);
57 if (fd < 0) {
58 mkrk27_set_error("Failed to open file %s. ", in_file);
59 return -1;
60 }
61
62 FILE *file = fopen(out_file, "wb");
63 if (!file) {
64 mkrk27_set_error("Failed to open file %s. ", out_file);
65 close(fd);
66 return -1;
67 }
68
69 while (nread = read(fd, buf, sizeof buf), nread > 0) {
70 char *out_ptr = buf;
71 int nwritten;
72
73 do {
74 nwritten = fwrite(buf, 1, nread, file);
75
76 if (nwritten >= 0) {
77 nread -= nwritten;
78 out_ptr += nwritten;
79 } else if (errno != EINTR) {
80 mkrk27_set_error("Writting to file %s failed.", out_file);
81 goto exit;
82 }
83 } while(nread > 0);
84 }
85
86 if (nread == 0) {
87 fclose(file);
88 close(fd);
89 return 0;
90 } else {
91 mkrk27_set_error("Copy from %s to %s failed.", out_file, in_file);
92 }
93exit:
94 fclose(file);
95 close(fd);
96 return -1;
97}
98
99/* Replace out_file in FAT image with in_file */
100static int replace_file(const char *in_file, const char *out_file) {
101 char buf[81920];
102 int fd;
103 int nread;
104
105 fd = creat(out_file, 0666);
106 if (fd < 0) {
107 mkrk27_set_error("Failed to open file %s. ", out_file);
108 return -1;
109 }
110
111 FILE *file = fopen(in_file, "rb");
112 if (!file) {
113 mkrk27_set_error("Failed to open file %s. ", in_file);
114 close(fd);
115 return -1;
116 }
117
118 while (nread = fread(buf, 1, sizeof buf, file), nread > 0) {
119 char *out_ptr = buf;
120 int nwritten;
121
122 do {
123 nwritten = write(fd, buf, nread);
124 if (nwritten >= 0) {
125 nread -= nwritten;
126 out_ptr += nwritten;
127 } else {
128 mkrk27_set_error("Writting to file %s failed.", out_file);
129 goto exit;
130 }
131 } while(nread > 0);
132 }
133
134 if (nread == 0) {
135 fclose(file);
136 close(fd);
137 return 0;
138 } else {
139 mkrk27_set_error("Replacing %s with %s failed.", out_file, in_file);
140 }
141
142exit:
143 fclose(file);
144 close(fd);
145 return -1;
146}
147
148static int mkrk27_init(const char *filename) {
149 int i;
150 int rc;
151 srand(clock());
152
153 img_filename = filename;
154
155 if(ata_init()) {
156 mkrk27_set_error("Warning! The disk is uninitialized\n");
157 return -1;
158 }
159
160 struct partinfo *pinfo = disk_init();
161
162 if (!pinfo) {
163 mkrk27_set_error("Failed reading partitions\n");
164 return -1;
165 }
166
167 for ( i=0; i<4; i++ ) {
168 if ( pinfo[i].type == PARTITION_TYPE_FAT32
169#ifdef HAVE_FAT16SUPPORT
170 || pinfo[i].type == PARTITION_TYPE_FAT16
171#endif
172 ) {
173 rc = fat_mount(IF_MV(0,) IF_MD(0,) pinfo[i].start);
174 if(rc) {
175 mkrk27_set_error("mount: %d",rc);
176 return -1;
177 }
178 break;
179 }
180 }
181 if ( i==4 ) {
182 if(fat_mount(IF_MV(0,) IF_MD(0,) 0)) {
183 mkrk27_set_error("FAT32 partition!");
184 return -1;
185 }
186 }
187 return 0;
188}
189
190extern void ata_exit(void);
191
192static void mkrk27_deinit(void) {
193 ata_exit();
194}
195
196/* copy file */
197static int copy(const char *to, const char *from) {
198 FILE* fd_to, *fd_from;
199 char buf[4096];
200 ssize_t nread;
201
202 if (to == from) {
203 return 0;
204 }
205
206 fd_from = fopen(from, "rb");
207 if (!fd_from) {
208 mkrk27_set_error("Failed to open file %s.", from);
209 return -1;
210 }
211
212 fd_to = fopen(to, "wb");
213 if (!fd_to) {
214 mkrk27_set_error("Failed to open file %s.", to);
215 goto out_error;
216 }
217
218 while (nread = fread(buf, 1, sizeof buf, fd_from), nread > 0) {
219 char *out_ptr = buf;
220 ssize_t nwritten;
221
222 do {
223 nwritten = fwrite(out_ptr, 1, nread, fd_to);
224
225 if (nwritten >= 0)
226 {
227 nread -= nwritten;
228 out_ptr += nwritten;
229 }
230 else if (errno != EINTR)
231 {
232 mkrk27_set_error( "Writing to file %s failed.", to);
233 goto out_error;
234 }
235 } while (nread > 0);
236 }
237
238 if (nread == 0) {
239 fclose(fd_to);
240 fclose(fd_from);
241 return 0;
242 } else {
243 mkrk27_set_error("Copy from %s to %s failed.", from, to);
244 }
245
246out_error:
247
248 fclose(fd_from);
249 fclose(fd_to);
250
251 return -1;
252}
253
254char* mkrk27_get_error(void) {
255 return mkrk27_error_msg;
256}
257
258
259/* Patch rk27 firmware.
260 - img_file - original FAT image file, containing OF,
261 - rkw_file - rkw file which will replace BASE.RKW from OF,
262 - out_img_file - patched img file,
263 - out_rkw_file - BASE.RKW extracted from OF.
264*/
265int mkrk27_patch(const char* img_file, const char* rkw_file, const char* out_img_file, const char* out_rkw_file) {
266 if (copy(out_img_file, img_file)) {
267 return -1;
268 }
269 if (mkrk27_init(out_img_file)) {
270 return -1;
271 }
272 if (extract_file("/SYSTEM/BASE.RKW", out_rkw_file)) {
273 return -1;
274 }
275 if (replace_file(rkw_file, "/SYSTEM/BASE.RKW") ||
276 replace_file(rkw_file, "/SYSTEM00/BASE.RKW")) {
277 return -1;
278 }
279 mkrk27_deinit();
280 return 0;
281}
diff --git a/utils/mkrk27boot/mkrk27boot.h b/utils/mkrk27boot/mkrk27boot.h
new file mode 100644
index 0000000000..dc8c2e8133
--- /dev/null
+++ b/utils/mkrk27boot/mkrk27boot.h
@@ -0,0 +1,36 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2012 by Andrew Ryabinin
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef _MKRK27BOOT_H
22#define _MKRK27BOOT_H
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28int mkrk27_patch(const char* img_file, const char* rkw_file, const char* out_img_file, const char* out_rkw_file);
29char *mkrk27_get_error(void);
30
31#ifdef __cplusplus
32}
33#endif
34
35
36#endif
diff --git a/utils/mks5lboot/.gitignore b/utils/mks5lboot/.gitignore
new file mode 100644
index 0000000000..9b9b1de6ab
--- /dev/null
+++ b/utils/mks5lboot/.gitignore
@@ -0,0 +1,5 @@
1buildposix/
2buildmingw/
3builddarwin/
4mks5lboot
5mks5lboot.exe
diff --git a/utils/mks5lboot/Makefile b/utils/mks5lboot/Makefile
new file mode 100644
index 0000000000..72ea521d5f
--- /dev/null
+++ b/utils/mks5lboot/Makefile
@@ -0,0 +1,43 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7CC := gcc
8CFLAGS += -Wall -Wextra
9
10OUTPUT = mks5lboot
11
12# inputs for lib
13LIBSOURCES := dualboot.c mkdfu.c ipoddfu.c
14# inputs for binary only
15SOURCES := $(LIBSOURCES) main.c
16# dependencies for binary
17EXTRADEPS :=
18
19CPPDEFINES := $(shell echo foo | $(CROSS)$(CC) -dM -E -)
20
21ifeq ($(findstring WIN32,$(CPPDEFINES)),WIN32)
22LDOPTS += -lsetupapi
23# optional libusb support (needed for WinUSB and libusbK drivers)
24ifeq ($(findstring MINGW,$(CPPDEFINES)),MINGW)
25ifeq ($(USE_LIBUSBAPI),1)
26CFLAGS += -DUSE_LIBUSBAPI
27LDOPTS += -Wl,-Bstatic -lusb-1.0
28endif
29endif
30else
31ifeq ($(findstring APPLE,$(CPPDEFINES)),APPLE)
32LDOPTS += -L/usr/local/lib -framework IOKit -framework CoreFoundation
33else # Linux
34CFLAGS += -DUSE_LIBUSBAPI
35LDOPTS += -lusb-1.0
36endif
37endif
38
39include ../libtools.make
40
41# explicit dependencies on dualboot.{c,h} and mks5lboot.h
42$(OBJDIR)mks5lboot.o: dualboot.h dualboot.c mks5lboot.h
43$(OBJDIR)main.o: dualboot.h dualboot.c main.c mks5lboot.h
diff --git a/utils/mks5lboot/README b/utils/mks5lboot/README
new file mode 100644
index 0000000000..c424f7e617
--- /dev/null
+++ b/utils/mks5lboot/README
@@ -0,0 +1,228 @@
1mks5lboot
2---------
3
4A tool to install/uninstall a dual bootloader into a s5l8702 based
5device:
6
7 - iPod Classic 6G
8 - iPod Nano 3G (WIP)
9
10
11Usage
12-----
13
14 mks5lboot --bl-inst <bootloader.ipod> [-p <pid>] [--single]
15 --bl-uninst <platform> [-p <pid>]
16 --dfuscan [--loop [<sec>]] [-p <pid>]
17 --dfusend <infile.dfu> [-p <pid>]
18 --dfureset [--loop [<sec>]] [-p <pid>]
19 --mkdfu-inst <bootloader.ipod> <outfile.dfu> [--single]
20 --mkdfu-uninst <platform> <outfile.dfu>
21 --mkdfu-raw <filename.bin> <outfile.dfu>
22
23Commands:
24 --bl-inst Install file <bootloader.ipod> into an iPod device
25 (same as --mkdfu-inst and --dfusend).
26 --bl-uninst Remove a bootloader from an iPod device (same as
27 --mkdfu-uninst and --dfusend).
28
29 --dfuscan scan for DFU USB devices and outputs the status.
30 --dfusend send DFU image <infile.dfu> to the device.
31 --dfureset reset DFU USB device bus.
32
33 --mkdfu-inst Build a DFU image containing an installer for
34 <bootloader.ipod>, save it as <outfile.dfu>.
35 --mkdfu-uninst Build a DFU image containing an uninstaler for
36 <platform> devices, save it as <outfile.dfu>.
37 --mkdfu-raw Build a DFU image containing raw executable
38 code, save it as <outfile.dfu>. <infile.bin>
39 is the code you want to run, it is loaded at
40 address 0x2200030c and executed.
41
42 <bootloader.ipod> is the rockbox bootloader that you want to
43 install (previously scrambled with tools/scramble utility).
44
45 <platform> is the name of the platform (type of device) for
46 which the DFU uninstaller will be built. Currently supported
47 platform names are:
48 ipod6g: iPod Classic 6G
49
50Options:
51 -p, --pid <pid> Use a specific <pid> (Product Id) USB device,
52 if this option is ommited then it uses the
53 first USB DFU device found.
54 -l, --loop <sec> Run the command every <sec> seconds, default
55 period (<sec> ommited) is 1 seconds.
56 -S, --single Be careful using this option. The bootloader
57 is installed for single boot, the original
58 Apple NOR boot is destroyed (if it exists),
59 and only Rockbox can be used.
60
61
62Dual bootloader installation
63----------------------------
64
65Prerequisites:
66
67 - An iPod Classic 6th with Apple firmware installed and running, current
68 supported FW versions for existing models:
69
70 Classic 6th 80/160 Late 2007 (1G): 1.1.2
71 Classic 6th 120 Late 2008 (2G): 2.0.1
72 Classic 6th 160 Late 2009 (3G): 2.0.4
73 Classic 6th 160 Late 2012 (4G): 2.0.5
74
75 - If your iPod is formated using Apple partitions you must convert this
76 ipod to FAT32 format (aka a "winpod"), see http://www.rockbox.org/
77 wiki/IpodConversionToFAT32
78
79 - It is recommended to install the RB firmware before installing the dual
80 bootloader for the first time. Install Rockbox using RockboxUtility or
81 download the latest daily build and uncompress it into the root folder
82 of the iPod.
83
84 Windows only:
85
86 - If iTunes is installed:
87 . Configure iTunes: Summary -> Options -> check "Enable disk use".
88
89 - If iTunes is not installed:
90 . You need a DFU USB driver for your device. To check if there is a
91 valid USB driver installed, put your device on DFU mode and choose
92 one of either:
93 a) Use Windows Device Manager to verify if you USB DFU device is
94 present.
95 b) Use mks5lboot tool running "mks5lboot --dfuscan", common output:
96 . When the DFU device is found and a valid driver is installed:
97 [INFO] DFU device state: 2
98 . When the device is found but there is no driver installed:
99 [ERR] Could not open USB device: LIBUSB_ERROR_NOT_SUPPORTED
100 . When the device is found but driver is not valid (probably a
101 libusb-win32 driver is installed):
102 [ERR] Could not set USB configuration: LIBUSB_ERROR_NOT_FOUND
103 . If there is no valid DFU driver installed, try one of these:
104 a) Use Zadig (http://zadig.akeo.ie/) to build and install a WinUSB
105 (libusb.info) or libusbK driver for your device. Note that
106 libusb-win32 (libusb0) drivers are not valid for mks5lboot.
107 b) Use Apple Mobile Device USB driver (included with iTunes). To
108 install this driver without iTunes see https://www.freemyipod.org
109 /wiki/EmCORE_Installation/iPodClassic/InstalliTunesDrivers
110
111Command line install:
112
113 - If you are using iTunes on Windows, close iTunes and kill (or pause)
114 iTunesHelper.exe before entering DFU mode.
115
116 - If you are using iTunes on Mac, quit iTunes and kill (or pause) the
117 iTunesHelper process before entering DFU mode.
118 You can use "ps x | grep iTunesHelper" to locate the process <PID>,
119 use "kill -STOP <PID>" to suspend the process and "kill -CONT <PID>"
120 to resume it once the bootloader is installed.
121
122 - Put you device on DFU mode by pressing and holding SELECT+MENU buttons
123 for about 12 seconds.
124
125 You can notice when the device enters DFU mode running the next command
126 to scan the USB bus every second (press Ctrl-C to abort the scan):
127 ./mks5lboot --dfuscan --loop
128
129 - To install or update a bootloader, build the DFU installer and send it
130 to the device:
131 ./mks5lboot --bl-inst path/to/bootloader-ipod6g.ipod
132
133 When the DFU image is loaded and executed, the device emits an 'alive'
134 tone (2000Hz/100ms). When the bootloader is successfully installed then
135 a dual tone beep sounds (1000Hz/100ms+2000Hz/150ms) and the device
136 reboots. If something went bad then 330Hz/500ms tone is emited and the
137 device reboots. When three 330Hz tones sounds, it means that the NOR
138 got corrupted and the device must be restored using iTunes (should not
139 happen).
140
141 - To remove a previously installed bootloader, build the DFU uninstaler
142 and send it to the device:
143 ./mks5lboot --bl-uninst ipod6g
144
145 Notes:
146
147 - If USB access is denied, try to run the mks5lboot tool using a privileged
148 user (i.e. Administrator or root).
149
150 - On Windows, use 'mks5lboot' or 'mks5lboot.exe' instead of './mks5lboot'.
151
152
153
154Dual-Boot
155---------
156
157The purpose of this program is to provide dual-boot between the original
158firmware and the new (rockbox) firmware.
159
160The button press check is done ~800 ms. after power-up or reboot, then:
161
162 SELECT + MENU: resets the device after ~5 seconds, then if SELECT+MENU
163 remains pressed the device enters DFU mode after an
164 additional period of ~8 seconds.
165 SELECT + LEFT: enter OF diagnostics (after ~7 seconds).
166 SELECT + PLAY: enter OF diskmode (after ~7 seconds).
167 SELECT + RIGHT: enter bootloader USB mode.
168 MENU: enter OF
169 Hold Switch locked: enter OF (see below for details).
170 Any other combination: launch Rockbox.
171
172Switch current firmware:
173
174 Tries to behave like ipod Video, see http://download.rockbox.org/manual/
175 rockbox-ipodvideo/rockbox-buildch3.html#x5-290003.1.3
176
177 Apple is the current FW:
178 - Stop playback and wait a few seconds for hard disk spin-down.
179 - Press and hold SELECT+MENU, after ~5 seconds the player hard resets,
180 release the buttons when the screen goes black.
181
182 Rockbox is the current FW:
183 - Shut down the device using "Long Play" key press.
184 - Once the device is powered off, there are three ways to enter OF:
185 1) Press and hold MENU button for at least ~800 ms.
186 2) Turn on the Hold switch immediately after turning the player on,
187 it must be done before "Loading Rockbox..." message appears (~3
188 seconds from power-on). Be careful, if the hold switch is locked
189 when Rockbox starts then your RB settings will be cleared!
190 3) You can also load the original firmware by shutting down the
191 device, then clicking the Hold switch on and connecting the iPod
192 to your computer.
193
194
195Single-Boot
196-----------
197
198Use --single option if the Apple firmware is not installed on your iPod
199and/or you want to force the installation of the bootloader to use Rockbox
200as unique firmware. The single-boot installer writes the bootloader on the
201NOR with no previous check, the original Apple NOR boot is destroyed if it
202exists.
203
204To build the DFU single-boot installer and send it to the device:
205 mks5lboot --bl-inst --single /path/to/bootloader-ipod6g.ipod
206
207
208Build
209-----
210
211To build type 'make'.
212
213Linux needs libusb >= 1.0, use your package manager to install libusb.
214
215For Windows, to build with libusb support type 'make USE_LIBUSBAPI=1'.
216
217Tested on:
218 Linux: gcc-4.9.2 + libusb-1.0.19
219 Windows XP: mingw32-gcc-4.8.1 + libusbx-1.0.15
220 OS X 10.11: clang-7.3.0 + libusb-1.0.20
221 MXE: i686-w64-mingw32.static-gcc 5.4.0 + libusb-1.0.21
222
223
224Hacking
225-------
226
227See comments in mkdfu.c, ipoddfu.c, dualboot.c and bootloader/ipod6g.c for
228more information.
diff --git a/utils/mks5lboot/dualboot.c b/utils/mks5lboot/dualboot.c
new file mode 100644
index 0000000000..4c1608fc41
--- /dev/null
+++ b/utils/mks5lboot/dualboot.c
@@ -0,0 +1,664 @@
1/* Generated by bin2c */
2
3#include "dualboot.h"
4
5unsigned char dualboot_install_ipod6g[5396] = {
6 0xd7, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x24, 0xd0, 0x9f, 0xe5, 0xdb, 0x00, 0xa0, 0xe3,
7 0x00, 0xf0, 0x21, 0xe1, 0x18, 0xd0, 0x9f, 0xe5, 0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
8 0x10, 0xd0, 0x9f, 0xe5, 0x05, 0x08, 0xa0, 0xe3, 0x78, 0x00, 0x80, 0xe3, 0x10, 0x0f, 0x01, 0xee,
9 0x1d, 0x00, 0x00, 0xeb, 0x0c, 0x03, 0x00, 0x22, 0x0c, 0x03, 0x00, 0x22, 0x7f, 0x40, 0x2d, 0xe9,
10 0x5c, 0x10, 0x9f, 0xe5, 0x10, 0x20, 0xa0, 0xe3, 0x0d, 0x00, 0xa0, 0xe1, 0xea, 0x04, 0x00, 0xeb,
11 0x00, 0x00, 0xa0, 0xe3, 0x02, 0x10, 0xa0, 0xe3, 0x0d, 0x20, 0xa0, 0xe1, 0x10, 0x30, 0xa0, 0xe3,
12 0x8d, 0x04, 0x00, 0xeb, 0x3c, 0x60, 0x9f, 0xe5, 0x0d, 0x40, 0xa0, 0xe1, 0x00, 0x50, 0xa0, 0xe3,
13 0x06, 0x10, 0xa0, 0xe1, 0x0d, 0x00, 0xa0, 0xe1, 0x10, 0x20, 0xa0, 0xe3, 0x77, 0x00, 0x00, 0xeb,
14 0x10, 0x60, 0x86, 0xe2, 0x00, 0x00, 0x50, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x01, 0x50, 0x85, 0xe2,
15 0x04, 0x00, 0x55, 0xe3, 0xf5, 0xff, 0xff, 0x1a, 0x05, 0x00, 0xa0, 0xe1, 0x10, 0xd0, 0x8d, 0xe2,
16 0x70, 0x80, 0xbd, 0xe8, 0x10, 0x00, 0x02, 0x22, 0x54, 0x17, 0x00, 0x22, 0x70, 0x40, 0x2d, 0xe9,
17 0xae, 0x00, 0x00, 0xeb, 0x7c, 0x41, 0x9f, 0xe5, 0x7c, 0x01, 0x9f, 0xe5, 0xa3, 0x04, 0x00, 0xeb,
18 0x00, 0x00, 0xa0, 0xe3, 0x04, 0x10, 0xa0, 0xe3, 0xc4, 0x00, 0x00, 0xeb, 0x0e, 0x30, 0xd4, 0xe5,
19 0x0d, 0x00, 0xd4, 0xe5, 0x0c, 0x10, 0xd4, 0xe5, 0x0f, 0x20, 0xd4, 0xe5, 0x03, 0x38, 0xa0, 0xe1,
20 0x00, 0x34, 0x83, 0xe1, 0x01, 0x30, 0x83, 0xe1, 0x02, 0x2c, 0x83, 0xe1, 0x40, 0x50, 0xd4, 0xe5,
21 0x02, 0x00, 0xa0, 0xe3, 0x02, 0x1b, 0x84, 0xe2, 0x10, 0x30, 0x84, 0xe2, 0xee, 0x01, 0x00, 0xeb,
22 0x40, 0x20, 0xa0, 0xe3, 0x02, 0x00, 0xa0, 0xe3, 0x04, 0x10, 0xa0, 0xe1, 0x02, 0x30, 0x84, 0xe0,
23 0xe9, 0x01, 0x00, 0xeb, 0x00, 0x00, 0x55, 0xe3, 0x08, 0x00, 0x00, 0x0a, 0x04, 0x10, 0xa0, 0xe1,
24 0x02, 0x09, 0xa0, 0xe3, 0x62, 0x03, 0x00, 0xeb, 0x10, 0x31, 0x9f, 0xe5, 0x10, 0x21, 0x9f, 0xe5,
25 0x00, 0x00, 0x50, 0xe3, 0x02, 0x00, 0xa0, 0x11, 0x03, 0x00, 0xa0, 0x01, 0x33, 0x00, 0x00, 0xea,
26 0x02, 0x09, 0xa0, 0xe3, 0xfc, 0x10, 0x9f, 0xe5, 0xfc, 0x20, 0x9f, 0xe5, 0x77, 0x03, 0x00, 0xeb,
27 0x00, 0x00, 0x50, 0xe3, 0x2c, 0x00, 0x00, 0x1a, 0xb7, 0xff, 0xff, 0xeb, 0x04, 0x00, 0x50, 0xe3,
28 0x0a, 0x00, 0x00, 0x1a, 0xdc, 0x00, 0x9f, 0xe5, 0xc5, 0x01, 0x00, 0xeb, 0xd4, 0x10, 0x9f, 0xe5,
29 0xd4, 0x20, 0x9f, 0xe5, 0x02, 0x09, 0x80, 0xe2, 0x6c, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x50, 0xe3,
30 0x21, 0x00, 0x00, 0x1a, 0xac, 0xff, 0xff, 0xeb, 0x04, 0x00, 0x50, 0xe3, 0x1e, 0x00, 0x00, 0x0a,
31 0xa0, 0x00, 0x9f, 0xe5, 0xba, 0x01, 0x00, 0xeb, 0x00, 0x40, 0xa0, 0xe1, 0x23, 0x03, 0x00, 0xeb,
32 0x04, 0x00, 0x50, 0xe1, 0xa4, 0x00, 0x9f, 0x35, 0x18, 0x00, 0x00, 0x3a, 0x02, 0x09, 0x84, 0xe2,
33 0x90, 0x10, 0x9f, 0xe5, 0x3e, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x50, 0xe3, 0x05, 0x00, 0x00, 0x0a,
34 0x02, 0x09, 0xa0, 0xe3, 0x6c, 0x10, 0x9f, 0xe5, 0x39, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x50, 0xe3,
35 0x6c, 0x00, 0x9f, 0x15, 0x0d, 0x00, 0x00, 0x1a, 0x6c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0xa0, 0xe3,
36 0x60, 0x10, 0x9f, 0xe5, 0xc8, 0x01, 0x00, 0xeb, 0x02, 0x09, 0xa0, 0xe3, 0x54, 0x10, 0x9f, 0xe5,
37 0x2f, 0x03, 0x00, 0xeb, 0x58, 0x30, 0x9f, 0xe5, 0x0c, 0x20, 0x83, 0xe2, 0x00, 0x00, 0x50, 0xe3,
38 0x03, 0x00, 0xa0, 0x01, 0x02, 0x00, 0xa0, 0x11, 0x00, 0x00, 0x00, 0xea, 0x2c, 0x00, 0x9f, 0xe5,
39 0x40, 0x20, 0x9f, 0xe5, 0x40, 0x30, 0x9f, 0xe5, 0xb4, 0x10, 0x92, 0xe5, 0x03, 0x00, 0x51, 0xe1,
40 0xfc, 0xff, 0xff, 0x9a, 0x49, 0x04, 0x00, 0xeb, 0x01, 0x26, 0xa0, 0xe3, 0xf2, 0x35, 0xa0, 0xe3,
41 0x00, 0x20, 0x83, 0xe5, 0xfe, 0xff, 0xff, 0xea, 0xd0, 0x17, 0x00, 0x22, 0x94, 0x17, 0x00, 0x22,
42 0x4c, 0x17, 0x00, 0x22, 0x9c, 0x17, 0x00, 0x22, 0x00, 0x00, 0x02, 0x22, 0x00, 0x08, 0x02, 0x22,
43 0x46, 0x17, 0x00, 0x22, 0x40, 0x17, 0x00, 0x22, 0x00, 0x00, 0x70, 0x3c, 0x7f, 0x84, 0x1e, 0x00,
44 0x10, 0x40, 0x2d, 0xe9, 0x00, 0x30, 0xa0, 0xe3, 0x07, 0x00, 0x00, 0xea, 0x03, 0x40, 0xd0, 0xe7,
45 0x03, 0xc0, 0xd1, 0xe7, 0x01, 0x20, 0x42, 0xe2, 0x0c, 0x00, 0x54, 0xe1, 0x01, 0x30, 0x83, 0xe2,
46 0x01, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x6c, 0xe0, 0x10, 0x80, 0xbd, 0xe8, 0x00, 0x00, 0x52, 0xe3,
47 0xf5, 0xff, 0xff, 0x1a, 0x02, 0x00, 0xa0, 0xe1, 0x10, 0x80, 0xbd, 0xe8, 0x1f, 0x30, 0x00, 0xe2,
48 0x01, 0x20, 0xa0, 0xe3, 0xc0, 0x02, 0xa0, 0xe1, 0x00, 0x00, 0x51, 0xe3, 0x12, 0x33, 0xa0, 0xe1,
49 0x02, 0x20, 0x00, 0xe0, 0x08, 0x00, 0x00, 0x0a, 0x3c, 0x10, 0x9f, 0xe5, 0x3c, 0x00, 0x9f, 0xe5,
50 0x00, 0x00, 0x52, 0xe3, 0x00, 0x20, 0xa0, 0x11, 0x01, 0x20, 0xa0, 0x01, 0x00, 0x10, 0x92, 0xe5,
51 0x03, 0x30, 0xc1, 0xe1, 0x00, 0x30, 0x82, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x18, 0x10, 0x9f, 0xe5,
52 0x18, 0x00, 0x9f, 0xe5, 0x00, 0x00, 0x52, 0xe3, 0x01, 0x00, 0xa0, 0x01, 0x00, 0x20, 0x90, 0xe5,
53 0x03, 0x30, 0x82, 0xe1, 0x00, 0x30, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x48, 0x00, 0x50, 0x3c,
54 0x4c, 0x00, 0x50, 0x3c, 0x70, 0x40, 0x2d, 0xe9, 0x10, 0x50, 0x9d, 0xe5, 0x01, 0x30, 0x43, 0xe2,
55 0x01, 0x50, 0x45, 0xe2, 0x03, 0x60, 0x02, 0xe2, 0x0f, 0x30, 0x03, 0xe2, 0x05, 0x52, 0xa0, 0xe1,
56 0x03, 0xc0, 0xc0, 0xe3, 0xff, 0x50, 0x05, 0xe2, 0x06, 0x36, 0x83, 0xe1, 0x00, 0x40, 0x9c, 0xe5,
57 0x05, 0x30, 0x83, 0xe1, 0x30, 0x50, 0x9f, 0xe5, 0x02, 0x20, 0x00, 0xe2, 0x82, 0x21, 0xa0, 0xe1,
58 0x00, 0x00, 0x51, 0xe3, 0x02, 0x19, 0xa0, 0x03, 0x00, 0x10, 0xa0, 0x13, 0x35, 0x42, 0x04, 0xe0,
59 0x01, 0x30, 0x83, 0xe1, 0x13, 0x22, 0x84, 0xe1, 0x00, 0x20, 0x8c, 0xe5, 0xb0, 0x20, 0xd0, 0xe1,
60 0x03, 0x00, 0x52, 0xe1, 0xfc, 0xff, 0xff, 0x1a, 0x70, 0x80, 0xbd, 0xe8, 0x00, 0x00, 0xff, 0xff,
61 0x5c, 0xc0, 0x9f, 0xe5, 0x13, 0x40, 0x2d, 0xe9, 0x44, 0xe0, 0x9c, 0xe5, 0x01, 0x40, 0xa0, 0xe3,
62 0x01, 0xec, 0xce, 0xe3, 0x00, 0x20, 0xa0, 0xe3, 0x04, 0x30, 0xa0, 0xe1, 0x44, 0xe0, 0x8c, 0xe5,
63 0x40, 0x00, 0x9f, 0xe5, 0x04, 0x10, 0xa0, 0xe1, 0x00, 0x40, 0x8d, 0xe5, 0xd8, 0xff, 0xff, 0xeb,
64 0x04, 0x10, 0xa0, 0xe1, 0x25, 0x00, 0xa0, 0xe3, 0xbb, 0xff, 0xff, 0xeb, 0x28, 0x30, 0x9f, 0xe5,
65 0x11, 0x2d, 0xa0, 0xe3, 0xa0, 0x20, 0x83, 0xe5, 0x0b, 0x20, 0xa0, 0xe3, 0xb0, 0x20, 0x83, 0xe5,
66 0x00, 0x20, 0xe0, 0xe3, 0xa8, 0x20, 0x83, 0xe5, 0x04, 0x20, 0x82, 0xe2, 0xa4, 0x20, 0x83, 0xe5,
67 0x1c, 0x80, 0xbd, 0xe8, 0x00, 0x00, 0x50, 0x3c, 0x12, 0x00, 0x50, 0x3c, 0x00, 0x00, 0x70, 0x3c,
68 0x04, 0x30, 0x9f, 0xe5, 0x00, 0x11, 0x83, 0xe7, 0x1e, 0xff, 0x2f, 0xe1, 0xac, 0x17, 0x00, 0x22,
69 0x80, 0x20, 0x9f, 0xe5, 0x00, 0x00, 0x51, 0xe3, 0x7c, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x11,
70 0x01, 0x00, 0x50, 0xe3, 0x0a, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x50, 0xe3, 0x0f, 0x00, 0x00, 0x0a,
71 0x00, 0x00, 0x50, 0xe3, 0x1e, 0xff, 0x2f, 0x11, 0x60, 0x10, 0x9f, 0xe5, 0x00, 0x20, 0x91, 0xe5,
72 0x22, 0x28, 0xa0, 0xe1, 0x02, 0x28, 0xa0, 0xe1, 0x02, 0x30, 0x83, 0xe1, 0x00, 0x30, 0x81, 0xe5,
73 0x1e, 0xff, 0x2f, 0xe1, 0x44, 0x10, 0x9f, 0xe5, 0xc0, 0x20, 0x91, 0xe5, 0x02, 0x28, 0xa0, 0xe1,
74 0x22, 0x28, 0xa0, 0xe1, 0x03, 0x38, 0x82, 0xe1, 0xc0, 0x30, 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1,
75 0x28, 0x00, 0x9f, 0xe5, 0xc0, 0x21, 0x90, 0xe5, 0xff, 0x24, 0xc2, 0xe3, 0x03, 0x2c, 0x82, 0xe1,
76 0xc0, 0x21, 0x80, 0xe5, 0xe0, 0x21, 0x90, 0xe5, 0xff, 0x20, 0xc2, 0xe3, 0x23, 0x34, 0x82, 0xe1,
77 0xe0, 0x31, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x22, 0x22, 0x00, 0x00, 0xef, 0xee, 0x00, 0x00,
78 0x00, 0x00, 0xf0, 0x3c, 0x01, 0x00, 0x50, 0xe3, 0x01, 0x10, 0x21, 0xe2, 0x06, 0x00, 0x00, 0x0a,
79 0x02, 0x00, 0x50, 0xe3, 0x06, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x50, 0xe3, 0x24, 0x30, 0x9f, 0x05,
80 0x0e, 0x10, 0x81, 0x03, 0x00, 0x12, 0x83, 0x05, 0x1e, 0xff, 0x2f, 0xe1, 0x18, 0x30, 0x9f, 0xe5,
81 0x00, 0x00, 0x00, 0xea, 0x14, 0x30, 0x9f, 0xe5, 0x08, 0x20, 0x9f, 0xe5, 0x03, 0x30, 0x81, 0xe1,
82 0x00, 0x32, 0x82, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0xf0, 0x3c, 0x0e, 0x04, 0x06, 0x00,
83 0x0e, 0x06, 0x0e, 0x00, 0x02, 0x00, 0x50, 0xe3, 0x10, 0x40, 0x2d, 0xe9, 0xbc, 0x30, 0x9f, 0x05,
84 0x03, 0x00, 0x00, 0x0a, 0xb8, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3, 0xb4, 0x30, 0x9f, 0xe5,
85 0x02, 0x30, 0xa0, 0x01, 0xb0, 0x40, 0x9f, 0xe5, 0xb0, 0xc0, 0x9f, 0xe5, 0x01, 0x20, 0xa0, 0xe3,
86 0x00, 0x20, 0x83, 0xe5, 0x02, 0x00, 0x50, 0xe3, 0xa4, 0x30, 0x9f, 0x05, 0x02, 0x00, 0x00, 0x0a,
87 0x01, 0x00, 0x50, 0xe3, 0x04, 0x30, 0xa0, 0x01, 0x0c, 0x30, 0xa0, 0x11, 0x00, 0x30, 0x93, 0xe5,
88 0x1f, 0x3e, 0x03, 0xe2, 0x01, 0x0c, 0x53, 0xe3, 0xf5, 0xff, 0xff, 0x0a, 0x02, 0x00, 0x50, 0xe3,
89 0x80, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x7c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3,
90 0x78, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x5c, 0xc0, 0x9f, 0xe5, 0x5c, 0x20, 0x9f, 0xe5,
91 0x00, 0x10, 0x83, 0xe5, 0x02, 0x00, 0x50, 0xe3, 0x54, 0x30, 0x9f, 0x05, 0x02, 0x00, 0x00, 0x0a,
92 0x01, 0x00, 0x50, 0xe3, 0x0c, 0x30, 0xa0, 0x01, 0x02, 0x30, 0xa0, 0x11, 0x00, 0x30, 0x93, 0xe5,
93 0x3e, 0x0c, 0x13, 0xe3, 0xf6, 0xff, 0xff, 0x0a, 0x02, 0x00, 0x50, 0xe3, 0x40, 0x00, 0x9f, 0x05,
94 0x04, 0x00, 0x00, 0x0a, 0x3c, 0x30, 0x9f, 0xe5, 0x3c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3,
95 0x02, 0x00, 0xa0, 0x01, 0x03, 0x00, 0xa0, 0x11, 0x00, 0x00, 0x90, 0xe5, 0x10, 0x80, 0xbd, 0xe8,
96 0x34, 0x00, 0x20, 0x3d, 0x34, 0x00, 0xe0, 0x3c, 0x34, 0x00, 0x30, 0x3c, 0x08, 0x00, 0xe0, 0x3c,
97 0x08, 0x00, 0x30, 0x3c, 0x08, 0x00, 0x20, 0x3d, 0x10, 0x00, 0x20, 0x3d, 0x10, 0x00, 0xe0, 0x3c,
98 0x10, 0x00, 0x30, 0x3c, 0x20, 0x00, 0x20, 0x3d, 0x20, 0x00, 0x30, 0x3c, 0x20, 0x00, 0xe0, 0x3c,
99 0x02, 0x00, 0x50, 0xe3, 0xf0, 0x40, 0x2d, 0xe9, 0xd8, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a,
100 0xd4, 0xc0, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3, 0xd0, 0x30, 0x9f, 0xe5, 0x0c, 0x30, 0xa0, 0x01,
101 0x02, 0x00, 0x50, 0xe3, 0x00, 0x10, 0x83, 0xe5, 0xc4, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a,
102 0xc0, 0xc0, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3, 0xbc, 0x30, 0x9f, 0xe5, 0x0c, 0x30, 0xa0, 0x01,
103 0x00, 0x40, 0x93, 0xe5, 0x00, 0xc0, 0xa0, 0xe3, 0x01, 0x40, 0x84, 0xe3, 0x00, 0x40, 0x83, 0xe5,
104 0xa8, 0x70, 0x9f, 0xe5, 0xa8, 0x60, 0x9f, 0xe5, 0xa8, 0x50, 0x9f, 0xe5, 0xa8, 0x40, 0x9f, 0xe5,
105 0x12, 0x00, 0x00, 0xea, 0x02, 0x00, 0x50, 0xe3, 0xa0, 0x30, 0x9f, 0x05, 0x02, 0x00, 0x00, 0x0a,
106 0x01, 0x00, 0x50, 0xe3, 0x07, 0x30, 0xa0, 0x01, 0x06, 0x30, 0xa0, 0x11, 0x00, 0x30, 0x93, 0xe5,
107 0x3e, 0x0c, 0x13, 0xe3, 0xf6, 0xff, 0xff, 0x0a, 0x02, 0x00, 0x50, 0xe3, 0x80, 0x30, 0x9f, 0x05,
108 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x05, 0x30, 0xa0, 0x01, 0x04, 0x30, 0xa0, 0x11,
109 0x00, 0x30, 0x93, 0xe5, 0x01, 0x10, 0x41, 0xe2, 0x0c, 0x30, 0xc2, 0xe7, 0x01, 0xc0, 0x8c, 0xe2,
110 0x00, 0x00, 0x51, 0xe3, 0xea, 0xff, 0xff, 0x1a, 0x02, 0x00, 0x50, 0xe3, 0x30, 0x00, 0x9f, 0x05,
111 0x04, 0x00, 0x00, 0x0a, 0x2c, 0x30, 0x9f, 0xe5, 0x2c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3,
112 0x02, 0x00, 0xa0, 0x11, 0x03, 0x00, 0xa0, 0x01, 0x00, 0x30, 0x90, 0xe5, 0x01, 0x30, 0xc3, 0xe3,
113 0x00, 0x30, 0x80, 0xe5, 0xf0, 0x80, 0xbd, 0xe8, 0x34, 0x00, 0x20, 0x3d, 0x34, 0x00, 0xe0, 0x3c,
114 0x34, 0x00, 0x30, 0x3c, 0x04, 0x00, 0x20, 0x3d, 0x04, 0x00, 0xe0, 0x3c, 0x04, 0x00, 0x30, 0x3c,
115 0x08, 0x00, 0xe0, 0x3c, 0x08, 0x00, 0x30, 0x3c, 0x20, 0x00, 0xe0, 0x3c, 0x20, 0x00, 0x30, 0x3c,
116 0x08, 0x00, 0x20, 0x3d, 0x20, 0x00, 0x20, 0x3d, 0x02, 0x00, 0x50, 0xe3, 0x2e, 0x00, 0x80, 0x02,
117 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x2b, 0x00, 0xa0, 0x03, 0x22, 0x00, 0xa0, 0x13,
118 0x00, 0x10, 0xa0, 0xe3, 0xe4, 0xfe, 0xff, 0xea, 0x02, 0x00, 0x50, 0xe3, 0x10, 0x40, 0x2d, 0xe9,
119 0x00, 0x40, 0xa0, 0xe1, 0x30, 0x00, 0xa0, 0x03, 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x54, 0xe3,
120 0x2b, 0x00, 0xa0, 0x03, 0x22, 0x00, 0xa0, 0x13, 0x01, 0x10, 0xa0, 0xe3, 0xda, 0xfe, 0xff, 0xeb,
121 0x02, 0x00, 0x54, 0xe3, 0x04, 0x31, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x00, 0x21, 0x9f, 0xe5,
122 0x01, 0x00, 0x54, 0xe3, 0xfc, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x02, 0x00, 0x54, 0xe3,
123 0x0f, 0x20, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0xec, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a,
124 0xe8, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0xe4, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01,
125 0x00, 0x20, 0x93, 0xe5, 0x02, 0x00, 0x54, 0xe3, 0x0c, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x83, 0xe5,
126 0xd0, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0xcc, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3,
127 0xc8, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0xc4, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x54, 0xe3,
128 0x04, 0x21, 0x92, 0xe7, 0x00, 0x20, 0x83, 0xe5, 0xb8, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a,
129 0xb4, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0xb0, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01,
130 0x02, 0x00, 0x54, 0xe3, 0x06, 0x20, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0xa0, 0x30, 0x9f, 0x05,
131 0x03, 0x00, 0x00, 0x0a, 0x9c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0x98, 0x30, 0x9f, 0xe5,
132 0x02, 0x30, 0xa0, 0x01, 0x94, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x54, 0xe3, 0x00, 0x20, 0x83, 0xe5,
133 0x54, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x50, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3,
134 0x4c, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x00, 0x20, 0x93, 0xe5, 0x02, 0x00, 0x54, 0xe3,
135 0x0c, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0x2c, 0x40, 0x9f, 0x05, 0x04, 0x00, 0x00, 0x0a,
136 0x2c, 0x30, 0x9f, 0xe5, 0x24, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0x02, 0x40, 0xa0, 0x01,
137 0x03, 0x40, 0xa0, 0x11, 0x01, 0x30, 0xa0, 0xe3, 0x00, 0x30, 0x84, 0xe5, 0x10, 0x80, 0xbd, 0xe8,
138 0x08, 0x00, 0x20, 0x3d, 0x08, 0x00, 0xe0, 0x3c, 0x08, 0x00, 0x30, 0x3c, 0x00, 0x00, 0x20, 0x3d,
139 0x00, 0x00, 0xe0, 0x3c, 0x00, 0x00, 0x30, 0x3c, 0x30, 0x00, 0x20, 0x3d, 0x30, 0x00, 0xe0, 0x3c,
140 0x30, 0x00, 0x30, 0x3c, 0xac, 0x17, 0x00, 0x22, 0x0c, 0x00, 0x20, 0x3d, 0x0c, 0x00, 0xe0, 0x3c,
141 0x0c, 0x00, 0x30, 0x3c, 0x04, 0x00, 0x20, 0x3d, 0x04, 0x00, 0xe0, 0x3c, 0x04, 0x00, 0x30, 0x3c,
142 0x18, 0x06, 0x01, 0x00, 0x0c, 0x30, 0x80, 0xe2, 0x02, 0xc0, 0xd3, 0xe5, 0x01, 0x10, 0xd3, 0xe5,
143 0x0c, 0x20, 0xd0, 0xe5, 0x03, 0x30, 0xd3, 0xe5, 0x0c, 0x08, 0xa0, 0xe1, 0x01, 0x04, 0x80, 0xe1,
144 0x02, 0x00, 0x80, 0xe1, 0x03, 0x0c, 0x80, 0xe1, 0x5f, 0x0d, 0x80, 0xe2, 0x3f, 0x00, 0x80, 0xe2,
145 0xff, 0x0e, 0xc0, 0xe3, 0x0f, 0x00, 0xc0, 0xe3, 0x1e, 0xff, 0x2f, 0xe1, 0x70, 0x40, 0x2d, 0xe9,
146 0x18, 0xd0, 0x4d, 0xe2, 0x04, 0x40, 0x8d, 0xe2, 0x03, 0x50, 0xa0, 0xe1, 0x00, 0x60, 0xa0, 0xe1,
147 0x01, 0x00, 0xa0, 0xe1, 0x02, 0x10, 0xa0, 0xe1, 0x04, 0x20, 0xa0, 0xe1, 0xf5, 0x01, 0x00, 0xeb,
148 0x04, 0x10, 0xa0, 0xe1, 0x05, 0x00, 0xa0, 0xe1, 0x10, 0x20, 0xa0, 0xe3, 0xc2, 0x02, 0x00, 0xeb,
149 0x06, 0x10, 0xa0, 0xe1, 0x05, 0x20, 0xa0, 0xe1, 0x01, 0x00, 0xa0, 0xe3, 0x10, 0x30, 0xa0, 0xe3,
150 0x65, 0x02, 0x00, 0xeb, 0x18, 0xd0, 0x8d, 0xe2, 0x70, 0x80, 0xbd, 0xe8, 0x01, 0x00, 0x50, 0xe3,
151 0xf0, 0x47, 0x2d, 0xe9, 0x0c, 0x50, 0xd1, 0xe5, 0x0c, 0x30, 0x81, 0xe2, 0x00, 0x40, 0xa0, 0xe1,
152 0x01, 0x00, 0xa0, 0x03, 0x02, 0x00, 0xa0, 0x13, 0x03, 0x80, 0xd3, 0xe5, 0x02, 0x70, 0xd3, 0xe5,
153 0x01, 0x60, 0xd3, 0xe5, 0x02, 0xa0, 0xa0, 0xe1, 0x07, 0x00, 0xc1, 0xe5, 0x40, 0x30, 0x81, 0xe2,
154 0x02, 0x00, 0xa0, 0xe3, 0x40, 0x20, 0xa0, 0xe3, 0xdb, 0xff, 0xff, 0xeb, 0x07, 0x78, 0xa0, 0xe1,
155 0x06, 0x64, 0x87, 0xe1, 0x05, 0x50, 0x86, 0xe1, 0x08, 0x3c, 0x85, 0xe1, 0x04, 0x00, 0xa0, 0xe1,
156 0x0a, 0x20, 0xa0, 0xe1, 0x02, 0x10, 0xa0, 0xe3, 0xf0, 0x47, 0xbd, 0xe8, 0x4a, 0x02, 0x00, 0xea,
157 0x10, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
158 0xbf, 0xfe, 0xff, 0xeb, 0x05, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xd0, 0xfe, 0xff, 0xeb,
159 0xff, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xcd, 0xfe, 0xff, 0xeb, 0x00, 0x10, 0xa0, 0xe3,
160 0x01, 0x30, 0x10, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x00, 0x00, 0x0a, 0xb4, 0xfe, 0xff, 0xeb,
161 0xf0, 0xff, 0xff, 0xea, 0x04, 0x00, 0xa0, 0xe1, 0x03, 0x10, 0xa0, 0xe1, 0x10, 0x40, 0xbd, 0xe8,
162 0xaf, 0xfe, 0xff, 0xea, 0x70, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0x51, 0xe2, 0x00, 0x40, 0xa0, 0xe1,
163 0x07, 0x00, 0x00, 0x1a, 0x01, 0x10, 0x81, 0xe2, 0xa9, 0xfe, 0xff, 0xeb, 0x04, 0x10, 0xa0, 0xe3,
164 0x04, 0x00, 0xa0, 0xe1, 0xba, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1,
165 0xa3, 0xfe, 0xff, 0xeb, 0x01, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xa0, 0xfe, 0xff, 0xeb,
166 0x50, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xb1, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
167 0x00, 0x10, 0xa0, 0xe3, 0x9a, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
168 0x97, 0xfe, 0xff, 0xeb, 0x01, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xa8, 0xfe, 0xff, 0xeb,
169 0x00, 0x00, 0x55, 0xe3, 0x1c, 0x10, 0xa0, 0x03, 0x00, 0x10, 0xa0, 0x13, 0x04, 0x00, 0xa0, 0xe1,
170 0xa3, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x8c, 0xfe, 0xff, 0xeb,
171 0x00, 0x00, 0x55, 0xe3, 0x70, 0x80, 0xbd, 0x08, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
172 0x87, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x06, 0x10, 0xa0, 0xe3, 0x98, 0xfe, 0xff, 0xeb,
173 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x70, 0x40, 0xbd, 0xe8, 0x80, 0xfe, 0xff, 0xea,
174 0x70, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x50, 0xa0, 0xe1, 0x1d, 0xff, 0xff, 0xeb,
175 0x04, 0x00, 0xa0, 0xe1, 0xb5, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
176 0xc7, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x74, 0xfe, 0xff, 0xeb,
177 0x04, 0x00, 0xa0, 0xe1, 0x20, 0x10, 0xa0, 0xe3, 0x85, 0xfe, 0xff, 0xeb, 0x25, 0x18, 0xa0, 0xe1,
178 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x81, 0xfe, 0xff, 0xeb, 0x25, 0x14, 0xa0, 0xe1,
179 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x7d, 0xfe, 0xff, 0xeb, 0xff, 0x10, 0x05, 0xe2,
180 0x04, 0x00, 0xa0, 0xe1, 0x7a, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3,
181 0x63, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0xb0, 0xff, 0xff, 0xeb,
182 0x04, 0x00, 0xa0, 0xe1, 0x70, 0x40, 0xbd, 0xe8, 0xf6, 0xfe, 0xff, 0xea, 0xf0, 0x45, 0x2d, 0xe9,
183 0x00, 0x40, 0xa0, 0xe1, 0x24, 0xd0, 0x4d, 0xe2, 0x02, 0x50, 0xa0, 0xe1, 0x03, 0x70, 0xa0, 0xe1,
184 0x01, 0x60, 0xa0, 0xe1, 0xf7, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x8f, 0xff, 0xff, 0xeb,
185 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x51, 0xfe, 0xff, 0xeb, 0x03, 0x10, 0xa0, 0xe3,
186 0x04, 0x00, 0xa0, 0xe1, 0x62, 0xfe, 0xff, 0xeb, 0x26, 0x18, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2,
187 0x04, 0x00, 0xa0, 0xe1, 0x5e, 0xfe, 0xff, 0xeb, 0x26, 0x14, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2,
188 0x04, 0x00, 0xa0, 0xe1, 0x5a, 0xfe, 0xff, 0xeb, 0xff, 0x10, 0x06, 0xe2, 0x04, 0x00, 0xa0, 0xe1,
189 0x57, 0xfe, 0xff, 0xeb, 0x00, 0x60, 0xa0, 0xe3, 0x0d, 0x80, 0xa0, 0xe1, 0x15, 0x00, 0x00, 0xea,
190 0x20, 0x00, 0x57, 0xe3, 0x07, 0xa0, 0xa0, 0xb1, 0x20, 0xa0, 0xa0, 0xa3, 0x04, 0x00, 0xa0, 0xe1,
191 0x0a, 0x10, 0xa0, 0xe1, 0x0d, 0x20, 0xa0, 0xe1, 0x8c, 0xfe, 0xff, 0xeb, 0x05, 0x00, 0xa0, 0xe1,
192 0x0d, 0x10, 0xa0, 0xe1, 0x0a, 0x20, 0xa0, 0xe1, 0xac, 0xfd, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3,
193 0x00, 0x00, 0x50, 0xe3, 0x01, 0x60, 0x86, 0x13, 0x03, 0x20, 0xd8, 0xe7, 0x02, 0x30, 0x83, 0xe2,
194 0xff, 0x00, 0x52, 0xe3, 0x02, 0x60, 0x86, 0x13, 0x0a, 0x00, 0x53, 0xe1, 0xf9, 0xff, 0xff, 0xba,
195 0x20, 0x50, 0x85, 0xe2, 0x20, 0x70, 0x47, 0xe2, 0x00, 0x00, 0x57, 0xe3, 0xe7, 0xff, 0xff, 0xca,
196 0x00, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0x25, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
197 0xbc, 0xfe, 0xff, 0xeb, 0x06, 0x00, 0xa0, 0xe1, 0x24, 0xd0, 0x8d, 0xe2, 0xf0, 0x85, 0xbd, 0xe8,
198 0xf0, 0x4f, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x14, 0xd0, 0x4d, 0xe2, 0x01, 0x50, 0xa0, 0xe1,
199 0x02, 0x70, 0xa0, 0xe1, 0x03, 0x80, 0xa0, 0xe1, 0x53, 0x00, 0x00, 0xea, 0x05, 0x6a, 0xa0, 0xe1,
200 0x26, 0x6a, 0xa0, 0xe1, 0x01, 0x6a, 0x66, 0xe2, 0x08, 0x00, 0x56, 0xe1, 0x08, 0x60, 0xa0, 0xa1,
201 0x04, 0x00, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1, 0x07, 0x20, 0xa0, 0xe1, 0x06, 0x30, 0xa0, 0xe1,
202 0xb1, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x10, 0xe3, 0x44, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x10, 0xe3,
203 0x03, 0x00, 0x00, 0x0a, 0xff, 0x1e, 0xc5, 0xe3, 0x0f, 0x10, 0xc1, 0xe3, 0x04, 0x00, 0xa0, 0xe1,
204 0x86, 0xff, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3, 0x03, 0x20, 0xd7, 0xe7, 0x07, 0x90, 0xa0, 0xe1,
205 0xff, 0x00, 0x52, 0xe3, 0x01, 0x30, 0x83, 0xe2, 0x02, 0x00, 0x00, 0x1a, 0x06, 0x00, 0x53, 0xe1,
206 0xf8, 0xff, 0xff, 0xba, 0x35, 0x00, 0x00, 0xea, 0x04, 0x00, 0xa0, 0xe1, 0x9d, 0xfe, 0xff, 0xeb,
207 0x04, 0x00, 0xa0, 0xe1, 0x35, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
208 0x47, 0xff, 0xff, 0xeb, 0x25, 0x34, 0xa0, 0xe1, 0xff, 0x30, 0x03, 0xe2, 0x25, 0x28, 0xa0, 0xe1,
209 0xff, 0x20, 0x02, 0xe2, 0x08, 0x30, 0x8d, 0xe5, 0x06, 0xa0, 0xa0, 0xe1, 0xff, 0x30, 0x05, 0xe2,
210 0x01, 0xb0, 0xa0, 0xe3, 0x04, 0x20, 0x8d, 0xe5, 0x0c, 0x30, 0x8d, 0xe5, 0x04, 0x00, 0xa0, 0xe1,
211 0x01, 0x10, 0xa0, 0xe3, 0xea, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0xad, 0x10, 0xa0, 0xe3,
212 0xfb, 0xfd, 0xff, 0xeb, 0x00, 0x00, 0x5b, 0xe3, 0x00, 0xb0, 0xa0, 0xe3, 0x08, 0x00, 0x00, 0x0a,
213 0x04, 0x10, 0x9d, 0xe5, 0x04, 0x00, 0xa0, 0xe1, 0xf5, 0xfd, 0xff, 0xeb, 0x08, 0x10, 0x9d, 0xe5,
214 0x04, 0x00, 0xa0, 0xe1, 0xf2, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x0c, 0x10, 0x9d, 0xe5,
215 0xef, 0xfd, 0xff, 0xeb, 0x00, 0x10, 0xd9, 0xe5, 0x04, 0x00, 0xa0, 0xe1, 0xec, 0xfd, 0xff, 0xeb,
216 0x01, 0x10, 0xd9, 0xe5, 0x04, 0x00, 0xa0, 0xe1, 0xe9, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
217 0x00, 0x10, 0xa0, 0xe3, 0xd2, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x0b, 0xff, 0xff, 0xeb,
218 0x02, 0xa0, 0x5a, 0xe2, 0x02, 0x90, 0x89, 0xe2, 0xdf, 0xff, 0xff, 0x1a, 0x04, 0x00, 0xa0, 0xe1,
219 0x0a, 0x10, 0xa0, 0xe1, 0x1a, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x61, 0xfe, 0xff, 0xeb,
220 0x08, 0x80, 0x66, 0xe0, 0x06, 0x70, 0x87, 0xe0, 0x06, 0x50, 0x85, 0xe0, 0x00, 0x00, 0x58, 0xe3,
221 0xa9, 0xff, 0xff, 0xca, 0x14, 0xd0, 0x8d, 0xe2, 0xf0, 0x8f, 0xbd, 0xe8, 0xf0, 0x41, 0x2d, 0xe9,
222 0x00, 0x40, 0xa0, 0xe1, 0x03, 0x50, 0xa0, 0xe1, 0x02, 0x70, 0xa0, 0xe1, 0x01, 0x60, 0xa0, 0xe1,
223 0x5c, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0xf4, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
224 0x01, 0x10, 0xa0, 0xe3, 0xb6, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x03, 0x10, 0xa0, 0xe3,
225 0xc7, 0xfd, 0xff, 0xeb, 0x26, 0x18, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1,
226 0xc3, 0xfd, 0xff, 0xeb, 0x26, 0x14, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1,
227 0xbf, 0xfd, 0xff, 0xeb, 0xff, 0x10, 0x06, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0xbc, 0xfd, 0xff, 0xeb,
228 0x04, 0x00, 0xa0, 0xe1, 0x07, 0x10, 0xa0, 0xe1, 0x05, 0x20, 0xa0, 0xe1, 0xf7, 0xfd, 0xff, 0xeb,
229 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0xa1, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
230 0xf0, 0x41, 0xbd, 0xe8, 0x37, 0xfe, 0xff, 0xea, 0x00, 0x10, 0xa0, 0xe3, 0x77, 0xfd, 0xff, 0xea,
231 0x10, 0x40, 0x2d, 0xe9, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x40, 0xa0, 0xe1, 0x73, 0xfd, 0xff, 0xeb,
232 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x10, 0x40, 0xbd, 0xe8, 0x94, 0xfd, 0xff, 0xea,
233 0xf0, 0x40, 0x2d, 0xe9, 0x6c, 0x40, 0x9f, 0xe5, 0x2c, 0xd0, 0x4d, 0xe2, 0x00, 0x00, 0xa0, 0xe3,
234 0xf2, 0xff, 0xff, 0xeb, 0x60, 0x70, 0x9f, 0xe5, 0x04, 0x50, 0xa0, 0xe1, 0x0d, 0x60, 0xa0, 0xe1,
235 0x04, 0x10, 0xa0, 0xe1, 0x28, 0x20, 0xa0, 0xe3, 0x0d, 0x30, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
236 0xc5, 0xff, 0xff, 0xeb, 0x0d, 0x00, 0xa0, 0xe1, 0x40, 0x10, 0x9f, 0xe5, 0x04, 0x20, 0xa0, 0xe3,
237 0xfa, 0xfc, 0xff, 0xeb, 0x28, 0x40, 0x84, 0xe2, 0x00, 0x00, 0x50, 0xe3, 0x04, 0x00, 0x00, 0x1a,
238 0x0c, 0x30, 0x9d, 0xe5, 0x03, 0x00, 0x55, 0xe1, 0x03, 0x50, 0xa0, 0x21, 0x07, 0x00, 0x54, 0xe1,
239 0xee, 0xff, 0xff, 0x1a, 0x00, 0x00, 0xa0, 0xe3, 0xda, 0xff, 0xff, 0xeb, 0x0a, 0x09, 0x45, 0xe2,
240 0x2c, 0xd0, 0x8d, 0xe2, 0xf0, 0x80, 0xbd, 0xe8, 0x00, 0xfe, 0x0f, 0x00, 0xe0, 0xff, 0x0f, 0x00,
241 0xb8, 0x17, 0x00, 0x22, 0x0c, 0x30, 0x81, 0xe2, 0x70, 0x40, 0x2d, 0xe9, 0x02, 0x50, 0xd3, 0xe5,
242 0x01, 0x40, 0xa0, 0xe1, 0x01, 0x10, 0xd3, 0xe5, 0x0c, 0x20, 0xd4, 0xe5, 0x03, 0x30, 0xd3, 0xe5,
243 0x05, 0x58, 0xa0, 0xe1, 0x01, 0x54, 0x85, 0xe1, 0x02, 0x50, 0x85, 0xe1, 0x03, 0x5c, 0x85, 0xe1,
244 0x00, 0x60, 0xa0, 0xe1, 0x02, 0x5b, 0x85, 0xe2, 0x00, 0x00, 0xa0, 0xe3, 0xc7, 0xff, 0xff, 0xeb,
245 0x06, 0x10, 0xa0, 0xe1, 0x04, 0x20, 0xa0, 0xe1, 0x05, 0x30, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
246 0x3e, 0xff, 0xff, 0xeb, 0x04, 0x20, 0xa0, 0xe1, 0x06, 0x10, 0xa0, 0xe1, 0x05, 0x30, 0xa0, 0xe1,
247 0x00, 0x00, 0xa0, 0xe3, 0xfc, 0xfe, 0xff, 0xeb, 0x00, 0x40, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
248 0xb8, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x24, 0xe2, 0x01, 0x00, 0x00, 0xe2, 0x70, 0x80, 0xbd, 0xe8,
249 0xf0, 0x45, 0x2d, 0xe9, 0x01, 0x40, 0xa0, 0xe1, 0x14, 0xd0, 0x4d, 0xe2, 0x00, 0x80, 0xa0, 0xe1,
250 0x00, 0x00, 0xa0, 0xe3, 0x02, 0x60, 0xa0, 0xe1, 0xb0, 0xff, 0xff, 0xeb, 0x08, 0x10, 0xa0, 0xe1,
251 0x02, 0x2b, 0xa0, 0xe3, 0x04, 0x30, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0x86, 0xff, 0xff, 0xeb,
252 0x00, 0x00, 0xa0, 0xe3, 0xa7, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x40, 0x11, 0x9f, 0xe5,
253 0x04, 0x20, 0xa0, 0xe3, 0xb9, 0xfc, 0xff, 0xeb, 0x00, 0x00, 0x50, 0xe3, 0x00, 0x00, 0xe0, 0x13,
254 0x49, 0x00, 0x00, 0x1a, 0x04, 0x10, 0xa0, 0xe1, 0x40, 0x20, 0xa0, 0xe3, 0x0d, 0x30, 0xa0, 0xe1,
255 0x02, 0x00, 0xa0, 0xe3, 0x48, 0xfe, 0xff, 0xeb, 0x0d, 0x00, 0xa0, 0xe1, 0x40, 0x10, 0x84, 0xe2,
256 0x10, 0x20, 0xa0, 0xe3, 0xad, 0xfc, 0xff, 0xeb, 0x0d, 0x50, 0xa0, 0xe1, 0x00, 0x70, 0x50, 0xe2,
257 0x01, 0x00, 0xe0, 0x13, 0x3c, 0x00, 0x00, 0x1a, 0x0c, 0x30, 0x84, 0xe2, 0x02, 0x50, 0xd3, 0xe5,
258 0x01, 0x10, 0xd3, 0xe5, 0x0c, 0x20, 0xd4, 0xe5, 0x05, 0x58, 0xa0, 0xe1, 0x03, 0x30, 0xd3, 0xe5,
259 0x01, 0x54, 0x85, 0xe1, 0x02, 0x50, 0x85, 0xe1, 0x03, 0x5c, 0x85, 0xe1, 0x7e, 0x0b, 0x55, 0xe3,
260 0x2e, 0x00, 0x00, 0x8a, 0x08, 0x30, 0x84, 0xe2, 0x02, 0xc0, 0xd3, 0xe5, 0x01, 0xa0, 0xd3, 0xe5,
261 0x08, 0x10, 0xd4, 0xe5, 0x03, 0x20, 0xd3, 0xe5, 0x0c, 0xc8, 0xa0, 0xe1, 0x0a, 0x34, 0x8c, 0xe1,
262 0x01, 0x30, 0x83, 0xe1, 0x02, 0x3c, 0x83, 0xe1, 0x05, 0x00, 0x53, 0xe1, 0x23, 0x00, 0x00, 0x8a,
263 0x07, 0x30, 0xd4, 0xe5, 0x01, 0x30, 0x43, 0xe2, 0x01, 0x00, 0x53, 0xe3, 0x03, 0x00, 0xe0, 0x83,
264 0x21, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x56, 0xe3, 0x1e, 0x00, 0x00, 0x0a, 0x77, 0xff, 0xff, 0xeb,
265 0x06, 0x30, 0xa0, 0xe1, 0x07, 0x00, 0xa0, 0xe1, 0x02, 0x1b, 0x88, 0xe2, 0x05, 0x20, 0xa0, 0xe1,
266 0x4d, 0xff, 0xff, 0xeb, 0x07, 0x00, 0xa0, 0xe1, 0x6e, 0xff, 0xff, 0xeb, 0x07, 0x30, 0xd4, 0xe5,
267 0x01, 0x00, 0x53, 0xe3, 0x03, 0x00, 0x00, 0x1a, 0x07, 0x00, 0xa0, 0xe1, 0x04, 0x10, 0xa0, 0xe1,
268 0x06, 0x20, 0xa0, 0xe1, 0x28, 0xfe, 0xff, 0xeb, 0x06, 0x10, 0xa0, 0xe1, 0x05, 0x20, 0xa0, 0xe1,
269 0x0d, 0x30, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x0f, 0xfe, 0xff, 0xeb, 0x0d, 0x00, 0xa0, 0xe1,
270 0x10, 0x10, 0x84, 0xe2, 0x10, 0x20, 0xa0, 0xe3, 0x74, 0xfc, 0xff, 0xeb, 0x0d, 0x70, 0xa0, 0xe1,
271 0x00, 0x00, 0x50, 0xe3, 0x04, 0x00, 0xe0, 0x13, 0x02, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x00, 0xea,
272 0x02, 0x00, 0xe0, 0xe3, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0xa0, 0xe3, 0x14, 0xd0, 0x8d, 0xe2,
273 0xf0, 0x85, 0xbd, 0xe8, 0xbd, 0x17, 0x00, 0x22, 0xf0, 0x4f, 0x2d, 0xe9, 0x00, 0x50, 0xa0, 0xe1,
274 0x54, 0xd0, 0x4d, 0xe2, 0x01, 0x40, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0x01, 0x10, 0xa0, 0xe3,
275 0x02, 0x60, 0xa0, 0xe1, 0x70, 0xfc, 0xff, 0xeb, 0x0e, 0x23, 0xa0, 0xe3, 0x01, 0x10, 0xa0, 0xe3,
276 0x02, 0xc0, 0xa0, 0xe1, 0x10, 0x30, 0x8d, 0xe2, 0x04, 0x10, 0x82, 0xe5, 0x00, 0x00, 0x9c, 0xe5,
277 0x0e, 0x23, 0xa0, 0xe3, 0x01, 0x00, 0x10, 0xe2, 0xfb, 0xff, 0xff, 0x1a, 0x40, 0xc0, 0x64, 0xe2,
278 0xa4, 0x72, 0xa0, 0xe1, 0x84, 0xe1, 0xa0, 0xe1, 0x7c, 0x81, 0x9f, 0xe5, 0xa4, 0xaa, 0xa0, 0xe1,
279 0xa4, 0x96, 0xa0, 0xe1, 0xff, 0x70, 0x07, 0xe2, 0xff, 0xe0, 0x0e, 0xe2, 0x0c, 0xc0, 0x65, 0xe0,
280 0xff, 0x90, 0x09, 0xe2, 0x04, 0x70, 0x8d, 0xe5, 0x00, 0xe0, 0x8d, 0xe5, 0x0c, 0xc0, 0x8d, 0xe5,
281 0x02, 0x10, 0xa0, 0xe1, 0xff, 0xa0, 0x0a, 0xe2, 0x00, 0x70, 0xa0, 0xe1, 0xa4, 0x4e, 0xa0, 0xe1,
282 0x10, 0xc0, 0x8d, 0xe2, 0x02, 0xe0, 0xa0, 0xe1, 0x04, 0x00, 0x82, 0xe5, 0x08, 0x90, 0x8d, 0xe5,
283 0x00, 0x00, 0x82, 0xe5, 0x0c, 0x20, 0x9d, 0xe5, 0x02, 0x00, 0x85, 0xe0, 0x00, 0x00, 0x50, 0xe3,
284 0x25, 0x00, 0x00, 0xda, 0x00, 0x20, 0xa0, 0xe3, 0x02, 0x70, 0x8c, 0xe7, 0x04, 0x20, 0x82, 0xe2,
285 0x40, 0x00, 0x52, 0xe3, 0xfb, 0xff, 0xff, 0x1a, 0x40, 0x00, 0x50, 0xe3, 0x07, 0x20, 0xa0, 0xd1,
286 0x40, 0x90, 0x60, 0xd2, 0x03, 0x00, 0x00, 0xda, 0x09, 0x00, 0x00, 0xea, 0x02, 0xb0, 0xd5, 0xe7,
287 0x02, 0xb0, 0xcc, 0xe7, 0x01, 0x20, 0x82, 0xe2, 0x09, 0x00, 0x52, 0xe1, 0xfa, 0xff, 0xff, 0xba,
288 0x07, 0x00, 0x50, 0xe3, 0x7f, 0x20, 0xe0, 0xe3, 0x09, 0x20, 0xc3, 0xe7, 0x00, 0x00, 0xa0, 0xd3,
289 0x08, 0x00, 0x00, 0xda, 0x3b, 0x40, 0xc3, 0xe5, 0x3c, 0xa0, 0xc3, 0xe5, 0x08, 0x20, 0x9d, 0xe5,
290 0x01, 0x00, 0xa0, 0xe3, 0x3d, 0x20, 0xc3, 0xe5, 0x04, 0x20, 0x9d, 0xe5, 0x3e, 0x20, 0xc3, 0xe5,
291 0x00, 0x20, 0x9d, 0xe5, 0x3f, 0x20, 0xc3, 0xe5, 0xb0, 0x20, 0x9f, 0xe5, 0x02, 0x90, 0x8c, 0xe0,
292 0x32, 0x93, 0x89, 0xe2, 0x40, 0x90, 0x49, 0xe2, 0x00, 0x90, 0x99, 0xe5, 0x04, 0x90, 0x82, 0xe4,
293 0x08, 0x00, 0x52, 0xe1, 0xf8, 0xff, 0xff, 0x1a, 0x09, 0x00, 0x00, 0xea, 0x8c, 0x20, 0x9f, 0xe5,
294 0x02, 0x00, 0x85, 0xe0, 0x32, 0x03, 0x80, 0xe2, 0x40, 0x00, 0x40, 0xe2, 0x00, 0x00, 0x90, 0xe5,
295 0x04, 0x00, 0x82, 0xe4, 0x08, 0x00, 0x52, 0xe1, 0xf8, 0xff, 0xff, 0x1a, 0x40, 0x50, 0x85, 0xe2,
296 0x00, 0x00, 0xa0, 0xe3, 0x00, 0x20, 0x91, 0xe5, 0x02, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x81, 0xe5,
297 0x00, 0x20, 0x91, 0xe5, 0x01, 0x00, 0x12, 0xe3, 0xfc, 0xff, 0xff, 0x1a, 0x00, 0x20, 0x9e, 0xe5,
298 0x00, 0x00, 0x50, 0xe3, 0x08, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x8e, 0xe5, 0xc0, 0xff, 0xff, 0x0a,
299 0x3c, 0x30, 0x9f, 0xe5, 0x3c, 0x10, 0x9f, 0xe5, 0x03, 0x20, 0xa0, 0xe1, 0x06, 0x00, 0x92, 0xe6,
300 0x04, 0x30, 0x83, 0xe2, 0x32, 0x23, 0x82, 0xe2, 0x20, 0x20, 0x42, 0xe2, 0x01, 0x00, 0x53, 0xe1,
301 0x00, 0x00, 0x82, 0xe5, 0xf7, 0xff, 0xff, 0x1a, 0x00, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe1,
302 0x05, 0xfc, 0xff, 0xeb, 0x54, 0xd0, 0x8d, 0xe2, 0xf0, 0x8f, 0xbd, 0xe8, 0x80, 0x00, 0x00, 0x38,
303 0x40, 0x00, 0x00, 0x38, 0x20, 0x00, 0x00, 0x38, 0x34, 0x00, 0x00, 0x38, 0xf0, 0x47, 0x2d, 0xe9,
304 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x50, 0xa0, 0xe1, 0x0a, 0x00, 0xa0, 0xe3, 0x01, 0x10, 0xa0, 0xe3,
305 0xe3, 0x85, 0xa0, 0xe3, 0x03, 0x60, 0xa0, 0xe1, 0x02, 0x70, 0xa0, 0xe1, 0x01, 0xa0, 0xa0, 0xe3,
306 0xf5, 0xfb, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3, 0x74, 0x30, 0x88, 0xe5, 0x78, 0x30, 0x88, 0xe5,
307 0x7c, 0x30, 0x88, 0xe5, 0x80, 0x30, 0x88, 0xe5, 0x08, 0xa0, 0x88, 0xe5, 0x08, 0x30, 0x88, 0xe5,
308 0x00, 0xa0, 0x88, 0xe5, 0x10, 0x30, 0x88, 0xe5, 0x6c, 0x50, 0x88, 0xe5, 0x6c, 0x20, 0x98, 0xe5,
309 0x0a, 0x00, 0x54, 0xe1, 0x09, 0x40, 0xa0, 0x03, 0x08, 0x40, 0xa0, 0x13, 0x02, 0x20, 0xe0, 0xe1,
310 0x88, 0x20, 0x88, 0xe5, 0x8c, 0x30, 0x88, 0xe5, 0x14, 0x40, 0x88, 0xe5, 0x18, 0x60, 0x88, 0xe5,
311 0x20, 0x70, 0x88, 0xe5, 0x24, 0x60, 0x88, 0xe5, 0x28, 0x70, 0x88, 0xe5, 0x2c, 0x60, 0x88, 0xe5,
312 0x30, 0x70, 0x88, 0xe5, 0x34, 0x60, 0x88, 0xe5, 0x3c, 0x00, 0x00, 0xeb, 0x08, 0x30, 0xa0, 0xe1,
313 0x04, 0xa0, 0x88, 0xe5, 0x0c, 0x20, 0x93, 0xe5, 0x0f, 0x00, 0x12, 0xe3, 0xfc, 0xff, 0xff, 0x0a,
314 0x0a, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0xf0, 0x47, 0xbd, 0xe8, 0xd2, 0xfb, 0xff, 0xea,
315 0x98, 0x30, 0x9f, 0xe5, 0xf0, 0x45, 0x2d, 0xe9, 0x94, 0xc0, 0x9f, 0xe5, 0xfa, 0x4f, 0xa0, 0xe3,
316 0x03, 0x60, 0xa0, 0xe1, 0x8c, 0x50, 0x9f, 0xe5, 0x1c, 0x00, 0x00, 0xea, 0xb4, 0x10, 0x93, 0xe5,
317 0xb2, 0x80, 0xd0, 0xe1, 0xa2, 0xa0, 0xa0, 0xe1, 0x94, 0x18, 0x27, 0xe0, 0x00, 0x20, 0xa0, 0xe3,
318 0x09, 0x00, 0x00, 0xea, 0x01, 0x20, 0x22, 0xe2, 0x06, 0x1c, 0x82, 0xe3, 0x0e, 0x10, 0x81, 0xe3,
319 0x00, 0x12, 0x8c, 0xe5, 0xb4, 0x10, 0x93, 0xe5, 0x01, 0x10, 0x8a, 0xe0, 0xb4, 0x80, 0x93, 0xe5,
320 0x08, 0x80, 0x61, 0xe0, 0x00, 0x00, 0x58, 0xe3, 0xfb, 0xff, 0xff, 0xba, 0xb4, 0x10, 0x93, 0xe5,
321 0x01, 0x10, 0x67, 0xe0, 0x00, 0x00, 0x51, 0xe3, 0xf1, 0xff, 0xff, 0xba, 0x00, 0x52, 0x8c, 0xe5,
322 0xb4, 0x70, 0xd0, 0xe1, 0xb4, 0x10, 0x96, 0xe5, 0x94, 0x17, 0x22, 0xe0, 0xb4, 0x10, 0x93, 0xe5,
323 0x01, 0x10, 0x62, 0xe0, 0x00, 0x00, 0x51, 0xe3, 0xfb, 0xff, 0xff, 0xba, 0x06, 0x00, 0x80, 0xe2,
324 0xb0, 0x20, 0xd0, 0xe1, 0x00, 0x00, 0x52, 0xe3, 0xdf, 0xff, 0xff, 0x1a, 0xf0, 0x85, 0xbd, 0xe8,
325 0x00, 0x00, 0x70, 0x3c, 0x00, 0x00, 0xf0, 0x3c, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x30, 0xa0, 0xe3,
326 0x02, 0x00, 0x00, 0xea, 0x03, 0xc0, 0xd1, 0xe7, 0x03, 0xc0, 0xc0, 0xe7, 0x01, 0x30, 0x83, 0xe2,
327 0x00, 0x00, 0x52, 0xe3, 0x01, 0x20, 0x42, 0xe2, 0xf9, 0xff, 0xff, 0x1a, 0x1e, 0xff, 0x2f, 0xe1,
328 0x7e, 0xff, 0x17, 0xee, 0xfd, 0xff, 0xff, 0x1a, 0x00, 0x10, 0xa0, 0xe3, 0x9a, 0x1f, 0x07, 0xee,
329 0x1e, 0xff, 0x2f, 0xe1, 0xb8, 0x0b, 0xf4, 0x01, 0xf4, 0x01, 0xb8, 0x0b, 0xf4, 0x01, 0xf4, 0x01,
330 0xb8, 0x0b, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x76, 0xdc, 0x1d, 0x32, 0xb2, 0x46,
331 0xa6, 0xc9, 0x7d, 0x5a, 0x61, 0xd3, 0x49, 0x4c, 0x1e, 0xf0, 0xd9, 0xde, 0xc2, 0x7e, 0xec, 0x02,
332 0x7c, 0x15, 0x76, 0xbb, 0x5c, 0x4f, 0x2d, 0x95, 0x06, 0x85, 0xdf, 0x28, 0xe4, 0xd7, 0xf4, 0x82,
333 0xc0, 0x73, 0xb0, 0x53, 0x26, 0xfc, 0xb0, 0xfe, 0x60, 0x80, 0x7d, 0x33, 0xa8, 0xde, 0xf8, 0x49,
334 0xbb, 0xbe, 0x01, 0x45, 0xff, 0x62, 0x40, 0x19, 0xf4, 0x01, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00,
335 0xe8, 0x03, 0x64, 0x00, 0x00, 0x00, 0xf4, 0x01, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x68, 0x73, 0x6c, 0x66,
337 0x00, 0x38, 0x37, 0x30, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x38, 0x37, 0x30, 0x32, 0x31, 0x2e, 0x30, 0x02, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343 0x00, 0x00, 0x00, 0x00
344};
345unsigned char dualboot_uninstall_ipod6g[5076] = {
346 0xd7, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x24, 0xd0, 0x9f, 0xe5, 0xdb, 0x00, 0xa0, 0xe3,
347 0x00, 0xf0, 0x21, 0xe1, 0x18, 0xd0, 0x9f, 0xe5, 0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
348 0x10, 0xd0, 0x9f, 0xe5, 0x05, 0x08, 0xa0, 0xe3, 0x78, 0x00, 0x80, 0xe3, 0x10, 0x0f, 0x01, 0xee,
349 0x1d, 0x00, 0x00, 0xeb, 0x0c, 0x03, 0x00, 0x22, 0x0c, 0x03, 0x00, 0x22, 0x7f, 0x40, 0x2d, 0xe9,
350 0x5c, 0x10, 0x9f, 0xe5, 0x10, 0x20, 0xa0, 0xe3, 0x0d, 0x00, 0xa0, 0xe1, 0xaf, 0x04, 0x00, 0xeb,
351 0x00, 0x00, 0xa0, 0xe3, 0x02, 0x10, 0xa0, 0xe3, 0x0d, 0x20, 0xa0, 0xe1, 0x10, 0x30, 0xa0, 0xe3,
352 0x52, 0x04, 0x00, 0xeb, 0x3c, 0x60, 0x9f, 0xe5, 0x0d, 0x40, 0xa0, 0xe1, 0x00, 0x50, 0xa0, 0xe3,
353 0x06, 0x10, 0xa0, 0xe1, 0x0d, 0x00, 0xa0, 0xe1, 0x10, 0x20, 0xa0, 0xe3, 0x50, 0x00, 0x00, 0xeb,
354 0x10, 0x60, 0x86, 0xe2, 0x00, 0x00, 0x50, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x01, 0x50, 0x85, 0xe2,
355 0x04, 0x00, 0x55, 0xe3, 0xf5, 0xff, 0xff, 0x1a, 0x05, 0x00, 0xa0, 0xe1, 0x10, 0xd0, 0x8d, 0xe2,
356 0x70, 0x80, 0xbd, 0xe8, 0x10, 0x00, 0x02, 0x22, 0x68, 0x16, 0x00, 0x22, 0x70, 0x40, 0x2d, 0xe9,
357 0x87, 0x00, 0x00, 0xeb, 0xe8, 0x00, 0x9f, 0xe5, 0x69, 0x04, 0x00, 0xeb, 0x00, 0x00, 0xa0, 0xe3,
358 0x04, 0x10, 0xa0, 0xe3, 0x9e, 0x00, 0x00, 0xeb, 0x02, 0x09, 0xa0, 0xe3, 0xd4, 0x10, 0x9f, 0xe5,
359 0x00, 0x20, 0xa0, 0xe3, 0x5a, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x50, 0xe3, 0x25, 0x00, 0x00, 0x1a,
360 0xd5, 0xff, 0xff, 0xeb, 0x04, 0x00, 0x50, 0xe3, 0x20, 0x00, 0x00, 0x1a, 0xb4, 0x00, 0x9f, 0xe5,
361 0xbc, 0x01, 0x00, 0xeb, 0xac, 0x10, 0x9f, 0xe5, 0xac, 0x20, 0x9f, 0xe5, 0x00, 0x50, 0xa0, 0xe1,
362 0x02, 0x09, 0x80, 0xe2, 0x4e, 0x03, 0x00, 0xeb, 0x00, 0x40, 0x50, 0xe2, 0x19, 0x00, 0x00, 0x1a,
363 0xc9, 0xff, 0xff, 0xeb, 0x04, 0x00, 0x50, 0xe3, 0x16, 0x00, 0x00, 0x0a, 0x01, 0x00, 0xa0, 0xe3,
364 0x80, 0x10, 0x9f, 0xe5, 0x80, 0x20, 0x9f, 0xe5, 0xd0, 0x01, 0x00, 0xeb, 0x02, 0x09, 0xa0, 0xe3,
365 0x70, 0x10, 0x9f, 0xe5, 0x23, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x50, 0xe3, 0x6c, 0x00, 0x9f, 0x05,
366 0x0d, 0x00, 0x00, 0x0a, 0x04, 0x00, 0xa0, 0xe1, 0x16, 0x03, 0x00, 0xeb, 0x54, 0x00, 0x9f, 0xe5,
367 0xa4, 0x01, 0x00, 0xeb, 0x25, 0x26, 0xa0, 0xe1, 0x02, 0x19, 0x80, 0xe2, 0x21, 0x16, 0xa0, 0xe1,
368 0x04, 0x00, 0xa0, 0xe1, 0x41, 0x02, 0x00, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x0b, 0x03, 0x00, 0xeb,
369 0x3c, 0x00, 0x9f, 0xe5, 0x00, 0x00, 0x00, 0xea, 0x38, 0x00, 0x9f, 0xe5, 0x38, 0x20, 0x9f, 0xe5,
370 0x38, 0x30, 0x9f, 0xe5, 0xb4, 0x10, 0x92, 0xe5, 0x03, 0x00, 0x51, 0xe1, 0xfc, 0xff, 0xff, 0x9a,
371 0x33, 0x04, 0x00, 0xeb, 0x01, 0x26, 0xa0, 0xe3, 0xf2, 0x35, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5,
372 0xfe, 0xff, 0xff, 0xea, 0xa8, 0x16, 0x00, 0x22, 0x00, 0x00, 0x02, 0x22, 0x00, 0x08, 0x02, 0x22,
373 0x54, 0x16, 0x00, 0x22, 0xb0, 0x16, 0x00, 0x22, 0x60, 0x16, 0x00, 0x22, 0x00, 0x00, 0x70, 0x3c,
374 0x7f, 0x84, 0x1e, 0x00, 0x10, 0x40, 0x2d, 0xe9, 0x00, 0x30, 0xa0, 0xe3, 0x07, 0x00, 0x00, 0xea,
375 0x03, 0x40, 0xd0, 0xe7, 0x03, 0xc0, 0xd1, 0xe7, 0x01, 0x20, 0x42, 0xe2, 0x0c, 0x00, 0x54, 0xe1,
376 0x01, 0x30, 0x83, 0xe2, 0x01, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x6c, 0xe0, 0x10, 0x80, 0xbd, 0xe8,
377 0x00, 0x00, 0x52, 0xe3, 0xf5, 0xff, 0xff, 0x1a, 0x02, 0x00, 0xa0, 0xe1, 0x10, 0x80, 0xbd, 0xe8,
378 0x1f, 0x30, 0x00, 0xe2, 0x01, 0x20, 0xa0, 0xe3, 0xc0, 0x02, 0xa0, 0xe1, 0x00, 0x00, 0x51, 0xe3,
379 0x12, 0x33, 0xa0, 0xe1, 0x02, 0x20, 0x00, 0xe0, 0x08, 0x00, 0x00, 0x0a, 0x3c, 0x10, 0x9f, 0xe5,
380 0x3c, 0x00, 0x9f, 0xe5, 0x00, 0x00, 0x52, 0xe3, 0x00, 0x20, 0xa0, 0x11, 0x01, 0x20, 0xa0, 0x01,
381 0x00, 0x10, 0x92, 0xe5, 0x03, 0x30, 0xc1, 0xe1, 0x00, 0x30, 0x82, 0xe5, 0x1e, 0xff, 0x2f, 0xe1,
382 0x18, 0x10, 0x9f, 0xe5, 0x18, 0x00, 0x9f, 0xe5, 0x00, 0x00, 0x52, 0xe3, 0x01, 0x00, 0xa0, 0x01,
383 0x00, 0x20, 0x90, 0xe5, 0x03, 0x30, 0x82, 0xe1, 0x00, 0x30, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1,
384 0x48, 0x00, 0x50, 0x3c, 0x4c, 0x00, 0x50, 0x3c, 0x70, 0x40, 0x2d, 0xe9, 0x10, 0x50, 0x9d, 0xe5,
385 0x01, 0x30, 0x43, 0xe2, 0x01, 0x50, 0x45, 0xe2, 0x03, 0x60, 0x02, 0xe2, 0x0f, 0x30, 0x03, 0xe2,
386 0x05, 0x52, 0xa0, 0xe1, 0x03, 0xc0, 0xc0, 0xe3, 0xff, 0x50, 0x05, 0xe2, 0x06, 0x36, 0x83, 0xe1,
387 0x00, 0x40, 0x9c, 0xe5, 0x05, 0x30, 0x83, 0xe1, 0x30, 0x50, 0x9f, 0xe5, 0x02, 0x20, 0x00, 0xe2,
388 0x82, 0x21, 0xa0, 0xe1, 0x00, 0x00, 0x51, 0xe3, 0x02, 0x19, 0xa0, 0x03, 0x00, 0x10, 0xa0, 0x13,
389 0x35, 0x42, 0x04, 0xe0, 0x01, 0x30, 0x83, 0xe1, 0x13, 0x22, 0x84, 0xe1, 0x00, 0x20, 0x8c, 0xe5,
390 0xb0, 0x20, 0xd0, 0xe1, 0x03, 0x00, 0x52, 0xe1, 0xfc, 0xff, 0xff, 0x1a, 0x70, 0x80, 0xbd, 0xe8,
391 0x00, 0x00, 0xff, 0xff, 0x5c, 0xc0, 0x9f, 0xe5, 0x13, 0x40, 0x2d, 0xe9, 0x44, 0xe0, 0x9c, 0xe5,
392 0x01, 0x40, 0xa0, 0xe3, 0x01, 0xec, 0xce, 0xe3, 0x00, 0x20, 0xa0, 0xe3, 0x04, 0x30, 0xa0, 0xe1,
393 0x44, 0xe0, 0x8c, 0xe5, 0x40, 0x00, 0x9f, 0xe5, 0x04, 0x10, 0xa0, 0xe1, 0x00, 0x40, 0x8d, 0xe5,
394 0xd8, 0xff, 0xff, 0xeb, 0x04, 0x10, 0xa0, 0xe1, 0x25, 0x00, 0xa0, 0xe3, 0xbb, 0xff, 0xff, 0xeb,
395 0x28, 0x30, 0x9f, 0xe5, 0x11, 0x2d, 0xa0, 0xe3, 0xa0, 0x20, 0x83, 0xe5, 0x0b, 0x20, 0xa0, 0xe3,
396 0xb0, 0x20, 0x83, 0xe5, 0x00, 0x20, 0xe0, 0xe3, 0xa8, 0x20, 0x83, 0xe5, 0x04, 0x20, 0x82, 0xe2,
397 0xa4, 0x20, 0x83, 0xe5, 0x1c, 0x80, 0xbd, 0xe8, 0x00, 0x00, 0x50, 0x3c, 0x12, 0x00, 0x50, 0x3c,
398 0x00, 0x00, 0x70, 0x3c, 0x04, 0x30, 0x9f, 0xe5, 0x00, 0x11, 0x83, 0xe7, 0x1e, 0xff, 0x2f, 0xe1,
399 0xc0, 0x16, 0x00, 0x22, 0x80, 0x20, 0x9f, 0xe5, 0x00, 0x00, 0x51, 0xe3, 0x7c, 0x30, 0x9f, 0xe5,
400 0x02, 0x30, 0xa0, 0x11, 0x01, 0x00, 0x50, 0xe3, 0x0a, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x50, 0xe3,
401 0x0f, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x50, 0xe3, 0x1e, 0xff, 0x2f, 0x11, 0x60, 0x10, 0x9f, 0xe5,
402 0x00, 0x20, 0x91, 0xe5, 0x22, 0x28, 0xa0, 0xe1, 0x02, 0x28, 0xa0, 0xe1, 0x02, 0x30, 0x83, 0xe1,
403 0x00, 0x30, 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x44, 0x10, 0x9f, 0xe5, 0xc0, 0x20, 0x91, 0xe5,
404 0x02, 0x28, 0xa0, 0xe1, 0x22, 0x28, 0xa0, 0xe1, 0x03, 0x38, 0x82, 0xe1, 0xc0, 0x30, 0x81, 0xe5,
405 0x1e, 0xff, 0x2f, 0xe1, 0x28, 0x00, 0x9f, 0xe5, 0xc0, 0x21, 0x90, 0xe5, 0xff, 0x24, 0xc2, 0xe3,
406 0x03, 0x2c, 0x82, 0xe1, 0xc0, 0x21, 0x80, 0xe5, 0xe0, 0x21, 0x90, 0xe5, 0xff, 0x20, 0xc2, 0xe3,
407 0x23, 0x34, 0x82, 0xe1, 0xe0, 0x31, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x22, 0x22, 0x00, 0x00,
408 0xef, 0xee, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3c, 0x01, 0x00, 0x50, 0xe3, 0x01, 0x10, 0x21, 0xe2,
409 0x06, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x50, 0xe3, 0x06, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x50, 0xe3,
410 0x24, 0x30, 0x9f, 0x05, 0x0e, 0x10, 0x81, 0x03, 0x00, 0x12, 0x83, 0x05, 0x1e, 0xff, 0x2f, 0xe1,
411 0x18, 0x30, 0x9f, 0xe5, 0x00, 0x00, 0x00, 0xea, 0x14, 0x30, 0x9f, 0xe5, 0x08, 0x20, 0x9f, 0xe5,
412 0x03, 0x30, 0x81, 0xe1, 0x00, 0x32, 0x82, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0xf0, 0x3c,
413 0x0e, 0x04, 0x06, 0x00, 0x0e, 0x06, 0x0e, 0x00, 0x02, 0x00, 0x50, 0xe3, 0x10, 0x40, 0x2d, 0xe9,
414 0xbc, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0xb8, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3,
415 0xb4, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0xb0, 0x40, 0x9f, 0xe5, 0xb0, 0xc0, 0x9f, 0xe5,
416 0x01, 0x20, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0x02, 0x00, 0x50, 0xe3, 0xa4, 0x30, 0x9f, 0x05,
417 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x04, 0x30, 0xa0, 0x01, 0x0c, 0x30, 0xa0, 0x11,
418 0x00, 0x30, 0x93, 0xe5, 0x1f, 0x3e, 0x03, 0xe2, 0x01, 0x0c, 0x53, 0xe3, 0xf5, 0xff, 0xff, 0x0a,
419 0x02, 0x00, 0x50, 0xe3, 0x80, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x7c, 0x20, 0x9f, 0xe5,
420 0x01, 0x00, 0x50, 0xe3, 0x78, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x5c, 0xc0, 0x9f, 0xe5,
421 0x5c, 0x20, 0x9f, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x02, 0x00, 0x50, 0xe3, 0x54, 0x30, 0x9f, 0x05,
422 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x0c, 0x30, 0xa0, 0x01, 0x02, 0x30, 0xa0, 0x11,
423 0x00, 0x30, 0x93, 0xe5, 0x3e, 0x0c, 0x13, 0xe3, 0xf6, 0xff, 0xff, 0x0a, 0x02, 0x00, 0x50, 0xe3,
424 0x40, 0x00, 0x9f, 0x05, 0x04, 0x00, 0x00, 0x0a, 0x3c, 0x30, 0x9f, 0xe5, 0x3c, 0x20, 0x9f, 0xe5,
425 0x01, 0x00, 0x50, 0xe3, 0x02, 0x00, 0xa0, 0x01, 0x03, 0x00, 0xa0, 0x11, 0x00, 0x00, 0x90, 0xe5,
426 0x10, 0x80, 0xbd, 0xe8, 0x34, 0x00, 0x20, 0x3d, 0x34, 0x00, 0xe0, 0x3c, 0x34, 0x00, 0x30, 0x3c,
427 0x08, 0x00, 0xe0, 0x3c, 0x08, 0x00, 0x30, 0x3c, 0x08, 0x00, 0x20, 0x3d, 0x10, 0x00, 0x20, 0x3d,
428 0x10, 0x00, 0xe0, 0x3c, 0x10, 0x00, 0x30, 0x3c, 0x20, 0x00, 0x20, 0x3d, 0x20, 0x00, 0x30, 0x3c,
429 0x20, 0x00, 0xe0, 0x3c, 0x02, 0x00, 0x50, 0xe3, 0xf0, 0x40, 0x2d, 0xe9, 0xd8, 0x30, 0x9f, 0x05,
430 0x03, 0x00, 0x00, 0x0a, 0xd4, 0xc0, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3, 0xd0, 0x30, 0x9f, 0xe5,
431 0x0c, 0x30, 0xa0, 0x01, 0x02, 0x00, 0x50, 0xe3, 0x00, 0x10, 0x83, 0xe5, 0xc4, 0x30, 0x9f, 0x05,
432 0x03, 0x00, 0x00, 0x0a, 0xc0, 0xc0, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3, 0xbc, 0x30, 0x9f, 0xe5,
433 0x0c, 0x30, 0xa0, 0x01, 0x00, 0x40, 0x93, 0xe5, 0x00, 0xc0, 0xa0, 0xe3, 0x01, 0x40, 0x84, 0xe3,
434 0x00, 0x40, 0x83, 0xe5, 0xa8, 0x70, 0x9f, 0xe5, 0xa8, 0x60, 0x9f, 0xe5, 0xa8, 0x50, 0x9f, 0xe5,
435 0xa8, 0x40, 0x9f, 0xe5, 0x12, 0x00, 0x00, 0xea, 0x02, 0x00, 0x50, 0xe3, 0xa0, 0x30, 0x9f, 0x05,
436 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x07, 0x30, 0xa0, 0x01, 0x06, 0x30, 0xa0, 0x11,
437 0x00, 0x30, 0x93, 0xe5, 0x3e, 0x0c, 0x13, 0xe3, 0xf6, 0xff, 0xff, 0x0a, 0x02, 0x00, 0x50, 0xe3,
438 0x80, 0x30, 0x9f, 0x05, 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x05, 0x30, 0xa0, 0x01,
439 0x04, 0x30, 0xa0, 0x11, 0x00, 0x30, 0x93, 0xe5, 0x01, 0x10, 0x41, 0xe2, 0x0c, 0x30, 0xc2, 0xe7,
440 0x01, 0xc0, 0x8c, 0xe2, 0x00, 0x00, 0x51, 0xe3, 0xea, 0xff, 0xff, 0x1a, 0x02, 0x00, 0x50, 0xe3,
441 0x30, 0x00, 0x9f, 0x05, 0x04, 0x00, 0x00, 0x0a, 0x2c, 0x30, 0x9f, 0xe5, 0x2c, 0x20, 0x9f, 0xe5,
442 0x01, 0x00, 0x50, 0xe3, 0x02, 0x00, 0xa0, 0x11, 0x03, 0x00, 0xa0, 0x01, 0x00, 0x30, 0x90, 0xe5,
443 0x01, 0x30, 0xc3, 0xe3, 0x00, 0x30, 0x80, 0xe5, 0xf0, 0x80, 0xbd, 0xe8, 0x34, 0x00, 0x20, 0x3d,
444 0x34, 0x00, 0xe0, 0x3c, 0x34, 0x00, 0x30, 0x3c, 0x04, 0x00, 0x20, 0x3d, 0x04, 0x00, 0xe0, 0x3c,
445 0x04, 0x00, 0x30, 0x3c, 0x08, 0x00, 0xe0, 0x3c, 0x08, 0x00, 0x30, 0x3c, 0x20, 0x00, 0xe0, 0x3c,
446 0x20, 0x00, 0x30, 0x3c, 0x08, 0x00, 0x20, 0x3d, 0x20, 0x00, 0x20, 0x3d, 0x02, 0x00, 0x50, 0xe3,
447 0x2e, 0x00, 0x80, 0x02, 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x2b, 0x00, 0xa0, 0x03,
448 0x22, 0x00, 0xa0, 0x13, 0x00, 0x10, 0xa0, 0xe3, 0xe4, 0xfe, 0xff, 0xea, 0x02, 0x00, 0x50, 0xe3,
449 0x10, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x30, 0x00, 0xa0, 0x03, 0x02, 0x00, 0x00, 0x0a,
450 0x01, 0x00, 0x54, 0xe3, 0x2b, 0x00, 0xa0, 0x03, 0x22, 0x00, 0xa0, 0x13, 0x01, 0x10, 0xa0, 0xe3,
451 0xda, 0xfe, 0xff, 0xeb, 0x02, 0x00, 0x54, 0xe3, 0x04, 0x31, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a,
452 0x00, 0x21, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0xfc, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01,
453 0x02, 0x00, 0x54, 0xe3, 0x0f, 0x20, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0xec, 0x30, 0x9f, 0x05,
454 0x03, 0x00, 0x00, 0x0a, 0xe8, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0xe4, 0x30, 0x9f, 0xe5,
455 0x02, 0x30, 0xa0, 0x01, 0x00, 0x20, 0x93, 0xe5, 0x02, 0x00, 0x54, 0xe3, 0x0c, 0x20, 0x82, 0xe3,
456 0x00, 0x20, 0x83, 0xe5, 0xd0, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0xcc, 0x20, 0x9f, 0xe5,
457 0x01, 0x00, 0x54, 0xe3, 0xc8, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0xc4, 0x20, 0x9f, 0xe5,
458 0x02, 0x00, 0x54, 0xe3, 0x04, 0x21, 0x92, 0xe7, 0x00, 0x20, 0x83, 0xe5, 0xb8, 0x30, 0x9f, 0x05,
459 0x03, 0x00, 0x00, 0x0a, 0xb4, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0xb0, 0x30, 0x9f, 0xe5,
460 0x02, 0x30, 0xa0, 0x01, 0x02, 0x00, 0x54, 0xe3, 0x06, 0x20, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5,
461 0xa0, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x9c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3,
462 0x98, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x94, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x54, 0xe3,
463 0x00, 0x20, 0x83, 0xe5, 0x54, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x50, 0x20, 0x9f, 0xe5,
464 0x01, 0x00, 0x54, 0xe3, 0x4c, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x00, 0x20, 0x93, 0xe5,
465 0x02, 0x00, 0x54, 0xe3, 0x0c, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0x2c, 0x40, 0x9f, 0x05,
466 0x04, 0x00, 0x00, 0x0a, 0x2c, 0x30, 0x9f, 0xe5, 0x24, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3,
467 0x02, 0x40, 0xa0, 0x01, 0x03, 0x40, 0xa0, 0x11, 0x01, 0x30, 0xa0, 0xe3, 0x00, 0x30, 0x84, 0xe5,
468 0x10, 0x80, 0xbd, 0xe8, 0x08, 0x00, 0x20, 0x3d, 0x08, 0x00, 0xe0, 0x3c, 0x08, 0x00, 0x30, 0x3c,
469 0x00, 0x00, 0x20, 0x3d, 0x00, 0x00, 0xe0, 0x3c, 0x00, 0x00, 0x30, 0x3c, 0x30, 0x00, 0x20, 0x3d,
470 0x30, 0x00, 0xe0, 0x3c, 0x30, 0x00, 0x30, 0x3c, 0xc0, 0x16, 0x00, 0x22, 0x0c, 0x00, 0x20, 0x3d,
471 0x0c, 0x00, 0xe0, 0x3c, 0x0c, 0x00, 0x30, 0x3c, 0x04, 0x00, 0x20, 0x3d, 0x04, 0x00, 0xe0, 0x3c,
472 0x04, 0x00, 0x30, 0x3c, 0x18, 0x06, 0x01, 0x00, 0x0c, 0x30, 0x80, 0xe2, 0x02, 0xc0, 0xd3, 0xe5,
473 0x01, 0x10, 0xd3, 0xe5, 0x0c, 0x20, 0xd0, 0xe5, 0x03, 0x30, 0xd3, 0xe5, 0x0c, 0x08, 0xa0, 0xe1,
474 0x01, 0x04, 0x80, 0xe1, 0x02, 0x00, 0x80, 0xe1, 0x03, 0x0c, 0x80, 0xe1, 0x5f, 0x0d, 0x80, 0xe2,
475 0x3f, 0x00, 0x80, 0xe2, 0xff, 0x0e, 0xc0, 0xe3, 0x0f, 0x00, 0xc0, 0xe3, 0x1e, 0xff, 0x2f, 0xe1,
476 0x70, 0x40, 0x2d, 0xe9, 0x18, 0xd0, 0x4d, 0xe2, 0x04, 0x40, 0x8d, 0xe2, 0x03, 0x50, 0xa0, 0xe1,
477 0x00, 0x60, 0xa0, 0xe1, 0x01, 0x00, 0xa0, 0xe1, 0x02, 0x10, 0xa0, 0xe1, 0x04, 0x20, 0xa0, 0xe1,
478 0xe1, 0x01, 0x00, 0xeb, 0x04, 0x10, 0xa0, 0xe1, 0x05, 0x00, 0xa0, 0xe1, 0x10, 0x20, 0xa0, 0xe3,
479 0xae, 0x02, 0x00, 0xeb, 0x06, 0x10, 0xa0, 0xe1, 0x05, 0x20, 0xa0, 0xe1, 0x01, 0x00, 0xa0, 0xe3,
480 0x10, 0x30, 0xa0, 0xe3, 0x51, 0x02, 0x00, 0xeb, 0x18, 0xd0, 0x8d, 0xe2, 0x70, 0x80, 0xbd, 0xe8,
481 0x01, 0x00, 0x50, 0xe3, 0xf0, 0x47, 0x2d, 0xe9, 0x0c, 0x50, 0xd1, 0xe5, 0x0c, 0x30, 0x81, 0xe2,
482 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x00, 0xa0, 0x03, 0x02, 0x00, 0xa0, 0x13, 0x03, 0x80, 0xd3, 0xe5,
483 0x02, 0x70, 0xd3, 0xe5, 0x01, 0x60, 0xd3, 0xe5, 0x02, 0xa0, 0xa0, 0xe1, 0x07, 0x00, 0xc1, 0xe5,
484 0x40, 0x30, 0x81, 0xe2, 0x02, 0x00, 0xa0, 0xe3, 0x40, 0x20, 0xa0, 0xe3, 0xdb, 0xff, 0xff, 0xeb,
485 0x07, 0x78, 0xa0, 0xe1, 0x06, 0x64, 0x87, 0xe1, 0x05, 0x50, 0x86, 0xe1, 0x08, 0x3c, 0x85, 0xe1,
486 0x04, 0x00, 0xa0, 0xe1, 0x0a, 0x20, 0xa0, 0xe1, 0x02, 0x10, 0xa0, 0xe3, 0xf0, 0x47, 0xbd, 0xe8,
487 0x36, 0x02, 0x00, 0xea, 0x10, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x04, 0x00, 0xa0, 0xe1,
488 0x01, 0x10, 0xa0, 0xe3, 0xbf, 0xfe, 0xff, 0xeb, 0x05, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1,
489 0xd0, 0xfe, 0xff, 0xeb, 0xff, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xcd, 0xfe, 0xff, 0xeb,
490 0x00, 0x10, 0xa0, 0xe3, 0x01, 0x30, 0x10, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x00, 0x00, 0x0a,
491 0xb4, 0xfe, 0xff, 0xeb, 0xf0, 0xff, 0xff, 0xea, 0x04, 0x00, 0xa0, 0xe1, 0x03, 0x10, 0xa0, 0xe1,
492 0x10, 0x40, 0xbd, 0xe8, 0xaf, 0xfe, 0xff, 0xea, 0x70, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0x51, 0xe2,
493 0x00, 0x40, 0xa0, 0xe1, 0x07, 0x00, 0x00, 0x1a, 0x01, 0x10, 0x81, 0xe2, 0xa9, 0xfe, 0xff, 0xeb,
494 0x04, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xba, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
495 0x05, 0x10, 0xa0, 0xe1, 0xa3, 0xfe, 0xff, 0xeb, 0x01, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1,
496 0xa0, 0xfe, 0xff, 0xeb, 0x50, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xb1, 0xfe, 0xff, 0xeb,
497 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x9a, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
498 0x01, 0x10, 0xa0, 0xe3, 0x97, 0xfe, 0xff, 0xeb, 0x01, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1,
499 0xa8, 0xfe, 0xff, 0xeb, 0x00, 0x00, 0x55, 0xe3, 0x1c, 0x10, 0xa0, 0x03, 0x00, 0x10, 0xa0, 0x13,
500 0x04, 0x00, 0xa0, 0xe1, 0xa3, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3,
501 0x8c, 0xfe, 0xff, 0xeb, 0x00, 0x00, 0x55, 0xe3, 0x70, 0x80, 0xbd, 0x08, 0x04, 0x00, 0xa0, 0xe1,
502 0x01, 0x10, 0xa0, 0xe3, 0x87, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x06, 0x10, 0xa0, 0xe3,
503 0x98, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x70, 0x40, 0xbd, 0xe8,
504 0x80, 0xfe, 0xff, 0xea, 0x70, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x50, 0xa0, 0xe1,
505 0x1d, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0xb5, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
506 0x01, 0x10, 0xa0, 0xe3, 0xc7, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
507 0x74, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x20, 0x10, 0xa0, 0xe3, 0x85, 0xfe, 0xff, 0xeb,
508 0x25, 0x18, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x81, 0xfe, 0xff, 0xeb,
509 0x25, 0x14, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x7d, 0xfe, 0xff, 0xeb,
510 0xff, 0x10, 0x05, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x7a, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
511 0x00, 0x10, 0xa0, 0xe3, 0x63, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3,
512 0xb0, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x70, 0x40, 0xbd, 0xe8, 0xf6, 0xfe, 0xff, 0xea,
513 0x70, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0xa0, 0xe1, 0x01, 0x46, 0xa0, 0xe1, 0x02, 0x60, 0xa0, 0xe1,
514 0x00, 0x00, 0x00, 0xea, 0xd6, 0xff, 0xff, 0xeb, 0x00, 0x00, 0x56, 0xe3, 0x04, 0x10, 0xa0, 0xe1,
515 0x05, 0x00, 0xa0, 0xe1, 0x01, 0x4a, 0x84, 0xe2, 0x01, 0x60, 0x46, 0xe2, 0xf8, 0xff, 0xff, 0x1a,
516 0x70, 0x80, 0xbd, 0xe8, 0xf0, 0x45, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x24, 0xd0, 0x4d, 0xe2,
517 0x02, 0x50, 0xa0, 0xe1, 0x03, 0x70, 0xa0, 0xe1, 0x01, 0x60, 0xa0, 0xe1, 0xea, 0xfe, 0xff, 0xeb,
518 0x04, 0x00, 0xa0, 0xe1, 0x82, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
519 0x44, 0xfe, 0xff, 0xeb, 0x03, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0x55, 0xfe, 0xff, 0xeb,
520 0x26, 0x18, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x51, 0xfe, 0xff, 0xeb,
521 0x26, 0x14, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x4d, 0xfe, 0xff, 0xeb,
522 0xff, 0x10, 0x06, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x4a, 0xfe, 0xff, 0xeb, 0x00, 0x60, 0xa0, 0xe3,
523 0x0d, 0x80, 0xa0, 0xe1, 0x15, 0x00, 0x00, 0xea, 0x20, 0x00, 0x57, 0xe3, 0x07, 0xa0, 0xa0, 0xb1,
524 0x20, 0xa0, 0xa0, 0xa3, 0x04, 0x00, 0xa0, 0xe1, 0x0a, 0x10, 0xa0, 0xe1, 0x0d, 0x20, 0xa0, 0xe1,
525 0x7f, 0xfe, 0xff, 0xeb, 0x05, 0x00, 0xa0, 0xe1, 0x0d, 0x10, 0xa0, 0xe1, 0x0a, 0x20, 0xa0, 0xe1,
526 0x9f, 0xfd, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3, 0x00, 0x00, 0x50, 0xe3, 0x01, 0x60, 0x86, 0x13,
527 0x03, 0x20, 0xd8, 0xe7, 0x02, 0x30, 0x83, 0xe2, 0xff, 0x00, 0x52, 0xe3, 0x02, 0x60, 0x86, 0x13,
528 0x0a, 0x00, 0x53, 0xe1, 0xf9, 0xff, 0xff, 0xba, 0x20, 0x50, 0x85, 0xe2, 0x20, 0x70, 0x47, 0xe2,
529 0x00, 0x00, 0x57, 0xe3, 0xe7, 0xff, 0xff, 0xca, 0x00, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1,
530 0x18, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0xaf, 0xfe, 0xff, 0xeb, 0x06, 0x00, 0xa0, 0xe1,
531 0x24, 0xd0, 0x8d, 0xe2, 0xf0, 0x85, 0xbd, 0xe8, 0xf0, 0x4f, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1,
532 0x14, 0xd0, 0x4d, 0xe2, 0x01, 0x50, 0xa0, 0xe1, 0x02, 0x70, 0xa0, 0xe1, 0x03, 0x80, 0xa0, 0xe1,
533 0x53, 0x00, 0x00, 0xea, 0x05, 0x6a, 0xa0, 0xe1, 0x26, 0x6a, 0xa0, 0xe1, 0x01, 0x6a, 0x66, 0xe2,
534 0x08, 0x00, 0x56, 0xe1, 0x08, 0x60, 0xa0, 0xa1, 0x04, 0x00, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1,
535 0x07, 0x20, 0xa0, 0xe1, 0x06, 0x30, 0xa0, 0xe1, 0xb1, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x10, 0xe3,
536 0x44, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x10, 0xe3, 0x03, 0x00, 0x00, 0x0a, 0xff, 0x1e, 0xc5, 0xe3,
537 0x0f, 0x10, 0xc1, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0x79, 0xff, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3,
538 0x03, 0x20, 0xd7, 0xe7, 0x07, 0x90, 0xa0, 0xe1, 0xff, 0x00, 0x52, 0xe3, 0x01, 0x30, 0x83, 0xe2,
539 0x02, 0x00, 0x00, 0x1a, 0x06, 0x00, 0x53, 0xe1, 0xf8, 0xff, 0xff, 0xba, 0x35, 0x00, 0x00, 0xea,
540 0x04, 0x00, 0xa0, 0xe1, 0x90, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x28, 0xff, 0xff, 0xeb,
541 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x3a, 0xff, 0xff, 0xeb, 0x25, 0x34, 0xa0, 0xe1,
542 0xff, 0x30, 0x03, 0xe2, 0x25, 0x28, 0xa0, 0xe1, 0xff, 0x20, 0x02, 0xe2, 0x08, 0x30, 0x8d, 0xe5,
543 0x06, 0xa0, 0xa0, 0xe1, 0xff, 0x30, 0x05, 0xe2, 0x01, 0xb0, 0xa0, 0xe3, 0x04, 0x20, 0x8d, 0xe5,
544 0x0c, 0x30, 0x8d, 0xe5, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0xdd, 0xfd, 0xff, 0xeb,
545 0x04, 0x00, 0xa0, 0xe1, 0xad, 0x10, 0xa0, 0xe3, 0xee, 0xfd, 0xff, 0xeb, 0x00, 0x00, 0x5b, 0xe3,
546 0x00, 0xb0, 0xa0, 0xe3, 0x08, 0x00, 0x00, 0x0a, 0x04, 0x10, 0x9d, 0xe5, 0x04, 0x00, 0xa0, 0xe1,
547 0xe8, 0xfd, 0xff, 0xeb, 0x08, 0x10, 0x9d, 0xe5, 0x04, 0x00, 0xa0, 0xe1, 0xe5, 0xfd, 0xff, 0xeb,
548 0x04, 0x00, 0xa0, 0xe1, 0x0c, 0x10, 0x9d, 0xe5, 0xe2, 0xfd, 0xff, 0xeb, 0x00, 0x10, 0xd9, 0xe5,
549 0x04, 0x00, 0xa0, 0xe1, 0xdf, 0xfd, 0xff, 0xeb, 0x01, 0x10, 0xd9, 0xe5, 0x04, 0x00, 0xa0, 0xe1,
550 0xdc, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0xc5, 0xfd, 0xff, 0xeb,
551 0x04, 0x00, 0xa0, 0xe1, 0xfe, 0xfe, 0xff, 0xeb, 0x02, 0xa0, 0x5a, 0xe2, 0x02, 0x90, 0x89, 0xe2,
552 0xdf, 0xff, 0xff, 0x1a, 0x04, 0x00, 0xa0, 0xe1, 0x0a, 0x10, 0xa0, 0xe1, 0x0d, 0xff, 0xff, 0xeb,
553 0x04, 0x00, 0xa0, 0xe1, 0x54, 0xfe, 0xff, 0xeb, 0x08, 0x80, 0x66, 0xe0, 0x06, 0x70, 0x87, 0xe0,
554 0x06, 0x50, 0x85, 0xe0, 0x00, 0x00, 0x58, 0xe3, 0xa9, 0xff, 0xff, 0xca, 0x14, 0xd0, 0x8d, 0xe2,
555 0xf0, 0x8f, 0xbd, 0xe8, 0xf0, 0x41, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x03, 0x50, 0xa0, 0xe1,
556 0x02, 0x70, 0xa0, 0xe1, 0x01, 0x60, 0xa0, 0xe1, 0x4f, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
557 0xe7, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0xa9, 0xfd, 0xff, 0xeb,
558 0x04, 0x00, 0xa0, 0xe1, 0x03, 0x10, 0xa0, 0xe3, 0xba, 0xfd, 0xff, 0xeb, 0x26, 0x18, 0xa0, 0xe1,
559 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0xb6, 0xfd, 0xff, 0xeb, 0x26, 0x14, 0xa0, 0xe1,
560 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0xb2, 0xfd, 0xff, 0xeb, 0xff, 0x10, 0x06, 0xe2,
561 0x04, 0x00, 0xa0, 0xe1, 0xaf, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x07, 0x10, 0xa0, 0xe1,
562 0x05, 0x20, 0xa0, 0xe1, 0xea, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3,
563 0x94, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0xf0, 0x41, 0xbd, 0xe8, 0x2a, 0xfe, 0xff, 0xea,
564 0x00, 0x10, 0xa0, 0xe3, 0x6a, 0xfd, 0xff, 0xea, 0x10, 0x40, 0x2d, 0xe9, 0x01, 0x10, 0xa0, 0xe3,
565 0x00, 0x40, 0xa0, 0xe1, 0x66, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3,
566 0x10, 0x40, 0xbd, 0xe8, 0x87, 0xfd, 0xff, 0xea, 0x0c, 0x30, 0x81, 0xe2, 0x70, 0x40, 0x2d, 0xe9,
567 0x02, 0x50, 0xd3, 0xe5, 0x01, 0x40, 0xa0, 0xe1, 0x01, 0x10, 0xd3, 0xe5, 0x0c, 0x20, 0xd4, 0xe5,
568 0x03, 0x30, 0xd3, 0xe5, 0x05, 0x58, 0xa0, 0xe1, 0x01, 0x54, 0x85, 0xe1, 0x02, 0x50, 0x85, 0xe1,
569 0x03, 0x5c, 0x85, 0xe1, 0x00, 0x60, 0xa0, 0xe1, 0x02, 0x5b, 0x85, 0xe2, 0x00, 0x00, 0xa0, 0xe3,
570 0xe8, 0xff, 0xff, 0xeb, 0x06, 0x10, 0xa0, 0xe1, 0x04, 0x20, 0xa0, 0xe1, 0x05, 0x30, 0xa0, 0xe1,
571 0x00, 0x00, 0xa0, 0xe3, 0x5f, 0xff, 0xff, 0xeb, 0x04, 0x20, 0xa0, 0xe1, 0x06, 0x10, 0xa0, 0xe1,
572 0x05, 0x30, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0x1d, 0xff, 0xff, 0xeb, 0x00, 0x40, 0xa0, 0xe1,
573 0x00, 0x00, 0xa0, 0xe3, 0xd9, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x24, 0xe2, 0x01, 0x00, 0x00, 0xe2,
574 0x70, 0x80, 0xbd, 0xe8, 0xf0, 0x45, 0x2d, 0xe9, 0x01, 0x40, 0xa0, 0xe1, 0x14, 0xd0, 0x4d, 0xe2,
575 0x00, 0x80, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0x02, 0x60, 0xa0, 0xe1, 0xd1, 0xff, 0xff, 0xeb,
576 0x08, 0x10, 0xa0, 0xe1, 0x02, 0x2b, 0xa0, 0xe3, 0x04, 0x30, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
577 0xa7, 0xff, 0xff, 0xeb, 0x00, 0x00, 0xa0, 0xe3, 0xc8, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
578 0x40, 0x11, 0x9f, 0xe5, 0x04, 0x20, 0xa0, 0xe3, 0xcd, 0xfc, 0xff, 0xeb, 0x00, 0x00, 0x50, 0xe3,
579 0x00, 0x00, 0xe0, 0x13, 0x49, 0x00, 0x00, 0x1a, 0x04, 0x10, 0xa0, 0xe1, 0x40, 0x20, 0xa0, 0xe3,
580 0x0d, 0x30, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x5c, 0xfe, 0xff, 0xeb, 0x0d, 0x00, 0xa0, 0xe1,
581 0x40, 0x10, 0x84, 0xe2, 0x10, 0x20, 0xa0, 0xe3, 0xc1, 0xfc, 0xff, 0xeb, 0x0d, 0x50, 0xa0, 0xe1,
582 0x00, 0x70, 0x50, 0xe2, 0x01, 0x00, 0xe0, 0x13, 0x3c, 0x00, 0x00, 0x1a, 0x0c, 0x30, 0x84, 0xe2,
583 0x02, 0x50, 0xd3, 0xe5, 0x01, 0x10, 0xd3, 0xe5, 0x0c, 0x20, 0xd4, 0xe5, 0x05, 0x58, 0xa0, 0xe1,
584 0x03, 0x30, 0xd3, 0xe5, 0x01, 0x54, 0x85, 0xe1, 0x02, 0x50, 0x85, 0xe1, 0x03, 0x5c, 0x85, 0xe1,
585 0x7e, 0x0b, 0x55, 0xe3, 0x2e, 0x00, 0x00, 0x8a, 0x08, 0x30, 0x84, 0xe2, 0x02, 0xc0, 0xd3, 0xe5,
586 0x01, 0xa0, 0xd3, 0xe5, 0x08, 0x10, 0xd4, 0xe5, 0x03, 0x20, 0xd3, 0xe5, 0x0c, 0xc8, 0xa0, 0xe1,
587 0x0a, 0x34, 0x8c, 0xe1, 0x01, 0x30, 0x83, 0xe1, 0x02, 0x3c, 0x83, 0xe1, 0x05, 0x00, 0x53, 0xe1,
588 0x23, 0x00, 0x00, 0x8a, 0x07, 0x30, 0xd4, 0xe5, 0x01, 0x30, 0x43, 0xe2, 0x01, 0x00, 0x53, 0xe3,
589 0x03, 0x00, 0xe0, 0x83, 0x21, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x56, 0xe3, 0x1e, 0x00, 0x00, 0x0a,
590 0x98, 0xff, 0xff, 0xeb, 0x06, 0x30, 0xa0, 0xe1, 0x07, 0x00, 0xa0, 0xe1, 0x02, 0x1b, 0x88, 0xe2,
591 0x05, 0x20, 0xa0, 0xe1, 0x6e, 0xff, 0xff, 0xeb, 0x07, 0x00, 0xa0, 0xe1, 0x8f, 0xff, 0xff, 0xeb,
592 0x07, 0x30, 0xd4, 0xe5, 0x01, 0x00, 0x53, 0xe3, 0x03, 0x00, 0x00, 0x1a, 0x07, 0x00, 0xa0, 0xe1,
593 0x04, 0x10, 0xa0, 0xe1, 0x06, 0x20, 0xa0, 0xe1, 0x3c, 0xfe, 0xff, 0xeb, 0x06, 0x10, 0xa0, 0xe1,
594 0x05, 0x20, 0xa0, 0xe1, 0x0d, 0x30, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x23, 0xfe, 0xff, 0xeb,
595 0x0d, 0x00, 0xa0, 0xe1, 0x10, 0x10, 0x84, 0xe2, 0x10, 0x20, 0xa0, 0xe3, 0x88, 0xfc, 0xff, 0xeb,
596 0x0d, 0x70, 0xa0, 0xe1, 0x00, 0x00, 0x50, 0xe3, 0x04, 0x00, 0xe0, 0x13, 0x02, 0x00, 0x00, 0x0a,
597 0x02, 0x00, 0x00, 0xea, 0x02, 0x00, 0xe0, 0xe3, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0xa0, 0xe3,
598 0x14, 0xd0, 0x8d, 0xe2, 0xf0, 0x85, 0xbd, 0xe8, 0xd1, 0x16, 0x00, 0x22, 0xf0, 0x4f, 0x2d, 0xe9,
599 0x00, 0x50, 0xa0, 0xe1, 0x54, 0xd0, 0x4d, 0xe2, 0x01, 0x40, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
600 0x01, 0x10, 0xa0, 0xe3, 0x02, 0x60, 0xa0, 0xe1, 0x84, 0xfc, 0xff, 0xeb, 0x0e, 0x23, 0xa0, 0xe3,
601 0x01, 0x10, 0xa0, 0xe3, 0x02, 0xc0, 0xa0, 0xe1, 0x10, 0x30, 0x8d, 0xe2, 0x04, 0x10, 0x82, 0xe5,
602 0x00, 0x00, 0x9c, 0xe5, 0x0e, 0x23, 0xa0, 0xe3, 0x01, 0x00, 0x10, 0xe2, 0xfb, 0xff, 0xff, 0x1a,
603 0x40, 0xc0, 0x64, 0xe2, 0xa4, 0x72, 0xa0, 0xe1, 0x84, 0xe1, 0xa0, 0xe1, 0x7c, 0x81, 0x9f, 0xe5,
604 0xa4, 0xaa, 0xa0, 0xe1, 0xa4, 0x96, 0xa0, 0xe1, 0xff, 0x70, 0x07, 0xe2, 0xff, 0xe0, 0x0e, 0xe2,
605 0x0c, 0xc0, 0x65, 0xe0, 0xff, 0x90, 0x09, 0xe2, 0x04, 0x70, 0x8d, 0xe5, 0x00, 0xe0, 0x8d, 0xe5,
606 0x0c, 0xc0, 0x8d, 0xe5, 0x02, 0x10, 0xa0, 0xe1, 0xff, 0xa0, 0x0a, 0xe2, 0x00, 0x70, 0xa0, 0xe1,
607 0xa4, 0x4e, 0xa0, 0xe1, 0x10, 0xc0, 0x8d, 0xe2, 0x02, 0xe0, 0xa0, 0xe1, 0x04, 0x00, 0x82, 0xe5,
608 0x08, 0x90, 0x8d, 0xe5, 0x00, 0x00, 0x82, 0xe5, 0x0c, 0x20, 0x9d, 0xe5, 0x02, 0x00, 0x85, 0xe0,
609 0x00, 0x00, 0x50, 0xe3, 0x25, 0x00, 0x00, 0xda, 0x00, 0x20, 0xa0, 0xe3, 0x02, 0x70, 0x8c, 0xe7,
610 0x04, 0x20, 0x82, 0xe2, 0x40, 0x00, 0x52, 0xe3, 0xfb, 0xff, 0xff, 0x1a, 0x40, 0x00, 0x50, 0xe3,
611 0x07, 0x20, 0xa0, 0xd1, 0x40, 0x90, 0x60, 0xd2, 0x03, 0x00, 0x00, 0xda, 0x09, 0x00, 0x00, 0xea,
612 0x02, 0xb0, 0xd5, 0xe7, 0x02, 0xb0, 0xcc, 0xe7, 0x01, 0x20, 0x82, 0xe2, 0x09, 0x00, 0x52, 0xe1,
613 0xfa, 0xff, 0xff, 0xba, 0x07, 0x00, 0x50, 0xe3, 0x7f, 0x20, 0xe0, 0xe3, 0x09, 0x20, 0xc3, 0xe7,
614 0x00, 0x00, 0xa0, 0xd3, 0x08, 0x00, 0x00, 0xda, 0x3b, 0x40, 0xc3, 0xe5, 0x3c, 0xa0, 0xc3, 0xe5,
615 0x08, 0x20, 0x9d, 0xe5, 0x01, 0x00, 0xa0, 0xe3, 0x3d, 0x20, 0xc3, 0xe5, 0x04, 0x20, 0x9d, 0xe5,
616 0x3e, 0x20, 0xc3, 0xe5, 0x00, 0x20, 0x9d, 0xe5, 0x3f, 0x20, 0xc3, 0xe5, 0xb0, 0x20, 0x9f, 0xe5,
617 0x02, 0x90, 0x8c, 0xe0, 0x32, 0x93, 0x89, 0xe2, 0x40, 0x90, 0x49, 0xe2, 0x00, 0x90, 0x99, 0xe5,
618 0x04, 0x90, 0x82, 0xe4, 0x08, 0x00, 0x52, 0xe1, 0xf8, 0xff, 0xff, 0x1a, 0x09, 0x00, 0x00, 0xea,
619 0x8c, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x85, 0xe0, 0x32, 0x03, 0x80, 0xe2, 0x40, 0x00, 0x40, 0xe2,
620 0x00, 0x00, 0x90, 0xe5, 0x04, 0x00, 0x82, 0xe4, 0x08, 0x00, 0x52, 0xe1, 0xf8, 0xff, 0xff, 0x1a,
621 0x40, 0x50, 0x85, 0xe2, 0x00, 0x00, 0xa0, 0xe3, 0x00, 0x20, 0x91, 0xe5, 0x02, 0x20, 0x82, 0xe3,
622 0x00, 0x20, 0x81, 0xe5, 0x00, 0x20, 0x91, 0xe5, 0x01, 0x00, 0x12, 0xe3, 0xfc, 0xff, 0xff, 0x1a,
623 0x00, 0x20, 0x9e, 0xe5, 0x00, 0x00, 0x50, 0xe3, 0x08, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x8e, 0xe5,
624 0xc0, 0xff, 0xff, 0x0a, 0x3c, 0x30, 0x9f, 0xe5, 0x3c, 0x10, 0x9f, 0xe5, 0x03, 0x20, 0xa0, 0xe1,
625 0x06, 0x00, 0x92, 0xe6, 0x04, 0x30, 0x83, 0xe2, 0x32, 0x23, 0x82, 0xe2, 0x20, 0x20, 0x42, 0xe2,
626 0x01, 0x00, 0x53, 0xe1, 0x00, 0x00, 0x82, 0xe5, 0xf7, 0xff, 0xff, 0x1a, 0x00, 0x00, 0xa0, 0xe3,
627 0x00, 0x10, 0xa0, 0xe1, 0x19, 0xfc, 0xff, 0xeb, 0x54, 0xd0, 0x8d, 0xe2, 0xf0, 0x8f, 0xbd, 0xe8,
628 0x80, 0x00, 0x00, 0x38, 0x40, 0x00, 0x00, 0x38, 0x20, 0x00, 0x00, 0x38, 0x34, 0x00, 0x00, 0x38,
629 0xf0, 0x47, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x50, 0xa0, 0xe1, 0x0a, 0x00, 0xa0, 0xe3,
630 0x01, 0x10, 0xa0, 0xe3, 0xe3, 0x85, 0xa0, 0xe3, 0x03, 0x60, 0xa0, 0xe1, 0x02, 0x70, 0xa0, 0xe1,
631 0x01, 0xa0, 0xa0, 0xe3, 0x09, 0xfc, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3, 0x74, 0x30, 0x88, 0xe5,
632 0x78, 0x30, 0x88, 0xe5, 0x7c, 0x30, 0x88, 0xe5, 0x80, 0x30, 0x88, 0xe5, 0x08, 0xa0, 0x88, 0xe5,
633 0x08, 0x30, 0x88, 0xe5, 0x00, 0xa0, 0x88, 0xe5, 0x10, 0x30, 0x88, 0xe5, 0x6c, 0x50, 0x88, 0xe5,
634 0x6c, 0x20, 0x98, 0xe5, 0x0a, 0x00, 0x54, 0xe1, 0x09, 0x40, 0xa0, 0x03, 0x08, 0x40, 0xa0, 0x13,
635 0x02, 0x20, 0xe0, 0xe1, 0x88, 0x20, 0x88, 0xe5, 0x8c, 0x30, 0x88, 0xe5, 0x14, 0x40, 0x88, 0xe5,
636 0x18, 0x60, 0x88, 0xe5, 0x20, 0x70, 0x88, 0xe5, 0x24, 0x60, 0x88, 0xe5, 0x28, 0x70, 0x88, 0xe5,
637 0x2c, 0x60, 0x88, 0xe5, 0x30, 0x70, 0x88, 0xe5, 0x34, 0x60, 0x88, 0xe5, 0x3c, 0x00, 0x00, 0xeb,
638 0x08, 0x30, 0xa0, 0xe1, 0x04, 0xa0, 0x88, 0xe5, 0x0c, 0x20, 0x93, 0xe5, 0x0f, 0x00, 0x12, 0xe3,
639 0xfc, 0xff, 0xff, 0x0a, 0x0a, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0xf0, 0x47, 0xbd, 0xe8,
640 0xe6, 0xfb, 0xff, 0xea, 0x98, 0x30, 0x9f, 0xe5, 0xf0, 0x45, 0x2d, 0xe9, 0x94, 0xc0, 0x9f, 0xe5,
641 0xfa, 0x4f, 0xa0, 0xe3, 0x03, 0x60, 0xa0, 0xe1, 0x8c, 0x50, 0x9f, 0xe5, 0x1c, 0x00, 0x00, 0xea,
642 0xb4, 0x10, 0x93, 0xe5, 0xb2, 0x80, 0xd0, 0xe1, 0xa2, 0xa0, 0xa0, 0xe1, 0x94, 0x18, 0x27, 0xe0,
643 0x00, 0x20, 0xa0, 0xe3, 0x09, 0x00, 0x00, 0xea, 0x01, 0x20, 0x22, 0xe2, 0x06, 0x1c, 0x82, 0xe3,
644 0x0e, 0x10, 0x81, 0xe3, 0x00, 0x12, 0x8c, 0xe5, 0xb4, 0x10, 0x93, 0xe5, 0x01, 0x10, 0x8a, 0xe0,
645 0xb4, 0x80, 0x93, 0xe5, 0x08, 0x80, 0x61, 0xe0, 0x00, 0x00, 0x58, 0xe3, 0xfb, 0xff, 0xff, 0xba,
646 0xb4, 0x10, 0x93, 0xe5, 0x01, 0x10, 0x67, 0xe0, 0x00, 0x00, 0x51, 0xe3, 0xf1, 0xff, 0xff, 0xba,
647 0x00, 0x52, 0x8c, 0xe5, 0xb4, 0x70, 0xd0, 0xe1, 0xb4, 0x10, 0x96, 0xe5, 0x94, 0x17, 0x22, 0xe0,
648 0xb4, 0x10, 0x93, 0xe5, 0x01, 0x10, 0x62, 0xe0, 0x00, 0x00, 0x51, 0xe3, 0xfb, 0xff, 0xff, 0xba,
649 0x06, 0x00, 0x80, 0xe2, 0xb0, 0x20, 0xd0, 0xe1, 0x00, 0x00, 0x52, 0xe3, 0xdf, 0xff, 0xff, 0x1a,
650 0xf0, 0x85, 0xbd, 0xe8, 0x00, 0x00, 0x70, 0x3c, 0x00, 0x00, 0xf0, 0x3c, 0x0e, 0x06, 0x00, 0x00,
651 0x00, 0x30, 0xa0, 0xe3, 0x02, 0x00, 0x00, 0xea, 0x03, 0xc0, 0xd1, 0xe7, 0x03, 0xc0, 0xc0, 0xe7,
652 0x01, 0x30, 0x83, 0xe2, 0x00, 0x00, 0x52, 0xe3, 0x01, 0x20, 0x42, 0xe2, 0xf9, 0xff, 0xff, 0x1a,
653 0x1e, 0xff, 0x2f, 0xe1, 0x7e, 0xff, 0x17, 0xee, 0xfd, 0xff, 0xff, 0x1a, 0x00, 0x10, 0xa0, 0xe3,
654 0x9a, 0x1f, 0x07, 0xee, 0x1e, 0xff, 0x2f, 0xe1, 0xb8, 0x0b, 0xf4, 0x01, 0xf4, 0x01, 0xb8, 0x0b,
655 0xf4, 0x01, 0xf4, 0x01, 0xb8, 0x0b, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x76, 0xdc,
656 0x1d, 0x32, 0xb2, 0x46, 0xa6, 0xc9, 0x7d, 0x5a, 0x61, 0xd3, 0x49, 0x4c, 0x1e, 0xf0, 0xd9, 0xde,
657 0xc2, 0x7e, 0xec, 0x02, 0x7c, 0x15, 0x76, 0xbb, 0x5c, 0x4f, 0x2d, 0x95, 0x06, 0x85, 0xdf, 0x28,
658 0xe4, 0xd7, 0xf4, 0x82, 0xc0, 0x73, 0xb0, 0x53, 0x26, 0xfc, 0xb0, 0xfe, 0x60, 0x80, 0x7d, 0x33,
659 0xa8, 0xde, 0xf8, 0x49, 0xbb, 0xbe, 0x01, 0x45, 0xff, 0x62, 0x40, 0x19, 0xf4, 0x01, 0x64, 0x00,
660 0x00, 0x00, 0x00, 0x00, 0xe8, 0x03, 0x64, 0x00, 0x00, 0x00, 0xf4, 0x01, 0x96, 0x00, 0x00, 0x00,
661 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
662 0x68, 0x73, 0x6c, 0x66, 0x00, 0x38, 0x37, 0x30, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
663 0x00, 0x00, 0x00, 0x00
664};
diff --git a/utils/mks5lboot/dualboot.h b/utils/mks5lboot/dualboot.h
new file mode 100644
index 0000000000..c8952a4c07
--- /dev/null
+++ b/utils/mks5lboot/dualboot.h
@@ -0,0 +1,4 @@
1/* Generated by bin2c */
2
3extern unsigned char dualboot_install_ipod6g[5396];
4extern unsigned char dualboot_uninstall_ipod6g[5076];
diff --git a/utils/mks5lboot/dualboot/.gitignore b/utils/mks5lboot/dualboot/.gitignore
new file mode 100644
index 0000000000..34c53b3c82
--- /dev/null
+++ b/utils/mks5lboot/dualboot/.gitignore
@@ -0,0 +1,3 @@
1build/
2*.arm-bin
3bin2c
diff --git a/utils/mks5lboot/dualboot/Makefile b/utils/mks5lboot/dualboot/Makefile
new file mode 100644
index 0000000000..51ce816ca0
--- /dev/null
+++ b/utils/mks5lboot/dualboot/Makefile
@@ -0,0 +1,97 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9ifndef V
10SILENT = @
11endif
12
13CC = gcc
14LD = ld
15OC = objcopy
16CROSS ?= arm-elf-eabi-
17
18ROOTDIR = ../../..
19FIRMDIR = $(ROOTDIR)/firmware
20FWARM = $(FIRMDIR)/target/arm
21FW8702 = $(FWARM)/s5l8702
22BUILDDIR = build/
23LINKFILE = dualboot.lds
24
25# Edit the following variables when adding a new target.
26# mks5lboot.c also needs to be edited to refer to these
27# To add a new target x you need to:
28# 1) add x to the list in TARGETS
29# 2) create a variable named OPT_x of the form:
30# OPT_x=target specific defines
31TARGETS = ipod6g
32OPT_ipod6g = -DIPOD_6G -DMEMORYSIZE=64
33
34LOADERS = install uninstall
35OPT_install =
36OPT_uninstall = -DDUALBOOT_UNINSTALL
37
38# target/loader specific options
39$(foreach l, $(LOADERS),$(foreach t, $(TARGETS),\
40 $(eval OPT_$(l)_$(t) = $(OPT_$(l)) $(OPT_$(t)))))
41
42DEFINES = -DBOOTLOADER
43
44SOURCES = init.S dualboot.c
45SOURCES += $(ROOTDIR)/lib/arm_support/support-arm.S
46SOURCES += $(wildcard $(FIRMDIR)/asm/mem*.c $(FIRMDIR)/libc/mem*.c)
47SOURCES += $(addprefix $(FWARM)/, mmu-arm.S)
48SOURCES += $(addprefix $(FW8702)/, clocking-s5l8702.c spi-s5l8702.c nor-s5l8702.c crypto-s5l8702.c)
49# target/loader specific sources
50SRCTARGET = piezo-.c
51$(foreach l, $(LOADERS), $(foreach t, $(TARGETS),\
52 $(eval SRC_$(l)_$(t) = $(addprefix $(FW8702)/$(t)/, $(subst -.,-$(subst ipod,,$(t)).,$(SRCTARGET))))))
53
54INCLUDES += -I. -I.. -I$(FIRMDIR) -I$(FWARM) -I$(FW8702)
55INCLUDES += $(addprefix -I$(FIRMDIR)/, export include libc/include kernel/include)
56# target/loader specific includes
57$(foreach l,$(LOADERS),$(foreach t,$(TARGETS),$(eval INC_$(l)_$(t) = -I$(FW8702)/$(t))))
58
59CFLAGS = $(INCLUDES) -mcpu=arm926ej-s -std=gnu99 -nostdlib -ffreestanding -Os -W -Wall\
60 -Wundef -Wstrict-prototypes -ffunction-sections -fdata-sections -Wl,--gc-sections $(DEFINES)
61
62# Build filenames prefix
63PFX = dualboot_
64
65BOOTBINS = $(foreach l, $(LOADERS),$(foreach t, $(TARGETS),$(PFX)$(l)_$(t).arm-bin))
66
67OUTPUTDUALBOOT = ../dualboot.h ../dualboot.c
68OUTPUTDEBUG = $(BOOTBINS:%.arm-bin=$(BUILDDIR)%.arm-elf) $(BOOTBINS:%.arm-bin=$(BUILDDIR)%.lds)
69
70
71all: $(BUILDDIR) $(OUTPUTDUALBOOT)
72
73$(BUILDDIR)$(PFX)%.lds: $(LINKFILE)
74 @echo Creating $@
75 $(SILENT)$(CROSS)$(CC) $(INC_$*) $(CFLAGS) $(OPT_$*) -E -x c - < $< | sed '/#/d' > $@
76
77$(BUILDDIR)$(PFX)%.arm-elf: $(BUILDDIR)$(PFX)%.lds $(SOURCES)
78 @echo CC -T $(notdir $^ $(SRC_$*))
79 $(SILENT)$(CROSS)$(CC) $(INC_$*) $(CFLAGS) $(OPT_$*) -o $@ -T$^ $(SRC_$*)
80
81$(PFX)%.arm-bin: $(BUILDDIR)$(PFX)%.arm-elf
82 @echo OC $<
83 $(SILENT)$(CROSS)$(OC) -O binary $< $@
84
85bin2c: bin2c.c
86 $(CC) -o $@ $<
87
88$(OUTPUTDUALBOOT): bin2c $(BOOTBINS)
89 ./bin2c ../dualboot $(BOOTBINS)
90
91$(BUILDDIR):
92 mkdir -p $@
93
94clean:
95 rm -rf bin2c $(BOOTBINS) $(BUILDDIR)
96
97.PRECIOUS: $(OUTPUTDEBUG)
diff --git a/utils/mks5lboot/dualboot/autoconf.h b/utils/mks5lboot/dualboot/autoconf.h
new file mode 100644
index 0000000000..cd5b3f9aeb
--- /dev/null
+++ b/utils/mks5lboot/dualboot/autoconf.h
@@ -0,0 +1,74 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2012 by Andrew Ryabinin
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __BUILD_AUTOCONF_H
22#define __BUILD_AUTOCONF_H
23
24/* lower case names match the what's exported in the Makefile
25 * upper case name looks nicer in the code */
26
27#define arch_none 0
28#define ARCH_NONE 0
29
30#define arch_sh 1
31#define ARCH_SH 1
32
33#define arch_m68k 2
34#define ARCH_M68K 2
35
36#define arch_arm 3
37#define ARCH_ARM 3
38
39#define arch_mips 4
40#define ARCH_MIPS 4
41
42#define arch_x86 5
43#define ARCH_X86 5
44
45#define arch_amd64 6
46#define ARCH_AMD64 6
47
48/* Define target machine architecture */
49#define ARCH arch_arm
50/* Optionally define architecture version */
51#define ARCH_VERSION 5
52
53/* Define endianess for the target or simulator platform */
54#define ROCKBOX_LITTLE_ENDIAN 1
55
56/* Define this if you build rockbox to support the logf logging and display */
57#undef ROCKBOX_HAS_LOGF
58
59/* Define this if you want logf to output to the serial port */
60#undef LOGF_SERIAL
61
62/* Define this to record a chart with timings for the stages of boot */
63#undef DO_BOOTCHART
64
65/* the threading backend we use */
66#define ASSEMBLER_THREADS
67
68/* root of Rockbox */
69#define ROCKBOX_DIR "/.rockbox"
70#define ROCKBOX_SHARE_PATH ""
71#define ROCKBOX_BINARY_PATH ""
72#define ROCKBOX_LIBRARY_PATH ""
73
74#endif /* __BUILD_AUTOCONF_H */
diff --git a/utils/mks5lboot/dualboot/bin2c.c b/utils/mks5lboot/dualboot/bin2c.c
new file mode 100644
index 0000000000..4d74a19696
--- /dev/null
+++ b/utils/mks5lboot/dualboot/bin2c.c
@@ -0,0 +1,140 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdio.h>
23#include <string.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <unistd.h>
27#include <fcntl.h>
28#include <stdlib.h>
29#include <libgen.h>
30
31#ifndef O_BINARY
32#define O_BINARY 0
33#endif
34
35static off_t filesize(int fd)
36{
37 struct stat buf;
38
39 fstat(fd,&buf);
40 return buf.st_size;
41}
42
43static void write_cfile(const unsigned char* buf, off_t len, FILE* fp, const char *name)
44{
45 int i;
46
47 fprintf(fp,"unsigned char %s[%ld] = {",name,len);
48
49 for (i=0;i<len;i++) {
50 if ((i % 16) == 0) {
51 fprintf(fp,"\n ");
52 }
53 if (i == (len-1)) {
54 fprintf(fp,"0x%02x",buf[i]);
55 } else if ((i % 16) == 15) {
56 fprintf(fp,"0x%02x,",buf[i]);
57 } else {
58 fprintf(fp,"0x%02x, ",buf[i]);
59 }
60 }
61 fprintf(fp,"\n};\n");
62}
63
64int main (int argc, char* argv[])
65{
66 char* cname;
67 int i;
68 FILE *cfile, *hfile;
69 char cfilename[256], hfilename[256];
70
71 if (argc < 3) {
72 fprintf(stderr,"Usage: bin2c cname file1 [file2 [file3 ...]]\n");
73 return 1;
74 }
75
76 cname=argv[1];
77
78 snprintf(cfilename,256,"%s.c",cname);
79 cfile = fopen(cfilename,"w+");
80 if (cfile == NULL) {
81 fprintf(stderr,"Couldn't open %s\n",cfilename);
82 return 2;
83 }
84
85 snprintf(hfilename,256,"%s.h",cname);
86 hfile = fopen(hfilename,"w+");
87 if (hfile == NULL) {
88 fprintf(stderr,"Couldn't open %s\n",hfilename);
89 fclose(cfile);
90 return 3;
91 }
92
93 fprintf(cfile,"/* Generated by bin2c */\n\n");
94 fprintf(cfile,"#include \"%s\"\n\n", basename(hfilename));
95 fprintf(hfile,"/* Generated by bin2c */\n\n");
96
97 for(i=0; i < argc - 2; i++) {
98 unsigned char* buf;
99 off_t len;
100 off_t orig_len;
101 char *ext;
102 char *array = argv[2+i];
103
104 int fd = open(array,O_RDONLY|O_BINARY);
105 if (fd < 0) {
106 fprintf(stderr,"Can not open %s\n",argv[2+i]);
107 fclose(cfile);
108 fclose(hfile);
109 return 4;
110 }
111
112 orig_len = filesize(fd);
113 /* pad to 32bit */
114 len = (orig_len + 3) & ~3;
115
116 buf = malloc(len);
117 if (read(fd,buf,orig_len) < orig_len) {
118 fprintf(stderr,"Short read, aborting\n");
119 return 5;
120 }
121
122 /* pad to 32bit with zeros */
123 if (len > orig_len)
124 memset(buf+orig_len, 0, len-orig_len);
125
126 /* remove file extension */
127 ext = strchr (array, '.');
128 if (ext != NULL)
129 *ext = '\0';
130 write_cfile (buf, len, cfile, array);
131 fprintf(hfile,"extern unsigned char %s[%ld];\n",array,len);
132
133 close(fd);
134 }
135
136 fclose(cfile);
137 fclose(hfile);
138
139 return 0;
140}
diff --git a/utils/mks5lboot/dualboot/dualboot.c b/utils/mks5lboot/dualboot/dualboot.c
new file mode 100644
index 0000000000..b8167ec124
--- /dev/null
+++ b/utils/mks5lboot/dualboot/dualboot.c
@@ -0,0 +1,287 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2015 by Cástor Muñoz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <stdint.h>
22#include <string.h>
23
24#include "config.h"
25#include "system.h"
26#include "button.h"
27
28#include "s5l8702.h"
29#include "clocking-s5l8702.h"
30#include "spi-s5l8702.h"
31#include "nor-target.h"
32#include "piezo.h"
33
34/* How it works:
35 *
36 * - dualboot-installer: installs or updates a RB bootloader, the bootloader
37 * to install/update is already included into dualboot-installer.dfu file,
38 * once it is executed by the iPod device:
39 *
40 * 1) locates an original NORBOOT (ONB): first it looks at offset=32KB, if
41 * a NORBOOT is found but it is not an ONB then it is supposed it is a
42 * RB bootloader (that should be updated), then the ONB is loaded from
43 * offset=32KB+old_BLSIZE).
44 * 2) write ONB at 32KB+new_BLSIZE, if it fails then:
45 * 2a) try to restore ONB to its 'pristine' place (offset=32KB), if it
46 * also fails then the NOR got corrupted (ONB probably destroyed)
47 * and iTunes should be used to restore the iPod.
48 * 3) write new (included) RB bootloader at offset=32KB, it it fails then
49 * goto 2a)
50 *
51 * - dualboot-uninstaller: uninstall RB bootloader from NOR, leaving it at
52 * it's previous (pristine) state.
53 *
54 * See bootloader/ipod6g.c for notes on how the RB bootloader works.
55 *
56 *
57 * Pristine NOR Rockboxed NOR
58 * 1MB ______________
59 * | |
60 * | flsh DIR |
61 * 1MB-0x200 |______________|
62 * | |
63 * | File 1 |
64 * |..............|
65 * | |
66 * . .
67 * . .
68 * . .
69 * | |
70 * |..............|
71 * | | . .
72 * | File N | . .
73 * |______________| |______________|
74 * | | | |
75 * | | | |
76 * | | | Unused |
77 * | | | |
78 * | Unused | 160KB+BLSZ |______________|
79 * | | | |
80 * | | | Original |
81 * | | | NOR boot |
82 * 160KB |______________| | (decrypted) |
83 * | | | |
84 * | | 32KB+BLSZ |______________|
85 * | Original | | |
86 * | NOR boot | | Decrypted |
87 * | (encrypted) | | Rockbox |
88 * | | | Bootloader |
89 * 32KB |______________| 32KB |______________|
90 * | | | |
91 * | | . .
92 * | | . .
93 * |______________|
94 * | |
95 * | SysCfg |
96 * 0 |______________|
97 *
98 */
99
100#define OF_LOADADDR IRAM1_ORIG
101
102/* tone sequences: period (uS), duration (ms), silence (ms) */
103static uint16_t alive[] = { 500,100,0, 0 };
104static uint16_t happy[] = { 1000,100,0, 500,150,0, 0 };
105static uint16_t fatal[] = { 3000,500,500, 3000,500,500, 3000,500,0, 0 };
106#define sad2 (&fatal[3])
107#define sad (&fatal[6])
108
109/* iPod Classic: decrypted hashes for known OFs */
110static unsigned char of_sha[][SIGN_SZ] = {
111 "\x66\x66\x76\xDC\x1D\x32\xB2\x46\xA6\xC9\x7D\x5A\x61\xD3\x49\x4C", /* v1.1.2 */
112 "\x1E\xF0\xD9\xDE\xC2\x7E\xEC\x02\x7C\x15\x76\xBB\x5C\x4F\x2D\x95", /* v2.0.1 */
113 "\x06\x85\xDF\x28\xE4\xD7\xF4\x82\xC0\x73\xB0\x53\x26\xFC\xB0\xFE", /* v2.0.4 */
114 "\x60\x80\x7D\x33\xA8\xDE\xF8\x49\xBB\xBE\x01\x45\xFF\x62\x40\x19" /* v2.0.5 */
115};
116#define N_OF (int)(sizeof(of_sha)/SIGN_SZ)
117
118/* we can assume that unknown FW is a RB bootloader */
119#define FW_RB N_OF
120
121static int identify_fw(struct Im3Info *hinfo)
122{
123 unsigned char hash[SIGN_SZ];
124 int of;
125
126 /* decrypt hash to identify OF */
127 memcpy(hash, hinfo->u.enc12.data_sign, SIGN_SZ);
128 hwkeyaes(HWKEYAES_DECRYPT, HWKEYAES_UKEY, hash, SIGN_SZ);
129
130 for (of = 0; of < N_OF; of++)
131 if (memcmp(hash, of_sha[of], SIGN_SZ) == 0)
132 break;
133
134 return of;
135}
136
137#ifdef DUALBOOT_UNINSTALL
138/* Uninstall RB bootloader */
139void main(void)
140{
141 struct Im3Info *hinfo;
142 void *fw_addr;
143 uint16_t *status;
144 unsigned bl_nor_sz;
145
146 usec_timer_init();
147 piezo_seq(alive);
148 spi_clkdiv(SPI_PORT, 4); /* SPI clock = 27/5 MHz. */
149
150 hinfo = (struct Im3Info*)OF_LOADADDR;
151 fw_addr = (void*)hinfo + IM3HDR_SZ;
152
153 if (im3_read(NORBOOT_OFF, hinfo, NULL) != 0) {
154 status = sad;
155 goto bye; /* no FW found */
156 }
157
158 if (identify_fw(hinfo) != FW_RB) {
159 status = happy;
160 goto bye; /* RB bootloader not installed, nothing to do */
161 }
162
163 /* if found FW is a RB bootloader, OF should start just behind it */
164 bl_nor_sz = im3_nor_sz(hinfo);
165 if ((im3_read(NORBOOT_OFF + bl_nor_sz, hinfo, fw_addr) != 0)
166 || (identify_fw(hinfo) == FW_RB)) {
167 status = sad;
168 goto bye; /* OF not found */
169 }
170
171 /* decrypted OF correctly loaded, encrypt it before restoration */
172 im3_crypt(HWKEYAES_ENCRYPT, hinfo, fw_addr);
173
174 /* restore OF to it's original place */
175 if (!im3_write(NORBOOT_OFF, hinfo)) {
176 status = fatal;
177 goto bye; /* corrupted NOR, use iTunes to restore */
178 }
179
180 /* erase freed NOR blocks */
181 bootflash_init(SPI_PORT);
182 bootflash_erase_blocks(SPI_PORT,
183 (NORBOOT_OFF + im3_nor_sz(hinfo)) >> 12, bl_nor_sz >> 12);
184 bootflash_close(SPI_PORT);
185
186 status = happy;
187
188bye:
189 /* minimum time between the initial and the final beeps */
190 while (USEC_TIMER < 2000000);
191 piezo_seq(status);
192 WDTCON = 0x100000; /* WDT reset */
193 while (1);
194}
195
196#else
197/* Install RB bootloader */
198struct Im3Info bl_hinfo __attribute__((section(".im3info.data"))) =
199{
200 .ident = IM3_IDENT,
201 .version = IM3_VERSION,
202 .enc_type = 2,
203};
204
205static uint32_t get_uint32le(unsigned char *p)
206{
207 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
208}
209
210void main(void)
211{
212 uint16_t *status = happy;
213 int single_boot;
214 struct Im3Info *hinfo;
215 void *fw_addr;
216 unsigned bl_nor_sz;
217
218 usec_timer_init();
219 piezo_seq(alive);
220 spi_clkdiv(SPI_PORT, 4); /* SPI clock = 27/5 MHz. */
221
222 /* check for single boot installation, is is configured when
223 mks5lboot.exe builds the .dfu image */
224 single_boot = bl_hinfo.info_sign[0];
225
226 /* sign RB bootloader (data and header), but don't encrypt it,
227 use current decrypted image for faster load */
228 im3_sign(HWKEYAES_UKEY, (void*)&bl_hinfo + IM3HDR_SZ,
229 get_uint32le(bl_hinfo.data_sz), bl_hinfo.u.enc12.data_sign);
230 im3_sign(HWKEYAES_UKEY, &bl_hinfo, IM3INFOSIGN_SZ, bl_hinfo.info_sign);
231
232 if (single_boot) {
233 if (!im3_write(NORBOOT_OFF, &bl_hinfo))
234 status = sad;
235 goto bye;
236 }
237
238 hinfo = (struct Im3Info*)OF_LOADADDR;
239 fw_addr = (void*)hinfo + IM3HDR_SZ;
240
241 if (im3_read(NORBOOT_OFF, hinfo, fw_addr) != 0) {
242 status = sad;
243 goto bye; /* no FW found */
244 }
245
246 if (identify_fw(hinfo) == FW_RB) {
247 /* FW found, but not OF, assume it is a RB bootloader,
248 already decrypted OF should be located just behind */
249 int nor_offset = NORBOOT_OFF + im3_nor_sz(hinfo);
250 if ((im3_read(nor_offset, hinfo, fw_addr) != 0)
251 || (identify_fw(hinfo) == FW_RB)) {
252 status = sad;
253 goto bye; /* OF not found, use iTunes to restore */
254 }
255 }
256
257 bl_nor_sz = im3_nor_sz(&bl_hinfo);
258 /* safety check - verify we are not going to overwrite useful data */
259 if (flsh_get_unused() < bl_nor_sz) {
260 status = sad2;
261 goto bye; /* no space if flash, use iTunes to restore */
262 }
263
264 /* write decrypted OF and RB bootloader, if any of these fails we
265 will try to retore OF to its original place */
266 if (!im3_write(NORBOOT_OFF + bl_nor_sz, hinfo)
267 || !im3_write(NORBOOT_OFF, &bl_hinfo)) {
268 im3_crypt(HWKEYAES_ENCRYPT, hinfo, fw_addr);
269 if (!im3_write(NORBOOT_OFF, hinfo)) {
270 /* corrupted NOR, use iTunes to restore */
271 status = fatal;
272 }
273 else {
274 /* RB bootloader not succesfully intalled, but device
275 was restored and should be working as before */
276 status = sad;
277 }
278 }
279
280bye:
281 /* minimum time between the initial and the final beeps */
282 while (USEC_TIMER < 2000000);
283 piezo_seq(status);
284 WDTCON = 0x100000; /* WDT reset */
285 while (1);
286}
287#endif /* DUALBOOT_UNINSTALL */
diff --git a/utils/mks5lboot/dualboot/dualboot.lds b/utils/mks5lboot/dualboot/dualboot.lds
new file mode 100644
index 0000000000..cb92e2a286
--- /dev/null
+++ b/utils/mks5lboot/dualboot/dualboot.lds
@@ -0,0 +1,59 @@
1#define ASM
2#include "config.h"
3#include "cpu.h"
4#include "mks5lboot.h"
5
6ENTRY(_start)
7OUTPUT_FORMAT(elf32-littlearm)
8OUTPUT_ARCH(arm)
9
10#define BIN_ORIG DFU_LOADADDR + BIN_OFFSET
11#define BIN_SIZE MAX_PAYLOAD
12
13MEMORY
14{
15 IRAM : ORIGIN = BIN_ORIG, LENGTH = BIN_SIZE
16}
17
18SECTIONS
19{
20 .text : {
21 *(.init.text*)
22 *(.text*)
23 *(.icode*)
24 . = ALIGN(4);
25 } > IRAM
26
27 /* include initialized BSS (if any) into DFU image */
28 .bss : {
29 *(.bss*)
30 *(.ibss*)
31 *(COMMON)
32 . = ALIGN(4);
33 } > IRAM
34
35#if 1
36 /* reuse pwnage as stack, 0x30c bytes available */
37 _exception_stack = BIN_ORIG;
38 _supervisor_stack = _exception_stack;
39#else
40 /* include stack into DFU image */
41 .stack : {
42 . += 0x400;
43 _supervisor_stack = .;
44 . += 0x200;
45 _exception_stack = .;
46 } > IRAM
47#endif
48
49 .data : {
50 *(.data*)
51 *(.rodata*)
52 *(.idata*)
53 *(.irodata*)
54 /* place bootloader IM3 header at the end, mkdfu
55 will concatenate the bootloader binary here */
56 . = ALIGN(16);
57 *(.im3info.data*)
58 } > IRAM
59}
diff --git a/utils/mks5lboot/dualboot/init.S b/utils/mks5lboot/dualboot/init.S
new file mode 100644
index 0000000000..bd049515f4
--- /dev/null
+++ b/utils/mks5lboot/dualboot/init.S
@@ -0,0 +1,43 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:
9 *
10 * Copyright © 2009 Michael Sparmann
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22 .section .init.text, "ax", %progbits
23 .global _start
24
25_start:
26 mov r0, #0xD7
27 msr CPSR_c, r0 @ Abort mode, IRQs/FIQs disabled
28 ldr sp, =_exception_stack
29
30 mov r0, #0xDB
31 msr CPSR_c, r0 @ Undefined Instruction mode, IRQs/FIQs disabled
32 ldr sp, =_exception_stack
33
34 mov r0, #0xD3
35 msr CPSR_c, r0 @ Supervisor mode, IRQs/FIQs disabled
36 ldr sp, =_supervisor_stack
37
38 MOV R0, #0x00050000
39 ORR R0, #0x00000078
40 MCR p15, 0, R0, c1, c0, 0 @ Get rid of some CPU "features" likely to cause trouble
41
42 bl main
43 .ltorg
diff --git a/utils/mks5lboot/ipoddfu.c b/utils/mks5lboot/ipoddfu.c
new file mode 100644
index 0000000000..5e2914af4b
--- /dev/null
+++ b/utils/mks5lboot/ipoddfu.c
@@ -0,0 +1,1061 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2015 by Cástor Muñoz
11 *
12 * based on:
13 * ipoddfu_c by user890104
14 * xpwn/pwnmetheus2
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22 * KIND, either express or implied.
23 *
24 ****************************************************************************/
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <unistd.h>
29#include <stdbool.h>
30#include <string.h>
31#ifdef WIN32
32#include <windows.h>
33#include <setupapi.h>
34#endif
35#ifdef USE_LIBUSBAPI
36#include <libusb-1.0/libusb.h>
37#endif
38#ifdef __APPLE__
39#include <CoreFoundation/CoreFoundation.h>
40#include <IOKit/IOCFPlugIn.h>
41#include <IOKit/usb/IOUSBLib.h>
42#endif
43
44#include "mks5lboot.h"
45
46
47#ifdef WIN32
48#define sleep_ms(ms) Sleep(ms)
49#else
50#include <time.h>
51static void sleep_ms(unsigned int ms)
52{
53 struct timespec req;
54 req.tv_sec = ms / 1000;
55 req.tv_nsec = (ms % 1000) * 1000000;
56 nanosleep(&req, NULL);
57}
58#endif
59
60static void put_uint32le(unsigned char* p, uint32_t x)
61{
62 p[0] = x & 0xff;
63 p[1] = (x >> 8) & 0xff;
64 p[2] = (x >> 16) & 0xff;
65 p[3] = (x >> 24) & 0xff;
66}
67
68/*
69 * CRC32 functions
70 * Based on public domain implementation by Finn Yannick Jacobs.
71 *
72 * Written and copyright 1999 by Finn Yannick Jacobs
73 * No rights were reserved to this, so feel free to
74 * manipulate or do with it, what you want or desire :)
75 */
76
77/* crc32table[] built by crc32_init() */
78static uint32_t crc32table[256];
79
80/* Calculate crc32 */
81static uint32_t crc32(void *data, unsigned int len, uint32_t previousCrc32)
82{
83 uint32_t crc = ~previousCrc32;
84 unsigned char *d = (unsigned char*) data;
85 while (len--)
86 crc = (crc >> 8) ^ crc32table[(crc & 0xFF) ^ *d++];
87 return ~crc;
88}
89
90/* Calculate crc32table */
91static void crc32_init()
92{
93 uint32_t poly = 0xEDB88320L;
94 uint32_t crc;
95 int i, j;
96 for (i = 0; i < 256; ++i)
97 {
98 crc = i;
99 for (j = 0; j < 8; ++j)
100 crc = (crc >> 1) ^ ((crc & 1) ? poly : 0);
101 crc32table[i] = crc;
102 }
103}
104
105/* USB */
106#define APPLE_VID 0x05AC
107
108struct pid_info {
109 int pid;
110 int mode; /* 0->DFU, 1->WTF */
111 char *desc;
112};
113
114struct pid_info known_pids[] =
115{
116 /* DFU */
117 { 0x1220, 0, "Nano 2G" },
118 { 0x1223, 0, "Nano 3G / Classic" },
119 { 0x1224, 0, "Shuffle 3G" },
120 { 0x1225, 0, "Nano 4G" },
121 { 0x1231, 0, "Nano 5G" },
122 { 0x1232, 0, "Nano 6G" },
123 { 0x1233, 0, "Shuffle 4G" },
124 { 0x1234, 0, "Nano 7G" },
125 /* WTF */
126 { 0x1240, 1, "Nano 2G" },
127 { 0x1241, 1, "Classic 1G" },
128 { 0x1242, 1, "Nano 3G" },
129 { 0x1243, 1, "Nano 4G" },
130 { 0x1245, 1, "Classic 2G" },
131 { 0x1246, 1, "Nano 5G" },
132 { 0x1247, 1, "Classic 3G" },
133 { 0x1248, 1, "Nano 6G" },
134 { 0x1249, 1, "Nano 7G" },
135 { 0x124a, 1, "Nano 7G" },
136 { 0x1250, 1, "Classic 4G" },
137};
138#define N_KNOWN_PIDS (sizeof(known_pids)/sizeof(struct pid_info))
139
140struct usbControlSetup {
141 uint8_t bmRequestType;
142 uint8_t bRequest;
143 uint16_t wValue;
144 uint16_t wIndex;
145 uint16_t wLength;
146} __attribute__ ((packed));
147#define USB_CS_SZ (sizeof(struct usbControlSetup))
148
149struct usbStatusData {
150 uint8_t bStatus;
151 uint8_t bwPollTimeout0;
152 uint8_t bwPollTimeout1;
153 uint8_t bwPollTimeout2;
154 uint8_t bState;
155 uint8_t iString;
156} __attribute__ ((packed));
157
158
159/*
160 * DFU API
161 */
162#define DFU_PKT_SZ 2048 /* must be pow2 <= wTransferSize (2048) */
163
164/* DFU 1.1 specs */
165typedef enum {
166 appIDLE = 0,
167 appDETACH = 1,
168 dfuIDLE = 2,
169 dfuDNLOAD_SYNC = 3,
170 dfuDNBUSY = 4,
171 dfuDNLOAD_IDLE = 5,
172 dfuMANIFEST_SYNC = 6,
173 dfuMANIFEST = 7,
174 dfuMANIFEST_WAIT_RESET = 8,
175 dfuUPLOAD_IDLE = 9,
176 dfuERROR = 10
177} DFUState;
178
179typedef enum {
180 errNONE = 0,
181 errTARGET = 1,
182 errFILE = 2,
183 errWRITE = 3,
184 errERASE = 4,
185 errCHECK_ERASED = 5,
186 errPROG = 6,
187 errVERIFY = 7,
188 errADDRESS = 8,
189 errNOTDONE = 9,
190 errFIRMWARE = 10,
191 errVENDOR = 11,
192 errUSBR = 12,
193 errPOR = 13,
194 errUNKNOWN = 14,
195 errSTALLEDPKT = 15
196} DFUStatus;
197
198typedef enum {
199 DFU_DETACH = 0,
200 DFU_DNLOAD = 1,
201 DFU_UPLOAD = 2,
202 DFU_GETSTATUS = 3,
203 DFU_CLRSTATUS = 4,
204 DFU_GETSTATE = 5,
205 DFU_ABORT = 6
206} DFURequest;
207
208typedef enum {
209 DFUAPIFail = 0,
210 DFUAPISuccess,
211} dfuAPIResult;
212
213struct dfuDev {
214 struct dfuAPI *api;
215 int found_pid;
216 int detached;
217 char descr[256];
218 dfuAPIResult res;
219 char err[256];
220 /* API private */
221#ifdef WIN32
222 HANDLE fh;
223 HANDLE ph;
224 DWORD ec; /* winapi error code */
225#endif
226#ifdef USE_LIBUSBAPI
227 libusb_context* ctx;
228 libusb_device_handle* devh;
229 int rc; /* libusb return code */
230#endif
231#ifdef __APPLE__
232 IOUSBDeviceInterface** dev;
233 kern_return_t kr;
234#endif
235};
236
237struct dfuAPI {
238 char *name;
239 dfuAPIResult (*open_fn)(struct dfuDev*, int*);
240 dfuAPIResult (*dfureq_fn)(struct dfuDev*, struct usbControlSetup*, void*);
241 dfuAPIResult (*reset_fn)(struct dfuDev*);
242 void (*close_fn)(struct dfuDev*);
243};
244
245
246/*
247 * DFU API low-level (specific) functions
248 */
249static bool dfu_check_id(int vid, int pid, int *pid_list)
250{
251 int *p;
252 if (vid != APPLE_VID)
253 return 0;
254 for (p = pid_list; *p; p++)
255 if (*p == pid)
256 return 1;
257 return 0;
258}
259
260/* adds extra DFU request error info */
261static void dfu_add_reqerrstr(struct dfuDev *dfuh, struct usbControlSetup *cs)
262{
263 snprintf(dfuh->err + strlen(dfuh->err),
264 sizeof(dfuh->err) - strlen(dfuh->err), " (cs=%02x/%d/%d/%d/%d)",
265 cs->bmRequestType, cs->bRequest, cs->wValue, cs->wIndex, cs->wLength);
266}
267
268#ifdef WIN32
269static bool dfu_winapi_chkrc(struct dfuDev *dfuh, char *str, bool success)
270{
271 dfuh->res = (success) ? DFUAPISuccess : DFUAPIFail;
272 if (!success) {
273 dfuh->ec = GetLastError();
274 snprintf(dfuh->err, sizeof(dfuh->err), "%s error %ld", str, dfuh->ec);
275 }
276 return success;
277}
278
279static dfuAPIResult dfu_winapi_request(struct dfuDev *dfuh,
280 struct usbControlSetup* cs, void* data)
281{
282 unsigned char buf[USB_CS_SZ + DFU_PKT_SZ];
283 DWORD rdwr;
284 bool rc;
285
286 memcpy(buf, cs, USB_CS_SZ);
287
288 if (cs->bmRequestType & 0x80)
289 {
290 rc = ReadFile(dfuh->ph, buf, USB_CS_SZ + cs->wLength, &rdwr, NULL);
291 memcpy(data, buf+USB_CS_SZ, cs->wLength);
292 dfu_winapi_chkrc(dfuh, "DFU request failed: ReadFile()", rc);
293 }
294 else
295 {
296 memcpy(buf+USB_CS_SZ, data, cs->wLength);
297 rc = WriteFile(dfuh->ph, buf, USB_CS_SZ + cs->wLength, &rdwr, NULL);
298 dfu_winapi_chkrc(dfuh, "DFU request failed: WriteFile()", rc);
299 }
300 if (!rc)
301 dfu_add_reqerrstr(dfuh, cs);
302
303 return dfuh->res;
304}
305
306static dfuAPIResult dfu_winapi_reset(struct dfuDev *dfuh)
307{
308 DWORD bytesReturned;
309 bool rc = DeviceIoControl(dfuh->fh,
310 0x22000c, NULL, 0, NULL, 0, &bytesReturned, NULL);
311 dfu_winapi_chkrc(dfuh,
312 "Could not reset USB device: DeviceIoControl()", rc);
313 return dfuh->res;
314}
315
316static void dfu_winapi_close(struct dfuDev *dfuh)
317{
318 if (dfuh->fh != INVALID_HANDLE_VALUE) {
319 CloseHandle(dfuh->fh);
320 dfuh->fh = INVALID_HANDLE_VALUE;
321 }
322 if (dfuh->ph != INVALID_HANDLE_VALUE) {
323 CloseHandle(dfuh->ph);
324 dfuh->ph = INVALID_HANDLE_VALUE;
325 }
326}
327
328static const GUID GUID_AAPLDFU =
329 { 0xB8085869L, 0xFEB9, 0x404B, {0x8C, 0xB1, 0x1E, 0x5C, 0x14, 0xFA, 0x8C, 0x54}};
330
331static dfuAPIResult dfu_winapi_open(struct dfuDev *dfuh, int *pid_list)
332{
333 const GUID *guid = &GUID_AAPLDFU;
334 HDEVINFO devinfo = NULL;
335 SP_DEVICE_INTERFACE_DETAIL_DATA_A* details = NULL;
336 SP_DEVICE_INTERFACE_DATA iface;
337 char *path = NULL;
338 DWORD i, size;
339 bool rc;
340
341 dfuh->fh =
342 dfuh->ph = INVALID_HANDLE_VALUE;
343 dfuh->found_pid = 0;
344 dfuh->res = DFUAPISuccess;
345 dfuh->ec = 0;
346
347 /* Get DFU path */
348 devinfo = SetupDiGetClassDevsA(guid, NULL, NULL,
349 DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
350 if (!dfu_winapi_chkrc(dfuh, "SetupDiGetClassDevsA()",
351 (devinfo != INVALID_HANDLE_VALUE)))
352 goto error;
353
354 iface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
355
356 for (i = 0; SetupDiEnumDeviceInterfaces(devinfo, NULL, guid, i, &iface); i++)
357 {
358 int vid, pid;
359
360 SetupDiGetDeviceInterfaceDetailA(devinfo, &iface, NULL, 0, &size, NULL);
361
362 if (details) free(details);
363 details = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(size);
364 details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
365 rc = SetupDiGetDeviceInterfaceDetailA(devinfo, &iface, details, size, NULL, NULL);
366 if (!dfu_winapi_chkrc(dfuh, "SetupDiGetDeviceInterfaceDetailA()", rc))
367 goto error;
368
369 CharUpperA(details->DevicePath);
370 if (sscanf(details->DevicePath, "%*4cUSB#VID_%04x&PID_%04x%*s", &vid, &pid) != 2)
371 continue;
372 if (!dfu_check_id(vid, pid, pid_list))
373 continue;
374
375 if (path) free(path);
376 path = malloc(size - sizeof(DWORD) + 16);
377 memcpy(path, details->DevicePath, size - sizeof(DWORD));
378
379 dfuh->fh = CreateFileA(path, GENERIC_READ|GENERIC_WRITE,
380 FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
381 if (!dfu_winapi_chkrc(dfuh, "CreateFileA(fh)", (dfuh->fh != INVALID_HANDLE_VALUE)))
382 goto error;
383
384 strcat(path, "\\PIPE0");
385 dfuh->ph = CreateFileA(path, GENERIC_READ|GENERIC_WRITE,
386 FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
387 if (!dfu_winapi_chkrc(dfuh, "CreateFileA(ph)", (dfuh->ph != INVALID_HANDLE_VALUE)))
388 goto error;
389
390 /* ok */
391 snprintf(dfuh->descr, sizeof(dfuh->descr), "%s", details->DevicePath);
392 dfuh->found_pid = pid;
393 goto bye;
394 }
395
396 if (!dfu_winapi_chkrc(dfuh, "SetupDiEnumDeviceInterfaces()",
397 (GetLastError() == ERROR_NO_MORE_ITEMS)))
398 goto error;
399
400 /* no devices found */
401
402bye:
403 if (path) free(path);
404 if (details) free(details);
405 if (devinfo) SetupDiDestroyDeviceInfoList(devinfo);
406 return dfuh->res;
407
408error:
409 dfu_winapi_close(dfuh);
410 goto bye;
411}
412#endif /* WIN32 */
413
414#ifdef USE_LIBUSBAPI
415static bool dfu_libusb_chkrc(struct dfuDev *dfuh, char *str)
416{
417 dfuh->res = (dfuh->rc < LIBUSB_SUCCESS) ? DFUAPIFail : DFUAPISuccess;
418 if (dfuh->res == DFUAPIFail)
419 snprintf(dfuh->err, sizeof(dfuh->err),
420 "%s: %s", str, libusb_error_name(dfuh->rc));
421 return (dfuh->res == DFUAPISuccess);
422}
423
424static dfuAPIResult dfu_libusb_request(struct dfuDev *dfuh,
425 struct usbControlSetup *cs, void *data)
426{
427 dfuh->rc = libusb_control_transfer(dfuh->devh, cs->bmRequestType,
428 cs->bRequest, cs->wValue, cs->wIndex, data, cs->wLength, 500);
429 if (!dfu_libusb_chkrc(dfuh, "DFU request failed"))
430 dfu_add_reqerrstr(dfuh, cs);
431 return dfuh->res;
432}
433
434static dfuAPIResult dfu_libusb_reset(struct dfuDev *dfuh)
435{
436 dfuh->rc = libusb_reset_device(dfuh->devh);
437 dfu_libusb_chkrc(dfuh, "Could not reset USB device");
438 return dfuh->res;
439}
440
441static void dfu_libusb_close(struct dfuDev *dfuh)
442{
443 if (dfuh->devh) {
444 libusb_release_interface(dfuh->devh, 0);
445 if (dfuh->detached)
446 libusb_attach_kernel_driver(dfuh->devh, 0);
447 libusb_close(dfuh->devh);
448 dfuh->devh = NULL;
449 }
450 if (dfuh->ctx) {
451 libusb_exit(dfuh->ctx);
452 dfuh->ctx = NULL;
453 }
454}
455
456static dfuAPIResult dfu_libusb_open(struct dfuDev *dfuh, int *pid_list)
457{
458 struct libusb_device_descriptor desc;
459 libusb_device **devs = NULL, *dev;
460 int n_devs, i;
461
462 dfuh->devh = NULL;
463 dfuh->found_pid = 0;
464 dfuh->detached = 0;
465 dfuh->res = DFUAPISuccess;
466
467 dfuh->rc = libusb_init(&(dfuh->ctx));
468 if (!dfu_libusb_chkrc(dfuh, "Could not init USB library")) {
469 dfuh->ctx = NULL; /* invalidate ctx (if any) */
470 goto error;
471 }
472
473 n_devs =
474 dfuh->rc = libusb_get_device_list(dfuh->ctx, &devs);
475 if (!dfu_libusb_chkrc(dfuh, "Could not get USB device list"))
476 goto error;
477
478 for (i = 0; i < n_devs; ++i)
479 {
480 dev = devs[i];
481
482 /* Note: since libusb-1.0.16 (LIBUSB_API_VERSION >= 0x01000102)
483 this function always succeeds. */
484 if (libusb_get_device_descriptor(dev, &desc) != LIBUSB_SUCCESS)
485 continue; /* Unable to get device descriptor */
486
487 if (!dfu_check_id(desc.idVendor, desc.idProduct, pid_list))
488 continue;
489
490 dfuh->rc = libusb_open(dev, &(dfuh->devh));
491 if (!dfu_libusb_chkrc(dfuh, "Could not open USB device"))
492 goto error;
493
494 dfuh->rc = libusb_set_configuration(dfuh->devh, 1);
495 if (!dfu_libusb_chkrc(dfuh, "Could not set USB configuration"))
496 goto error;
497
498 dfuh->rc = libusb_kernel_driver_active(dfuh->devh, 0);
499 if (dfuh->rc != LIBUSB_ERROR_NOT_SUPPORTED) {
500 if (!dfu_libusb_chkrc(dfuh, "Could not get USB driver status"))
501 goto error;
502 if (dfuh->rc == 1) {
503 dfuh->rc = libusb_detach_kernel_driver(dfuh->devh, 0);
504 if (!dfu_libusb_chkrc(dfuh, "Could not detach USB driver"))
505 goto error;
506 dfuh->detached = 1;
507 }
508 }
509
510 dfuh->rc = libusb_claim_interface(dfuh->devh, 0);
511 if (!dfu_libusb_chkrc(dfuh, "Could not claim USB interface"))
512 goto error;
513
514 /* ok */
515 snprintf(dfuh->descr, sizeof(dfuh->descr),
516 "[%04x:%04x] at bus %d, device %d, USB ver. %04x",
517 desc.idVendor, desc.idProduct, libusb_get_bus_number(dev),
518 libusb_get_device_address(dev), desc.bcdUSB);
519 dfuh->found_pid = desc.idProduct;
520 break;
521 }
522
523bye:
524 if (devs)
525 libusb_free_device_list(devs, 1);
526 if (!dfuh->found_pid)
527 dfu_libusb_close(dfuh);
528 return dfuh->res;
529
530error:
531 goto bye;
532}
533#endif /* USE_LIBUSBAPI */
534
535#ifdef __APPLE__
536static bool dfu_iokit_chkrc(struct dfuDev *dfuh, char *str)
537{
538 dfuh->res = (dfuh->kr == kIOReturnSuccess) ? DFUAPISuccess : DFUAPIFail;
539 if (dfuh->res == DFUAPIFail)
540 snprintf(dfuh->err, sizeof(dfuh->err),
541 "%s: error %08x", str, dfuh->kr);
542 return (dfuh->res == DFUAPISuccess);
543}
544
545static dfuAPIResult dfu_iokit_request(struct dfuDev *dfuh,
546 struct usbControlSetup *cs, void *data)
547{
548 IOUSBDevRequest req;
549 req.bmRequestType = cs->bmRequestType;
550 req.bRequest = cs->bRequest;
551 req.wValue = cs->wValue;
552 req.wIndex = cs->wIndex;
553 req.wLength = cs->wLength;
554 req.pData = data;
555
556 dfuh->kr = (*(dfuh->dev))->DeviceRequest(dfuh->dev, &req);
557 if (!dfu_iokit_chkrc(dfuh, "DFU request failed"))
558 dfu_add_reqerrstr(dfuh, cs);
559
560 return dfuh->res;
561}
562
563static dfuAPIResult dfu_iokit_reset(struct dfuDev *dfuh)
564{
565 dfuh->kr = (*(dfuh->dev))->ResetDevice(dfuh->dev);
566#if 0
567 /* On 10.11+ ResetDevice() returns no error but does not perform
568 * any reset, just a kernel log message.
569 * USBDeviceReEnumerate() could be used as a workaround.
570 */
571 dfuh->kr = (*(dfuh->dev))->USBDeviceReEnumerate(dfuh->dev, 0);
572#endif
573 dfu_iokit_chkrc(dfuh, "Could not reset USB device");
574 return dfuh->res;
575}
576
577static void dfu_iokit_close(struct dfuDev *dfuh)
578{
579 if (dfuh->dev) {
580 (*(dfuh->dev))->USBDeviceClose(dfuh->dev);
581 (*(dfuh->dev))->Release(dfuh->dev);
582 dfuh->dev = NULL;
583 }
584}
585
586static dfuAPIResult dfu_iokit_open(struct dfuDev *dfuh, int *pid_list)
587{
588 kern_return_t kr;
589 CFMutableDictionaryRef usb_matching_dict = 0;
590 io_object_t usbDevice;
591 io_iterator_t usb_iterator = IO_OBJECT_NULL;
592 IOCFPlugInInterface **plugInInterface = NULL;
593 IOUSBDeviceInterface **dev = NULL;
594 HRESULT result;
595 SInt32 score;
596 UInt16 vendor;
597 UInt16 product;
598 UInt16 release;
599
600 dfuh->dev = NULL;
601 dfuh->found_pid = 0;
602 dfuh->res = DFUAPISuccess;
603
604 usb_matching_dict = IOServiceMatching(kIOUSBDeviceClassName);
605 dfuh->kr = IOServiceGetMatchingServices(
606 kIOMasterPortDefault, usb_matching_dict, &usb_iterator);
607 if (!dfu_iokit_chkrc(dfuh, "Could not get matching services"))
608 goto error;
609
610 while ((usbDevice = IOIteratorNext(usb_iterator)))
611 {
612 /* Create an intermediate plug-in */
613 kr = IOCreatePlugInInterfaceForService(usbDevice,
614 kIOUSBDeviceUserClientTypeID,
615 kIOCFPlugInInterfaceID,
616 &plugInInterface,
617 &score);
618 IOObjectRelease(usbDevice);
619
620 if ((kIOReturnSuccess != kr) || !plugInInterface)
621 continue; /* Unable to create a plugin */
622
623 /* Now create the device interface */
624 result = (*plugInInterface)->QueryInterface(plugInInterface,
625 CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
626 (LPVOID*)&dev);
627 (*plugInInterface)->Release(plugInInterface);
628
629 if (result || !dev)
630 continue; /* Couldn't create a device interface */
631
632 kr = (*dev)->GetDeviceVendor(dev, &vendor);
633 kr = (*dev)->GetDeviceProduct(dev, &product);
634 kr = (*dev)->GetDeviceReleaseNumber(dev, &release);
635
636 if (!dfu_check_id(vendor, product, pid_list)) {
637 (*dev)->Release(dev);
638 continue;
639 }
640
641 /* Device found, open it */
642 dfuh->kr = (*dev)->USBDeviceOpen(dev);
643 if (!dfu_iokit_chkrc(dfuh, "Could not open USB device")) {
644 (*dev)->Release(dev);
645 goto error;
646 }
647
648 /* ok */
649 dfuh->found_pid = product;
650 dfuh->dev = dev;
651 snprintf(dfuh->descr, sizeof(dfuh->descr),
652 "[%04x:%04x] release: %d", vendor, product, release);
653 break;
654 }
655
656bye:
657 if (usb_iterator != IO_OBJECT_NULL)
658 IOObjectRelease(usb_iterator);
659 return dfuh->res;
660
661error:
662 goto bye;
663}
664#endif /* __APPLE__ */
665
666/* list of suported APIs */
667static struct dfuAPI api_list[] =
668{
669#ifdef WIN32
670 { "winapi",
671 dfu_winapi_open,
672 dfu_winapi_request,
673 dfu_winapi_reset,
674 dfu_winapi_close },
675#endif
676#ifdef USE_LIBUSBAPI
677 { "libusb",
678 dfu_libusb_open,
679 dfu_libusb_request,
680 dfu_libusb_reset,
681 dfu_libusb_close },
682#endif
683#ifdef __APPLE__
684 { "IOKit",
685 dfu_iokit_open,
686 dfu_iokit_request,
687 dfu_iokit_reset,
688 dfu_iokit_close },
689#endif
690};
691#define N_DFU_APIS (sizeof(api_list)/sizeof(struct dfuAPI))
692
693
694/*
695 * DFU API common functions
696 */
697static int DEBUG_DFUREQ = 0;
698
699static dfuAPIResult dfuapi_request(struct dfuDev *dfuh,
700 struct usbControlSetup *cs, void *data)
701{
702 if (!DEBUG_DFUREQ)
703 return dfuh->api->dfureq_fn(dfuh, cs, data);
704
705 /* DEBUG */
706
707 /* previous state */
708 unsigned char ste = 0;
709 struct usbControlSetup css = { 0xA1, DFU_GETSTATE, 0, 0, sizeof(ste) };
710 if (dfuh->api->dfureq_fn(dfuh, &css, &ste) != DFUAPISuccess) {
711 snprintf(dfuh->err + strlen(dfuh->err), sizeof(dfuh->err) -
712 strlen(dfuh->err), " [DEBUG_DFUREQ ERROR: state=%d]", ste);
713 goto error;
714 }
715
716 dfuh->api->dfureq_fn(dfuh, cs, data);
717 fprintf(stderr, "[DEBUG]: REQ: ste=%d, cs=%2x/%d/%d/%d/%d -> %s",
718 ste, cs->bmRequestType, cs->bRequest, cs->wValue,
719 cs->wIndex, cs->wLength,
720 (dfuh->res == DFUAPISuccess) ? "ok" : "ERROR");
721 if (cs->bRequest == DFU_GETSTATE)
722 fprintf(stderr, " (state=%d)", *((unsigned char*)(data)));
723 if (cs->bRequest == DFU_GETSTATUS) {
724 struct usbStatusData *sd = (struct usbStatusData*)data;
725 fprintf(stderr, " (status=%d, polltmo=%d, state=%d)", sd->bStatus,
726 (sd->bwPollTimeout2 << 16) | (sd->bwPollTimeout1 << 8) |
727 (sd->bwPollTimeout0), sd->bState);
728 }
729 fputc('\n', stderr);
730 fflush(stderr);
731
732bye:
733 return dfuh->res;
734error:
735 goto bye;
736}
737
738static dfuAPIResult dfuapi_req_getstatus(struct dfuDev *dfuh,
739 DFUStatus *status, int *poll_tmo /*ms*/,
740 DFUState *state)
741{
742 struct usbStatusData sd = { 0, 0, 0, 0, 0, 0 };
743 struct usbControlSetup cs = { 0xA1, DFU_GETSTATUS, 0, 0, sizeof(sd) };
744 dfuapi_request(dfuh, &cs, &sd);
745 if (status) *status = sd.bStatus;
746 if (state) *state = sd.bState;
747 if (poll_tmo) *poll_tmo = (sd.bwPollTimeout2 << 16) |
748 (sd.bwPollTimeout1 << 8) | (sd.bwPollTimeout0);
749 return dfuh->res;
750}
751
752static dfuAPIResult dfuapi_req_getstate(struct dfuDev *dfuh, DFUState *state)
753{
754 unsigned char sts = 0;
755 struct usbControlSetup cs = { 0xA1, DFU_GETSTATE, 0, 0, sizeof(sts) };
756 dfuapi_request(dfuh, &cs, &sts);
757 if (state) *state = sts;
758 return dfuh->res;
759}
760
761static dfuAPIResult dfuapi_req_dnload(struct dfuDev* dfuh, uint16_t blknum,
762 uint16_t len, unsigned char *data)
763{
764 struct usbControlSetup cs = { 0x21, DFU_DNLOAD, blknum, 0, len };
765 return dfuapi_request(dfuh, &cs, data);
766}
767
768/* not used */
769#if 0
770static dfuAPIResult dfuapi_req_upload(struct dfuDev* dfuh,
771 uint16_t blknum, uint16_t len, unsigned char *data)
772{
773 struct usbControlSetup cs = { 0xA1, DFU_UPLOAD, blknum, 0, len };
774 return dfuapi_request(dfuh, &cs, data);
775}
776
777static dfuAPIResult dfuapi_req_clrstatus(struct dfuDev* dfuh)
778{
779 struct usbControlSetup cs = { 0x21, DFU_CLRSTATUS, 0, 0, 0 };
780 return dfuapi_request(dfuh, &cs, NULL);
781}
782
783static dfuAPIResult dfuapi_req_abort(struct dfuDev* dfuh)
784{
785 struct usbControlSetup cs = { 0x21, DFU_ABORT, 0, 0, 0 };
786 return dfuapi_request(dfuh, &cs, NULL);
787}
788
789/* not implemented on DFU8702 */
790static dfuAPIResult dfuapi_req_detach(struct dfuDev* dfuh, int tmo)
791{
792 struct usbControlSetup cs = { 0x21, DFU_DETACH, tmo, 0, 0 };
793 return dfuapi_request(dfuh, &cs, NULL);
794}
795#endif
796
797static dfuAPIResult dfuapi_reset(struct dfuDev *dfuh)
798{
799 return dfuh->api->reset_fn(dfuh);
800}
801
802static dfuAPIResult dfuapi_send_packet(struct dfuDev* dfuh, uint16_t blknum,
803 uint16_t len, unsigned char *data, DFUStatus *status,
804 int *poll_tmo, DFUState *state, DFUState *pre_state)
805{
806 if (dfuapi_req_dnload(dfuh, blknum, len, data) != DFUAPISuccess)
807 goto error;
808
809 /* device is in dfuDLSYNC state, waiting for a GETSTATUS request
810 * to enter the next state, if she respond with dfuDLBUSY then
811 * we must wait to resend the GETSTATUS request */
812
813 if (dfuapi_req_getstatus(dfuh, status, poll_tmo, state) != DFUAPISuccess)
814 goto error;
815
816 if (*state == dfuDNBUSY) {
817 if (*poll_tmo)
818 sleep_ms(*poll_tmo);
819 if (pre_state)
820 if (dfuapi_req_getstate(dfuh, pre_state) != DFUAPISuccess)
821 goto error;
822 if (dfuapi_req_getstatus(dfuh, status, poll_tmo, state) != DFUAPISuccess)
823 goto error;
824 }
825
826bye:
827 return dfuh->res;
828error:
829 goto bye;
830}
831
832static void dfuapi_set_err(struct dfuDev *dfuh, char *str)
833{
834 dfuh->res = DFUAPIFail;
835 strncpy(dfuh->err, str, sizeof(dfuh->err));
836}
837
838static dfuAPIResult dfuapi_open(struct dfuDev *dfuh, int pid)
839{
840 int pid_l[N_KNOWN_PIDS+1] = { 0 };
841 struct dfuAPI *api;
842 unsigned i, p;
843
844 /* fill pid list */
845 if (pid)
846 pid_l[0] = pid;
847 else
848 for (p = 0; p < N_KNOWN_PIDS; p++)
849 pid_l[p] = known_pids[p].pid;
850
851 for (i = 0; i < N_DFU_APIS; i++)
852 {
853 api = &api_list[i];
854 if (api->open_fn(dfuh, pid_l) != DFUAPISuccess)
855 goto error;
856 if (dfuh->found_pid) {
857 /* ok */
858 dfuh->api = api;
859 printf("[INFO] %s: found %s\n", api->name, dfuh->descr);
860 for (p = 0; p < N_KNOWN_PIDS; p++) {
861 if (known_pids[p].pid == dfuh->found_pid) {
862 printf("[INFO] iPod %s, mode: %s\n", known_pids[p].desc,
863 known_pids[p].mode ? "WTF" : "DFU");
864 break;
865 }
866 }
867 fflush(stdout);
868 goto bye;
869 }
870 printf("[INFO] %s: no DFU devices found\n", api->name);
871 fflush(stdout);
872 }
873
874 /* error */
875 dfuapi_set_err(dfuh, "DFU device not found");
876
877bye:
878 return dfuh->res;
879error:
880 goto bye;
881}
882
883static void dfuapi_destroy(struct dfuDev *dfuh)
884{
885 if (dfuh) {
886 if (dfuh->api)
887 dfuh->api->close_fn(dfuh);
888 free(dfuh);
889 }
890}
891
892static struct dfuDev *dfuapi_create(void)
893{
894 return calloc(sizeof(struct dfuDev), 1);
895}
896
897
898/*
899 * app level functions
900 */
901static int ipoddfu_download_file(struct dfuDev* dfuh,
902 unsigned char *data, unsigned long size)
903{
904 unsigned int blknum, len, remaining;
905 int poll_tmo;
906 DFUStatus status;
907 DFUState state;
908
909 if (dfuapi_req_getstate(dfuh, &state) != DFUAPISuccess)
910 goto error;
911
912 if (state != dfuIDLE) {
913 dfuapi_set_err(dfuh, "Could not start DFU download: not idle");
914 goto error;
915 }
916
917 blknum = 0;
918 remaining = size;
919 while (remaining)
920 {
921 len = (remaining < DFU_PKT_SZ) ? remaining : DFU_PKT_SZ;
922
923 if (dfuapi_send_packet(dfuh, blknum, len, data + blknum*DFU_PKT_SZ,
924 &status, &poll_tmo, &state, NULL) != DFUAPISuccess)
925 goto error;
926
927 if (state != dfuDNLOAD_IDLE) {
928 dfuapi_set_err(dfuh, "DFU download aborted: unexpected state");
929 goto error;
930 }
931
932 remaining -= len;
933 blknum++;
934 }
935
936 /* send ZLP */
937 DFUState pre_state = appIDLE; /* dummy state */
938 if (dfuapi_send_packet(dfuh, blknum, 0, NULL,
939 &status, &poll_tmo, &state, &pre_state) != DFUAPISuccess) {
940 if (pre_state == dfuMANIFEST_SYNC)
941 goto ok; /* pwnaged .dfu file */
942 goto error;
943 }
944
945 if (state != dfuMANIFEST) {
946 if (status == errFIRMWARE)
947 dfuapi_set_err(dfuh, "DFU download failed: corrupt firmware");
948 else
949 dfuapi_set_err(dfuh, "DFU download failed: unexpected state");
950 goto error;
951 }
952
953 /* wait for manifest stage */
954 if (poll_tmo)
955 sleep_ms(poll_tmo);
956
957 if (dfuapi_req_getstatus(dfuh, &status, NULL, &state) != DFUAPISuccess)
958 goto ok; /* 1223 .dfu file */
959
960 /* XXX: next code never tested */
961
962 if (state != dfuMANIFEST_WAIT_RESET) {
963 if (status == errVERIFY)
964 dfuapi_set_err(dfuh, "DFU manifest failed: wrong FW verification");
965 else
966 dfuapi_set_err(dfuh, "DFU manifest failed: unexpected state");
967 goto error;
968 }
969
970 if (dfuapi_reset(dfuh) != DFUAPISuccess)
971 goto error;
972
973ok:
974 return 1;
975error:
976 return 0;
977}
978
979/* exported functions */
980int ipoddfu_send(int pid, unsigned char *data, int size,
981 char* errstr, int errstrsize)
982{
983 struct dfuDev *dfuh;
984 unsigned char *buf;
985 uint32_t checksum;
986 int ret = 1; /* ok */
987
988 dfuh = dfuapi_create();
989
990 buf = malloc(size+4);
991 if (!buf) {
992 dfuapi_set_err(dfuh, "Could not allocate memory for DFU buffer");
993 goto error;
994 }
995
996 if (memcmp(data, IM3_IDENT, 4)) {
997 dfuapi_set_err(dfuh, "Bad DFU image data");
998 goto error;
999 }
1000
1001 crc32_init();
1002 checksum = crc32(data, size, 0);
1003 memcpy(buf, data, size);
1004 put_uint32le(buf+size, ~checksum);
1005
1006 if (dfuapi_open(dfuh, pid) != DFUAPISuccess)
1007 goto error;
1008
1009 if (!ipoddfu_download_file(dfuh, buf, size+4))
1010 goto error;
1011
1012bye:
1013 if (buf) free(buf);
1014 dfuapi_destroy(dfuh);
1015 return ret;
1016
1017error:
1018 ret = 0;
1019 if (errstr)
1020 snprintf(errstr, errstrsize, "[ERR] %s", dfuh->err);
1021 goto bye;
1022}
1023
1024/* search for the DFU device and gets its DFUState */
1025int ipoddfu_scan(int pid, int *state, int reset,
1026 char* errstr, int errstrsize)
1027{
1028 struct dfuDev *dfuh;
1029 int ret = 1; /* ok */
1030
1031 dfuh = dfuapi_create();
1032
1033 if (dfuapi_open(dfuh, pid) != DFUAPISuccess)
1034 goto error;
1035
1036 if (reset)
1037 if (dfuapi_reset(dfuh) != DFUAPISuccess)
1038 goto error;
1039
1040 if (state) {
1041 DFUState sts;
1042 if (dfuapi_req_getstate(dfuh, &sts) != DFUAPISuccess)
1043 goto error;
1044 *state = (int)sts;
1045 }
1046
1047bye:
1048 dfuapi_destroy(dfuh);
1049 return ret;
1050
1051error:
1052 ret = 0;
1053 if (errstr)
1054 snprintf(errstr, errstrsize, "[ERR] %s", dfuh->err);
1055 goto bye;
1056}
1057
1058void ipoddfu_debug(int debug)
1059{
1060 DEBUG_DFUREQ = debug;
1061}
diff --git a/utils/mks5lboot/main.c b/utils/mks5lboot/main.c
new file mode 100644
index 0000000000..31e16eca82
--- /dev/null
+++ b/utils/mks5lboot/main.c
@@ -0,0 +1,296 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2015 by Cástor Muñoz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <unistd.h>
26#include <fcntl.h>
27#include <sys/types.h>
28#include <sys/stat.h>
29
30#include "mks5lboot.h"
31
32/* Win32 compatibility */
33#ifndef O_BINARY
34#define O_BINARY 0
35#endif
36
37#ifdef WIN32
38#include <windows.h>
39#define sleep_ms(ms) Sleep(ms)
40#else
41#include <time.h>
42static void sleep_ms(unsigned int ms)
43{
44 struct timespec req;
45 req.tv_sec = ms / 1000;
46 req.tv_nsec = (ms % 1000) * 1000000;
47 nanosleep(&req, NULL);
48}
49#endif
50
51#define DEFAULT_LOOP_PERIOD 1 /* seconds */
52
53#define _ERR(format, ...) \
54 do { \
55 snprintf(errstr, errstrsize, "[ERR] "format, __VA_ARGS__); \
56 goto error; \
57 } while(0)
58
59static int write_file(char *outfile, unsigned char* buf,
60 int bufsize, char* errstr, int errstrsize)
61{
62 int fd = open(outfile, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0666);
63 if (fd < 0)
64 _ERR("Could not open %s for writing", outfile);
65
66 if (write(fd, buf, bufsize) != bufsize)
67 _ERR("Could not write file %s", outfile);
68
69 return 1;
70
71error:
72 return 0;
73}
74
75static unsigned char *read_file(char *infile, int *bufsize,
76 char* errstr, int errstrsize)
77{
78 unsigned char *buf;
79 int fd;
80 struct stat s;
81
82 fd = open(infile, O_RDONLY|O_BINARY);
83 if (fd < 0)
84 _ERR("Could not open %s for reading", infile);
85
86 if (fstat(fd, &s) < 0)
87 _ERR("Checking size of input file %s", infile);
88
89 *bufsize = s.st_size;
90
91 buf = malloc(*bufsize);
92 if (buf == NULL)
93 _ERR("Could not allocate memory for %s", infile);
94
95 if (read(fd, buf, *bufsize) != *bufsize)
96 _ERR("Could not read file %s", infile);
97
98 return buf;
99
100error:
101 return NULL;
102}
103
104static void usage(void)
105{
106 fprintf(stderr,
107 "Usage:\n"
108 " mks5lboot --bl-inst <bootloader.ipod> [-p <pid>] [--single]\n"
109 " --bl-uninst <platform> [-p <pid>]\n"
110 " --dfuscan [--loop [<sec>]] [-p <pid>]\n"
111 " --dfusend <infile.dfu> [-p <pid>]\n"
112 " --dfureset [--loop [<sec>]] [-p <pid>]\n"
113 " --mkdfu-inst <bootloader.ipod> <outfile.dfu> [--single]\n"
114 " --mkdfu-uninst <platform> <outfile.dfu>\n"
115 " --mkdfu-raw <filename.bin> <outfile.dfu>\n"
116 "\n"
117 "Commands:\n"
118 " --bl-inst Install file <bootloader.ipod> into an iPod device\n"
119 " (same as --mkdfu-inst and --dfusend).\n"
120 " --bl-uninst Remove a bootloader from an iPod device (same as\n"
121 " --mkdfu-uninst and --dfusend).\n"
122 "\n"
123 " --dfuscan scan for DFU USB devices and outputs the status.\n"
124 " --dfusend send DFU image <infile.dfu> to the device.\n"
125 " --dfureset reset DFU USB device bus.\n"
126 "\n"
127 " --mkdfu-inst Build a DFU image containing an installer for\n"
128 " <bootloader.ipod>, save it as <outfile.dfu>.\n"
129 " --mkdfu-uninst Build a DFU image containing an uninstaler for\n"
130 " <platform> devices, save it as <outfile.dfu>.\n"
131 " --mkdfu-raw Build a DFU image containing raw executable\n"
132 " code, save it ass <outfile.dfu>. <infile.bin>\n"
133 " is the code you want to run, it is loaded at\n"
134 " address 0x%08x and executed.\n"
135 "\n"
136 " <bootloader.ipod> is the rockbox bootloader that you want to\n"
137 " install (previously scrambled with tools/scramble utility).\n"
138 "\n"
139 " <platform> is the name of the platform (type of device) for\n"
140 " which the DFU uninstaller will be built. Currently supported\n"
141 " platform names are:\n"
142 " ipod6g: iPod Classic 6G\n"
143 "\n"
144 "Options:\n"
145 " -p, --pid <pid> Use a specific <pid> (Product Id) USB device,\n"
146 " if this option is ommited then it uses the\n"
147 " first USB DFU device found.\n"
148 " -l, --loop <sec> Run the command every <sec> seconds, default\n"
149 " period (<sec> ommited) is %d seconds.\n"
150 " -S, --single Be careful using this option. The bootloader\n"
151 " is installed for single boot, the original\n"
152 " Apple NOR boot is destroyed (if it exists),\n"
153 " and only Rockbox can be used.\n"
154 , DFU_LOADADDR + BIN_OFFSET
155 , DEFAULT_LOOP_PERIOD);
156
157 exit(1);
158}
159
160int main(int argc, char* argv[])
161{
162 char *dfuoutfile = NULL;
163 char *dfuinfile = NULL;
164 char *dfu_arg = NULL;
165 int dfu_type = DFU_NONE;
166 int n_cmds = 0;
167 int scan = 0;
168 int pid = 0;
169 int reset = 0;
170 int loop = 0;
171 int single = 0;
172 char errstr[200];
173 unsigned char *dfubuf;
174 int dfusize;
175
176 fprintf(stderr,
177#if defined(WIN32) && defined(USE_LIBUSBAPI)
178 "mks5lboot Version " VERSION " (libusb)\n"
179#else
180 "mks5lboot Version " VERSION "\n"
181#endif
182 "This is free software; see the source for copying conditions. There is NO\n"
183 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
184 "\n");
185 fflush(stderr);
186
187 while (--argc)
188 {
189 argv++;
190 if (!memcmp(*argv, "--bl", 4)) {
191 if (!strcmp(*argv+4, "-inst")) dfu_type = DFU_INST;
192 else if (!strcmp(*argv+4, "-uninst")) dfu_type = DFU_UNINST;
193 else usage();
194 if (!--argc) usage();
195 dfu_arg = *++argv;
196 n_cmds++;
197 }
198 else if (!memcmp(*argv, "--mkdfu", 7)) {
199 if (!strcmp(*argv+7, "-inst")) dfu_type = DFU_INST;
200 else if (!strcmp(*argv+7, "-uninst")) dfu_type = DFU_UNINST;
201 else if (!strcmp(*argv+7, "-raw")) dfu_type = DFU_RAW;
202 else usage();
203 if (!--argc) usage();
204 dfu_arg = *++argv;
205 if (!--argc) usage();
206 dfuoutfile = *++argv;
207 n_cmds++;
208 }
209 else if (!strcmp(*argv, "--dfusend")) {
210 if (!--argc) usage();
211 dfuinfile = *++argv;
212 n_cmds++;
213 }
214 else if (!strcmp(*argv, "--dfuscan")) {
215 scan = 1;
216 n_cmds++;
217 }
218 else if (!strcmp(*argv, "--dfureset")) {
219 scan = 1;
220 reset = 1;
221 n_cmds++;
222 }
223 else if (!strcmp(*argv, "--pid") || !strcmp(*argv, "-p")) {
224 if (!--argc) usage();
225 if (sscanf(*++argv, "%x", &pid) != 1) usage();
226 }
227 else if (!strcmp(*argv, "--loop") || !strcmp (*argv, "-l")) {
228 if (!(argc-1) || *(argv+1)[0] == '-') {
229 loop = DEFAULT_LOOP_PERIOD;
230 }
231 else {
232 if ((sscanf(*++argv, "%d", &loop) != 1) || !loop) usage();
233 argc--;
234 }
235 }
236 else if (!strcmp(*argv, "--single") || !strcmp(*argv, "-S")) {
237 single = 1;
238 }
239 else if (!strcmp(*argv, "--debug")) {
240 ipoddfu_debug(1);
241 }
242 else
243 usage();
244 }
245
246 if (n_cmds != 1)
247 usage();
248
249 if ((dfu_type == DFU_INST) && single)
250 dfu_type = DFU_INST_SINGLE;
251
252 if (scan) {
253 int cnt = 0;
254 while (1) {
255 int state, res;
256 if (loop) printf("[%d] ", cnt);
257 else printf("[INFO] ");
258 printf("DFU %s:\n", reset ? "reset":"scan");
259 res = ipoddfu_scan(pid, &state, reset, errstr, sizeof(errstr));
260 if (res == 0)
261 printf("%s\n", errstr);
262 else
263 printf("[INFO] DFU device state: %d\n", state);
264 if (!loop)
265 exit(!res);
266 fflush(stdout);
267 sleep_ms(loop*1000);
268 cnt += loop;
269 }
270 }
271
272 if (dfuinfile)
273 dfubuf = read_file(dfuinfile, &dfusize, errstr, sizeof(errstr));
274 else
275 dfubuf = mkdfu(dfu_type, dfu_arg, &dfusize, errstr, sizeof(errstr));
276
277 if (!dfubuf)
278 goto error;
279
280 if (dfuoutfile) {
281 if (write_file(dfuoutfile, dfubuf, dfusize, errstr, sizeof(errstr))) {
282 printf("[INFO] Created file %s (%d bytes)\n", dfuoutfile, dfusize);
283 exit(0);
284 }
285 }
286 else {
287 if (ipoddfu_send(pid, dfubuf, dfusize, errstr, sizeof(errstr))) {
288 printf("[INFO] DFU image sent successfully (%d bytes)\n", dfusize);
289 exit(0);
290 }
291 }
292
293error:
294 printf("%s\n", errstr);
295 exit(1);
296}
diff --git a/utils/mks5lboot/mkdfu.c b/utils/mks5lboot/mkdfu.c
new file mode 100644
index 0000000000..bb1929bffd
--- /dev/null
+++ b/utils/mks5lboot/mkdfu.c
@@ -0,0 +1,318 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2015 by Cástor Muñoz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <stdio.h>
22#include <stdlib.h>
23#include <stdint.h>
24#include <stdbool.h>
25
26#include <sys/types.h>
27#include <sys/stat.h>
28#include <fcntl.h>
29#include <unistd.h>
30#include <string.h>
31
32#include "mks5lboot.h"
33
34/* Header for ARM code binaries */
35#include "dualboot.h"
36
37/* Win32 compatibility */
38#ifndef O_BINARY
39#define O_BINARY 0
40#endif
41
42/*
43 * This code is based on emCORE, adds a couple of improvements thanks to
44 * some extra features in Apple's ROM:
45 * - Generic Im3Info header valid for all payloads. It is done by moving
46 * the certificate to a fixed position (before data), and using a 'magic'
47 * value (0x300) for signature offset.
48 * - Some integer overflows in ROM make it possible to use the free space
49 * available in Im3Hdr, resulting a maximum payload size of:
50 * 128 KiB - 0x50 bytes (IM3INFO_SZ) - 700 bytes (CERT_SIZE).
51 */
52
53const struct ipod_models ipod_identity[] =
54{
55 [MODEL_IPOD6G] = {
56 "Classic 6G", "ipod6g", "ip6g", 71,
57 dualboot_install_ipod6g, sizeof(dualboot_install_ipod6g),
58 dualboot_uninstall_ipod6g, sizeof(dualboot_uninstall_ipod6g) },
59};
60
61struct Im3Info s5l8702hdr =
62{
63 .ident = IM3_IDENT,
64 .version = IM3_VERSION,
65 .enc_type = 3,
66 .u.enc34 = {
67 .sign_off = "\x00\x03\x00\x00",
68 .cert_off = "\x50\xF8\xFF\xFF", /* -0x800 + CERT_OFFSET */
69 .cert_sz = "\xBA\x02\x00\x00", /* CERT_SIZE */
70 },
71 .info_sign = "\xC2\x54\x51\x31\xDC\xC0\x84\xA4"
72 "\x7F\xD1\x45\x08\xE8\xFF\xE8\x1D",
73};
74
75unsigned char s5l8702pwnage[/*CERT_SIZE*/] =
76{
77 "\x30\x82\x00\x7A\x30\x66\x02\x00\x30\x0D\x06\x09\x2A\x86\x48\x86"
78 "\xF7\x0D\x01\x01\x05\x05\x00\x30\x0B\x31\x09\x30\x07\x06\x03\x55"
79 "\x04\x03\x13\x00\x30\x1E\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00"
80 "\x00\x00\x00\x00\x00\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00\x00"
81 "\x00\x00\x00\x00\x30\x0B\x31\x09\x30\x07\x06\x03\x55\x04\x03\x13"
82 "\x00\x30\x19\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01"
83 "\x05\x00\x03\x08\x00\x30\x05\x02\x01\x00\x02\x00\x30\x0D\x06\x09"
84 "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x03\x01\x00\x30\x82"
85 "\x00\x7A\x30\x66\x02\x00\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D"
86 "\x01\x01\x05\x05\x00\x30\x0B\x31\x09\x30\x07\x06\x03\x55\x04\x03"
87 "\x13\x00\x30\x1E\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
88 "\x00\x00\x00\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
89 "\x00\x00\x30\x0B\x31\x09\x30\x07\x06\x03\x55\x04\x03\x13\x00\x30"
90 "\x19\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00"
91 "\x03\x08\x00\x30\x05\x02\x01\x00\x02\x00\x30\x0D\x06\x09\x2A\x86"
92 "\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x03\x01\x00\x30\x82\x01\xBA"
93 "\x30\x50\x02\x00\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01"
94 "\x05\x05\x00\x30\x00\x30\x1E\x17\x0D\x00\x00\x00\x00\x00\x00\x00"
95 "\x00\x00\x00\x00\x00\x00\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00"
96 "\x00\x00\x00\x00\x00\x30\x00\x30\x19\x30\x0D\x06\x09\x2A\x86\x48"
97 "\x86\xF7\x0D\x01\x01\x01\x05\x00\x03\x08\x00\x30\x05\x02\x01\x00"
98 "\x02\x00\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05"
99 "\x00\x03\x82\x01\x55"
100};
101
102static uint32_t get_uint32le(unsigned char* p)
103{
104 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
105}
106
107static uint32_t get_uint32be(unsigned char* p)
108{
109 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
110}
111
112static void put_uint32le(unsigned char* p, uint32_t x)
113{
114 p[0] = x & 0xff;
115 p[1] = (x >> 8) & 0xff;
116 p[2] = (x >> 16) & 0xff;
117 p[3] = (x >> 24) & 0xff;
118}
119
120#define _ERR(format, ...) \
121 do { \
122 snprintf(errstr, errstrsize, "[ERR] "format, __VA_ARGS__); \
123 goto error; \
124 } while(0)
125
126static unsigned char *load_file(char *filename, int *bufsize,
127 const struct ipod_models** model,
128 char* errstr, int errstrsize)
129{
130 int fd, i;
131 struct stat s;
132 unsigned char header[8];
133 unsigned char *buf = NULL;
134 bool is_rbbl = (model);
135
136 fd = open(filename, O_RDONLY|O_BINARY);
137 if (fd < 0)
138 _ERR("Could not open %s for reading", filename);
139
140 if (fstat(fd, &s) < 0)
141 _ERR("Checking filesize of input file %s", filename);
142 *bufsize = s.st_size;
143
144 if (is_rbbl) {
145 /* Read Rockbox header */
146 if (read(fd, header, sizeof(header)) != sizeof(header))
147 _ERR("Could not read file %s", filename);
148 *bufsize -= sizeof(header);
149
150 for (i = 0; i < NUM_MODELS; i++)
151 if (memcmp(ipod_identity[i].rb_model_name, header + 4, 4) == 0)
152 break;
153
154 if (i == NUM_MODELS)
155 _ERR("Model name \"%4.4s\" unknown. "
156 "Is this really a rockbox bootloader?", header + 4);
157
158 *model = &ipod_identity[i];
159 }
160
161 buf = malloc(*bufsize);
162 if (buf == NULL)
163 _ERR("Could not allocate memory for %s", filename);
164
165 if (read(fd, buf, *bufsize) != *bufsize)
166 _ERR("Could not read file %s", filename);
167
168 if (is_rbbl) {
169 /* Check checksum */
170 uint32_t sum = (*model)->rb_model_num;
171 for (i = 0; i < *bufsize; i++) {
172 /* add 8 unsigned bits but keep a 32 bit sum */
173 sum += buf[i];
174 }
175 if (sum != get_uint32be(header))
176 _ERR("Checksum mismatch in %s", filename);
177 }
178
179 close(fd);
180 return buf;
181
182error:
183 if (fd >= 0)
184 close(fd);
185 if (buf)
186 free(buf);
187 return NULL;
188}
189
190unsigned char *mkdfu(int dfu_type, char *dfu_arg, int* dfu_size,
191 char* errstr, int errstrsize)
192{
193 const struct ipod_models *model = NULL;
194 unsigned char *dfu_buf = NULL;
195 unsigned char *f_buf;
196 int f_size;
197 uint32_t padded_bl_size;
198 uint32_t cert_off, cert_sz;
199 off_t cur_off;
200 char *dfu_desc;
201 int i;
202
203 switch (dfu_type)
204 {
205 case DFU_INST:
206 case DFU_INST_SINGLE:
207 f_buf = load_file(dfu_arg, &f_size, &model, errstr, errstrsize);
208 if (f_buf == NULL)
209 goto error;
210 /* IM3 data size should be padded to 16 */
211 padded_bl_size = ((f_size + 0xf) & ~0xf);
212 *dfu_size = BIN_OFFSET + (model->dualboot_install_size +
213 (IM3HDR_SZ - (int)IM3INFO_SZ) + (int)padded_bl_size);
214 dfu_desc = (dfu_type == DFU_INST_SINGLE) ? "BL installer (single)"
215 : "BL installer";
216 break;
217
218 case DFU_UNINST:
219 for (i = 0; i < NUM_MODELS; i++) {
220 if (!strcmp(ipod_identity[i].platform_name, dfu_arg)) {
221 model = &ipod_identity[i];
222 break;
223 }
224 }
225 if (!model)
226 _ERR("Platform name \"%s\" unknown", dfu_arg);
227
228 *dfu_size = BIN_OFFSET + model->dualboot_uninstall_size;
229 dfu_desc = "BL uninstaller";
230 break;
231
232 case DFU_RAW:
233 default:
234 f_buf = load_file(dfu_arg, &f_size, NULL, errstr, errstrsize);
235 if (f_buf == NULL)
236 goto error;
237 /* IM3 data size should be padded to 16 */
238 *dfu_size = BIN_OFFSET + ((f_size + 0xf) & ~0xf);
239 dfu_desc = "raw binary";
240 break;
241 }
242
243 printf("[INFO] Building DFU:\n");
244 printf("[INFO] type: %s\n", dfu_desc);
245 if ((dfu_type == DFU_INST) || (dfu_type == DFU_INST_SINGLE))
246 printf("[INFO] BL size: %d\n", f_size);
247 if (dfu_type == DFU_RAW)
248 printf("[INFO] BIN size: %d\n", f_size);
249 printf("[INFO] DFU size: %d\n", *dfu_size);
250 if (model) {
251 printf("[INFO] model name: %s\n", model->model_name);
252 printf("[INFO] platform: %s\n", model->platform_name);
253 printf("[INFO] RB name: %s\n", model->rb_model_name);
254 printf("[INFO] RB num: %d\n", model->rb_model_num);
255 }
256
257 if (*dfu_size > DFU_MAXSIZE)
258 _ERR("DFU image (%d bytes) too big", *dfu_size);
259
260 dfu_buf = calloc(*dfu_size, 1);
261 if (!dfu_buf)
262 _ERR("Could not allocate %d bytes for DFU image", *dfu_size);
263
264 cert_off = get_uint32le(s5l8702hdr.u.enc34.cert_off);
265 cert_sz = get_uint32le(s5l8702hdr.u.enc34.cert_sz);
266
267 memcpy(dfu_buf, &s5l8702hdr, sizeof(s5l8702hdr));
268
269 cur_off = IM3HDR_SZ + cert_off;
270
271 memcpy(dfu_buf + cur_off, s5l8702pwnage, sizeof(s5l8702pwnage));
272
273 /* set entry point */
274 cur_off += cert_sz - 4;
275 put_uint32le(dfu_buf + cur_off, DFU_LOADADDR + BIN_OFFSET);
276
277 cur_off = BIN_OFFSET;
278
279 switch (dfu_type)
280 {
281 case DFU_INST:
282 case DFU_INST_SINGLE:
283 /* copy the dualboot installer binary */
284 memcpy(dfu_buf + cur_off, model->dualboot_install,
285 model->dualboot_install_size);
286 /* point to the start of the included IM3 header info */
287 cur_off += model->dualboot_install_size - IM3INFO_SZ;
288 /* set bootloader data size */
289 struct Im3Info *bl_info = (struct Im3Info*)(dfu_buf + cur_off);
290 put_uint32le(bl_info->data_sz, padded_bl_size);
291 /* use info_sign to pass params to the dualboot installer */
292 if (dfu_type == DFU_INST_SINGLE)
293 bl_info->info_sign[0] = 0x1;
294 /* add bootloader binary */
295 cur_off += IM3HDR_SZ;
296 memcpy(dfu_buf + cur_off, f_buf, f_size);
297 break;
298
299 case DFU_UNINST:
300 /* copy the dualboot uninstaller binary */
301 memcpy(dfu_buf + cur_off, model->dualboot_uninstall,
302 model->dualboot_uninstall_size);
303 break;
304
305 case DFU_RAW:
306 default:
307 /* add raw binary */
308 memcpy(dfu_buf + cur_off, f_buf, f_size);
309 break;
310 }
311
312 return dfu_buf;
313
314error:
315 if (dfu_buf)
316 free(dfu_buf);
317 return NULL;
318}
diff --git a/utils/mks5lboot/mks5lboot.h b/utils/mks5lboot/mks5lboot.h
new file mode 100644
index 0000000000..084bec61f9
--- /dev/null
+++ b/utils/mks5lboot/mks5lboot.h
@@ -0,0 +1,129 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2015 by Cástor Muñoz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __MK6GBOOT_H__
22#define __MK6GBOOT_H__
23
24/* useful for dualboot.lds */
25#define DFU_LOADADDR 0x22000000
26#define DFU_MAXSIZE 0x20000 /* maximum .dfu file size */
27
28#define CERT_OFFSET 0x50 /* IM3INFO_SZ */
29#define CERT_SIZE 698
30#define BIN_OFFSET (CERT_OFFSET + ((CERT_SIZE + 0x3) & ~ 0x3))
31#define MAX_PAYLOAD (DFU_MAXSIZE - BIN_OFFSET)
32
33#ifndef ASM
34#include <stddef.h>
35#include <stdint.h>
36
37#ifdef __cplusplus
38extern "C" {
39#endif
40
41#define IM3_IDENT "8702"
42#define IM3_VERSION "1.0"
43#define IM3HDR_SZ 0x800
44#define IM3INFO_SZ (sizeof(struct Im3Info))
45#define IM3INFOSIGN_SZ (offsetof(struct Im3Info, info_sign))
46
47#define SIGN_SZ 16
48
49struct Im3Info
50{
51 uint8_t ident[4];
52 uint8_t version[3];
53 uint8_t enc_type;
54 uint8_t entry[4]; /* LE */
55 uint8_t data_sz[4]; /* LE */
56 union {
57 struct {
58 uint8_t data_sign[SIGN_SZ];
59 uint8_t _reserved[32];
60 } enc12;
61 struct {
62 uint8_t sign_off[4]; /* LE */
63 uint8_t cert_off[4]; /* LE */
64 uint8_t cert_sz[4]; /* LE */
65 uint8_t _reserved[36];
66 } enc34;
67 } u;
68 uint8_t info_sign[SIGN_SZ];
69} __attribute__ ((packed));
70
71struct Im3Hdr
72{
73 struct Im3Info info;
74 uint8_t _zero[IM3HDR_SZ - sizeof(struct Im3Info)];
75} __attribute__ ((packed));
76
77
78/* Supported models */
79enum {
80 MODEL_UNKNOWN = -1,
81 MODEL_IPOD6G = 0,
82 /* new models go here */
83
84 NUM_MODELS
85};
86
87struct ipod_models {
88 /* Descriptive name of this model */
89 const char* model_name;
90 /* for bootloader uninstallers */
91 const char* platform_name;
92 /* Model name used in the Rockbox header in ".ipod" files - these match the
93 -add parameter to the "scramble" tool */
94 const char* rb_model_name;
95 /* Model number used to initialise the checksum in the Rockbox header in
96 ".ipod" files - these are the same as MODEL_NUMBER in config-target.h */
97 const int rb_model_num;
98 /* Dualboot functions for this model */
99 const unsigned char* dualboot_install;
100 int dualboot_install_size;
101 const unsigned char* dualboot_uninstall;
102 int dualboot_uninstall_size;
103};
104extern const struct ipod_models ipod_identity[];
105
106
107enum {
108 DFU_NONE = -1,
109 DFU_INST, /* RB installer */
110 DFU_INST_SINGLE, /* RB installer (single) */
111 DFU_UNINST, /* RB uninstaller */
112 DFU_RAW /* raw binary */
113};
114
115unsigned char *mkdfu(int dfu_type, char *dfu_arg, int* dfu_size,
116 char* errstr, int errstrsize);
117
118int ipoddfu_send(int pid, unsigned char *buf, int size,
119 char* errstr, int errstrsize);
120int ipoddfu_scan(int pid, int *state, int reset,
121 char* errstr, int errstrsize);
122void ipoddfu_debug(int debug);
123
124#ifdef __cplusplus
125};
126#endif
127#endif /* ASM */
128
129#endif /* __MK6GBOOT_H__ */
diff --git a/utils/mktccboot/Makefile b/utils/mktccboot/Makefile
new file mode 100644
index 0000000000..4943a8c568
--- /dev/null
+++ b/utils/mktccboot/Makefile
@@ -0,0 +1,28 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10# We use the Telechips code available in the Rockbox tools/ directory
11TOOLSDIR = ../../tools/
12CFLAGS += -O -g -W -Wall -Wshadow -pedantic -I$(TOOLSDIR)
13
14OUTPUT = mktccboot
15
16
17# inputs
18LIBSOURCES := mktccboot.c $(TOOLSDIR)telechips.c
19SOURCES := main.c
20EXTRADEPS :=
21
22include ../libtools.make
23
24# rule for sources from tools dir
25# Rules go _after_ including mkboot.make to have OBJDIR set up correctly.
26# Paths are assumed to end with a /
27telechips.o: $(OBJDIR)telechips.o
28
diff --git a/utils/mktccboot/README b/utils/mktccboot/README
new file mode 100644
index 0000000000..719846f2e8
--- /dev/null
+++ b/utils/mktccboot/README
@@ -0,0 +1,35 @@
1mktccboot
2---------
3
4A tool to inject a bootloader into a Telechips 77X/78X firmware file.
5
6Usage
7-----
8
9mktccboot <firmware file> <boot file> <output file>
10
11<firmware file> is an original Telechips firmware file.
12
13<boot file> is the code you want to execute (a rockbox bootloader), previously
14 scrambled with tools/scramble utility.
15
16<output file> is the resulting firmware file which you'll have to copy on your
17 player. See "Firmware filenames".
18
19Dual-Boot
20---------
21
22The purpose of this program is to provide dual-boot between the original
23firmware and the new (rockbox) firmware.
24
25By default the player will boot into the new firmware.
26
27To boot into the Original Firmware, you need to press the <???> key.
28
29The player will boot into the Original Firmware as well if it is powered up by
30inserting an usb cable.
31
32Hacking
33-------
34
35See comments in mktccboot.c for more information.
diff --git a/utils/mktccboot/main.c b/utils/mktccboot/main.c
new file mode 100644
index 0000000000..4dd5d0c6c4
--- /dev/null
+++ b/utils/mktccboot/main.c
@@ -0,0 +1,133 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Dave Chapman
11 *
12 * Based on mkboot, Copyright (C) 2005 by Linus Nielsen Feltzing
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <unistd.h>
27#include <sys/types.h>
28#include <sys/stat.h>
29#include <fcntl.h>
30#include <inttypes.h>
31#include "mktccboot.h"
32#include "telechips.h"
33
34static void usage(void)
35{
36 printf("Usage: mktccboot <firmware file> <boot file> <output file>\n");
37
38 exit(1);
39}
40
41int main(int argc, char *argv[])
42{
43 char *infile, *bootfile, *outfile;
44 int fdout = -1;
45 int n, of_size, boot_size, patched_size;
46 unsigned char *of_buf;
47 unsigned char *boot_buf = NULL;
48 unsigned char* image = NULL;
49 int ret = 0;
50
51 if(argc < 3) {
52 usage();
53 }
54
55 infile = argv[1];
56 bootfile = argv[2];
57 outfile = argv[3];
58
59 /* Read OF and boot files */
60 of_buf = file_read(infile, &of_size);
61 if (!of_buf)
62 {
63 ret = 1;
64 goto error_exit;
65 }
66
67 /* Validate input file */
68 if (test_firmware_tcc(of_buf, of_size))
69 {
70 printf("[ERR] Unknown OF file used, aborting\n");
71 ret = 2;
72 goto error_exit;
73 }
74
75 boot_buf = file_read(bootfile, &boot_size);
76 if (!boot_buf)
77 {
78 ret = 3;
79 goto error_exit;
80 }
81
82 /* Allocate buffer for patched firmware */
83 image = malloc(of_size + boot_size);
84 if (image == NULL)
85 {
86 printf("[ERR] Could not allocate memory, aborting\n");
87 ret = 4;
88 goto error_exit;
89 }
90
91 /* Create the patched firmware */
92 image = patch_firmware_tcc(of_buf, of_size, boot_buf, boot_size,
93 &patched_size);
94 if (!image)
95 {
96 printf("[ERR] Error creating patched firmware, aborting\n");
97 ret = 5;
98 goto error_exit;
99 }
100
101 fdout = open(outfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
102 if (fdout < 0)
103 {
104 perror(outfile);
105 ret = 6;
106 goto error_exit;
107 }
108
109 n = write(fdout, image, patched_size);
110 if (n != patched_size)
111 {
112 printf("[ERR] Could not write output file %s\n",outfile);
113 ret = 7;
114 goto error_exit;
115 }
116
117error_exit:
118
119 if (fdout >= 0)
120 close(fdout);
121
122 if (of_buf)
123 free(of_buf);
124
125 if (boot_buf)
126 free(boot_buf);
127
128 if (image)
129 free(image);
130
131 return ret;
132}
133
diff --git a/utils/mktccboot/mktccboot.c b/utils/mktccboot/mktccboot.c
new file mode 100644
index 0000000000..4f2c3258db
--- /dev/null
+++ b/utils/mktccboot/mktccboot.c
@@ -0,0 +1,176 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Dave Chapman
11 *
12 * Based on mkboot, Copyright (C) 2005 by Linus Nielsen Feltzing
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <unistd.h>
27#include <sys/types.h>
28#include <sys/stat.h>
29#include <fcntl.h>
30#include <inttypes.h>
31#include "mktccboot.h"
32#include "telechips.h"
33
34/*
35
36Append a Rockbox bootloader to a Telechips original firmware file.
37
38The first instruction in a TCC firmware file is always of the form:
39
40 ldr pc, [pc, #xxx]
41
42where [pc, #xxx] is the entry point of the firmware - e.g. 0x20000020
43
44mktccboot appends the Rockbox bootloader to the end of the original
45firmware image and replaces the contents of [pc, #xxx] with the entry
46point of our bootloader - i.e. the length of the original firmware plus
470x20000000.
48
49It then stores the original entry point from [pc, #xxx] in a fixed
50offset in the Rockbox boootloader, which is used by the bootloader to
51dual-boot.
52
53Finally, mktccboot corrects the length and CRCs in the main firmware
54header, creating a new legal firmware file which can be installed on
55the device.
56
57*/
58
59/* win32 compatibility */
60
61#ifndef O_BINARY
62#define O_BINARY 0
63#endif
64
65static void put_uint32le(uint32_t x, unsigned char* p)
66{
67 p[0] = x & 0xff;
68 p[1] = (x >> 8) & 0xff;
69 p[2] = (x >> 16) & 0xff;
70 p[3] = (x >> 24) & 0xff;
71}
72
73static uint32_t get_uint32le(unsigned char* p)
74{
75 return (p[3] << 24) | (p[2] << 16) | (p[1]<<8) | p[0];
76}
77
78static off_t filesize(int fd) {
79 struct stat buf;
80
81 if (fstat(fd,&buf) < 0) {
82 perror("[ERR] Checking filesize of input file");
83 return -1;
84 } else {
85 return(buf.st_size);
86 }
87}
88
89#define DRAMORIG 0x20000000
90/* Injects a bootloader into a Telechips 77X/78X firmware file */
91unsigned char *patch_firmware_tcc(unsigned char *of_buf, int of_size,
92 unsigned char *boot_buf, int boot_size, int *patched_size)
93{
94 unsigned char *patched_buf;
95 uint32_t ldr, old_ep_offset, new_ep_offset;
96 int of_offset;
97
98 patched_buf = malloc(of_size + boot_size);
99 if (!patched_buf)
100 return NULL;
101
102 memcpy(patched_buf, of_buf, of_size);
103 memcpy(patched_buf + of_size, boot_buf, boot_size);
104
105 ldr = get_uint32le(patched_buf);
106
107 /* TODO: Verify it's a LDR instruction */
108 of_offset = (ldr & 0xfff) + 8;
109 old_ep_offset = get_uint32le(patched_buf + of_offset);
110 new_ep_offset = DRAMORIG + of_size;
111
112 printf("OF entry point: 0x%08x\n", old_ep_offset);
113 printf("New entry point: 0x%08x\n", new_ep_offset + 8);
114
115 /* Save the OF entry point at the start of the bootloader image */
116 put_uint32le(old_ep_offset, patched_buf + of_size);
117 put_uint32le(new_ep_offset, patched_buf + of_size + 4);
118
119 /* Change the OF entry point to the third word in our bootloader */
120 put_uint32le(new_ep_offset + 8, patched_buf + of_offset);
121
122 telechips_encode_crc(patched_buf, of_size + boot_size);
123 *patched_size = of_size + boot_size;
124
125 return patched_buf;
126}
127
128unsigned char *file_read(char *filename, int *size)
129{
130 unsigned char *buf = NULL;
131 int n, fd = -1;
132
133 /* Open file for reading */
134 fd = open(filename, O_RDONLY|O_BINARY);
135 if (fd < 0)
136 {
137 printf("[ERR] Could open file for reading, aborting\n");
138 perror(filename);
139 goto error;
140 }
141
142 /* Get file size, and allocate a buffer of that size */
143 *size = filesize(fd);
144 buf = malloc(*size);
145 if (buf == NULL)
146 {
147 printf("[ERR] Could not allocate memory, aborting\n");
148 goto error;
149 }
150
151 /* Read the file's content to the buffer */
152 n = read(fd, buf, *size);
153 if (n != *size)
154 {
155 printf("[ERR] Could not read from %s\n", filename);
156 goto error;
157 }
158
159 return buf;
160
161error:
162 if (fd >= 0)
163 close(fd);
164
165 if (buf)
166 free(buf);
167
168 return NULL;
169}
170
171/* A CRC test in order to reject non OF file */
172int test_firmware_tcc(unsigned char* buf, int length)
173{
174 return telechips_test_crc(buf, length);
175}
176
diff --git a/utils/mktccboot/mktccboot.h b/utils/mktccboot/mktccboot.h
new file mode 100644
index 0000000000..17179c11e7
--- /dev/null
+++ b/utils/mktccboot/mktccboot.h
@@ -0,0 +1,50 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * mktccboot.h - a tool to inject a bootloader into a Telechips 77X/78X firmware
11 * file.
12 *
13 * Copyright (C) 2009 Tomer Shalev
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#ifndef _MKTCCBOOT_H_
26#define _MKTCCBOOT_H_
27
28/* win32 compatibility */
29#ifndef O_BINARY
30#define O_BINARY 0
31
32#endif
33#ifdef __cplusplus
34extern "C" {
35#endif
36
37/* Injects a bootloader into a Telechips 77X/78X firmware file */
38unsigned char *patch_firmware_tcc(unsigned char *of_buf, int of_size,
39 unsigned char *boot_buf, int boot_size, int *patched_size);
40
41unsigned char *file_read(char *filename, int *size);
42
43/* Test TCC firmware file for consistency using CRC test */
44int test_firmware_tcc(unsigned char* buf, int length);
45
46#ifdef __cplusplus
47};
48#endif
49
50#endif
diff --git a/utils/mkzenboot/Makefile b/utils/mkzenboot/Makefile
new file mode 100644
index 0000000000..ebc7a1670a
--- /dev/null
+++ b/utils/mkzenboot/Makefile
@@ -0,0 +1,30 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7
8# We use the HMAC-SHA1 code from tools/
9TOOLS_DIR=../../tools/
10CFLAGS += -Wall -I$(TOOLS_DIR)
11CFLAGS += -std=c99 -g
12LDOPTS += -lz
13
14OUTPUT = mkzenboot
15
16# inputs for lib
17TOOLS_SOURCES = hmac-sha1.c
18LIBSOURCES := dualboot.c mkzenboot.c md5.c utils.c \
19 $(addprefix $(TOOLS_DIR),$(TOOLS_SOURCES))
20
21# inputs for binary only
22SOURCES := main.c
23# dependencies for binary
24EXTRADEPS :=
25
26include ../libtools.make
27
28# explicit dependencies on dualboot.{c,h} and mkimxboot.h
29$(OBJDIR)mkzenboot.o: dualboot.h dualboot.c mkzenboot.c mkzenboot.h
30$(OBJDIR)main.o: dualboot.h dualboot.c main.c mkzenboot.h
diff --git a/utils/mkzenboot/dualboot.c b/utils/mkzenboot/dualboot.c
new file mode 100644
index 0000000000..4c98468b3b
--- /dev/null
+++ b/utils/mkzenboot/dualboot.c
@@ -0,0 +1,56 @@
1/* Generated by bin2c */
2
3#include "dualboot.h"
4
5unsigned char dualboot_zenmozaic[168] = {
6 0x10, 0x40, 0x2d, 0xe9, 0x7c, 0x30, 0x9f, 0xe5, 0x00, 0x30, 0x93, 0xe5, 0x78, 0x20, 0x9f, 0xe5,
7 0x00, 0x00, 0x92, 0xe5, 0x74, 0x20, 0x9f, 0xe5, 0x02, 0x11, 0xa0, 0xe3, 0x08, 0x10, 0x82, 0xe5,
8 0x03, 0x11, 0x81, 0xe2, 0x08, 0x10, 0x82, 0xe5, 0xff, 0x14, 0x81, 0xe2, 0x58, 0x10, 0x82, 0xe5,
9 0xc2, 0x14, 0x81, 0xe2, 0x24, 0x10, 0x82, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x18, 0x10, 0x82, 0xe5,
10 0x04, 0x10, 0x82, 0xe5, 0x02, 0x10, 0xa0, 0xe1, 0x10, 0x20, 0x91, 0xe5, 0x01, 0x00, 0x12, 0xe3,
11 0xfc, 0xff, 0xff, 0x0a, 0x34, 0x20, 0x9f, 0xe5, 0x50, 0x20, 0x92, 0xe5, 0xff, 0x24, 0xc2, 0xe3,
12 0x3f, 0x27, 0xc2, 0xe3, 0xa5, 0x2e, 0x42, 0xe2, 0x0a, 0x20, 0x42, 0xe2, 0x63, 0x00, 0x52, 0xe3,
13 0x00, 0x30, 0xa0, 0x93, 0x20, 0x00, 0x83, 0x95, 0x14, 0x20, 0x9f, 0xe5, 0x00, 0x00, 0x92, 0xe5,
14 0x33, 0xff, 0x2f, 0xe1, 0x10, 0x80, 0xbd, 0xe8, 0xa0, 0x00, 0x00, 0x41, 0x9c, 0x00, 0x00, 0x41,
15 0x00, 0x00, 0x05, 0x80, 0xa4, 0x00, 0x00, 0x41, 0xda, 0x00, 0xeb, 0x1c, 0x00, 0x00, 0x00, 0x00,
16 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
17};
18unsigned char dualboot_zenxfi[168] = {
19 0x10, 0x40, 0x2d, 0xe9, 0x7c, 0x30, 0x9f, 0xe5, 0x00, 0x30, 0x93, 0xe5, 0x78, 0x20, 0x9f, 0xe5,
20 0x00, 0x00, 0x92, 0xe5, 0x74, 0x20, 0x9f, 0xe5, 0x02, 0x11, 0xa0, 0xe3, 0x08, 0x10, 0x82, 0xe5,
21 0x03, 0x11, 0x81, 0xe2, 0x08, 0x10, 0x82, 0xe5, 0xff, 0x14, 0x81, 0xe2, 0x58, 0x10, 0x82, 0xe5,
22 0xc2, 0x14, 0x81, 0xe2, 0x24, 0x10, 0x82, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x18, 0x10, 0x82, 0xe5,
23 0x04, 0x10, 0x82, 0xe5, 0x02, 0x10, 0xa0, 0xe1, 0x10, 0x20, 0x91, 0xe5, 0x01, 0x00, 0x12, 0xe3,
24 0xfc, 0xff, 0xff, 0x0a, 0x34, 0x20, 0x9f, 0xe5, 0x50, 0x20, 0x92, 0xe5, 0xff, 0x24, 0xc2, 0xe3,
25 0x3f, 0x27, 0xc2, 0xe3, 0xa5, 0x2e, 0x42, 0xe2, 0x0a, 0x20, 0x42, 0xe2, 0x63, 0x00, 0x52, 0xe3,
26 0x00, 0x30, 0xa0, 0x93, 0x20, 0x00, 0x83, 0x95, 0x14, 0x20, 0x9f, 0xe5, 0x00, 0x00, 0x92, 0xe5,
27 0x33, 0xff, 0x2f, 0xe1, 0x10, 0x80, 0xbd, 0xe8, 0xa0, 0x00, 0x00, 0x41, 0x9c, 0x00, 0x00, 0x41,
28 0x00, 0x00, 0x05, 0x80, 0xa4, 0x00, 0x00, 0x41, 0xda, 0x00, 0xeb, 0x1c, 0x00, 0x00, 0x00, 0x00,
29 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
30};
31unsigned char dualboot_zen[168] = {
32 0x10, 0x40, 0x2d, 0xe9, 0x7c, 0x30, 0x9f, 0xe5, 0x00, 0x30, 0x93, 0xe5, 0x78, 0x20, 0x9f, 0xe5,
33 0x00, 0x00, 0x92, 0xe5, 0x74, 0x20, 0x9f, 0xe5, 0x02, 0x11, 0xa0, 0xe3, 0x08, 0x10, 0x82, 0xe5,
34 0x03, 0x11, 0x81, 0xe2, 0x08, 0x10, 0x82, 0xe5, 0xff, 0x14, 0x81, 0xe2, 0x58, 0x10, 0x82, 0xe5,
35 0xc2, 0x14, 0x81, 0xe2, 0x24, 0x10, 0x82, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x18, 0x10, 0x82, 0xe5,
36 0x04, 0x10, 0x82, 0xe5, 0x02, 0x10, 0xa0, 0xe1, 0x10, 0x20, 0x91, 0xe5, 0x01, 0x00, 0x12, 0xe3,
37 0xfc, 0xff, 0xff, 0x0a, 0x34, 0x20, 0x9f, 0xe5, 0x50, 0x20, 0x92, 0xe5, 0xff, 0x24, 0xc2, 0xe3,
38 0x3f, 0x27, 0xc2, 0xe3, 0xa5, 0x2e, 0x42, 0xe2, 0x0a, 0x20, 0x42, 0xe2, 0x63, 0x00, 0x52, 0xe3,
39 0x00, 0x30, 0xa0, 0x93, 0x20, 0x00, 0x83, 0x95, 0x14, 0x20, 0x9f, 0xe5, 0x00, 0x00, 0x92, 0xe5,
40 0x33, 0xff, 0x2f, 0xe1, 0x10, 0x80, 0xbd, 0xe8, 0xa0, 0x00, 0x00, 0x41, 0x9c, 0x00, 0x00, 0x41,
41 0x00, 0x00, 0x05, 0x80, 0xa4, 0x00, 0x00, 0x41, 0xda, 0x00, 0xeb, 0x1c, 0x00, 0x00, 0x00, 0x00,
42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
43};
44unsigned char dualboot_zenv[168] = {
45 0x10, 0x40, 0x2d, 0xe9, 0x7c, 0x30, 0x9f, 0xe5, 0x00, 0x30, 0x93, 0xe5, 0x78, 0x20, 0x9f, 0xe5,
46 0x00, 0x00, 0x92, 0xe5, 0x74, 0x20, 0x9f, 0xe5, 0x02, 0x11, 0xa0, 0xe3, 0x08, 0x10, 0x82, 0xe5,
47 0x03, 0x11, 0x81, 0xe2, 0x08, 0x10, 0x82, 0xe5, 0xff, 0x14, 0x81, 0xe2, 0x58, 0x10, 0x82, 0xe5,
48 0xc2, 0x14, 0x81, 0xe2, 0x24, 0x10, 0x82, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x18, 0x10, 0x82, 0xe5,
49 0x04, 0x10, 0x82, 0xe5, 0x02, 0x10, 0xa0, 0xe1, 0x10, 0x20, 0x91, 0xe5, 0x01, 0x00, 0x12, 0xe3,
50 0xfc, 0xff, 0xff, 0x0a, 0x34, 0x20, 0x9f, 0xe5, 0x50, 0x20, 0x92, 0xe5, 0xff, 0x24, 0xc2, 0xe3,
51 0x3f, 0x27, 0xc2, 0xe3, 0xa5, 0x2e, 0x42, 0xe2, 0x0a, 0x20, 0x42, 0xe2, 0x63, 0x00, 0x52, 0xe3,
52 0x00, 0x30, 0xa0, 0x93, 0x20, 0x00, 0x83, 0x95, 0x14, 0x20, 0x9f, 0xe5, 0x00, 0x00, 0x92, 0xe5,
53 0x33, 0xff, 0x2f, 0xe1, 0x10, 0x80, 0xbd, 0xe8, 0xa0, 0x00, 0x00, 0x61, 0x9c, 0x00, 0x00, 0x61,
54 0x00, 0x00, 0x05, 0x80, 0xa4, 0x00, 0x00, 0x61, 0xda, 0x00, 0xeb, 0x1c, 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
56};
diff --git a/utils/mkzenboot/dualboot.h b/utils/mkzenboot/dualboot.h
new file mode 100644
index 0000000000..2497d2900c
--- /dev/null
+++ b/utils/mkzenboot/dualboot.h
@@ -0,0 +1,6 @@
1/* Generated by bin2c */
2
3extern unsigned char dualboot_zenmozaic[168];
4extern unsigned char dualboot_zenxfi[168];
5extern unsigned char dualboot_zen[168];
6extern unsigned char dualboot_zenv[168];
diff --git a/utils/mkzenboot/dualboot/Makefile b/utils/mkzenboot/dualboot/Makefile
new file mode 100644
index 0000000000..752cc3ca28
--- /dev/null
+++ b/utils/mkzenboot/dualboot/Makefile
@@ -0,0 +1,51 @@
1CC=gcc
2LD=ld
3OC=objcopy
4CROSS_PREFIX=arm-elf-eabi-
5REGS_PATH=../../../firmware/target/arm/imx233/regs
6CFLAGS=-mcpu=arm926ej-s -std=gnu99 -I. -I$(REGS_PATH) -nostdlib -ffreestanding -fomit-frame-pointer -O
7LDFLAGS=
8# Edit the following variables when adding a new target.
9# mkimxboot.c also needs to be edited to refer to these
10# To add a new target x you need to:
11# 1) add x to the list in TARGETS
12# 2) create a variable named OPT_x of the form:
13# OPT_x=target specific defines
14TARGETS=zenmozaic zenxfi zen zenv
15OPT_zenmozaic=-DCREATIVE_ZENMOZAIC -DIMX233_SUBTARGET=3700
16OPT_zenxfi=-DCREATIVE_ZENXFI -DIMX233_SUBTARGET=3700
17OPT_zen=-DCREATIVE_ZEN -DIMX233_SUBTARGET=3700
18OPT_zenv=-DCREATIVE_ZENV -DIMX233_SUBTARGET=3600
19
20BOOTLDS=$(patsubst %, dualboot_%.lds, $(TARGETS))
21BOOTOBJS=$(patsubst %, dualboot_%.o, $(TARGETS))
22BOOTBINS=$(patsubst %, dualboot_%.arm-bin, $(TARGETS))
23BOOTELFS=$(patsubst %, dualboot_%.arm-elf, $(TARGETS))
24
25all: ../dualboot.h ../dualboot.c $(BOOTELFS)
26
27# Dualboot bootloaders
28
29dualboot_%.o: dualboot.c
30 $(CROSS_PREFIX)$(CC) $(CFLAGS) $(OPT_$(@:dualboot_%.o=%)) -c -o $@ $^
31
32dualboot_%.lds: dualboot.lds
33 $(CROSS_PREFIX)$(CC) $(CFLAGS) $(OPT_$(@:dualboot_%.lds=%)) -E -x c - < $< | sed '/#/d' > $@
34
35dualboot_%.arm-elf: dualboot_%.o dualboot_%.lds
36 $(CROSS_PREFIX)$(LD) $(LDFLAGS) -T$(@:dualboot_%.arm-elf=dualboot_%.lds) -o $@ $<
37
38# Rules for the ARM code embedded in mkamsboot - assemble, link, then extract
39# the binary code and finally convert to .h for building in mkamsboot
40
41%.arm-bin: %.arm-elf
42 $(CROSS_PREFIX)$(OC) -O binary $< $@
43
44../dualboot.c ../dualboot.h: $(BOOTBINS) bin2c
45 ./bin2c ../dualboot $(BOOTBINS)
46
47bin2c: bin2c.c
48 $(CC) -o bin2c bin2c.c
49
50clean:
51 rm -f *~ bin2c $(BOOTBINS) $(BOOTOBJS) $(BOOTELFS) $(BOOTLDS)
diff --git a/utils/mkzenboot/dualboot/bin2c.c b/utils/mkzenboot/dualboot/bin2c.c
new file mode 100644
index 0000000000..b02af88a4d
--- /dev/null
+++ b/utils/mkzenboot/dualboot/bin2c.c
@@ -0,0 +1,140 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdio.h>
23#include <string.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <unistd.h>
27#include <fcntl.h>
28#include <stdlib.h>
29#include <libgen.h>
30
31#ifndef O_BINARY
32#define O_BINARY 0
33#endif
34
35static off_t filesize(int fd)
36{
37 struct stat buf;
38
39 fstat(fd,&buf);
40 return buf.st_size;
41}
42
43static void write_cfile(const unsigned char* buf, off_t len, FILE* fp, const char *name)
44{
45 int i;
46
47 fprintf(fp,"unsigned char %s[%ld] = {",name,len);
48
49 for (i=0;i<len;i++) {
50 if ((i % 16) == 0) {
51 fprintf(fp,"\n ");
52 }
53 if (i == (len-1)) {
54 fprintf(fp,"0x%02x",buf[i]);
55 } else if ((i % 16) == 15) {
56 fprintf(fp,"0x%02x,",buf[i]);
57 } else {
58 fprintf(fp,"0x%02x, ",buf[i]);
59 }
60 }
61 fprintf(fp,"\n};\n");
62}
63
64int main (int argc, char* argv[])
65{
66 char* cname;
67 int i;
68 FILE *cfile, *hfile;
69 char cfilename[256], hfilename[256];
70
71 if (argc < 3) {
72 fprintf(stderr,"Usage: bin2c cname file1 [file2 [file3 ...]]\n");
73 return 1;
74 }
75
76 cname=argv[1];
77
78 snprintf(cfilename,256,"%s.c",cname);
79 cfile = fopen(cfilename,"w+");
80 if (cfile == NULL) {
81 fprintf(stderr,"Couldn't open %s\n",cfilename);
82 return 2;
83 }
84
85 snprintf(hfilename,256,"%s.h",cname);
86 hfile = fopen(hfilename,"w+");
87 if (hfile == NULL) {
88 fprintf(stderr,"Couldn't open %s\n",hfilename);
89 fclose(cfile);
90 return 3;
91 }
92
93 fprintf(cfile,"/* Generated by bin2c */\n\n");
94 fprintf(cfile,"#include \"%s\"\n\n", basename(hfilename));
95 fprintf(hfile,"/* Generated by bin2c */\n\n");
96
97 for(i=0; i < argc - 2; i++) {
98 unsigned char* buf;
99 off_t len;
100 off_t orig_len;
101 char *ext;
102 char *array = argv[2+i];
103
104 int fd = open(array,O_RDONLY|O_BINARY);
105 if (fd < 0) {
106 fprintf(stderr,"Can not open %s\n",argv[2+i]);
107 fclose(cfile);
108 fclose(hfile);
109 return 4;
110 }
111
112 orig_len = filesize(fd);
113 /* pad to 32bit */
114 len = (orig_len + 3) & ~3;
115
116 buf = malloc(len);
117 if (read(fd,buf,orig_len) < orig_len) {
118 fprintf(stderr,"Short read, aborting\n");
119 return 5;
120 }
121
122 /* pad to 32bit with zeros */
123 if (len > orig_len)
124 memset(buf+orig_len, 0, len-orig_len);
125
126 /* remove file extension */
127 ext = strchr (array, '.');
128 if (ext != NULL)
129 *ext = '\0';
130 write_cfile (buf, len, cfile, array);
131 fprintf(hfile,"extern unsigned char %s[%ld];\n",array,len);
132
133 close(fd);
134 }
135
136 fclose(cfile);
137 fclose(hfile);
138
139 return 0;
140}
diff --git a/utils/mkzenboot/dualboot/config.h b/utils/mkzenboot/dualboot/config.h
new file mode 100644
index 0000000000..ff59cee710
--- /dev/null
+++ b/utils/mkzenboot/dualboot/config.h
@@ -0,0 +1,22 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2013 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22/** empty, used by register files */
diff --git a/utils/mkzenboot/dualboot/dualboot.c b/utils/mkzenboot/dualboot/dualboot.c
new file mode 100644
index 0000000000..0b32772afb
--- /dev/null
+++ b/utils/mkzenboot/dualboot/dualboot.c
@@ -0,0 +1,136 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2013 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "regs-pinctrl.h"
22#include "regs-power.h"
23#include "regs-lradc.h"
24#include "regs-digctl.h"
25
26typedef unsigned long uint32_t;
27
28// target specific boot decision
29enum boot_t
30{
31 BOOT_STOP, /* power down */
32 BOOT_ROCK, /* boot to Rockbox */
33 BOOT_OF, /* boot to OF */
34};
35
36/**
37 * Helper functions
38 */
39
40static inline int __attribute__((always_inline)) read_gpio(int bank, int pin)
41{
42 return (HW_PINCTRL_DINn(bank) >> pin) & 1;
43}
44
45static inline int __attribute__((always_inline)) read_pswitch(void)
46{
47#if IMX233_SUBTARGET >= 3700
48 return BF_RD(POWER_STS, PSWITCH);
49#else
50 return BF_RD(DIGCTL_STATUS, PSWITCH);
51#endif
52}
53
54/* only works for channels <=7, always divide by 2, never accumulates */
55static inline void __attribute__((always_inline)) setup_lradc(int src)
56{
57 BF_CLR(LRADC_CTRL0, SFTRST);
58 BF_CLR(LRADC_CTRL0, CLKGATE);
59 /* don't bother changing the source, we are early enough at boot so that
60 * channel x is mapped to source x */
61 HW_LRADC_CHn_CLR(src) = BM_OR2(LRADC_CHn, NUM_SAMPLES, ACCUMULATE);
62 BF_SETV(LRADC_CTRL2, DIVIDE_BY_TWO, 1 << src);
63}
64
65#define BP_LRADC_CTRL1_LRADCx_IRQ(x) (x)
66#define BM_LRADC_CTRL1_LRADCx_IRQ(x) (1 << (x))
67
68static inline int __attribute__((always_inline)) read_lradc(int src)
69{
70 BF_CLR(LRADC_CTRL1, LRADCx_IRQ(src));
71 BF_SETV(LRADC_CTRL0, SCHEDULE, 1 << src);
72 while(!BF_RD(LRADC_CTRL1, LRADCx_IRQ(src)));
73 return BF_RDn(LRADC_CHn, src, VALUE);
74}
75
76static inline void __attribute__((noreturn)) power_down()
77{
78 /* power down */
79 HW_POWER_RESET = BM_OR2(POWER_RESET, UNLOCK, PWD);
80 while(1);
81}
82
83/**
84 * Boot decision functions
85 */
86
87#if defined(CREATIVE_ZENMOZAIC) || defined(CREATIVE_ZEN) || defined(CREATIVE_ZENXFI) \
88 || defined(CREATIVE_ZENV)
89static enum boot_t boot_decision()
90{
91 setup_lradc(0); // setup LRADC channel 0 to read keys
92 /* make a decision */
93 /* read keys */
94 int val = read_lradc(0);
95 /* if back is pressed, boot to OF
96 * otherwise boot to RB */
97 if(val >= 2650 && val < 2750) // conveniently, all players use the same value
98 return BOOT_OF;
99 return BOOT_ROCK;
100}
101#else
102#warning You should define a target specific boot decision function
103static int boot_decision()
104{
105 return BOOT_ROCK;
106}
107#endif
108
109static int main(uint32_t rb_addr, uint32_t of_addr)
110{
111 switch(boot_decision())
112 {
113 case BOOT_ROCK:
114 return rb_addr;
115 case BOOT_OF:
116 /* fix back the loading address
117 /* NOTE: see mkzenboot for more details */
118 *(uint32_t *)0x20 = of_addr;
119 return 0;
120 case BOOT_STOP:
121 default:
122 power_down();
123 }
124}
125
126/** Glue for the linker mostly */
127
128extern uint32_t of_vector;
129extern uint32_t rb_vector;
130extern uint32_t boot_arg;
131
132void __attribute__((section(".start"))) start()
133{
134 uint32_t addr = main(rb_vector, of_vector);
135 ((void (*)(uint32_t))addr)(boot_arg);
136}
diff --git a/utils/mkzenboot/dualboot/dualboot.lds b/utils/mkzenboot/dualboot/dualboot.lds
new file mode 100644
index 0000000000..7444a1e427
--- /dev/null
+++ b/utils/mkzenboot/dualboot/dualboot.lds
@@ -0,0 +1,32 @@
1ENTRY(start)
2OUTPUT_FORMAT(elf32-littlearm)
3OUTPUT_ARCH(arm)
4
5MEMORY
6{
7 /* keep this consistent with the address in mkzenboot.c */
8#if IMX233_SUBTARGET == 3700
9 RAM : ORIGIN = 0x41000000, LENGTH = 0x8000
10#elif IMX233_SUBTARGET == 3600
11 RAM : ORIGIN = 0x61000000, LENGTH = 0x8000
12#else
13#error define me
14#endif
15}
16
17SECTIONS
18{
19 .text :
20 {
21 *(.start*)
22 *(.text*)
23 . = ALIGN(4);
24 LONG(0x1ceb00da)
25 of_vector = .;
26 . += 4;
27 rb_vector = .;
28 . += 4;
29 boot_arg = .;
30 . += 4;
31 } > RAM
32}
diff --git a/utils/mkzenboot/main.c b/utils/mkzenboot/main.c
new file mode 100644
index 0000000000..7aef2b76a3
--- /dev/null
+++ b/utils/mkzenboot/main.c
@@ -0,0 +1,123 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2013 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <getopt.h>
23#include <stdlib.h>
24#include <stdio.h>
25#include <string.h>
26#include "mkzenboot.h"
27
28static void usage(void)
29{
30 printf("Usage: mkzenboot [options | file]...\n");
31 printf("Options:\n");
32 printf(" -?/--help Display this message\n");
33 printf(" -i <file> Set input file\n");
34 printf(" -o <file> Set output file\n");
35 printf(" -b <file> Set boot file\n");
36 printf(" -t <type> Set output type\n");
37 printf(" -d/--debug Enable debug output\n");
38 printf("Output types: dualboot, deferred_dualboot, singleboot, recovery\n");
39 printf("By default a dualboot image is built\n");
40 exit(1);
41}
42
43int main(int argc, char *argv[])
44{
45 char *outfile = NULL;
46 char *bootfile = NULL;
47 char *infile = NULL;
48 struct zen_option_t opt;
49 memset(&opt, 0, sizeof(opt));
50
51 if(argc == 1)
52 usage();
53
54 while(1)
55 {
56 static struct option long_options[] =
57 {
58 {"help", no_argument, 0, '?'},
59 {"debug", no_argument, 0, 'd'},
60 {0, 0, 0, 0}
61 };
62
63 int c = getopt_long(argc, argv, "?di:o:b:t:", long_options, NULL);
64 if(c == -1)
65 break;
66 switch(c)
67 {
68 case 'd':
69 opt.debug = true;
70 break;
71 case '?':
72 usage();
73 break;
74 case 'o':
75 outfile = optarg;
76 break;
77 case 'i':
78 infile = optarg;
79 break;
80 case 'b':
81 bootfile = optarg;
82 break;
83 case 't':
84 if(strcmp(optarg, "dualboot") == 0) opt.output = ZEN_DUALBOOT;
85 else if(strcmp(optarg, "mixedboot") == 0) opt.output = ZEN_MIXEDBOOT;
86 else if(strcmp(optarg, "singleboot") == 0) opt.output = ZEN_SINGLEBOOT;
87 else if(strcmp(optarg, "recovery") == 0) opt.output = ZEN_RECOVERY;
88 else
89 {
90 printf("Unknown output type '%s'\n", optarg);
91 return 1;
92 }
93 break;
94 default:
95 abort();
96 }
97 }
98
99 if(!outfile)
100 {
101 printf("You must specify an output file\n");
102 return 1;
103 }
104 if(!bootfile)
105 {
106 printf("You must specify a boot file\n");
107 return 1;
108 }
109 if(!infile)
110 {
111 printf("You must specify an input file\n");
112 return 1;
113 }
114 if(optind != argc)
115 {
116 printf("Extra arguments on command line\n");
117 return 1;
118 }
119
120 enum zen_error_t err = mkzenboot(infile, bootfile, outfile, opt);
121 printf("Result: %d\n", err);
122 return 0;
123}
diff --git a/utils/mkzenboot/md5.c b/utils/mkzenboot/md5.c
new file mode 100644
index 0000000000..530d8df15a
--- /dev/null
+++ b/utils/mkzenboot/md5.c
@@ -0,0 +1,246 @@
1/*
2 * RFC 1321 compliant MD5 implementation
3 *
4 * Copyright (C) 2001-2003 Christophe Devine
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <string.h>
22
23#include "md5.h"
24
25#define GET_UINT32(n,b,i) \
26{ \
27 (n) = ( (uint32) (b)[(i) ] ) \
28 | ( (uint32) (b)[(i) + 1] << 8 ) \
29 | ( (uint32) (b)[(i) + 2] << 16 ) \
30 | ( (uint32) (b)[(i) + 3] << 24 ); \
31}
32
33#define PUT_UINT32(n,b,i) \
34{ \
35 (b)[(i) ] = (uint8) ( (n) ); \
36 (b)[(i) + 1] = (uint8) ( (n) >> 8 ); \
37 (b)[(i) + 2] = (uint8) ( (n) >> 16 ); \
38 (b)[(i) + 3] = (uint8) ( (n) >> 24 ); \
39}
40
41void md5_starts( md5_context *ctx )
42{
43 ctx->total[0] = 0;
44 ctx->total[1] = 0;
45
46 ctx->state[0] = 0x67452301;
47 ctx->state[1] = 0xEFCDAB89;
48 ctx->state[2] = 0x98BADCFE;
49 ctx->state[3] = 0x10325476;
50}
51
52void md5_process( md5_context *ctx, uint8 data[64] )
53{
54 uint32 X[16], A, B, C, D;
55
56 GET_UINT32( X[0], data, 0 );
57 GET_UINT32( X[1], data, 4 );
58 GET_UINT32( X[2], data, 8 );
59 GET_UINT32( X[3], data, 12 );
60 GET_UINT32( X[4], data, 16 );
61 GET_UINT32( X[5], data, 20 );
62 GET_UINT32( X[6], data, 24 );
63 GET_UINT32( X[7], data, 28 );
64 GET_UINT32( X[8], data, 32 );
65 GET_UINT32( X[9], data, 36 );
66 GET_UINT32( X[10], data, 40 );
67 GET_UINT32( X[11], data, 44 );
68 GET_UINT32( X[12], data, 48 );
69 GET_UINT32( X[13], data, 52 );
70 GET_UINT32( X[14], data, 56 );
71 GET_UINT32( X[15], data, 60 );
72
73#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
74
75#define P(a,b,c,d,k,s,t) \
76{ \
77 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
78}
79
80 A = ctx->state[0];
81 B = ctx->state[1];
82 C = ctx->state[2];
83 D = ctx->state[3];
84
85#define F(x,y,z) (z ^ (x & (y ^ z)))
86
87 P( A, B, C, D, 0, 7, 0xD76AA478 );
88 P( D, A, B, C, 1, 12, 0xE8C7B756 );
89 P( C, D, A, B, 2, 17, 0x242070DB );
90 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
91 P( A, B, C, D, 4, 7, 0xF57C0FAF );
92 P( D, A, B, C, 5, 12, 0x4787C62A );
93 P( C, D, A, B, 6, 17, 0xA8304613 );
94 P( B, C, D, A, 7, 22, 0xFD469501 );
95 P( A, B, C, D, 8, 7, 0x698098D8 );
96 P( D, A, B, C, 9, 12, 0x8B44F7AF );
97 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
98 P( B, C, D, A, 11, 22, 0x895CD7BE );
99 P( A, B, C, D, 12, 7, 0x6B901122 );
100 P( D, A, B, C, 13, 12, 0xFD987193 );
101 P( C, D, A, B, 14, 17, 0xA679438E );
102 P( B, C, D, A, 15, 22, 0x49B40821 );
103
104#undef F
105
106#define F(x,y,z) (y ^ (z & (x ^ y)))
107
108 P( A, B, C, D, 1, 5, 0xF61E2562 );
109 P( D, A, B, C, 6, 9, 0xC040B340 );
110 P( C, D, A, B, 11, 14, 0x265E5A51 );
111 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
112 P( A, B, C, D, 5, 5, 0xD62F105D );
113 P( D, A, B, C, 10, 9, 0x02441453 );
114 P( C, D, A, B, 15, 14, 0xD8A1E681 );
115 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
116 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
117 P( D, A, B, C, 14, 9, 0xC33707D6 );
118 P( C, D, A, B, 3, 14, 0xF4D50D87 );
119 P( B, C, D, A, 8, 20, 0x455A14ED );
120 P( A, B, C, D, 13, 5, 0xA9E3E905 );
121 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
122 P( C, D, A, B, 7, 14, 0x676F02D9 );
123 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
124
125#undef F
126
127#define F(x,y,z) (x ^ y ^ z)
128
129 P( A, B, C, D, 5, 4, 0xFFFA3942 );
130 P( D, A, B, C, 8, 11, 0x8771F681 );
131 P( C, D, A, B, 11, 16, 0x6D9D6122 );
132 P( B, C, D, A, 14, 23, 0xFDE5380C );
133 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
134 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
135 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
136 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
137 P( A, B, C, D, 13, 4, 0x289B7EC6 );
138 P( D, A, B, C, 0, 11, 0xEAA127FA );
139 P( C, D, A, B, 3, 16, 0xD4EF3085 );
140 P( B, C, D, A, 6, 23, 0x04881D05 );
141 P( A, B, C, D, 9, 4, 0xD9D4D039 );
142 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
143 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
144 P( B, C, D, A, 2, 23, 0xC4AC5665 );
145
146#undef F
147
148#define F(x,y,z) (y ^ (x | ~z))
149
150 P( A, B, C, D, 0, 6, 0xF4292244 );
151 P( D, A, B, C, 7, 10, 0x432AFF97 );
152 P( C, D, A, B, 14, 15, 0xAB9423A7 );
153 P( B, C, D, A, 5, 21, 0xFC93A039 );
154 P( A, B, C, D, 12, 6, 0x655B59C3 );
155 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
156 P( C, D, A, B, 10, 15, 0xFFEFF47D );
157 P( B, C, D, A, 1, 21, 0x85845DD1 );
158 P( A, B, C, D, 8, 6, 0x6FA87E4F );
159 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
160 P( C, D, A, B, 6, 15, 0xA3014314 );
161 P( B, C, D, A, 13, 21, 0x4E0811A1 );
162 P( A, B, C, D, 4, 6, 0xF7537E82 );
163 P( D, A, B, C, 11, 10, 0xBD3AF235 );
164 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
165 P( B, C, D, A, 9, 21, 0xEB86D391 );
166
167#undef F
168
169 ctx->state[0] += A;
170 ctx->state[1] += B;
171 ctx->state[2] += C;
172 ctx->state[3] += D;
173}
174
175void md5_update( md5_context *ctx, uint8 *input, uint32 length )
176{
177 uint32 left, fill;
178
179 if( ! length ) return;
180
181 left = ctx->total[0] & 0x3F;
182 fill = 64 - left;
183
184 ctx->total[0] += length;
185 ctx->total[0] &= 0xFFFFFFFF;
186
187 if( ctx->total[0] < length )
188 ctx->total[1]++;
189
190 if( left && length >= fill )
191 {
192 memcpy( (void *) (ctx->buffer + left),
193 (void *) input, fill );
194 md5_process( ctx, ctx->buffer );
195 length -= fill;
196 input += fill;
197 left = 0;
198 }
199
200 while( length >= 64 )
201 {
202 md5_process( ctx, input );
203 length -= 64;
204 input += 64;
205 }
206
207 if( length )
208 {
209 memcpy( (void *) (ctx->buffer + left),
210 (void *) input, length );
211 }
212}
213
214static uint8 md5_padding[64] =
215{
216 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
217 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
218 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
219 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
220};
221
222void md5_finish( md5_context *ctx, uint8 digest[16] )
223{
224 uint32 last, padn;
225 uint32 high, low;
226 uint8 msglen[8];
227
228 high = ( ctx->total[0] >> 29 )
229 | ( ctx->total[1] << 3 );
230 low = ( ctx->total[0] << 3 );
231
232 PUT_UINT32( low, msglen, 0 );
233 PUT_UINT32( high, msglen, 4 );
234
235 last = ctx->total[0] & 0x3F;
236 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
237
238 md5_update( ctx, md5_padding, padn );
239 md5_update( ctx, msglen, 8 );
240
241 PUT_UINT32( ctx->state[0], digest, 0 );
242 PUT_UINT32( ctx->state[1], digest, 4 );
243 PUT_UINT32( ctx->state[2], digest, 8 );
244 PUT_UINT32( ctx->state[3], digest, 12 );
245}
246
diff --git a/utils/mkzenboot/md5.h b/utils/mkzenboot/md5.h
new file mode 100644
index 0000000000..71fa395548
--- /dev/null
+++ b/utils/mkzenboot/md5.h
@@ -0,0 +1,25 @@
1#ifndef _MD5_H
2#define _MD5_H
3
4#ifndef uint8
5#define uint8 unsigned char
6#endif
7
8#ifndef uint32
9#define uint32 unsigned long int
10#endif
11
12typedef struct
13{
14 uint32 total[2];
15 uint32 state[4];
16 uint8 buffer[64];
17}
18md5_context;
19
20void md5_starts( md5_context *ctx );
21void md5_update( md5_context *ctx, uint8 *input, uint32 length );
22void md5_finish( md5_context *ctx, uint8 digest[16] );
23
24#endif /* md5.h */
25
diff --git a/utils/mkzenboot/mkzenboot.c b/utils/mkzenboot/mkzenboot.c
new file mode 100644
index 0000000000..88d6821759
--- /dev/null
+++ b/utils/mkzenboot/mkzenboot.c
@@ -0,0 +1,697 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Maurus Cuelenaere
11 * Based on zenutils by Rasmus Ry <rasmus.ry{at}gmail.com>
12 * Copyright (C) 2013 by Amaury Pouly
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#include <stdio.h>
24#include <stdlib.h>
25#include <stdarg.h>
26#include <string.h>
27#include "mkzenboot.h"
28#include "utils.h"
29#include "dualboot.h"
30
31/**
32 * Keys used by players
33 */
34static const char null_key_v1[] = "CTL:N0MAD|PDE0.SIGN.";
35static const char null_key_v2[] = "CTL:N0MAD|PDE0.DPMP.";
36static const char null_key_v3[] = "CTL:N0MAD|PDE0.DPFP.";
37static const char null_key_v4[] = "CTL:Z3N07|PDE0.DPMP.";
38
39static const char tl_zvm_key[] = "1sN0TM3D az u~may th1nk*"
40 "Creative Zen Vision:M";
41static const char tl_zvm60_key[] = "1sN0TM3D az u~may th1nk*"
42 "Creative Zen Vision:M (D"
43 "VP-HD0004)";
44static const char tl_zen_key[] = "1sN0TM3D az u~may th1nk*"
45 "Creative ZEN";
46static const char tl_zenxf_key[] = "1sN0TM3D az u~may th1nk*"
47 "Creative ZEN X-Fi";
48static const char tl_zenmo_key[] = "1sN0TM3D az u~may th1nk*"
49 "Creative ZEN Mozaic";
50static const char tl_zv_key[] = "1sN0TM3D az u~may th1nk*"
51 "Creative Zen Vision";
52static const char tl_zvw_key[] = "1sN0TM3D az u~may th1nk*"
53 "Creative ZEN Vision W";
54static const char tl_zm_key[] = "1sN0TM3D az u~may th1nk*"
55 "Creative Zen Micro";
56static const char tl_zmp_key[] = "1sN0TM3D az u~may th1nk*"
57 "Creative Zen MicroPhoto";
58static const char tl_zs_key[] = "1sN0TM3D az u~may th1nk*"
59 "Creative Zen Sleek";
60static const char tl_zsp_key[] = "1sN0TM3D az u~may th1nk*"
61 "Creative Zen Sleek Photo";
62static const char tl_zt_key[] = "1sN0TM3D az u~may th1nk*"
63 "Creative Zen Touch";
64static const char tl_zx_key[] = "1sN0TM3D az u~may th1nk*"
65 "NOMAD Jukebox Zen Xtra";
66static const char tl_zenv_key[] = "1sN0TM3D az u~may th1nk*"
67 "Creative ZEN V";
68static const char tl_zenvp_key[] = "1sN0TM3D az u~may th1nk*"
69 "Creative ZEN V Plus";
70static const char tl_zenvv_key[] = "1sN0TM3D az u~may th1nk*"
71 "Creative ZEN V (Video)";
72
73struct player_info_t
74{
75 const char* name;
76 const char* null_key; /* HMAC-SHA1 key */
77 const char* tl_key; /* BlowFish key */
78 bool big_endian;
79 char *cinf;
80};
81
82static struct player_info_t zen_players[] =
83{
84 {"Zen Vision:M", null_key_v2, tl_zvm_key, false, NULL},
85 {"Zen Vision:M 60GB", null_key_v2, tl_zvm60_key, false, NULL},
86 {"Zen", null_key_v4, tl_zen_key, false, "Creative ZEN"},
87 {"Zen X-Fi", null_key_v4, tl_zenxf_key, false, "Creative ZEN X-Fi"},
88 {"Zen Mozaic", null_key_v4, tl_zenmo_key, false, "Creative ZEN Mozaic"},
89 {"Zen Vision", null_key_v2, tl_zv_key, false, NULL},
90 {"Zen Vision W", null_key_v2, tl_zvw_key, false, NULL},
91 {"Zen Micro", null_key_v1, tl_zm_key, true, NULL},
92 {"Zen MicroPhoto", null_key_v1, tl_zmp_key, true, NULL},
93 {"Zen Sleek", null_key_v1, tl_zs_key, true, NULL},
94 {"Zen SleekPhoto", null_key_v1, tl_zsp_key, true, NULL},
95 {"Zen Touch", null_key_v1, tl_zt_key, true, NULL},
96 {"Zen Xtra", null_key_v1, tl_zx_key, true, NULL},
97 {"Zen V", null_key_v3, tl_zenv_key, false, "Creative ZEN V"},
98 {"Zen V Plus", null_key_v3, tl_zenvp_key, false, NULL},
99 {"Zen V Video", null_key_v3, tl_zenvv_key, false, NULL},
100 {NULL, NULL, NULL, false, NULL}
101};
102
103/**
104 * Information on how to patch firmwares
105 */
106struct zen_model_desc_t
107{
108 /* Descriptive name of this model (must match player in zen_players[]) */
109 const char *model_name;
110 /* Model name used in the Rockbox header in ".zen" files - these match the
111 -add parameter to the "scramble" tool */
112 const char *rb_model_name;
113 /* Model number used to initialise the checksum in the Rockbox header in
114 ".zen" files - these are the same as MODEL_NUMBER in config-target.h */
115 const int rb_model_num;
116 /* Bootloader load address */
117 uint32_t bootloader_addr;
118 /* Dualboot code for this model */
119 const unsigned char *dualboot;
120 /* Size of dualboot functions for this model */
121 int dualboot_size;
122};
123
124/* keep this consistent with the address in dualboot.lds */
125static const struct zen_model_desc_t zen_models[] =
126{
127 [MODEL_UNKNOWN] =
128 {
129 "Unknown", " ", 0, 0, NULL, 0
130 },
131 [MODEL_ZENV] =
132 {
133 "Zen V", "zenv", 92, 0x61000000, dualboot_zenv, sizeof(dualboot_zenv)
134 },
135 [MODEL_ZENXFI] =
136 {
137 "Zen X-Fi", "zxfi", 86, 0x41000000, dualboot_zenxfi, sizeof(dualboot_zenxfi)
138 },
139 [MODEL_ZENMOZAIC] =
140 {
141 "Zen Mozaic", "zmoz", 87, 0x41000000, dualboot_zenmozaic, sizeof(dualboot_zenmozaic)
142 },
143 [MODEL_ZEN] =
144 {
145 "Zen", "zen", 90, 0x41000000, dualboot_zen, sizeof(dualboot_zen)
146 },
147};
148
149/**
150 * MD5 knowledge base
151 */
152
153struct zen_md5sum_t
154{
155 /* Device model */
156 enum zen_model_t model;
157 /* md5sum of the file */
158 char *md5sum;
159 /* Version string */
160 const char *version;
161};
162
163static const struct zen_md5sum_t zen_sums[] =
164{
165 /** Zen Mozaic */
166 {
167 /* Version 1.06.01 */
168 MODEL_ZENMOZAIC, "8441402a8db9f92659b05f05c0abe8fb", "1.06.01"
169 },
170 {
171 /* Version 1.06.01e */
172 MODEL_ZENMOZAIC, "88a856f8273b2bc3fcacf1f067a44aa8", "1.06.01e"
173 },
174 /** Zen X-Fi */
175 {
176 /* Version 1.04.08e */
177 MODEL_ZENXFI, "f07e2e75069289a2aa14c6583bd9643b", "1.04.08e"
178 },
179 {
180 /* Version 1.04.08 */
181 MODEL_ZENXFI, "c3cddf8468d8c8982e93aa9986c5a152", "1.04.08"
182 },
183 /** Zen V */
184 {
185 /* Version 1.32.01e */
186 MODEL_ZENV, "2f6d3e619557583c30132ac87221bc3e", "1.32.01e"
187 },
188 /** Zen */
189 {
190 /* Version 1.21.03e */
191 MODEL_ZEN, "1fe28f587f87ac3c280281db28c42465", "1.21.03e"
192 }
193};
194
195#define NR_ZEN_PLAYERS (sizeof(zen_players) / sizeof(zen_players[0]))
196#define NR_ZEN_SUMS (sizeof(zen_sums) / sizeof(zen_sums[0]))
197#define NR_ZEN_MODELS (sizeof(zen_models) / sizeof(zen_models[0]))
198
199#define MAGIC_ROCK 0x726f636b /* 'rock' */
200#define MAGIC_RECOVERY 0xfee1dead
201#define MAGIC_NORMAL 0xcafebabe
202
203/**
204 * Stolen from various places in our codebase
205 */
206
207/**
208 * EDOC file format
209 */
210struct edoc_header_t
211{
212 char magic[4];
213 uint32_t total_size;
214 uint32_t zero;
215};
216
217struct edoc_section_header_t
218{
219 uint32_t addr;
220 uint32_t size;
221 uint32_t checksum;
222};
223
224uint32_t edoc_checksum(void *buffer, size_t size)
225{
226 uint32_t c = 0;
227 uint32_t *p = buffer;
228 while(size >= 4)
229 {
230 c += *p + (*p >> 16);
231 p++;
232 size -= 4;
233 }
234 if(size != 0)
235 printf("[WARN] EDOC Checksum section size is not a multiple of 4 bytes, result is undefined!\n");
236 return c & 0xffff;
237}
238
239#define errorf(err, ...) do { printf(__VA_ARGS__); return err; } while(0)
240
241/**
242 * How does patching code work
243 * ---------------------------
244 *
245 * All Creative firmwares work the same: they start at 0 and the code sequence at
246 * 0 always contains the vector table with ldr with offsets:
247 * 0: e59ff018 ldr pc, [pc, #24] ; 0x20
248 * 4: e59ff018 ldr pc, [pc, #24] ; 0x24
249 * 8: e59ff018 ldr pc, [pc, #24] ; 0x28
250 * c: e59ff018 ldr pc, [pc, #24] ; 0x2c
251 * 10: e59ff018 ldr pc, [pc, #24] ; 0x30
252 * 14: e59ff018 ldr pc, [pc, #24] ; 0x34
253 * 18: e59ff018 ldr pc, [pc, #24] ; 0x38
254 * 1c: e59ff018 ldr pc, [pc, #24] ; 0x3c
255 * 20: 0000dbd4 .word start
256 * 24: 0000dcac .word undef_instr_handler
257 * 28: 0000dcb0 .word software_int_handler
258 * 2c: 0000dcb4 .word prefetch_abort_handler
259 * 30: 0000dcb8 .word data_abort_handler
260 * 34: 0000dcbc .word reserved_handler
261 * 38: 0000dcc0 .word irq_handler
262 * 3c: 0000dd08 .word fiq_handler
263 *
264 * To build a dual-boot image, we modify the start address to point to some
265 * code we added to the image. Specifically we first add the stub, then
266 * the rockbox image. We also write the old start address to this
267 * stub so that it can either decide to run rockbox or patch back the
268 * start address and jump to 0.
269 * Singleboot and recovery is handled the same way except that both targets use
270 * the same address and we drop the OF, so we create a fake vector table!
271 */
272
273struct dualboot_footer_t
274{
275 uint32_t magic;
276 uint32_t of_addr;
277 uint32_t rb_addr;
278 uint32_t boot_arg;
279} __attribute__((packed));
280
281#define FOOTER_MAGIC 0x1ceb00da
282
283static enum zen_error_t create_fake_image(uint8_t **fw, uint32_t *fw_size)
284{
285 /** We need to create a fake EDOC image, so first a header and one section
286 * header with one data chunk. */
287 /** The fake image is as follows:
288 * 0: e59ff018 ldr pc, [pc, #24] ; 0x20
289 * 4: e59ff018 ldr pc, [pc, #24] ; 0x24
290 * 8: e59ff018 ldr pc, [pc, #24] ; 0x28
291 * c: e59ff018 ldr pc, [pc, #24] ; 0x2c
292 * 10: e59ff018 ldr pc, [pc, #24] ; 0x30
293 * 14: e59ff018 ldr pc, [pc, #24] ; 0x34
294 * 18: e59ff018 ldr pc, [pc, #24] ; 0x38
295 * 1c: e59ff018 ldr pc, [pc, #24] ; 0x3c
296 * 20: 00000040 .word hang
297 * 24: 00000040 .word hang
298 * 28: 00000040 .word hang
299 * 2c: 00000040 .word hang
300 * 30: 00000040 .word hang
301 * 34: 00000040 .word hang
302 * 38: 00000040 .word hang
303 * 3c: 00000040 .word hang
304 * 40 <hang>:
305 * 40: eafffffe b 40 <hang> */
306 *fw_size = sizeof(struct edoc_header_t) + sizeof(struct edoc_section_header_t) + 0x44;
307 *fw = malloc(*fw_size);
308 if(*fw == NULL)
309 errorf(ZEN_ERROR, "[ERR] Allocation failed");
310 struct edoc_header_t *hdr = (void *)*fw;
311 memcpy(hdr->magic, "EDOC", 4);
312 hdr->total_size = *fw_size - sizeof(struct edoc_header_t) + 4;
313 hdr->zero = 0;
314 struct edoc_section_header_t *sec = (void *)(hdr + 1);
315 sec->addr = 0;
316 sec->size = 0x44;
317 uint32_t *p = (void *)(sec + 1);
318 p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = 0xe59ff018;
319 p[8] = p[9] = p[10] = p[11] = p[12] = p[13] = p[14] = p[15] = 0x40;
320 p[16] = 0xeafffffe;
321 sec->checksum = edoc_checksum(p, 0x44);
322 return ZEN_SUCCESS;
323}
324
325static enum zen_error_t patch_firmware(uint8_t **fw, uint32_t *fw_size,
326 void *boot, size_t boot_size, struct zen_option_t opt)
327{
328 /* check if dualboot stub is available */
329 const void *dualboot = zen_models[opt.model].dualboot;
330 int dualboot_size = zen_models[opt.model].dualboot_size;
331 uint32_t dualboot_addr = zen_models[opt.model].bootloader_addr;
332 if(dualboot == NULL)
333 errorf(ZEN_DONT_KNOW_HOW_TO_PATCH, "[ERR] I don't have a dualboot stub for this model\n");
334 /* if not asked to dualboot, drop OF and create a fake image */
335 if(opt.output != ZEN_DUALBOOT)
336 {
337 enum zen_error_t ret = create_fake_image(fw, fw_size);
338 if(ret != ZEN_SUCCESS)
339 return ret;
340 }
341 /* compute final image size: add stub + bootloader in one block as a section */
342 int extra_size = sizeof(struct edoc_section_header_t) + dualboot_size + boot_size;
343 *fw_size += extra_size;
344 *fw = realloc(*fw, *fw_size);
345 if(*fw == NULL)
346 errorf(ZEN_ERROR, "[ERR] Allocation failed");
347 /* sanity check */
348 struct edoc_header_t *hdr = (void *)*fw;
349 if(memcmp(hdr->magic, "EDOC", 4) != 0)
350 errorf(ZEN_FW_INVALID, "[ERR] Firmware doesn't use EDOC format\n");
351 /* validate image and find OF start addr */
352 uint32_t of_addr = 0;
353 struct edoc_section_header_t *sec_hdr = (void *)(hdr + 1);
354 while((void *)sec_hdr - (void *)&hdr->zero < hdr->total_size)
355 {
356 if(sec_hdr->checksum != edoc_checksum(sec_hdr + 1, sec_hdr->size))
357 errorf(ZEN_FW_INVALID, "[ERR] Firmware checksum error\n");
358 if(sec_hdr->addr == 0)
359 {
360 uint32_t *start_vector = ((void *)(sec_hdr + 1) + 0x20);
361 /* extract address */
362 of_addr = *(uint32_t *)start_vector;
363 /* patch vector */
364 *start_vector = dualboot_addr;
365 /* fix checksum */
366 sec_hdr->checksum = edoc_checksum(sec_hdr + 1, sec_hdr->size);
367 }
368 sec_hdr = (void *)(sec_hdr + 1) + sec_hdr->size;
369 }
370 if(of_addr == 0)
371 errorf(ZEN_FW_INVALID, "[ERR] Firmware doesn't have the expected format\n");
372 printf("[INFO] OF start address: %#x\n", of_addr);
373 /* add extra section */
374 sec_hdr->addr = dualboot_addr;
375 sec_hdr->size = dualboot_size + boot_size;
376 /* add extra data */
377 memcpy(sec_hdr + 1, dualboot, dualboot_size);
378 memcpy((void *)(sec_hdr + 1) + dualboot_size, boot, boot_size);
379 /* locate and patch dualboot footer */
380 struct dualboot_footer_t *footer = (void *)(sec_hdr + 1) + dualboot_size -
381 sizeof(struct dualboot_footer_t);
382 if(footer->magic != FOOTER_MAGIC)
383 errorf(ZEN_FW_INVALID, "[ERR] Footer magic mismatch\n");
384 uint32_t rb_addr = dualboot_addr + dualboot_size;
385 printf("[INFO] RB start address: %#x\n", rb_addr);
386 footer->of_addr = opt.output == ZEN_DUALBOOT ? of_addr : rb_addr;
387 footer->rb_addr = rb_addr;
388 footer->boot_arg = opt.output == ZEN_RECOVERY ? 0xfee1dead : 0xcafebabe;
389 printf("[INFO] Footer: 0x%08x 0x%08x 0x%08x\n", footer->of_addr, footer->rb_addr,
390 footer->boot_arg);
391 /* fix image */
392 sec_hdr->checksum = edoc_checksum(sec_hdr + 1, sec_hdr->size);
393 hdr->total_size += extra_size;
394 return ZEN_SUCCESS;
395}
396
397struct player_info_t *get_player_info(enum zen_model_t model)
398{
399 for(int i = 0; zen_players[i].name; i++)
400 if(strcmp(zen_models[model].model_name, zen_players[i].name) == 0)
401 return &zen_players[i];
402 return NULL;
403}
404
405enum zen_error_t build_firmware(void *exec, size_t exec_size, void *boot, size_t boot_size,
406 const char *outfile, struct zen_option_t opt)
407{
408 uint8_t *buffer = exec;
409 /** find player info */
410 struct player_info_t *player = get_player_info(opt.model);
411 if(player == NULL)
412 errorf(ZEN_UNSUPPORTED, "[ERR] There is no player info for this model\n");
413 if(player->big_endian)
414 errorf(ZEN_UNSUPPORTED, "[ERR] Big-endian players are currently unsupported\n");
415
416 /** Find Win32 PE .data section */
417 uint32_t data_ptr;
418 uint32_t data_size;
419 enum zen_error_t err = find_pe_data(exec, exec_size, &data_ptr, &data_size);
420 if(err != ZEN_SUCCESS)
421 errorf(err, "[ERR] Cannot find .data section\n");
422 printf("[INFO] .data section is at 0x%x with size 0x%x\n", data_ptr, data_size);
423
424 /** look for firmware and key in data section */
425 uint32_t fw_offset = find_firmware_offset(&buffer[data_ptr], data_size);
426 if(fw_offset == 0)
427 errorf(ZEN_FW_INVALID, "[ERR] Couldn't find firmware offset\n");
428 uint32_t fw_size = le2int(&buffer[data_ptr + fw_offset]);
429 printf("[INFO] Firmware offset is at 0x%x with size 0x%x\n", data_ptr + fw_offset, fw_size);
430 const char *fw_key = find_firmware_key(exec, exec_size);
431 if(fw_key == NULL)
432 errorf(ZEN_FW_INVALID, "[ERR] Couldn't find firmware key\n");
433 printf("[INFO] Firmware key is %s\n", fw_key);
434
435 /** descramble firmware */
436 printf("[INFO] Descrambling firmware... ");
437 if(!crypt_firmware(fw_key, &buffer[data_ptr + fw_offset + 4], fw_size))
438 errorf(ZEN_ERROR, "Fail!\n");
439 else
440 printf("Done!\n");
441 /** decompress it */
442 uint8_t *out_buffer = malloc(fw_size * 2);
443 if(out_buffer == NULL)
444 errorf(ZEN_ERROR, "[ERR] Couldn't allocate memory");
445 memset(out_buffer, 0, fw_size * 2);
446 printf("[INFO] Decompressing firmware... ");
447 char *err_msg;
448 if(!inflate_to_buffer(&buffer[data_ptr + fw_offset + 4], fw_size, out_buffer,
449 fw_size * 2, &err_msg))
450 errorf(ZEN_ERROR, "Fail!\n[ERR] ZLib error: %s\n", err_msg);
451 else
452 printf("Done!\n");
453
454 /** check format and resize the buffer */
455 if(memcmp(out_buffer, "FFIC", 4) != 0)
456 errorf(ZEN_FW_INVALID, "[ERR] CIFF header doesn't match\n");
457 uint32_t ciff_size = le2int(&out_buffer[4]) + 8 + 28; /* CIFF block + NULL block*/
458 printf("[INFO] Total firmware size: %d\n", ciff_size);
459 out_buffer = realloc(out_buffer, ciff_size);
460 if(out_buffer == NULL)
461 errorf(ZEN_ERROR, "[ERR] Cannot resize memory block\n");
462
463 /** look for firmware file */
464 printf("[INFO] Locating encoded block... ");
465 uint32_t fw_off = 8;
466 uint8_t *cinf_ptr = NULL;
467 while(memcmp(&out_buffer[fw_off], " LT\xa9", 4) != 0 && fw_off < ciff_size)
468 {
469 if(memcmp(&out_buffer[fw_off], "FNIC", 4) == 0)
470 {
471 cinf_ptr = &out_buffer[fw_off + 8];
472 fw_off += 4 + 4 + 96;
473 }
474 else if(memcmp(&out_buffer[fw_off], "ATAD", 4) == 0)
475 {
476 fw_off += 4;
477 fw_off += le2int(&out_buffer[fw_off]);
478 fw_off += 4;
479 }
480 else
481 errorf(ZEN_FW_INVALID, "Fail!\n[ERR] Unknown block\n");
482 }
483 if(fw_off >= ciff_size || memcmp(&out_buffer[fw_off], " LT\xa9", 4) != 0)
484 errorf(ZEN_FW_INVALID, "Fail!\n[ERR] Couldn't find encoded block\n");
485 if(!cinf_ptr)
486 errorf(ZEN_FW_INVALID, "Fail!\n[ERR] Couldn't find CINF\n");
487 printf("Done!\n");
488
489 /** validate player if possible */
490 printf("[INFO] Checking player model...");
491 if(player->cinf)
492 {
493 char cinf_ascii[96];
494 for(int j = 0; j < 96; j++)
495 cinf_ascii[j] = *(unsigned short *)&cinf_ptr[2 * j];
496 if(strncmp(cinf_ascii, player->cinf, 96) != 0)
497 errorf(ZEN_FW_MISMATCH, "Fail!\n[ERR] Player mismatch: CINF indicates '%s' instead of '%s'\n",
498 cinf_ascii, player->cinf);
499 else
500 printf("Done!\n");
501 }
502 else
503 printf("Bypass!\n");
504
505 /** decrypt firmware */
506 printf("[INFO] Decrypting encoded block... ");
507 uint32_t iv[2];
508 iv[0] = 0;
509 iv[1] = swap(le2int(&out_buffer[fw_off + 4]));
510 if(!bf_cbc_decrypt((unsigned char*)player->tl_key, strlen(player->tl_key) + 1,
511 &out_buffer[fw_off + 8], le2int(&out_buffer[fw_off + 4]), (const unsigned char*)&iv))
512 errorf(ZEN_ERROR, "Fail!\n[ERR] Couldn't decrypt encoded block\n");
513 printf("Done!\n");
514
515 /** sanity checks on firmware */
516 uint32_t jrm_size = le2int(&out_buffer[fw_off + 8]);
517 if(jrm_size > le2int(&out_buffer[fw_off + 4]) * 3)
518 errorf(ZEN_FW_INVALID, "[ERR] Decrypted length of encoded block is unexpectedly large: 0x%08x\n", jrm_size);
519 printf("[INFO] Firmware size: %d\n", jrm_size);
520 uint8_t *jrm = malloc(jrm_size);
521 if(jrm == NULL)
522 errorf(ZEN_ERROR, "[ERR] Couldn't allocate memory\n");
523 memset(buffer, 0, jrm_size);
524
525 /** decompress firmware */
526 printf("[INFO] Decompressing encoded block... ");
527 if(!cenc_decode(&out_buffer[fw_off + 12], le2int(&out_buffer[fw_off + 4]) - 4, jrm, jrm_size))
528 errorf(ZEN_ERROR, "Fail!\n[ERR] Couldn't decompress the encoded block\n");
529 printf("Done!\n");
530
531 /** Copy OF because patching might modify it */
532 void *jrm_save = malloc(jrm_size);
533 uint32_t jrm_save_size = jrm_size;
534 if(jrm_save == NULL)
535 errorf(ZEN_ERROR, "[ERR] Couldn't allocate memory");
536 memcpy(jrm_save, jrm, jrm_size);
537
538 /** Patch firmware */
539 err = patch_firmware(&jrm, &jrm_size, boot, boot_size, opt);
540 if(err != ZEN_SUCCESS)
541 errorf(err, "[ERR] Couldn't patch firmware\n");
542
543 /** Rebuild archive */
544 bool keep_old_bits = opt.output == ZEN_DUALBOOT || opt.output == ZEN_MIXEDBOOT;
545 bool keep_of = opt.output == ZEN_MIXEDBOOT;
546 /* if we keep old stuff, keep everything up to LT block, otherwise just CIFF header */
547 uint32_t off = keep_old_bits ? fw_off : 8;
548 /* move the rest of the archive if keeping old stuff */
549 if(keep_old_bits)
550 {
551 uint32_t copy_off = fw_off + 8 + le2int(&out_buffer[fw_off + 4]);
552 uint32_t copy_size = ciff_size - fw_off - 8 - le2int(&out_buffer[fw_off + 4]) - 28;
553 memmove(&out_buffer[off], &out_buffer[copy_off], copy_size);
554 off += copy_size;
555 }
556 /* if we keep the OF, put a copy of it after renaming it to Hcreativeos.jrm */
557 if(keep_of)
558 {
559 out_buffer = realloc(out_buffer, off + jrm_save_size + 40);
560 if(out_buffer == NULL)
561 errorf(ZEN_ERROR, "[ERR] Couldn't resize memory block\n");
562 printf("[INFO] Renaming encoded block to Hcreativeos.jrm... ");
563 memcpy(&out_buffer[off], "ATAD", 4);
564 int2le(jrm_save_size + 32, &out_buffer[off + 4]);
565 memset(&out_buffer[off + 8], 0, 32);
566 memcpy(&out_buffer[off + 8], "H\0c\0r\0e\0a\0t\0i\0v\0e\0o\0s\0.\0j\0r\0m", 30);
567 memcpy(&out_buffer[off + 40], jrm_save, jrm_save_size);
568 off += jrm_save_size + 40;
569 printf("Done!\n");
570 }
571 /* put modified firmware */
572 out_buffer = realloc(out_buffer, off + jrm_size + 40);
573 if(out_buffer == NULL)
574 errorf(ZEN_ERROR, "[ERR] Couldn't resize memory block\n");
575 printf("[INFO] Adding Hjukebox2.jrm... ");
576 memcpy(&out_buffer[off], "ATAD", 4);
577 int2le(jrm_size + 32, &out_buffer[off + 4]);
578 memset(&out_buffer[off + 8], 0, 32);
579 memcpy(&out_buffer[off + 8], "H\0j\0u\0k\0e\0b\0o\0x\0""2\0.\0j\0r\0m", 26);
580 memcpy(&out_buffer[off + 40], jrm, jrm_size);
581 off += jrm_size + 40;
582 printf("Done!\n");
583
584 /** fix header */
585 int2le(off - 8, &out_buffer[4]);
586
587 /** update checksum */
588 printf("[INFO] Updating checksum... ");
589 out_buffer = realloc(out_buffer, off + 28);
590 if(out_buffer == NULL)
591 errorf(ZEN_ERROR, "[ERR] Couldn't resize memory block\n");
592 memcpy(&out_buffer[off], "LLUN", 4);
593 int2le(20, &out_buffer[off + 4]);
594 hmac_sha1((unsigned char*)player->null_key, strlen(player->null_key), out_buffer,
595 off, &out_buffer[off + 8]);
596 off += 28;
597 printf("Done!\n");
598
599 err = write_file(outfile, out_buffer, off);
600
601 free(jrm);
602 free(jrm_save);
603 free(out_buffer);
604 return err;
605}
606
607/* find an entry into zen_sums which matches the MD5 sum of a file */
608static enum zen_error_t find_model_by_md5sum(uint8_t file_md5sum[16], int *md5_idx)
609{
610 int i = 0;
611 while(i < NR_ZEN_SUMS)
612 {
613 uint8_t md5[20];
614 if(strlen(zen_sums[i].md5sum) != 32)
615 errorf(ZEN_ERROR, "[ERR][INTERNAL] Invalid MD5 sum in zen_sums\n");
616 for(int j = 0; j < 16; j++)
617 {
618 uint8_t a, b;
619 if(convxdigit(zen_sums[i].md5sum[2 * j], &a) || convxdigit(zen_sums[i].md5sum[2 * j + 1], &b))
620 errorf(ZEN_ERROR, "[ERR][INTERNAL] Bad checksum format: %s\n", zen_sums[i].md5sum);
621 md5[j] = (a << 4) | b;
622 }
623 if(memcmp(file_md5sum, md5, 16) == 0)
624 break;
625 i++;
626 }
627 if(i == NR_ZEN_SUMS)
628 errorf(ZEN_NO_MATCH, "[ERR] MD5 sum doesn't match any known file\n");
629 *md5_idx = i;
630 return ZEN_SUCCESS;
631}
632
633enum zen_error_t mkzenboot(const char *infile, const char *bootfile,
634 const char *outfile, struct zen_option_t opt)
635{
636 /* determine firmware model */
637 void *fw;
638 size_t fw_size;
639 enum zen_error_t err = read_file(infile, &fw, &fw_size);
640 uint8_t file_md5sum[16];
641 err = compute_md5sum_buf(fw, fw_size, file_md5sum);
642 if(err != ZEN_SUCCESS)
643 {
644 free(fw);
645 return err;
646 }
647 printf("[INFO] MD5 sum of the file: ");
648 for(int i = 0; i < 16; i++)
649 printf("%02X ", file_md5sum[i]);
650 printf("\n");
651 if(opt.model == MODEL_UNKNOWN)
652 {
653 int idx;
654 err = find_model_by_md5sum(file_md5sum, &idx);
655 if(err != ZEN_SUCCESS)
656 {
657 free(fw);
658 errorf(err, "[ERR] Cannot determine model type\n");
659 }
660 opt.model = zen_sums[idx].model;
661 printf("[INFO] MD5 matches %s, version %s\n",
662 zen_models[opt.model].model_name, zen_sums[idx].version);
663 }
664 printf("[INFO] Model is: %s\n", zen_models[opt.model].model_name);
665 /* load rockbox file */
666 uint8_t *boot;
667 size_t boot_size;
668 err = read_file(bootfile, (void **)&boot, &boot_size);
669 if(err != ZEN_SUCCESS)
670 {
671 free(fw);
672 errorf(err, "[ERR] Cannot read boot file\n");
673 }
674 /* validate checksum */
675 if(memcmp(boot + 4, zen_models[opt.model].rb_model_name, 4) != 0)
676 {
677 free(fw);
678 free(boot);
679 errorf(ZEN_BOOT_MISMATCH, "[ERR] Boot model mismatch\n");
680 }
681 printf("[INFO] Bootloader file matches model\n");
682 uint32_t sum = zen_models[opt.model].rb_model_num;
683 for(int i = 8; i < boot_size; i++)
684 sum += boot[i];
685 if(sum != be2int(boot))
686 {
687 free(fw);
688 free(boot);
689 errorf(ZEN_BOOT_CHECKSUM_ERROR, "[ERR] Checksum mismatch\n");
690 }
691 printf("[INFO] Bootloader file checksum is correct\n");
692 /* produce file */
693 err = build_firmware(fw, fw_size, boot + 8, boot_size - 8, outfile, opt);
694 free(boot);
695 free(fw);
696 return err;
697}
diff --git a/utils/mkzenboot/mkzenboot.h b/utils/mkzenboot/mkzenboot.h
new file mode 100644
index 0000000000..8da3e25762
--- /dev/null
+++ b/utils/mkzenboot/mkzenboot.h
@@ -0,0 +1,86 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2013 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef MKZENBOOT_H
23#define MKZENBOOT_H
24
25#include <stdbool.h>
26#include <stdint.h>
27#include <sys/types.h>
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33enum zen_error_t
34{
35 ZEN_SUCCESS = 0,
36 ZEN_ERROR = -1,
37 ZEN_OPEN_ERROR = -2,
38 ZEN_READ_ERROR = -3,
39 ZEN_NO_MATCH = -4,
40 ZEN_BOOT_INVALID = -5,
41 ZEN_BOOT_MISMATCH = -6,
42 ZEN_BOOT_CHECKSUM_ERROR = -7,
43 ZEN_DONT_KNOW_HOW_TO_PATCH = -8,
44 ZEN_WRITE_ERROR = -9,
45 ZEN_UNSUPPORTED = 10,
46 ZEN_FW_INVALID = -11,
47 ZEN_FW_MISMATCH = -12,
48 ZEN_FIRST_ZENTOOLS_ERROR = -12,
49};
50
51enum zen_output_type_t
52{
53 ZEN_DUALBOOT = 0, /* keep all OF data and pack OF+RB into firmware for dualboot */
54 ZEN_MIXEDBOOT, /* rename OF, keep data, put RB as firmware, use RB bootloader to dualboot */
55 ZEN_RECOVERY, /* only put rockbox with recovery mode */
56 ZEN_SINGLEBOOT, /* only put rockbox with recovery mode */
57};
58
59/* Supported models */
60enum zen_model_t
61{
62 MODEL_UNKNOWN = 0,
63 MODEL_ZENMOZAIC,
64 MODEL_ZENV,
65 MODEL_ZENXFI,
66 MODEL_ZEN,
67 /* new models go here */
68
69 NUM_MODELS
70};
71
72struct zen_option_t
73{
74 bool debug;
75 enum zen_output_type_t output;
76 enum zen_model_t model; /* pass MODEL_UNKNOWN to use MD5 knowledge base */
77};
78
79enum zen_error_t mkzenboot(const char *infile, const char *bootfile,
80 const char *outfile, struct zen_option_t opt);
81
82#ifdef __cplusplus
83}
84#endif
85#endif
86
diff --git a/utils/mkzenboot/utils.c b/utils/mkzenboot/utils.c
new file mode 100644
index 0000000000..b8ef3be237
--- /dev/null
+++ b/utils/mkzenboot/utils.c
@@ -0,0 +1,896 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Maurus Cuelenaere
11 * Based on zenutils by Rasmus Ry <rasmus.ry{at}gmail.com>
12 * Copyright (C) 2013 by Amaury Pouly
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#include "utils.h"
24#include "md5.h"
25#include <zlib.h>
26//#include "hmac-sha1.h"
27
28int filesize(FILE* fd)
29{
30 int tmp, tmp2 = ftell(fd);
31 fseek(fd, 0, SEEK_END);
32 tmp = ftell(fd);
33 fseek(fd, tmp2, SEEK_SET);
34 return tmp;
35}
36
37unsigned int le2int(unsigned char* buf)
38{
39 return ((buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]);
40}
41
42unsigned int be2int(unsigned char* buf)
43{
44 return ((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]);
45}
46
47void int2le(unsigned int val, unsigned char* addr)
48{
49 addr[0] = val & 0xFF;
50 addr[1] = (val >> 8) & 0xff;
51 addr[2] = (val >> 16) & 0xff;
52 addr[3] = (val >> 24) & 0xff;
53}
54
55const char* find_firmware_key(const unsigned char* buffer, size_t len)
56{
57 char szkey1[] = "34d1";
58 size_t cchkey1 = strlen(szkey1);
59 char szkey2[] = "TbnCboEbn";
60 size_t cchkey2 = strlen(szkey2);
61 uint32_t i;
62 for (i = 0; i < (uint32_t)len; i++)
63 {
64 if (len >= cchkey1)
65 {
66 if (!strncmp((char*)&buffer[i], szkey1, cchkey1))
67 return (const char*)&buffer[i];
68 }
69 if (len >= cchkey2)
70 {
71 if (!strncmp((char*)&buffer[i], szkey2, cchkey2))
72 return (const char*)&buffer[i];
73 }
74 }
75 return NULL;
76}
77
78uint32_t find_firmware_offset(unsigned char* buffer, size_t len)
79{
80 uint32_t i;
81 for (i = 0; i < (uint32_t)len; i += 0x10)
82 {
83 if (buffer[i + sizeof(uint32_t)] != 0
84 && buffer[i + sizeof(uint32_t) + 1] != 0
85 && buffer[i + sizeof(uint32_t) + 2] != 0
86 && buffer[i + sizeof(uint32_t) + 3] != 0)
87 {
88 return i;
89 }
90 if(i > 0xFF) /* Arbitrary guess */
91 return 0;
92 }
93 return 0;
94}
95
96bool crypt_firmware(const char* key, unsigned char* buffer, size_t len)
97{
98 char key_cpy[255];
99 unsigned int i;
100 unsigned int tmp = 0;
101 int key_length = strlen(key);
102
103 strcpy(key_cpy, key);
104 for(i=0; i < strlen(key); i++)
105 key_cpy[i] = key[i] - 1;
106
107 for(i=0; i < len; i++)
108 {
109 buffer[i] ^= key_cpy[tmp] | 0x80;
110 tmp = (tmp + 1) % key_length;
111 }
112
113 return true;
114}
115
116bool inflate_to_buffer(const unsigned char *buffer, size_t len, unsigned char* out_buffer, size_t out_len, char** err_msg)
117{
118 /* Initialize Zlib */
119 z_stream d_stream;
120 int ret;
121
122 d_stream.zalloc = Z_NULL;
123 d_stream.zfree = Z_NULL;
124 d_stream.opaque = Z_NULL;
125
126 d_stream.next_in = (unsigned char*)buffer;
127 d_stream.avail_in = len;
128
129 ret = inflateInit(&d_stream);
130 if (ret != Z_OK)
131 {
132 *err_msg = d_stream.msg;
133 return false;
134 }
135
136 d_stream.next_out = out_buffer;
137 d_stream.avail_out = out_len;
138
139 ret = inflate(&d_stream, Z_SYNC_FLUSH);
140 if(ret < 0)
141 {
142 *err_msg = d_stream.msg;
143 return false;
144 }
145 else
146 inflateEnd(&d_stream);
147
148 return true;
149}
150
151#define CODE_MASK 0xC0
152#define ARGS_MASK 0x3F
153
154#define REPEAT_CODE 0x00
155#define BLOCK_CODE 0x40
156#define LONG_RUN_CODE 0x80
157#define SHORT_RUN_CODE 0xC0
158
159#define BLOCK_ARGS 0x1F
160#define BLOCK_MODE 0x20
161
162
163static void decode_run(unsigned char* dst, uint16_t len, unsigned char val,
164 int* dstidx)
165{
166 memset(dst + *dstidx, val, len);
167 *dstidx += len;
168}
169
170static void decode_pattern(unsigned char* src, unsigned char* dst,
171 uint16_t len, int* srcidx, int* dstidx,
172 bool bdecode, int npasses)
173{
174 int i, j;
175 for (i = 0; i < npasses; i++)
176 {
177 if (bdecode)
178 {
179 for (j = 0; j < len; j++)
180 {
181 uint16_t c, d;
182 c = src[*srcidx + j];
183 d = (c >> 5) & 7;
184 c = (c << 3) & 0xF8;
185 src[*srcidx + j] = (unsigned char)(c | d);
186 }
187 bdecode = false;
188 }
189 memcpy(dst + *dstidx, src + *srcidx, len);
190 *dstidx += len;
191 }
192 *srcidx += len;
193}
194
195int cenc_decode(unsigned char* src, int srclen, unsigned char* dst, int dstlen)
196{
197 int i = 0, j = 0;
198 do
199 {
200 uint16_t c, d, e;
201 c = src[i++];
202 switch (c & CODE_MASK)
203 {
204 case REPEAT_CODE: /* 2 unsigned chars */
205 d = src[i++];
206 d = d + 2;
207
208 e = (c & ARGS_MASK) + 2;
209
210 decode_pattern(src, dst, e, &i, &j, false, d);
211 break;
212
213 case BLOCK_CODE: /* 1/2/3 unsigned chars */
214 d = c & BLOCK_ARGS;
215 if (!(c & BLOCK_MODE))
216 {
217 e = src[i++];
218 e = (d << 8) + (e + 0x21);
219
220 d = (uint16_t)(i ^ j);
221 }
222 else
223 {
224 e = d + 1;
225
226 d = (uint16_t)(i ^ j);
227 }
228 if (d & 1)
229 {
230 i++;
231 }
232
233 decode_pattern(src, dst, e, &i, &j, true, 1);
234 break;
235
236 case LONG_RUN_CODE: /* 3 unsigned chars */
237 d = src[i++];
238 e = ((c & ARGS_MASK) << 8) + (d + 0x42);
239
240 d = src[i++];
241 d = ((d & 7) << 5) | ((d >> 3) & 0x1F);
242
243 decode_run(dst, e, (unsigned char)(d), &j);
244 break;
245
246 case SHORT_RUN_CODE: /* 2 unsigned chars */
247 d = src[i++];
248 d = ((d & 3) << 6) | ((d >> 2) & 0x3F);
249
250 e = (c & ARGS_MASK) + 2;
251
252 decode_run(dst, e, (unsigned char)(d), &j);
253 break;
254 };
255 } while (i < srclen && j < dstlen);
256
257 return j;
258}
259
260/*
261 * Copyright (c) 1999, 2000, 2002 Virtual Unlimited B.V.
262 *
263 * This library is free software; you can redistribute it and/or
264 * modify it under the terms of the GNU Lesser General Public
265 * License as published by the Free Software Foundation; either
266 * version 2.1 of the License, or (at your option) any later version.
267 *
268 * This library is distributed in the hope that it will be useful,
269 * but WITHOUT ANY WARRANTY; without even the implied warranty of
270 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
271 * Lesser General Public License for more details.
272 *
273 * You should have received a copy of the GNU Lesser General Public
274 * License along with this library; if not, write to the Free Software
275 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
276 *
277 */
278
279#define BLOWFISHROUNDS 16
280#define BLOWFISHPSIZE (BLOWFISHROUNDS+2)
281#define WORDS_BIGENDIAN 0
282
283struct blowfishParam
284{
285 uint32_t p[BLOWFISHPSIZE];
286 uint32_t s[1024];
287 uint32_t fdback[2];
288};
289
290typedef enum
291{
292 NOCRYPT,
293 ENCRYPT,
294 DECRYPT
295} cipherOperation;
296
297static inline uint32_t swapu32(uint32_t n)
298{
299 return ( ((n & 0xffU) << 24) |
300 ((n & 0xff00U) << 8) |
301 ((n & 0xff0000U) >> 8) |
302 ((n & 0xff000000U) >> 24) );
303}
304
305static uint32_t _bf_p[BLOWFISHPSIZE] = {
306 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
307 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
308 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
309 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
310 0x9216d5d9, 0x8979fb1b
311};
312
313static uint32_t _bf_s[1024] = {
314 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
315 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
316 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
317 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
318 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
319 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
320 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
321 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
322 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
323 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
324 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
325 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
326 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
327 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
328 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
329 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
330 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
331 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
332 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
333 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
334 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
335 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
336 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
337 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
338 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
339 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
340 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
341 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
342 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
343 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
344 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
345 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
346 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
347 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
348 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
349 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
350 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
351 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
352 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
353 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
354 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
355 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
356 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
357 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
358 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
359 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
360 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
361 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
362 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
363 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
364 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
365 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
366 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
367 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
368 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
369 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
370 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
371 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
372 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
373 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
374 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
375 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
376 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
377 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
378 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
379 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
380 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
381 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
382 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
383 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
384 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
385 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
386 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
387 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
388 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
389 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
390 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
391 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
392 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
393 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
394 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
395 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
396 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
397 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
398 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
399 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
400 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
401 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
402 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
403 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
404 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
405 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
406 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
407 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
408 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
409 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
410 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
411 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
412 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
413 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
414 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
415 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
416 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
417 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
418 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
419 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
420 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
421 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
422 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
423 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
424 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
425 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
426 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
427 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
428 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
429 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
430 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
431 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
432 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
433 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
434 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
435 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
436 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
437 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
438 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
439 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
440 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
441 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
442 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
443 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
444 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
445 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
446 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
447 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
448 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
449 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
450 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
451 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
452 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
453 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
454 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
455 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
456 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
457 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
458 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
459 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
460 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
461 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
462 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
463 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
464 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
465 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
466 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
467 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
468 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
469 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
470 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
471 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
472 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
473 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
474 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
475 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
476 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
477 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
478 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
479 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
480 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
481 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
482 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
483 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
484 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
485 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
486 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
487 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
488 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
489 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
490 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
491 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
492 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
493 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
494 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
495 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
496 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
497 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
498 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
499 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
500 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
501 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
502 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
503 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
504 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
505 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
506 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
507 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
508 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
509 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
510 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
511 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
512 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
513 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
514 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
515 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
516 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
517 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
518 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
519 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
520 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
521 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
522 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
523 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
524 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
525 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
526 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
527 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
528 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
529 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
530 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
531 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
532 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
533 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
534 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
535 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
536 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
537 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
538 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
539 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
540 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
541 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
542 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
543 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
544 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
545 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
546 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
547 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
548 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
549 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
550 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
551 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
552 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
553 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
554 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
555 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
556 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
557 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
558 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
559 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
560 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
561 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
562 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
563 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
564 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
565 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
566 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
567 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
568 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
569 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
570};
571
572#define EROUND(l,r) l ^= *(p++); r ^= ((s[((l>>24)&0xff)+0x000]+s[((l>>16)&0xff)+0x100])^s[((l>>8)&0xff)+0x200])+s[((l>>0)&0xff)+0x300]
573#define DROUND(l,r) l ^= *(p--); r ^= ((s[((l>>24)&0xff)+0x000]+s[((l>>16)&0xff)+0x100])^s[((l>>8)&0xff)+0x200])+s[((l>>0)&0xff)+0x300]
574
575static int blowfishEncrypt(struct blowfishParam* bp, uint32_t* dst, const uint32_t* src)
576{
577 #if WORDS_BIGENDIAN
578 register uint32_t xl = src[0], xr = src[1];
579 #else
580 register uint32_t xl = swapu32(src[0]), xr = swapu32(src[1]);
581 #endif
582 register uint32_t* p = bp->p;
583 register uint32_t* s = bp->s;
584
585 EROUND(xl, xr); EROUND(xr, xl);
586 EROUND(xl, xr); EROUND(xr, xl);
587 EROUND(xl, xr); EROUND(xr, xl);
588 EROUND(xl, xr); EROUND(xr, xl);
589 EROUND(xl, xr); EROUND(xr, xl);
590 EROUND(xl, xr); EROUND(xr, xl);
591 EROUND(xl, xr); EROUND(xr, xl);
592 EROUND(xl, xr); EROUND(xr, xl);
593
594 #if WORDS_BIGENDIAN
595 dst[1] = xl ^ *(p++);
596 dst[0] = xr ^ *(p++);
597 #else
598 dst[1] = swapu32(xl ^ *(p++));
599 dst[0] = swapu32(xr ^ *(p++));
600 #endif
601
602 return 0;
603}
604
605static int blowfishDecrypt(struct blowfishParam* bp, uint32_t* dst, const uint32_t* src)
606{
607 #if WORDS_BIGENDIAN
608 register uint32_t xl = src[0], xr = src[1];
609 #else
610 register uint32_t xl = swapu32(src[0]), xr = swapu32(src[1]);
611 #endif
612 register uint32_t* p = bp->p+BLOWFISHPSIZE-1;
613 register uint32_t* s = bp->s;
614
615 DROUND(xl, xr); DROUND(xr, xl);
616 DROUND(xl, xr); DROUND(xr, xl);
617 DROUND(xl, xr); DROUND(xr, xl);
618 DROUND(xl, xr); DROUND(xr, xl);
619 DROUND(xl, xr); DROUND(xr, xl);
620 DROUND(xl, xr); DROUND(xr, xl);
621 DROUND(xl, xr); DROUND(xr, xl);
622 DROUND(xl, xr); DROUND(xr, xl);
623
624 #if WORDS_BIGENDIAN
625 dst[1] = xl ^ *(p--);
626 dst[0] = xr ^ *(p--);
627 #else
628 dst[1] = swapu32(xl ^ *(p--));
629 dst[0] = swapu32(xr ^ *(p--));
630 #endif
631
632 return 0;
633}
634
635static int blowfishSetup(struct blowfishParam* bp, const unsigned char* key, size_t keybits, cipherOperation op)
636{
637 if ((op != ENCRYPT) && (op != DECRYPT))
638 return -1;
639
640 if (((keybits & 7) == 0) && (keybits >= 32) && (keybits <= 448))
641 {
642 register uint32_t* p = bp->p;
643 register uint32_t* s = bp->s;
644 register unsigned int i, j, k;
645
646 uint32_t tmp, work[2];
647
648 memcpy(s, _bf_s, 1024 * sizeof(uint32_t));
649
650 for (i = 0, k = 0; i < BLOWFISHPSIZE; i++)
651 {
652 tmp = 0;
653 for (j = 0; j < 4; j++)
654 {
655 tmp <<= 8;
656 tmp |= key[k++];
657 if (k >= (keybits >> 3))
658 k = 0;
659 }
660 p[i] = _bf_p[i] ^ tmp;
661 }
662
663 work[0] = work[1] = 0;
664
665 for (i = 0; i < BLOWFISHPSIZE; i += 2, p += 2)
666 {
667 blowfishEncrypt(bp, work, work);
668 #if WORDS_BIGENDIAN
669 p[0] = work[0];
670 p[1] = work[1];
671 #else
672 p[0] = swapu32(work[0]);
673 p[1] = swapu32(work[1]);
674 #endif
675 }
676
677 for (i = 0; i < 1024; i += 2, s += 2)
678 {
679 blowfishEncrypt(bp, work, work);
680 #if WORDS_BIGENDIAN
681 s[0] = work[0];
682 s[1] = work[1];
683 #else
684 s[0] = swapu32(work[0]);
685 s[1] = swapu32(work[1]);
686 #endif
687 }
688
689 /* clear fdback/iv */
690 bp->fdback[0] = 0;
691 bp->fdback[1] = 0;
692
693 return 0;
694 }
695 return -1;
696}
697
698static int blowfishSetIV(struct blowfishParam* bp, const unsigned char* iv)
699{
700 if (iv)
701 memcpy(bp->fdback, iv, 8);
702 else
703 memset(bp->fdback, 0, 8);
704
705 return 0;
706}
707
708#define BLOWFISH_BLOCKSIZE 8
709static int blowfishDecryptCBC(struct blowfishParam* bp, uint32_t* dst, const uint32_t* src, unsigned int nblocks)
710{
711 register const unsigned int blockwords = BLOWFISH_BLOCKSIZE >> 2;
712 register uint32_t* fdback = bp->fdback;
713 register uint32_t* buf = (uint32_t*) malloc(blockwords * sizeof(uint32_t));
714
715 if (buf)
716 {
717 while (nblocks > 0)
718 {
719 register uint32_t tmp;
720 register unsigned int i;
721
722 blowfishDecrypt(bp, buf, src);
723
724 for (i = 0; i < blockwords; i++)
725 {
726 tmp = src[i];
727 dst[i] = buf[i] ^ fdback[i];
728 fdback[i] = tmp;
729 }
730
731 dst += blockwords;
732 src += blockwords;
733
734 nblocks--;
735 }
736 free(buf);
737 return 0;
738 }
739
740 return -1;
741}
742
743bool bf_cbc_decrypt(const unsigned char* key, size_t keylen,
744 unsigned char* data, size_t datalen,
745 const unsigned char* iv)
746{
747 struct blowfishParam param;
748 unsigned char *cipher;
749 unsigned int nblocks;
750
751 if (datalen % BLOWFISH_BLOCKSIZE)
752 return false;
753
754 if (blowfishSetup(&param, key, keylen * 8, ENCRYPT))
755 return false;
756 if (blowfishSetIV(&param, iv))
757 return false;
758
759 cipher = malloc(datalen);
760 memcpy(cipher, data, datalen);
761
762 nblocks = datalen / BLOWFISH_BLOCKSIZE;
763 if (blowfishDecryptCBC(&param, (uint32_t*)data, (uint32_t*)cipher,
764 nblocks))
765 {
766 free(cipher);
767 return false;
768 }
769
770 free(cipher);
771 return true;
772}
773
774uint32_t swap(uint32_t val)
775{
776 return ((val & 0xFF) << 24)
777 | ((val & 0xFF00) << 8)
778 | ((val & 0xFF0000) >> 8)
779 | ((val & 0xFF000000) >> 24);
780}
781
782/* read a file to a buffer */
783enum zen_error_t read_file(const char *file, void **buffer, size_t *size)
784{
785 FILE *f = fopen(file, "rb");
786 if(f == NULL)
787 {
788 printf("[ERR] Cannot open file '%s' for reading: %m\n", file);
789 return ZEN_OPEN_ERROR;
790 }
791 fseek(f, 0, SEEK_END);
792 *size = ftell(f);
793 fseek(f, 0, SEEK_SET);
794 *buffer = malloc(*size);
795 if(fread(*buffer, *size, 1, f) != 1)
796 {
797 free(*buffer);
798 fclose(f);
799 printf("[ERR] Cannot read file '%s': %m\n", file);
800 return ZEN_READ_ERROR;
801 }
802 fclose(f);
803 return ZEN_SUCCESS;
804}
805
806/* write a file from a buffer */
807enum zen_error_t write_file(const char *file, void *buffer, size_t size)
808{
809 FILE *f = fopen(file, "wb");
810 if(f == NULL)
811 {
812 printf("[ERR] Cannot open file '%s' for writing: %m\n", file);
813 return ZEN_OPEN_ERROR;
814 }
815 if(fwrite(buffer, size, 1, f) != 1)
816 {
817 fclose(f);
818 printf("[ERR] Cannot write file '%s': %m\n", file);
819 return ZEN_WRITE_ERROR;
820 }
821 fclose(f);
822 return ZEN_SUCCESS;
823}
824
825/* compute MD5 sum of a buffer */
826enum zen_error_t compute_md5sum_buf(void *buf, size_t sz, uint8_t file_md5sum[16])
827{
828 md5_context ctx;
829 md5_starts(&ctx);
830 md5_update(&ctx, buf, sz);
831 md5_finish(&ctx, file_md5sum);
832 return ZEN_SUCCESS;
833}
834
835/* compute MD5 of a file */
836enum zen_error_t compute_md5sum(const char *file, uint8_t file_md5sum[16])
837{
838 void *buf;
839 size_t sz;
840 enum zen_error_t err = read_file(file, &buf, &sz);
841 if(err != ZEN_SUCCESS)
842 return err;
843 compute_md5sum_buf(buf, sz, file_md5sum);
844 free(buf);
845 return ZEN_SUCCESS;
846}
847
848enum zen_error_t find_pe_data(void *fw, size_t fw_size, uint32_t *data_ptr, uint32_t *data_size)
849{
850 uint8_t *buffer = fw;
851 /* Rudimentary Win32 PE reading to find .data section */
852 if(memcmp(&buffer[0], "MZ", 2) != 0 && memcmp(&buffer[0x118], "PE", 2) != 0)
853 {
854 printf("[ERR] Input file isn't an executable\n");
855 return ZEN_FW_INVALID;
856 }
857 *data_ptr = 0, *data_size = 0;
858 uint32_t start_sec_addr = /*sizeof NT headers */ 0xf8 +
859 /* address of opt header */*(uint32_t *)&buffer[0x3c];
860 for(uint32_t i = start_sec_addr; i < 0x1000; i += 0x28)
861 {
862 if(strcmp((char*)&buffer[i], ".data") == 0)
863 {
864 *data_ptr = le2int(&buffer[i + 0x14]);
865 *data_size = le2int(&buffer[i + 0x10]);
866 break;
867 }
868 }
869 if(*data_ptr == 0 || *data_size == 0)
870 {
871 printf("[ERR] Couldn't find .data section\n");
872 return ZEN_FW_INVALID;
873 }
874 return ZEN_SUCCESS;
875}
876
877int convxdigit(char digit, uint8_t *val)
878{
879 if(digit >= '0' && digit <= '9')
880 {
881 *val = digit - '0';
882 return 0;
883 }
884 else if(digit >= 'A' && digit <= 'F')
885 {
886 *val = digit - 'A' + 10;
887 return 0;
888 }
889 else if(digit >= 'a' && digit <= 'f')
890 {
891 *val = digit - 'a' + 10;
892 return 0;
893 }
894 else
895 return 1;
896}
diff --git a/utils/mkzenboot/utils.h b/utils/mkzenboot/utils.h
new file mode 100644
index 0000000000..56edb4e20b
--- /dev/null
+++ b/utils/mkzenboot/utils.h
@@ -0,0 +1,53 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2013 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __UTILS__
22#define __UTILS__
23
24#include <stddef.h>
25#include <stdint.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <stdbool.h>
29#include <string.h>
30#include "mkzenboot.h"
31#include "hmac-sha1.h"
32
33int filesize(FILE* fd);
34unsigned int le2int(unsigned char* buf);
35unsigned int be2int(unsigned char* buf);
36void int2le(unsigned int val, unsigned char* addr);
37const char* find_firmware_key(const unsigned char* buffer, size_t len);
38uint32_t find_firmware_offset(unsigned char* buffer, size_t len);
39bool crypt_firmware(const char* key, unsigned char* buffer, size_t len);
40bool inflate_to_buffer(const unsigned char *buffer, size_t len,
41 unsigned char* out_buffer, size_t out_len, char** err_msg);
42int cenc_decode(unsigned char* src, int srclen, unsigned char* dst, int dstlen);
43bool bf_cbc_decrypt(const unsigned char* key, size_t keylen, unsigned char* data,
44 size_t datalen, const unsigned char* iv);
45uint32_t swap(uint32_t val);
46enum zen_error_t compute_md5sum(const char *file, uint8_t file_md5sum[16]);
47enum zen_error_t compute_md5sum_buf(void *buf, size_t sz, uint8_t file_md5sum[16]);
48enum zen_error_t read_file(const char *file, void **buffer, size_t *size);
49enum zen_error_t write_file(const char *file, void *buffer, size_t size);
50enum zen_error_t find_pe_data(void *fw, size_t fw_size, uint32_t *data_ptr, uint32_t *data_size);
51int convxdigit(char digit, uint8_t *val);
52
53#endif /* __UTILS__ */ \ No newline at end of file
diff --git a/utils/rbutil.pro b/utils/rbutil.pro
new file mode 100644
index 0000000000..d5d9053d6d
--- /dev/null
+++ b/utils/rbutil.pro
@@ -0,0 +1,83 @@
1#
2# __________ __ ___.
3# Open \______ \ ____ ____ | | _\_ |__ _______ ___
4# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7# \/ \/ \/ \/ \/
8#
9# All files in this archive are subject to the GNU General Public License.
10# See the file COPYING in the source tree root for full license agreement.
11#
12# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
13# KIND, either express or implied.
14#
15
16unix:!mac{
17 CCACHE = $$system(which ccache)
18 !isEmpty(CCACHE) {
19 message("using ccache at $$CCACHE")
20 QMAKE_CXX = ccache $$QMAKE_CXX
21 QMAKE_CC = ccache $$QMAKE_CC
22 }
23}
24
25TEMPLATE = subdirs
26SUBDIRS = rbutilqt ipodpatcher sansapatcher
27
28rbutilqt.depends = ipodpatcher sansapatcher
29
30
31unix:!macx {
32 LINUXDEPLOYQTURL = https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage
33 LINUXDEPLOYURL = https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
34
35 appimage_dl.commands = \
36 curl -C- -fLO $$LINUXDEPLOYQTURL -fLO $$LINUXDEPLOYURL ; \
37 chmod +x *.AppImage; \
38 touch appimage_dl
39
40 appimage_prepare.commands = \
41 mkdir -p AppImage/usr/bin; \
42 cp sansapatcher/sansapatcher AppImage/usr/bin; \
43 cp ipodpatcher/ipodpatcher AppImage/usr/bin; \
44 cp rbutilqt/RockboxUtility AppImage/usr/bin
45
46 appimage_prepare.depends = ipodpatcher sansapatcher rbutilqt appimage_dl
47
48 appimage.commands = \
49 ./linuxdeploy-x86_64.AppImage \
50 --appdir AppImage \
51 --verbosity 2 --plugin qt --output appimage \
52 -e AppImage/usr/bin/RockboxUtility \
53 -d $$_PRO_FILE_PWD_/rbutilqt/RockboxUtility.desktop \
54 -i $$_PRO_FILE_PWD_/../docs/logo/rockbox-clef.svg
55 appimage.depends = appimage_prepare
56
57 QMAKE_EXTRA_TARGETS += appimage_dl appimage_prepare appimage
58}
59
60macx {
61 dmgbuild.commands = \
62 python3 -m venv venv; \
63 venv/bin/python -m pip install dmgbuild
64
65 appbundle_merge.commands = \
66 cp -pr rbutilqt/RockboxUtility.app .; \
67 cp ipodpatcher/ipodpatcher.app/Contents/MacOS/ipodpatcher RockboxUtility.app/Contents/MacOS; \
68 cp sansapatcher/sansapatcher.app/Contents/MacOS/sansapatcher RockboxUtility.app/Contents/MacOS
69
70 appbundle_deploy.commands = \
71 $$[QT_INSTALL_BINS]/macdeployqt RockboxUtility.app
72 appbundle_deploy.depends = appbundle_merge
73
74 dmg.commands = \
75 venv/bin/dmgbuild -s $$_PRO_FILE_PWD_/rbutilqt/dmgbuild.cfg \
76 -Dbasepath=$$_PRO_FILE_PWD_ \"Rockbox Utility\" RockboxUtility.dmg
77
78 dmg.depends = appbundle_merge appbundle_deploy dmgbuild
79
80 QMAKE_EXTRA_TARGETS += dmgbuild appbundle_merge appbundle_deploy dmg
81}
82
83
diff --git a/utils/rbutilqt/INSTALL b/utils/rbutilqt/INSTALL
new file mode 100644
index 0000000000..884e7b3739
--- /dev/null
+++ b/utils/rbutilqt/INSTALL
@@ -0,0 +1,63 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * All files in this archive are subject to the GNU General Public License.
10 * See the file COPYING in the source tree root for full license agreement.
11 *
12 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
13 * KIND, either express or implied.
14 *
15 ****************************************************************************/
16
17This is Rockbox Utility, the graphical installer and housekeeping utility
18for Rockbox.
19
20Requirements:
21=============
22- gcc
23- Qt 4.5.0 or later
24- at least the following folders from Rockbox svn:
25 o lib/rbcodec/codecs/libspeex
26 o rbutil/
27 o tools/
28- libusb (Linux only)
29
30Building:
31=========
32- run qmake
33- run make
34
35Build Options:
36==============
37- static
38 add "-config static" to the qmake call to build a static binary. Note that
39 this also requires that you have a statically built version of Qt.
40- dbg
41 add "-config dbg" to build with debug symbols.
42- silent
43 add "-config silent" to the qmake call. This is an undocumented feature of
44 Qt itself. Note that this doesn't seem to work on Windows and Mac OS X until
45 recent versions of Qt.
46
47Installation / Deployment:
48==========================
49Rockbox Utility is build as all-in-one binary. This means for distribution
50you need:
51- RockboxUtility (main binary)
52- rbutil_*.qm (translation files, only for non-static builds)
53You don't need any other files like configuration files, especially
54rbutil.ini which will get included into the binary.
55
56The script utils/common/deploy-rbutil.py automates building deployment
57binaries. For a complete list of paths to get from svn to build please check
58its source.
59
60
61The website for Rockbox Utility is
62http://www.rockbox.org/wiki/RockboxUtility
63
diff --git a/utils/rbutilqt/Info.plist b/utils/rbutilqt/Info.plist
new file mode 100644
index 0000000000..af905a3f1e
--- /dev/null
+++ b/utils/rbutilqt/Info.plist
@@ -0,0 +1,24 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3<plist version="1.0">
4<dict>
5 <key>CFBundleExecutable</key>
6 <string>RockboxUtility</string>
7 <key>CFBundleName</key>
8 <string>Rockbox Utility</string>
9 <key>CFBundleShortVersionString</key>
10 <string>1.4.1 ($Rev$)</string>
11 <key>CFBundleIconFile</key>
12 <string>rbutilqt.icns</string>
13 <key>CFBundleIdentifier</key>
14 <string>com.rockbox.rbutil</string>
15 <key>CFBundlePackageType</key>
16 <string>APPL</string>
17 <key>CFBundleSignature</key>
18 <string>????</string>
19 <key>NSPrincipalClass</key>
20 <string>NSApplication</string>
21 <key>NSHighResolutionCapable</key>
22 <string>True</string>
23</dict>
24</plist>
diff --git a/utils/rbutilqt/Makefile.libs b/utils/rbutilqt/Makefile.libs
new file mode 100644
index 0000000000..a78f8b86e9
--- /dev/null
+++ b/utils/rbutilqt/Makefile.libs
@@ -0,0 +1,79 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7#
8
9ifndef V
10SILENT = @
11endif
12
13TARGET_DIR ?= $(abspath .)/build/
14BUILD_DIR ?= $(abspath .)/build/
15# allow using this Makefile directly. Otherwise those variables are set via
16# the generated one.
17ifndef RBBASE_DIR
18RBBASE_DIR := $(dir $(lastword $(MAKEFILE_LIST)))/../../
19endif
20EXTRALIBS_CC ?= gcc
21EXTRALIBS_AR ?= ar
22
23# re-export variables that might have been set via command line.
24# If set via command line sub-makefiles cannot override them, so use different
25# variable names in the calling makefile.
26export APPVERSION=\"rbutil\"
27export SYS_SPEEX
28export TARGET_DIR
29export RBBASE_DIR
30export CFLAGS=$(EXTRALIB_CFLAGS)
31export CXXFLAGS=$(EXTRALIB_CXXFLAGS)
32export CC=$(EXTRALIBS_CC)
33export CXX=$(EXTRALIBS_CXX)
34export AR=$(EXTRALIBS_AR)
35export ISYSROOT=$(EXTRALIB_ISYSROOT)
36
37libs: librbspeex libucl libipodpatcher libsansapatcher libmkamsboot libmktccboot libmkmpioboot libchinachippatcher libmkimxboot libmks5lboot libbspatch libbz2 librbtomcrypt
38
39# To support cross compiles, we explicitly pass the CC flag below for
40# all tools which override CC or CXX in their makefiles. CXX is only
41# used by mkimxboot.
42
43librbtomcrypt:
44 $(SILENT) $(MAKE) -C $(RBBASE_DIR)/utils/tomcrypt BUILD_DIR=$(BUILD_DIR)/tomcrypt librbtomcrypt.a
45librbspeex:
46 $(SILENT) $(MAKE) -C $(RBBASE_DIR)/tools/rbspeex BUILD_DIR=$(BUILD_DIR)/libspeex librbspeex.a
47
48libucl:
49 $(SILENT)$(MAKE) -C $(RBBASE_DIR)/tools/ucl/src BUILD_DIR=$(BUILD_DIR)/ucl libucl.a
50
51libipodpatcher:
52 $(SILENT)$(MAKE) -C $(RBBASE_DIR)/utils/ipodpatcher BUILD_DIR=$(BUILD_DIR)/ipodpatcher libipodpatcher.a CC=$(CC)
53
54libsansapatcher:
55 $(SILENT)$(MAKE) -C $(RBBASE_DIR)/utils/sansapatcher BUILD_DIR=$(BUILD_DIR)/sansapatcher libsansapatcher.a CC=$(CC)
56
57libmkamsboot:
58 $(SILENT)$(MAKE) -C $(RBBASE_DIR)/utils/mkamsboot BUILD_DIR=$(BUILD_DIR)/mkamsboot libmkamsboot.a CC=$(CC)
59
60libmktccboot:
61 $(SILENT)$(MAKE) -C $(RBBASE_DIR)/utils/mktccboot BUILD_DIR=$(BUILD_DIR)/mktccboot libmktccboot.a CC=$(CC)
62
63libmkmpioboot:
64 $(SILENT)$(MAKE) -C $(RBBASE_DIR)/utils/mkmpioboot BUILD_DIR=$(BUILD_DIR)/mkmpioboot libmkmpioboot.a CC=$(CC)
65
66libchinachippatcher:
67 $(SILENT)$(MAKE) -C $(RBBASE_DIR)/utils/chinachippatcher BUILD_DIR=$(BUILD_DIR)/chinachippatcher libchinachippatcher.a CC=$(CC)
68
69libmkimxboot:
70 $(SILENT)$(MAKE) -C $(RBBASE_DIR)/utils/mkimxboot BUILD_DIR=$(BUILD_DIR)/mkimxboot libmkimxboot.a CC=$(CC) CXX=$(CXX)
71
72libmks5lboot:
73 $(SILENT)$(MAKE) -C $(RBBASE_DIR)/utils/mks5lboot BUILD_DIR=$(BUILD_DIR)/mks5lboot libmks5lboot.a CC=$(CC)
74
75libbz2:
76 $(SILENT)$(MAKE) -C $(RBBASE_DIR)/utils/bzip2 BUILD_DIR=$(BUILD_DIR)/bzip2 libbz2.a CC=$(CC)
77
78libbspatch:
79 $(SILENT)$(MAKE) -C $(RBBASE_DIR)/utils/bspatch BUILD_DIR=$(BUILD_DIR)/bspatch libbspatch.a CC=$(CC)
diff --git a/utils/rbutilqt/RockboxUtility.desktop b/utils/rbutilqt/RockboxUtility.desktop
new file mode 100644
index 0000000000..bc5f45d53d
--- /dev/null
+++ b/utils/rbutilqt/RockboxUtility.desktop
@@ -0,0 +1,12 @@
1[Desktop Entry]
2GenericName=Rockbox Installer and Maintainance Tool
3Version=1.0
4Hidden=false
5Name=Rockbox Utility
6Type=Application
7Terminal=false
8StartupNotify=true
9Icon=rockbox-clef
10Exec=RockboxUtility
11Categories=Utility;
12
diff --git a/utils/rbutilqt/aboutbox.ui b/utils/rbutilqt/aboutbox.ui
new file mode 100644
index 0000000000..e13f06a15a
--- /dev/null
+++ b/utils/rbutilqt/aboutbox.ui
@@ -0,0 +1,198 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0" >
3 <class>aboutBox</class>
4 <widget class="QWidget" name="aboutBox" >
5 <property name="geometry" >
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>640</width>
10 <height>500</height>
11 </rect>
12 </property>
13 <property name="windowTitle" >
14 <string>About Rockbox Utility</string>
15 </property>
16 <layout class="QGridLayout" name="gridLayout" >
17 <item row="0" column="0" colspan="3" >
18 <layout class="QHBoxLayout" >
19 <item>
20 <widget class="QLabel" name="label" >
21 <property name="text" >
22 <string/>
23 </property>
24 <property name="pixmap" >
25 <pixmap>:/icons/rockbox-5.png</pixmap>
26 </property>
27 </widget>
28 </item>
29 <item>
30 <widget class="QLabel" name="labelTitle" >
31 <property name="text" >
32 <string>The Rockbox Utility</string>
33 </property>
34 </widget>
35 </item>
36 <item>
37 <spacer>
38 <property name="orientation" >
39 <enum>Qt::Horizontal</enum>
40 </property>
41 <property name="sizeHint" stdset="0" >
42 <size>
43 <width>40</width>
44 <height>20</height>
45 </size>
46 </property>
47 </spacer>
48 </item>
49 </layout>
50 </item>
51 <item row="1" column="0" colspan="3" >
52 <widget class="QLabel" name="labelText" >
53 <property name="text" >
54 <string>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</string>
55 </property>
56 <property name="textFormat" >
57 <enum>Qt::RichText</enum>
58 </property>
59 <property name="wordWrap" >
60 <bool>true</bool>
61 </property>
62 <property name="openExternalLinks" >
63 <bool>true</bool>
64 </property>
65 </widget>
66 </item>
67 <item row="2" column="0" colspan="3" >
68 <widget class="QTabWidget" name="tabWidget" >
69 <property name="currentIndex" >
70 <number>0</number>
71 </property>
72 <widget class="QWidget" name="creditsTab" >
73 <attribute name="title" >
74 <string>&amp;Credits</string>
75 </attribute>
76 <layout class="QGridLayout" >
77 <item row="0" column="0" >
78 <widget class="QTextBrowser" name="browserCredits" >
79 <property name="focusPolicy" >
80 <enum>Qt::TabFocus</enum>
81 </property>
82 <property name="acceptDrops" >
83 <bool>false</bool>
84 </property>
85 <property name="autoFillBackground" >
86 <bool>true</bool>
87 </property>
88 <property name="autoFormatting" >
89 <set>QTextEdit::AutoNone</set>
90 </property>
91 <property name="tabChangesFocus" >
92 <bool>true</bool>
93 </property>
94 <property name="textInteractionFlags" >
95 <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
96 </property>
97 <property name="openExternalLinks" >
98 <bool>true</bool>
99 </property>
100 </widget>
101 </item>
102 </layout>
103 </widget>
104 <widget class="QWidget" name="licenceTab" >
105 <attribute name="title" >
106 <string>&amp;License</string>
107 </attribute>
108 <layout class="QGridLayout" >
109 <item row="0" column="0" >
110 <widget class="QTextBrowser" name="browserLicense" >
111 <property name="focusPolicy" >
112 <enum>Qt::TabFocus</enum>
113 </property>
114 <property name="horizontalScrollBarPolicy" >
115 <enum>Qt::ScrollBarAlwaysOff</enum>
116 </property>
117 <property name="tabChangesFocus" >
118 <bool>true</bool>
119 </property>
120 <property name="lineWrapMode" >
121 <enum>QTextEdit::WidgetWidth</enum>
122 </property>
123 <property name="textInteractionFlags" >
124 <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
125 </property>
126 </widget>
127 </item>
128 </layout>
129 </widget>
130 <widget class="QWidget" name="licenseSpeex" >
131 <attribute name="title" >
132 <string>L&amp;ibraries</string>
133 </attribute>
134 <layout class="QGridLayout" name="gridLayout_2" >
135 <item row="0" column="0" >
136 <widget class="QTextBrowser" name="browserLicenses"/>
137 </item>
138 </layout>
139 </widget>
140 </widget>
141 </item>
142 <item row="3" column="0" >
143 <spacer>
144 <property name="orientation" >
145 <enum>Qt::Horizontal</enum>
146 </property>
147 <property name="sizeHint" stdset="0" >
148 <size>
149 <width>40</width>
150 <height>20</height>
151 </size>
152 </property>
153 </spacer>
154 </item>
155 <item row="3" column="1" >
156 <widget class="QPushButton" name="okButton" >
157 <property name="text" >
158 <string>&amp;Ok</string>
159 </property>
160 </widget>
161 </item>
162 <item row="3" column="2" >
163 <spacer>
164 <property name="orientation" >
165 <enum>Qt::Horizontal</enum>
166 </property>
167 <property name="sizeHint" stdset="0" >
168 <size>
169 <width>40</width>
170 <height>20</height>
171 </size>
172 </property>
173 </spacer>
174 </item>
175 </layout>
176 </widget>
177 <resources>
178 <include location="rbutilqt.qrc" />
179 </resources>
180 <connections>
181 <connection>
182 <sender>okButton</sender>
183 <signal>clicked()</signal>
184 <receiver>aboutBox</receiver>
185 <slot>close()</slot>
186 <hints>
187 <hint type="sourcelabel" >
188 <x>210</x>
189 <y>398</y>
190 </hint>
191 <hint type="destinationlabel" >
192 <x>210</x>
193 <y>210</y>
194 </hint>
195 </hints>
196 </connection>
197 </connections>
198</ui>
diff --git a/utils/rbutilqt/base/archiveutil.cpp b/utils/rbutilqt/base/archiveutil.cpp
new file mode 100644
index 0000000000..d5f0a12471
--- /dev/null
+++ b/utils/rbutilqt/base/archiveutil.cpp
@@ -0,0 +1,30 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2013 Amaury Pouly
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include <QDebug>
21#include "archiveutil.h"
22
23ArchiveUtil::ArchiveUtil(QObject* parent)
24 :QObject(parent)
25{
26}
27
28ArchiveUtil::~ArchiveUtil()
29{
30}
diff --git a/utils/rbutilqt/base/archiveutil.h b/utils/rbutilqt/base/archiveutil.h
new file mode 100644
index 0000000000..76616728c3
--- /dev/null
+++ b/utils/rbutilqt/base/archiveutil.h
@@ -0,0 +1,41 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2013 Amaury Pouly
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef ARCHIVEUTIL_H
20#define ARCHIVEUTIL_H
21
22#include <QtCore>
23
24class ArchiveUtil : public QObject
25{
26 Q_OBJECT
27
28 public:
29 ArchiveUtil(QObject* parent);
30 ~ArchiveUtil();
31 virtual bool close(void) = 0;
32 virtual bool extractArchive(const QString& dest, QString file = "") = 0;
33 virtual QStringList files(void) = 0;
34
35 signals:
36 void logProgress(int, int);
37 void logItem(QString, int);
38};
39#endif
40
41
diff --git a/utils/rbutilqt/base/autodetection.cpp b/utils/rbutilqt/base/autodetection.cpp
new file mode 100644
index 0000000000..341f219c30
--- /dev/null
+++ b/utils/rbutilqt/base/autodetection.cpp
@@ -0,0 +1,376 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include "autodetection.h"
21#include "rbsettings.h"
22#include "playerbuildinfo.h"
23
24#include "../ipodpatcher/ipodpatcher.h"
25#include "../sansapatcher/sansapatcher.h"
26
27
28#include "system.h"
29#include "utils.h"
30#include "rockboxinfo.h"
31#include "Logger.h"
32
33Autodetection::Autodetection(QObject* parent): QObject(parent)
34{
35}
36
37
38bool Autodetection::detect(void)
39{
40 QMap<PlayerStatus, QString> states;
41 states[PlayerOk] = "Ok";
42 states[PlayerAmbiguous] = "Ambiguous";
43 states[PlayerError] = "Error";
44 states[PlayerIncompatible] = "Incompatible";
45 states[PlayerMtpMode] = "MtpMode";
46
47 // clear detection state
48 m_detected.clear();
49
50 detectUsb();
51 mergeMounted();
52 mergePatcher();
53 // if any entry with usbdevices containing a value is left that entry
54 // hasn't been merged later. This indicates a problem during detection
55 // (ambiguous player but refining it failed). In this case create an entry
56 // for eacho of those so the user can select.
57 QList<struct Detected> detected;
58 for(int i = 0; i < m_detected.size(); ++i) {
59 int j = m_detected.at(i).usbdevices.size();
60 if(j > 0) {
61 struct Detected entry = m_detected.at(i);
62 while(j--) {
63 struct Detected d;
64 d.device = entry.usbdevices.at(j);
65 d.mountpoint = entry.mountpoint;
66 d.status = PlayerAmbiguous;
67 detected.append(d);
68 }
69 }
70 else {
71 detected.append(m_detected.at(i));
72 }
73 }
74 m_detected = detected;
75 for(int i = 0; i < m_detected.size(); ++i) {
76 LOG_INFO() << "Detected player:" << m_detected.at(i).device
77 << "at" << m_detected.at(i).mountpoint
78 << states[m_detected.at(i).status];
79 }
80
81 return m_detected.size() > 0;
82}
83
84
85/** @brief detect devices based on usb pid / vid.
86 */
87void Autodetection::detectUsb()
88{
89 // usb pid detection
90 QList<uint32_t> attached;
91 attached = System::listUsbIds();
92
93 int i = attached.size();
94 while(i--) {
95 QStringList a = PlayerBuildInfo::instance()->value(PlayerBuildInfo::UsbIdTargetList, attached.at(i)).toStringList();
96 if(a.size() > 0) {
97 struct Detected d;
98 d.status = PlayerOk;
99 d.usbdevices = a;
100 m_detected.append(d);
101 LOG_INFO() << "[USB] detected supported player" << d.usbdevices;
102 }
103 QStringList b = PlayerBuildInfo::instance()->value(PlayerBuildInfo::UsbIdErrorList, attached.at(i)).toStringList();
104 if(b.size() > 0) {
105 struct Detected d;
106 d.status = PlayerMtpMode;
107 d.usbdevices = b;
108 m_detected.append(d);
109 LOG_WARNING() << "[USB] detected problem with player" << d.device;
110 }
111 QString idstring = QString("%1").arg(attached.at(i), 8, 16, QChar('0'));
112 if(!PlayerBuildInfo::instance()->value(
113 PlayerBuildInfo::DisplayName, idstring).toString().isEmpty()) {
114 struct Detected d;
115 d.status = PlayerIncompatible;
116 d.device = idstring;
117 m_detected.append(d);
118 LOG_WARNING() << "[USB] detected incompatible player" << d.device;
119 }
120 }
121}
122
123
124// Merge players detected by checking mounted filesystems for known files:
125// - rockbox-info.txt / rbutil.log
126// - player specific files
127void Autodetection::mergeMounted(void)
128{
129 QStringList mounts = Utils::mountpoints(Utils::MountpointsSupported);
130 LOG_INFO() << "paths to check:" << mounts;
131
132 for(int i = 0; i < mounts.size(); i++)
133 {
134 // do the file checking
135 QDir dir(mounts.at(i));
136 if(dir.exists())
137 {
138 // check logfile first.
139 if(QFile(mounts.at(i) + "/.rockbox/rbutil.log").exists()) {
140 QSettings log(mounts.at(i) + "/.rockbox/rbutil.log",
141 QSettings::IniFormat, this);
142 if(!log.value("platform").toString().isEmpty()) {
143 struct Detected d;
144 d.device = log.value("platform").toString();
145 d.mountpoint = mounts.at(i);
146 d.status = PlayerOk;
147 updateDetectedDevice(d);
148 LOG_INFO() << "rbutil.log detected:"
149 << log.value("platform").toString() << mounts.at(i);
150 }
151 }
152
153 // check rockbox-info.txt afterwards.
154 RockboxInfo info(mounts.at(i));
155 if(info.success())
156 {
157 struct Detected d;
158 d.device = info.target();
159 d.mountpoint = mounts.at(i);
160 d.status = PlayerOk;
161 updateDetectedDevice(d);
162 LOG_INFO() << "rockbox-info.txt detected:"
163 << info.target() << mounts.at(i);
164 }
165
166 // check for some specific files in root folder
167 QDir root(mounts.at(i));
168 QStringList rootentries = root.entryList(QDir::Files);
169 if(rootentries.contains("archos.mod", Qt::CaseInsensitive))
170 {
171 // archos.mod in root folder -> Archos Player
172 struct Detected d;
173 d.device = "player";
174 d.mountpoint = mounts.at(i);
175 d.status = PlayerOk;
176 updateDetectedDevice(d);
177 }
178 if(rootentries.contains("ONDIOST.BIN", Qt::CaseInsensitive))
179 {
180 // ONDIOST.BIN in root -> Ondio FM
181 struct Detected d;
182 d.device = "ondiofm";
183 d.mountpoint = mounts.at(i);
184 d.status = PlayerOk;
185 updateDetectedDevice(d);
186 }
187 if(rootentries.contains("ONDIOSP.BIN", Qt::CaseInsensitive))
188 {
189 // ONDIOSP.BIN in root -> Ondio SP
190 struct Detected d;
191 d.device = "ondiosp";
192 d.mountpoint = mounts.at(i);
193 d.status = PlayerOk;
194 updateDetectedDevice(d);
195 }
196 if(rootentries.contains("ajbrec.ajz", Qt::CaseInsensitive))
197 {
198 LOG_INFO() << "ajbrec.ajz found. Trying detectAjbrec()";
199 struct Detected d;
200 d.device = detectAjbrec(mounts.at(i));
201 d.mountpoint = mounts.at(i);
202 d.status = PlayerOk;
203 if(!d.device.isEmpty()) {
204 LOG_INFO() << d.device;
205 updateDetectedDevice(d);
206 }
207 }
208 // detection based on player specific folders
209 QStringList rootfolders = root.entryList(QDir::Dirs
210 | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System);
211 if(rootfolders.contains("GBSYSTEM", Qt::CaseInsensitive))
212 {
213 // GBSYSTEM folder -> Gigabeat
214 struct Detected d;
215 d.device = "gigabeatf";
216 d.mountpoint = mounts.at(i);
217 updateDetectedDevice(d);
218 }
219 }
220 }
221#if 0
222 // Ipods have a folder "iPod_Control" in the root.
223 for(int i = 0; i < m_detected.size(); ++i) {
224 struct Detected entry = m_detected.at(i);
225 for(int j = 0; j < entry.usbdevices.size(); ++j) {
226 // limit this to Ipods only.
227 if(!entry.usbdevices.at(j).startsWith("ipod")
228 && !entry.device.startsWith("ipod")) {
229 continue;
230 }
231 // look for iPod_Control on all supported volumes.
232 for(int k = 0; k < mounts.size(); k++) {
233 QDir root(mounts.at(k));
234 QStringList rootfolders = root.entryList(QDir::Dirs
235 | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System);
236 if(rootfolders.contains("iPod_Control", Qt::CaseInsensitive)) {
237 entry.mountpoint = mounts.at(k);
238 m_detected.takeAt(i);
239 m_detected.append(entry);
240 }
241 }
242 }
243 }
244#endif
245
246}
247
248
249void Autodetection::mergePatcher(void)
250{
251 int n;
252 // try ipodpatcher
253 // initialize sector buffer. Needed.
254 struct ipod_t ipod;
255 ipod.sectorbuf = nullptr;
256 ipod_alloc_buffer(&ipod, BUFFER_SIZE);
257 n = ipod_scan(&ipod);
258 // FIXME: handle more than one Ipod connected in ipodpatcher.
259 if(n == 1) {
260 LOG_INFO() << "Ipod found:" << ipod.modelstr << "at" << ipod.diskname;
261 // since resolveMountPoint is doing exact matches we need to select
262 // the correct partition.
263 QString mp(ipod.diskname);
264#ifdef Q_OS_LINUX
265 mp.append("2");
266#endif
267#ifdef Q_OS_MACX
268 mp.append("s2");
269#endif
270 struct Detected d;
271 d.device = ipod.targetname;
272 d.mountpoint = Utils::resolveMountPoint(mp);
273 // if the found ipod is a macpod also notice it as device with problem.
274 if(ipod.macpod)
275 d.status = PlayerWrongFilesystem;
276 else
277 d.status = PlayerOk;
278 updateDetectedDevice(d);
279 }
280 else {
281 LOG_INFO() << "ipodpatcher: no Ipod found." << n;
282 }
283 ipod_dealloc_buffer(&ipod);
284
285 // try sansapatcher
286 // initialize sector buffer. Needed.
287 struct sansa_t sansa;
288 sansa_alloc_buffer(&sansa, BUFFER_SIZE);
289 n = sansa_scan(&sansa);
290 if(n == 1) {
291 LOG_INFO() << "Sansa found:"
292 << sansa.targetname << "at" << sansa.diskname;
293 QString mp(sansa.diskname);
294#ifdef Q_OS_LINUX
295 mp.append("1");
296#endif
297#ifdef Q_OS_MACX
298 mp.append("s1");
299#endif
300 struct Detected d;
301 d.device = QString("sansa%1").arg(sansa.targetname);
302 d.mountpoint = Utils::resolveMountPoint(mp);
303 d.status = PlayerOk;
304 updateDetectedDevice(d);
305 }
306 else {
307 LOG_INFO() << "sansapatcher: no Sansa found." << n;
308 }
309 sansa_dealloc_buffer(&sansa);
310}
311
312
313QString Autodetection::detectAjbrec(QString root)
314{
315 QFile f(root + "/ajbrec.ajz");
316 char header[24];
317 f.open(QIODevice::ReadOnly);
318 if(!f.read(header, 24)) return QString();
319 f.close();
320
321 // check the header of the file.
322 // recorder v1 had a 6 bytes sized header
323 // recorder v2, FM, Ondio SP and FM have a 24 bytes header.
324
325 // recorder v1 has the binary length in the first 4 bytes, so check
326 // for them first.
327 int len = (header[0]<<24) | (header[1]<<16) | (header[2]<<8) | header[3];
328 LOG_INFO() << "abjrec.ajz possible bin length:" << len
329 << "file len:" << f.size();
330 if((f.size() - 6) == len)
331 return "recorder";
332
333 // size didn't match, now we need to assume we have a headerlength of 24.
334 switch(header[11]) {
335 case 2:
336 return "recorderv2";
337 case 4:
338 return "fmrecorder";
339 case 8:
340 return "ondiofm";
341 case 16:
342 return "ondiosp";
343 default:
344 break;
345 }
346 return QString();
347}
348
349
350int Autodetection::findDetectedDevice(QString device)
351{
352 int i = m_detected.size();
353 while(i--) {
354 if(m_detected.at(i).usbdevices.contains(device))
355 return i;
356 }
357 i = m_detected.size();
358 while(i--) {
359 if(m_detected.at(i).device == device)
360 return i;
361 }
362 return -1;
363}
364
365
366void Autodetection::updateDetectedDevice(Detected& entry)
367{
368 int index = findDetectedDevice(entry.device);
369 if(index < 0) {
370 m_detected.append(entry);
371 }
372 else {
373 m_detected.takeAt(index);
374 m_detected.append(entry);
375 }
376}
diff --git a/utils/rbutilqt/base/autodetection.h b/utils/rbutilqt/base/autodetection.h
new file mode 100644
index 0000000000..cdbb94d303
--- /dev/null
+++ b/utils/rbutilqt/base/autodetection.h
@@ -0,0 +1,72 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21
22#ifndef AUTODETECTION_H_
23#define AUTODETECTION_H_
24
25#include <QObject>
26#include <QString>
27#include <QList>
28#include <QStringList>
29
30class Autodetection :public QObject
31{
32 Q_OBJECT
33
34public:
35 Autodetection(QObject* parent=nullptr);
36
37 enum PlayerStatus {
38 PlayerOk,
39 PlayerIncompatible,
40 PlayerMtpMode,
41 PlayerWrongFilesystem,
42 PlayerError,
43 PlayerAmbiguous,
44 };
45
46 struct Detected {
47 QString device;
48 QStringList usbdevices;
49 QString mountpoint;
50 enum PlayerStatus status;
51 };
52
53 bool detect();
54
55 QList<struct Detected> detected(void) { return m_detected; }
56
57private:
58 QString resolveMountPoint(QString);
59 void detectUsb(void);
60 void mergeMounted(void);
61 void mergePatcher(void);
62 QString detectAjbrec(QString);
63 int findDetectedDevice(QString device);
64 void updateDetectedDevice(struct Detected& entry);
65
66 QList<struct Detected> m_detected;
67 QList<int> m_usbconid;
68};
69
70
71#endif /*AUTODETECTION_H_*/
72
diff --git a/utils/rbutilqt/base/bootloaderinstallams.cpp b/utils/rbutilqt/base/bootloaderinstallams.cpp
new file mode 100644
index 0000000000..be43ed52db
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallams.cpp
@@ -0,0 +1,201 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include "bootloaderinstallbase.h"
21#include "bootloaderinstallams.h"
22#include "Logger.h"
23
24#include "../mkamsboot/mkamsboot.h"
25
26BootloaderInstallAms::BootloaderInstallAms(QObject *parent)
27 : BootloaderInstallBase(parent)
28{
29}
30
31QString BootloaderInstallAms::ofHint()
32{
33 return tr("Bootloader installation requires you to provide "
34 "a copy of the original Sandisk firmware (bin file). "
35 "This firmware file will be patched and then installed to your "
36 "player along with the rockbox bootloader. "
37 "You need to download this file yourself due to legal "
38 "reasons. Please browse the "
39 "<a href='http://forums.sandisk.com/sansa/'>Sansa Forums</a> "
40 "or refer to the "
41 "<a href='http://www.rockbox.org/manual.shtml'>manual</a> and "
42 "the <a href='http://www.rockbox.org/wiki/SansaAMS'>SansaAMS</a> "
43 "wiki page on how to obtain this file.<br/>"
44 "<b>Note:</b> This file is not present on your player and will "
45 "disappear automatically after installing it.<br/><br/>"
46 "Press Ok to continue and browse your computer for the firmware "
47 "file.");
48}
49
50bool BootloaderInstallAms::install(void)
51{
52 if(m_offile.isEmpty())
53 return false;
54
55 LOG_INFO() << "installing bootloader";
56
57 // download firmware from server
58 emit logItem(tr("Downloading bootloader file"), LOGINFO);
59
60 connect(this, &BootloaderInstallBase::downloadDone, this, &BootloaderInstallAms::installStage2);
61 downloadBlStart(m_blurl);
62
63 return true;
64}
65
66void BootloaderInstallAms::installStage2(void)
67{
68 LOG_INFO() << "installStage2";
69
70 unsigned char* buf;
71 unsigned char* of_packed;
72 int of_packedsize;
73 unsigned char* rb_packed;
74 int rb_packedsize;
75 off_t len;
76 struct md5sums sum;
77 char md5sum[33]; /* 32 hex digits, plus terminating zero */
78 int n;
79 int model;
80 int firmware_size;
81 int bootloader_size;
82 int patchable;
83 int totalsize;
84 char errstr[200];
85
86 sum.md5 = md5sum;
87
88 m_tempfile.open();
89 QString bootfile = m_tempfile.fileName();
90 m_tempfile.close();
91
92 /* Load bootloader file */
93 rb_packed = load_rockbox_file(bootfile.toLocal8Bit().data(), &model,
94 &bootloader_size,&rb_packedsize,
95 errstr,sizeof(errstr));
96 if (rb_packed == nullptr)
97 {
98 LOG_ERROR() << "could not load bootloader: " << bootfile;
99 emit logItem(errstr, LOGERROR);
100 emit logItem(tr("Could not load %1").arg(bootfile), LOGERROR);
101 emit done(true);
102 return;
103 }
104
105 /* Load original firmware file */
106 buf = load_of_file(m_offile.toLocal8Bit().data(), model, &len, &sum,
107 &firmware_size, &of_packed ,&of_packedsize,
108 errstr, sizeof(errstr));
109 if (buf == nullptr)
110 {
111 LOG_ERROR() << "could not load OF: " << m_offile;
112 emit logItem(errstr, LOGERROR);
113 emit logItem(tr("Could not load %1").arg(m_offile), LOGERROR);
114 free(rb_packed);
115 emit done(true);
116 return;
117 }
118
119 /* check total size */
120 patchable = check_sizes(sum.model, rb_packedsize, bootloader_size,
121 of_packedsize, firmware_size, &totalsize, errstr, sizeof(errstr));
122
123 if (!patchable)
124 {
125 LOG_ERROR() << "No room to insert bootloader";
126 emit logItem(errstr, LOGERROR);
127 emit logItem(tr("No room to insert bootloader, try another firmware version"),
128 LOGERROR);
129 free(buf);
130 free(of_packed);
131 free(rb_packed);
132 emit done(true);
133 return;
134 }
135
136 /* patch the firmware */
137 emit logItem(tr("Patching Firmware..."), LOGINFO);
138
139 patch_firmware(sum.model,firmware_revision(sum.model),firmware_size,buf,
140 len,of_packed,of_packedsize,rb_packed,rb_packedsize);
141
142 /* write out file */
143 QFile out(m_blfile);
144
145 if(!out.open(QIODevice::WriteOnly | QIODevice::Truncate))
146 {
147 LOG_ERROR() << "Could not open" << m_blfile << "for writing";
148 emit logItem(tr("Could not open %1 for writing").arg(m_blfile),LOGERROR);
149 free(buf);
150 free(of_packed);
151 free(rb_packed);
152 emit done(true);
153 return;
154 }
155
156 n = out.write((char*)buf, len);
157
158 if (n != len)
159 {
160 LOG_ERROR() << "Could not write firmware file";
161 emit logItem(tr("Could not write firmware file"),LOGERROR);
162 free(buf);
163 free(of_packed);
164 free(rb_packed);
165 emit done(true);
166 return;
167 }
168
169 out.close();
170
171 free(buf);
172 free(of_packed);
173 free(rb_packed);
174
175 //end of install
176 LOG_INFO() << "install successfull";
177 emit logItem(tr("Success: modified firmware file created"), LOGINFO);
178 logInstall(LogAdd);
179 emit done(false);
180 return;
181}
182
183bool BootloaderInstallAms::uninstall(void)
184{
185 emit logItem(tr("To uninstall, perform a normal upgrade with an unmodified "
186 "original firmware"), LOGINFO);
187 logInstall(LogRemove);
188 emit done(true);
189 return false;
190}
191
192BootloaderInstallBase::BootloaderType BootloaderInstallAms::installed(void)
193{
194 return BootloaderUnknown;
195}
196
197BootloaderInstallBase::Capabilities BootloaderInstallAms::capabilities(void)
198{
199 return (Install | NeedsOf);
200}
201
diff --git a/utils/rbutilqt/base/bootloaderinstallams.h b/utils/rbutilqt/base/bootloaderinstallams.h
new file mode 100644
index 0000000000..f3ce15ed24
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallams.h
@@ -0,0 +1,42 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18#ifndef BOOTLOADERINSTALLAMS_H
19#define BOOTLOADERINSTALLAMS_H
20
21#include <QtCore>
22#include "bootloaderinstallbase.h"
23
24//! bootloader installation derivate based on mkamsboot
25class BootloaderInstallAms : public BootloaderInstallBase
26{
27 Q_OBJECT
28 public:
29 BootloaderInstallAms(QObject *parent);
30 bool install(void);
31 bool uninstall(void);
32 BootloaderInstallBase::BootloaderType installed(void);
33 Capabilities capabilities(void);
34 QString ofHint();
35
36 private:
37
38 private slots:
39 void installStage2(void);
40};
41
42#endif
diff --git a/utils/rbutilqt/base/bootloaderinstallbase.cpp b/utils/rbutilqt/base/bootloaderinstallbase.cpp
new file mode 100644
index 0000000000..096c601b91
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallbase.cpp
@@ -0,0 +1,302 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19
20#include <QtCore>
21
22#include "bootloaderinstallbase.h"
23#include "utils.h"
24#include "ziputil.h"
25#include "mspackutil.h"
26#include "Logger.h"
27
28#if defined(Q_OS_MACX)
29#include <sys/param.h>
30#include <sys/ucred.h>
31#include <sys/mount.h>
32#endif
33
34
35BootloaderInstallBase::BootloaderType BootloaderInstallBase::installed(void)
36{
37 return BootloaderUnknown;
38}
39
40
41BootloaderInstallBase::Capabilities BootloaderInstallBase::capabilities(void)
42{
43 return Capabilities();
44}
45
46
47void BootloaderInstallBase::downloadBlStart(QUrl source)
48{
49 m_http.setFile(&m_tempfile);
50 m_http.setCache(true);
51 connect(&m_http, &HttpGet::done, this, &BootloaderInstallBase::downloadBlFinish);
52 // connect the http read signal to our logProgess *signal*
53 // to immediately emit it without any helper function.
54 connect(&m_http, &HttpGet::dataReadProgress,
55 this, &BootloaderInstallBase::logProgress);
56 m_http.getFile(source);
57}
58
59
60void BootloaderInstallBase::downloadReqFinished(int id, bool error)
61{
62 LOG_INFO() << "Download Request" << id
63 << "finished, error:" << m_http.errorString();
64
65 downloadBlFinish(error);
66}
67
68
69void BootloaderInstallBase::downloadBlFinish(bool error)
70{
71 LOG_INFO() << "Downloading bootloader finished, error:"
72 << error;
73
74 // update progress bar
75 emit logProgress(100, 100);
76
77 if(m_http.httpResponse() != 200) {
78 emit logItem(tr("Download error: received HTTP error %1.")
79 .arg(m_http.errorString()), LOGERROR);
80 emit done(true);
81 return;
82 }
83 if(error) {
84 emit logItem(tr("Download error: %1")
85 .arg(m_http.errorString()), LOGERROR);
86 emit done(true);
87 return;
88 }
89 else if(m_http.isCached())
90 emit logItem(tr("Download finished (cache used)."), LOGOK);
91 else
92 emit logItem(tr("Download finished."), LOGOK);
93
94 QCoreApplication::processEvents();
95 m_blversion = m_http.timestamp();
96 emit downloadDone();
97}
98
99
100void BootloaderInstallBase::installBlfile(void)
101{
102 LOG_INFO() << "installBlFile(void)";
103}
104
105
106void BootloaderInstallBase::progressAborted(void)
107{
108 LOG_INFO() << "progressAborted(void)";
109 emit installAborted();
110}
111
112
113//! @brief backup OF file.
114//! @param to folder to write backup file to. Folder will get created.
115//! @return true on success, false on error.
116bool BootloaderInstallBase::backup(QString to)
117{
118 LOG_INFO() << "Backing up bootloader file";
119 QDir targetDir(".");
120 emit logItem(tr("Creating backup of original firmware file."), LOGINFO);
121 if(!targetDir.mkpath(to)) {
122 emit logItem(tr("Creating backup folder failed"), LOGERROR);
123 return false;
124 }
125 QString tofile = to + "/" + QFileInfo(m_blfile).fileName();
126 LOG_INFO() << "trying to backup" << m_blfile << "to" << tofile;
127 if(!QFile::copy(Utils::resolvePathCase(m_blfile), tofile)) {
128 emit logItem(tr("Creating backup copy failed."), LOGERROR);
129 return false;
130 }
131 emit logItem(tr("Backup created."), LOGOK);
132 return true;
133}
134
135
136//! @brief log installation to logfile.
137//! @param mode action to perform. 0: add to log, 1: remove from log.
138//! @return 0 on success
139int BootloaderInstallBase::logInstall(LogMode mode)
140{
141 int result = 0;
142 QString section = m_blurl.path().section('/', -1);
143 QSettings s(m_logfile, QSettings::IniFormat, this);
144 emit logItem(tr("Creating installation log"), LOGINFO);
145
146 if(mode == LogAdd) {
147 s.setValue("Bootloader/" + section, m_blversion.toString(Qt::ISODate));
148 LOG_INFO() << "Writing log, version:"
149 << m_blversion.toString(Qt::ISODate);
150 }
151 else {
152 s.remove("Bootloader/" + section);
153 }
154 s.sync();
155
156 emit logItem(tr("Installation log created"), LOGOK);
157
158 return result;
159}
160
161
162#if defined(Q_OS_MACX)
163void BootloaderInstallBase::waitRemount()
164{
165 m_remountTries = 600;
166 emit logItem(tr("Waiting for system to remount player"), LOGINFO);
167
168 QTimer::singleShot(100, this, SLOT(checkRemount()));
169}
170#endif
171
172
173void BootloaderInstallBase::checkRemount()
174{
175#if defined(Q_OS_MACX)
176 if(m_remountTries--) {
177 int status = 0;
178 // check if device has been remounted
179 QCoreApplication::processEvents();
180 int num;
181 struct statfs *mntinf;
182
183 num = getmntinfo(&mntinf, MNT_WAIT);
184 while(num--) {
185 if(QString(mntinf->f_mntfromname).startsWith(m_remountDevice)
186 && QString(mntinf->f_fstypename).contains("msdos", Qt::CaseInsensitive))
187 status = 1;
188 mntinf++;
189 }
190 if(!status) {
191 // still not remounted, restart timer.
192 QTimer::singleShot(500, this, SLOT(checkRemount()));
193 LOG_INFO() << "Player not remounted yet" << m_remountDevice;
194 }
195 else {
196 emit logItem(tr("Player remounted"), LOGINFO);
197 emit remounted(true);
198 }
199 }
200 else {
201 emit logItem(tr("Timeout on remount"), LOGERROR);
202 emit remounted(false);
203 }
204#endif
205}
206
207
208//! @brief set list of possible bootloader files and pick the existing one.
209//! @param sl list of possible bootloader files.
210void BootloaderInstallBase::setBlFile(QStringList sl)
211{
212 // figue which of the possible bootloader filenames is correct.
213 for(int a = 0; a < sl.size(); a++) {
214 if(!Utils::resolvePathCase(sl.at(a)).isEmpty()) {
215 m_blfile = sl.at(a);
216 }
217 }
218 if(m_blfile.isEmpty()) {
219 m_blfile = sl.at(0);
220 }
221}
222
223
224bool BootloaderInstallBase::setOfFile(QString of, QStringList blfile)
225{
226 bool found = false;
227 ArchiveUtil *util = nullptr;
228
229 // check if we're actually looking for a zip file. If so we must avoid
230 // trying to unzip it.
231 bool wantZip = false;
232 for (int i = 0; i < blfile.size(); i++)
233 {
234 if (blfile.at(i).endsWith(".zip"))
235 wantZip = true;
236 }
237
238 // try ZIP first
239 ZipUtil *zu = new ZipUtil(this);
240 if(zu->open(of) && !wantZip)
241 {
242 emit logItem(tr("Zip file format detected"), LOGINFO);
243 util = zu;
244 }
245 else
246 delete zu;
247
248 // if ZIP failed, try CAB
249 if(util == nullptr)
250 {
251 MsPackUtil *msu = new MsPackUtil(this);
252 if(msu->open(of))
253 {
254 emit logItem(tr("CAB file format detected"), LOGINFO);
255 util = msu;
256 }
257 else
258 delete msu;
259 }
260
261 // check if the file set is in zip format
262 if(util) {
263 QStringList contents = util->files();
264 LOG_INFO() << "archive contains:" << contents;
265 for(int i = 0; i < blfile.size(); ++i) {
266 // strip any path, we don't know the structure in the zip
267 QString f = QFileInfo(blfile.at(i)).fileName();
268 LOG_INFO() << "searching archive for" << f;
269 // contents.indexOf() works case sensitive. Since the filename
270 // casing is unknown (and might change) do this manually.
271 // FIXME: support files in folders
272 for(int j = 0; j < contents.size(); ++j) {
273 if(contents.at(j).compare(f, Qt::CaseInsensitive) == 0) {
274 found = true;
275 emit logItem(tr("Extracting firmware %1 from archive")
276 .arg(f), LOGINFO);
277 // store in class temporary file
278 m_tempof.open();
279 m_offile = m_tempof.fileName();
280 m_tempof.close();
281 if(!util->extractArchive(m_offile, contents.at(j))) {
282 emit logItem(tr("Error extracting firmware from archive"), LOGERROR);
283 found = false;
284 break;
285 }
286 break;
287 }
288 }
289 }
290 if(!found) {
291 emit logItem(tr("Could not find firmware in archive"), LOGERROR);
292 }
293 delete util;
294 }
295 else {
296 m_offile = of;
297 found = true;
298 }
299
300 return found;
301}
302
diff --git a/utils/rbutilqt/base/bootloaderinstallbase.h b/utils/rbutilqt/base/bootloaderinstallbase.h
new file mode 100644
index 0000000000..23aac4f92f
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallbase.h
@@ -0,0 +1,118 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef BOOTLOADERINSTALLBASE_H
20#define BOOTLOADERINSTALLBASE_H
21
22#include <QtCore>
23#include "progressloggerinterface.h"
24#include "httpget.h"
25
26//! baseclass for all Bootloader installs
27class BootloaderInstallBase : public QObject
28{
29 Q_OBJECT
30 public:
31 enum Capability
32 { Install = 0x01, Uninstall = 0x02, Backup = 0x04,
33 IsFile = 0x08, IsRaw = 0x10, NeedsOf = 0x20,
34 CanCheckInstalled = 0x40, CanCheckVersion = 0x80 };
35 Q_DECLARE_FLAGS(Capabilities, Capability)
36
37 enum BootloaderType
38 { BootloaderNone, BootloaderRockbox, BootloaderOther, BootloaderUnknown };
39
40 BootloaderInstallBase(QObject *parent) : QObject(parent)
41 { }
42
43 //! install the bootloader, must be implemented
44 virtual bool install(void) = 0;
45 //! uninstall the bootloader, must be implemented
46 virtual bool uninstall(void) = 0;
47 //! returns the installed bootloader
48 virtual BootloaderType installed(void)=0;
49 //! returns the capabilities of the bootloader class
50 virtual Capabilities capabilities(void)=0;
51 //! returns a OF Firmware hint or empty if there is none
52 virtual QString ofHint() {return QString();}
53
54 //! backup a already installed bootloader
55 bool backup(QString to);
56
57 //! set the different filenames and paths
58 void setBlFile(QStringList f);
59 void setBlUrl(QUrl u)
60 { m_blurl = u; }
61 void setLogfile(QString f)
62 { m_logfile = f; }
63 bool setOfFile(QString of, QStringList blfile);
64
65 //! returns a port Install Hint or empty if there is none
66 //! static and in the base class, so the installer classes dont need to
67 // be modified for new targets
68 static QString postinstallHints(QString model);
69
70 //! returns the correct BootloaderInstaller object for the requested type
71 static BootloaderInstallBase* createBootloaderInstaller(QObject* parent,QString type);
72 protected slots:
73 void downloadReqFinished(int id, bool error);
74 void downloadBlFinish(bool error);
75 void installBlfile(void);
76 void progressAborted(void);
77
78 // NOTE: we need to keep this slot even on targets that don't need it
79 // -- using the preprocessor here confused moc.
80 void checkRemount(void);
81 protected:
82 enum LogMode
83 { LogAdd, LogRemove };
84
85 void downloadBlStart(QUrl source);
86 int logInstall(LogMode mode);
87
88 HttpGet m_http; //! http download object
89 QString m_blfile; //! bootloader filename on player
90 QString m_logfile; //! file for installation log
91 QUrl m_blurl; //! bootloader download URL
92 QTemporaryFile m_tempfile; //! temporary file for download
93 QTemporaryFile m_tempof; //! temporary file for OF extracted from archive
94 QDateTime m_blversion; //! download timestamp used for version information
95 QString m_offile; //! path to the offile
96#if defined(Q_OS_MACX)
97 void waitRemount(void);
98
99 int m_remountTries;
100 QString m_remountDevice;
101#endif
102
103 signals:
104 void downloadDone(void); //! internal signal sent when download finished.
105 void installAborted(void); //! internal signal sent on abort button click.
106 void done(bool);
107 void logItem(QString, int); //! set logger item
108 void logProgress(int, int); //! set progress bar.
109
110 // NOTE: we need to keep this signal even on targets that don't need it
111 // -- using the preprocessor here confused moc.
112 void remounted(bool);
113};
114
115Q_DECLARE_OPERATORS_FOR_FLAGS(BootloaderInstallBase::Capabilities)
116
117#endif
118
diff --git a/utils/rbutilqt/base/bootloaderinstallbspatch.cpp b/utils/rbutilqt/base/bootloaderinstallbspatch.cpp
new file mode 100644
index 0000000000..02291b0151
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallbspatch.cpp
@@ -0,0 +1,178 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2020 by Solomon Peachy
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include <QtDebug>
21#include "bootloaderinstallbase.h"
22#include "bootloaderinstallbspatch.h"
23#include "../bspatch/bspatch.h"
24#include "Logger.h"
25
26/* class for running bspatch() in a separate thread to keep the UI responsive. */
27class BootloaderThreadBSPatch : public QThread
28{
29 public:
30 void run(void);
31 void setInputFile(QString f)
32 { m_inputfile = f; }
33 void setOutputFile(QString f)
34 { m_outputfile = f; }
35 void setBootloaderFile(QString f)
36 { m_bootfile = f; }
37 int error(void)
38 { return m_error; }
39 private:
40 QString m_inputfile;
41 QString m_bootfile;
42 QString m_outputfile;
43 int m_error;
44};
45
46void BootloaderThreadBSPatch::run(void)
47{
48 LOG_INFO() << "Thread started.";
49
50 m_error = apply_bspatch(m_inputfile.toLocal8Bit().constData(),
51 m_outputfile.toLocal8Bit().constData(),
52 m_bootfile.toLocal8Bit().constData());
53
54 LOG_INFO() << "Thread finished, result:" << m_error;
55}
56
57BootloaderInstallBSPatch::BootloaderInstallBSPatch(QObject *parent)
58 : BootloaderInstallBase(parent)
59{
60 m_thread = nullptr;
61}
62
63QString BootloaderInstallBSPatch::ofHint()
64{
65 return tr("Bootloader installation requires you to provide "
66 "the correct verrsion of the original firmware file. "
67 "This file will be patched with the Rockbox bootloader and "
68 "installed to your player. You need to download this file "
69 "yourself due to legal reasons. Please refer to the "
70 "<a href='http://www.rockbox.org/wiki/'>rockbox wiki</a> "
71 "pages on how to obtain this file.<br/>"
72 "Press Ok to continue and browse your computer for the firmware "
73 "file.");
74}
75
76/** Start bootloader installation.
77 */
78bool BootloaderInstallBSPatch::install(void)
79{
80 if(!QFileInfo(m_offile).isReadable())
81 {
82 LOG_ERROR() << "could not read original firmware file"
83 << m_offile;
84 emit logItem(tr("Could not read original firmware file"), LOGERROR);
85 return false;
86 }
87
88 LOG_INFO() << "downloading bootloader";
89 // download bootloader from server
90 emit logItem(tr("Downloading bootloader file"), LOGINFO);
91 connect(this, &BootloaderInstallBase::downloadDone, this, &BootloaderInstallBSPatch::installStage2);
92 downloadBlStart(m_blurl);
93 return true;
94}
95
96void BootloaderInstallBSPatch::installStage2(void)
97{
98 LOG_INFO() << "patching file...";
99 emit logItem(tr("Patching file..."), LOGINFO);
100 m_tempfile.open();
101
102 // we have not detailed progress on the patching so just show a busy
103 // indicator instead.
104 emit logProgress(0, 0);
105 m_patchedFile.open();
106 m_thread = new BootloaderThreadBSPatch();
107 m_thread->setInputFile(m_offile);
108 m_thread->setBootloaderFile(m_tempfile.fileName());
109 m_thread->setOutputFile(m_patchedFile.fileName());
110 m_tempfile.close();
111 m_patchedFile.close();
112 connect(m_thread, &QThread::finished, this, &BootloaderInstallBSPatch::installStage3);
113 m_thread->start();
114}
115
116void BootloaderInstallBSPatch::installStage3(void)
117{
118 int err = m_thread->error();
119 emit logProgress(1, 1);
120 // if the patch failed
121 if (err != 0)
122 {
123 LOG_ERROR() << "Could not patch the original firmware file";
124 emit logItem(tr("Patching the original firmware failed"), LOGERROR);
125 emit done(true);
126 return;
127 }
128
129 LOG_INFO() << "Original Firmware succesfully patched";
130 emit logItem(tr("Succesfully patched firmware file"), LOGINFO);
131
132 // if a bootloader is already present delete it.
133 QString fwfile(m_blfile);
134 if(QFileInfo(fwfile).isFile())
135 {
136 LOG_INFO() << "deleting old target file";
137 QFile::remove(fwfile);
138 }
139
140 // place (new) bootloader. Copy, since the temporary file will be removed
141 // automatically.
142 LOG_INFO() << "moving patched bootloader to" << fwfile;
143 if(m_patchedFile.copy(fwfile))
144 {
145 emit logItem(tr("Bootloader successful installed"), LOGOK);
146 logInstall(LogAdd);
147 emit done(false);
148 }
149 else
150 {
151 emit logItem(tr("Patched bootloader could not be installed"), LOGERROR);
152 emit done(true);
153 }
154 // clean up thread object.
155 delete m_thread;
156 return;
157}
158
159bool BootloaderInstallBSPatch::uninstall(void)
160{
161 emit logItem(tr("To uninstall, perform a normal upgrade with an unmodified "
162 "original firmware."), LOGINFO);
163 logInstall(LogRemove);
164 emit done(true);
165 return false;
166}
167
168
169BootloaderInstallBase::BootloaderType BootloaderInstallBSPatch::installed(void)
170{
171 return BootloaderUnknown;
172}
173
174
175BootloaderInstallBase::Capabilities BootloaderInstallBSPatch::capabilities(void)
176{
177 return (Install | NeedsOf);
178}
diff --git a/utils/rbutilqt/base/bootloaderinstallbspatch.h b/utils/rbutilqt/base/bootloaderinstallbspatch.h
new file mode 100644
index 0000000000..7108820fda
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallbspatch.h
@@ -0,0 +1,47 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2020 Solomon Peachy
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18#ifndef BOOTLOADERINSTALLBSPATCH_H
19#define BOOTLOADERINSTALLBSPATCH_H
20
21#include <QtCore>
22#include "bootloaderinstallbase.h"
23
24class BootloaderThreadBSPatch;
25
26//! bootloader installation class for devices handled by mkimxboot.
27class BootloaderInstallBSPatch : public BootloaderInstallBase
28{
29 Q_OBJECT
30 public:
31 BootloaderInstallBSPatch(QObject *parent);
32 bool install(void);
33 bool uninstall(void);
34 BootloaderInstallBase::BootloaderType installed(void);
35 Capabilities capabilities(void);
36 QString ofHint();
37
38 private slots:
39 void installStage2(void);
40 void installStage3(void);
41
42 private:
43 BootloaderThreadBSPatch *m_thread;
44 QTemporaryFile m_patchedFile;
45};
46
47#endif
diff --git a/utils/rbutilqt/base/bootloaderinstallchinachip.cpp b/utils/rbutilqt/base/bootloaderinstallchinachip.cpp
new file mode 100644
index 0000000000..f6af952b9a
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallchinachip.cpp
@@ -0,0 +1,133 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2009 by Maurus Cuelenaere
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include "bootloaderinstallbase.h"
21#include "bootloaderinstallchinachip.h"
22
23#include "../chinachippatcher/chinachip.h"
24
25BootloaderInstallChinaChip::BootloaderInstallChinaChip(QObject *parent)
26 : BootloaderInstallBase(parent)
27{
28 (void)parent;
29}
30
31QString BootloaderInstallChinaChip::ofHint()
32{
33 return tr("Bootloader installation requires you to provide "
34 "a firmware file of the original firmware (HXF file). "
35 "You need to download this file yourself due to legal "
36 "reasons. Please refer to the "
37 "<a href='http://www.rockbox.org/manual.shtml'>manual</a> and the "
38 "<a href='http://www.rockbox.org/wiki/OndaVX747"
39 "#Download_and_extract_a_recent_ve'>OndaVX747</a> wiki page on "
40 "how to obtain this file.<br/>"
41 "Press Ok to continue and browse your computer for the firmware "
42 "file.");
43}
44
45bool BootloaderInstallChinaChip::install()
46{
47 if(m_offile.isEmpty())
48 return false;
49
50 emit logItem(tr("Downloading bootloader file"), LOGINFO);
51
52 connect(this, &BootloaderInstallBase::downloadDone, this, &BootloaderInstallChinaChip::installStage2);
53 downloadBlStart(m_blurl);
54
55 return true;
56}
57
58void BootloaderInstallChinaChip::installStage2()
59{
60 enum cc_error result;
61 bool error = true;
62 m_tempfile.open();
63 QString blfile = m_tempfile.fileName();
64 m_tempfile.close();
65
66 QString backupfile = QFileInfo(m_blfile).absoluteDir().absoluteFilePath("ccpmp.bin");
67
68 result = chinachip_patch(m_offile.toLocal8Bit(), blfile.toLocal8Bit(),
69 m_blfile.toLocal8Bit(), backupfile.toLocal8Bit());
70 switch(result) {
71 case E_OK:
72 error = false;
73 break;
74 case E_OPEN_FIRMWARE:
75 emit logItem(tr("Could not open firmware file"), LOGERROR);
76 break;
77 case E_OPEN_BOOTLOADER:
78 emit logItem(tr("Could not open bootloader file"), LOGERROR);
79 break;
80 case E_MEMALLOC:
81 emit logItem(tr("Could not allocate memory"), LOGERROR);
82 break;
83 case E_LOAD_FIRMWARE:
84 emit logItem(tr("Could not load firmware file"), LOGERROR);
85 break;
86 case E_INVALID_FILE:
87 emit logItem(tr("File is not a valid ChinaChip firmware"), LOGERROR);
88 break;
89 case E_NO_CCPMP:
90 emit logItem(tr("Could not find ccpmp.bin in input file"), LOGERROR);
91 break;
92 case E_OPEN_BACKUP:
93 emit logItem(tr("Could not open backup file for ccpmp.bin"), LOGERROR);
94 break;
95 case E_WRITE_BACKUP:
96 emit logItem(tr("Could not write backup file for ccpmp.bin"), LOGERROR);
97 break;
98 case E_LOAD_BOOTLOADER:
99 emit logItem(tr("Could not load bootloader file"), LOGERROR);
100 break;
101 case E_GET_TIME:
102 emit logItem(tr("Could not get current time"), LOGERROR);
103 break;
104 case E_OPEN_OUTFILE:
105 emit logItem(tr("Could not open output file"), LOGERROR);
106 break;
107 case E_WRITE_OUTFILE:
108 emit logItem(tr("Could not write output file"), LOGERROR);
109 break;
110 default:
111 emit logItem(tr("Unexpected error from chinachippatcher"), LOGERROR);
112 break;
113 }
114
115 emit done(error);
116}
117
118bool BootloaderInstallChinaChip::uninstall()
119{
120 /* TODO: only way is to restore the OF */
121 return false;
122}
123
124BootloaderInstallBase::BootloaderType BootloaderInstallChinaChip::installed()
125{
126 /* TODO: find a way to figure this out */
127 return BootloaderUnknown;
128}
129
130BootloaderInstallBase::Capabilities BootloaderInstallChinaChip::capabilities()
131{
132 return (Install | IsFile | NeedsOf);
133}
diff --git a/utils/rbutilqt/base/bootloaderinstallchinachip.h b/utils/rbutilqt/base/bootloaderinstallchinachip.h
new file mode 100644
index 0000000000..e92f292283
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallchinachip.h
@@ -0,0 +1,41 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2009 by Maurus Cuelenaere
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef BOOTLOADERINSTALLCCPMP_H
20#define BOOTLOADERINSTALLCCPMP_H
21
22#include <QtCore>
23#include "bootloaderinstallbase.h"
24
25class BootloaderInstallChinaChip : public BootloaderInstallBase
26{
27 Q_OBJECT
28
29 public:
30 BootloaderInstallChinaChip(QObject *parent = nullptr);
31 bool install(void);
32 bool uninstall(void);
33 BootloaderInstallBase::BootloaderType installed(void);
34 Capabilities capabilities(void);
35 QString ofHint();
36
37 private slots:
38 void installStage2(void);
39};
40
41#endif // BOOTLOADERINSTALLCCPMP_H
diff --git a/utils/rbutilqt/base/bootloaderinstallfile.cpp b/utils/rbutilqt/base/bootloaderinstallfile.cpp
new file mode 100644
index 0000000000..bf3d5e449d
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallfile.cpp
@@ -0,0 +1,159 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include <QtDebug>
21#include "bootloaderinstallfile.h"
22#include "utils.h"
23#include "Logger.h"
24
25
26BootloaderInstallFile::BootloaderInstallFile(QObject *parent)
27 : BootloaderInstallBase(parent)
28{
29}
30
31
32bool BootloaderInstallFile::install(void)
33{
34 emit logItem(tr("Downloading bootloader"), LOGINFO);
35 LOG_INFO() << "installing bootloader";
36 downloadBlStart(m_blurl);
37 connect(this, &BootloaderInstallBase::downloadDone, this, &BootloaderInstallFile::installStage2);
38 return true;
39}
40
41void BootloaderInstallFile::installStage2(void)
42{
43 emit logItem(tr("Installing Rockbox bootloader"), LOGINFO);
44 QCoreApplication::processEvents();
45
46 // if an old bootloader is present (Gigabeat) move it out of the way.
47 QString fwfile(Utils::resolvePathCase(m_blfile));
48 if(!fwfile.isEmpty()) {
49 QString moved = Utils::resolvePathCase(m_blfile) + ".ORIG";
50 LOG_INFO() << "renaming" << fwfile << "to" << moved;
51 QFile::rename(fwfile, moved);
52 }
53
54 // if no old file found resolve path without basename
55 QFileInfo fi(m_blfile);
56 QString absPath = Utils::resolvePathCase(fi.absolutePath());
57
58 // if it's not possible to locate the base path try to create it
59 if(absPath.isEmpty()) {
60 QStringList pathElements = m_blfile.split("/");
61 // remove filename from list and save last path element
62 pathElements.removeLast();
63 QString lastElement = pathElements.last();
64 // remove last path element for base
65 pathElements.removeLast();
66 QString basePath = pathElements.join("/");
67
68 // check for base and bail out if not found. Otherwise create folder.
69 absPath = Utils::resolvePathCase(basePath);
70 QDir d(absPath);
71 d.mkpath(lastElement);
72 absPath = Utils::resolvePathCase(fi.absolutePath());
73
74 if(absPath.isEmpty()) {
75 emit logItem(tr("Error accessing output folder"), LOGERROR);
76 emit done(true);
77 return;
78 }
79 }
80 fwfile = absPath + "/" + fi.fileName();
81
82 // place (new) bootloader
83 m_tempfile.open();
84 LOG_INFO() << "renaming" << m_tempfile.fileName()
85 << "to" << fwfile;
86 m_tempfile.close();
87
88 if(!Utils::resolvePathCase(fwfile).isEmpty()) {
89 emit logItem(tr("A firmware file is already present on player"), LOGERROR);
90 emit done(true);
91 return;
92 }
93 if(m_tempfile.copy(fwfile)) {
94 emit logItem(tr("Bootloader successful installed"), LOGOK);
95 }
96 else {
97 emit logItem(tr("Copying modified firmware file failed"), LOGERROR);
98 emit done(true);
99 return;
100 }
101
102 logInstall(LogAdd);
103
104 emit done(false);
105}
106
107
108bool BootloaderInstallFile::uninstall(void)
109{
110 LOG_INFO() << "Uninstalling bootloader";
111 emit logItem(tr("Removing Rockbox bootloader"), LOGINFO);
112 // check if a .ORIG file is present, and allow moving it back.
113 QString origbl = Utils::resolvePathCase(m_blfile + ".ORIG");
114 if(origbl.isEmpty()) {
115 emit logItem(tr("No original firmware file found."), LOGERROR);
116 emit done(true);
117 return false;
118 }
119 QString fwfile = Utils::resolvePathCase(m_blfile);
120 if(!QFile::remove(fwfile)) {
121 emit logItem(tr("Can't remove Rockbox bootloader file."), LOGERROR);
122 emit done(true);
123 return false;
124 }
125 if(!QFile::rename(origbl, fwfile)) {
126 emit logItem(tr("Can't restore bootloader file."), LOGERROR);
127 emit done(true);
128 return false;
129 }
130 emit logItem(tr("Original bootloader restored successfully."), LOGOK);
131 logInstall(LogRemove);
132 emit logProgress(1, 1);
133 emit done(false);
134
135 return true;
136}
137
138
139//! @brief check if bootloader is installed.
140//! @return BootloaderRockbox, BootloaderOther or BootloaderUnknown.
141BootloaderInstallBase::BootloaderType BootloaderInstallFile::installed(void)
142{
143 LOG_INFO() << "checking installed bootloader";
144 if(!Utils::resolvePathCase(m_blfile).isEmpty()
145 && !Utils::resolvePathCase(m_blfile + ".ORIG").isEmpty())
146 return BootloaderRockbox;
147 else if(!Utils::resolvePathCase(m_blfile).isEmpty())
148 return BootloaderOther;
149 else
150 return BootloaderUnknown;
151}
152
153
154BootloaderInstallBase::Capabilities BootloaderInstallFile::capabilities(void)
155{
156 LOG_INFO() << "getting capabilities";
157 return Install | Uninstall | IsFile | CanCheckInstalled | Backup;
158}
159
diff --git a/utils/rbutilqt/base/bootloaderinstallfile.h b/utils/rbutilqt/base/bootloaderinstallfile.h
new file mode 100644
index 0000000000..9f9586279c
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallfile.h
@@ -0,0 +1,48 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef BOOTLOADERINSTALLFILE_H
20#define BOOTLOADERINSTALLFILE_H
21
22#include <QtCore>
23#include "progressloggerinterface.h"
24#include "bootloaderinstallbase.h"
25
26//! install a bootloader by putting a single file on the player.
27// This installation method is used by Iaudio (firmware is flashed
28// automatically) and Gigabeat (Firmware is a file, OF needs to get
29// renamed).
30class BootloaderInstallFile : public BootloaderInstallBase
31{
32 Q_OBJECT
33
34 public:
35 BootloaderInstallFile(QObject *parent);
36 bool install(void);
37 bool uninstall(void);
38 BootloaderInstallBase::BootloaderType installed(void);
39 Capabilities capabilities(void);
40
41 private slots:
42 void installStage2(void);
43
44 private:
45};
46
47#endif
48
diff --git a/utils/rbutilqt/base/bootloaderinstallhelper.cpp b/utils/rbutilqt/base/bootloaderinstallhelper.cpp
new file mode 100644
index 0000000000..c94ed29140
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallhelper.cpp
@@ -0,0 +1,140 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2012 Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 * This file is a modified version of the AMS installer by Dominik Wenger
18 *
19 ****************************************************************************/
20
21#include <QtCore>
22
23#include "bootloaderinstallhelper.h"
24#include "bootloaderinstallmi4.h"
25#include "bootloaderinstallhex.h"
26#include "bootloaderinstallipod.h"
27#include "bootloaderinstallsansa.h"
28#include "bootloaderinstallfile.h"
29#include "bootloaderinstallchinachip.h"
30#include "bootloaderinstallams.h"
31#include "bootloaderinstalltcc.h"
32#include "bootloaderinstallmpio.h"
33#include "bootloaderinstallimx.h"
34#include "bootloaderinstalls5l.h"
35#include "bootloaderinstallbspatch.h"
36
37BootloaderInstallBase* BootloaderInstallHelper::createBootloaderInstaller(QObject* parent, QString type)
38{
39 if(type == "mi4") {
40 return new BootloaderInstallMi4(parent);
41 }
42 else if(type == "hex") {
43 return new BootloaderInstallHex(parent);
44 }
45 else if(type == "sansa") {
46 return new BootloaderInstallSansa(parent);
47 }
48 else if(type == "ipod") {
49 return new BootloaderInstallIpod(parent);
50 }
51 else if(type == "file") {
52 return new BootloaderInstallFile(parent);
53 }
54 else if(type == "chinachip") {
55 return new BootloaderInstallChinaChip(parent);
56 }
57 else if(type == "ams") {
58 return new BootloaderInstallAms(parent);
59 }
60 else if(type == "tcc") {
61 return new BootloaderInstallTcc(parent);
62 }
63 else if(type == "mpio") {
64 return new BootloaderInstallMpio(parent);
65 }
66 else if(type == "imx") {
67 return new BootloaderInstallImx(parent);
68 }
69 else if(type == "s5l") {
70 return new BootloaderInstallS5l(parent);
71 }
72 else if(type == "bspatch") {
73 return new BootloaderInstallBSPatch(parent);
74 }
75 else {
76 return nullptr;
77 }
78}
79
80
81//! @brief Return post install hints string.
82//! @param model model string
83//! @return hints.
84QString BootloaderInstallHelper::postinstallHints(QString model)
85{
86 bool hint = false;
87 QString msg = QObject::tr("Bootloader installation is almost complete. "
88 "Installation <b>requires</b> you to perform the "
89 "following steps manually:");
90
91 msg += "<ol>";
92 if(model != "sansafuzeplus") {
93 msg += QObject::tr("<li>Safely remove your player.</li>");
94 }
95 if(model == "iriverh100" || model == "iriverh120" || model == "iriverh300"
96 || model == "ondavx747" || model == "agptekrocker"
97 || model == "xduoox3" || model == "xduoox3ii" || model == "xduoox20") {
98 hint = true;
99 msg += QObject::tr("<li>Reboot your player into the original firmware.</li>"
100 "<li>Perform a firmware upgrade using the update functionality "
101 "of the original firmware. Please refer to your player's manual "
102 "on details.<br/><b>Important:</b> updating the firmware is a "
103 "critical process that must not be interrupted. <b>Make sure the "
104 "player is charged before starting the firmware update "
105 "process.</b></li>"
106 "<li>After the firmware has been updated reboot your player.</li>");
107 }
108 if(model == "sansafuzeplus") {
109 hint = true;
110 msg += QObject::tr("<li>Remove any previously inserted microSD card</li>");
111 msg += QObject::tr("<li>Disconnect your player. The player will reboot and "
112 "perform an update of the original firmware. "
113 "Please refer to your players manual on details.<br/>"
114 "<b>Important:</b> updating the firmware is a "
115 "critical process that must not be interrupted. <b>Make sure the "
116 "player is charged before disconnecting the player.</b></li>"
117 "<li>After the firmware has been updated reboot your player.</li>");
118 }
119 if(model == "iaudiox5" || model == "iaudiom5"
120 || model == "iaudiox5v" || model == "iaudiom3" || model == "mpioh200") {
121 hint = true;
122 msg += QObject::tr("<li>Turn the player off</li>"
123 "<li>Insert the charger</li>");
124 }
125 if(model == "gigabeatf") {
126 hint = true;
127 msg += QObject::tr("<li>Unplug USB and power adaptors</li>"
128 "<li>Hold <i>Power</i> to turn the player off</li>"
129 "<li>Toggle the battery switch on the player</li>"
130 "<li>Hold <i>Power</i> to boot into Rockbox</li>");
131 }
132 msg += "</ol>";
133 msg += QObject::tr("<p><b>Note:</b> You can safely install other parts first, but "
134 "the above steps are <b>required</b> to finish the installation!</p>");
135
136 if(hint)
137 return msg;
138 else
139 return QString();
140}
diff --git a/utils/rbutilqt/base/bootloaderinstallhelper.h b/utils/rbutilqt/base/bootloaderinstallhelper.h
new file mode 100644
index 0000000000..c89444d7a7
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallhelper.h
@@ -0,0 +1,36 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2012 Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 * This file is a modified version of the AMS installer by Dominik Wenger
18 *
19 ****************************************************************************/
20
21#ifndef BOOTLOADERINSTALLHELPER_H
22#define BOOTLOADERINSTALLHELPER_H
23
24#include <QtCore>
25#include "bootloaderinstallbase.h"
26
27class BootloaderInstallHelper : public QObject
28{
29 Q_OBJECT
30 public:
31 static BootloaderInstallBase* createBootloaderInstaller(QObject* parent, QString type);
32 static QString postinstallHints(QString model);
33};
34
35#endif
36
diff --git a/utils/rbutilqt/base/bootloaderinstallhex.cpp b/utils/rbutilqt/base/bootloaderinstallhex.cpp
new file mode 100644
index 0000000000..b3dde0bbfa
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallhex.cpp
@@ -0,0 +1,271 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include "bootloaderinstallbase.h"
21#include "bootloaderinstallhex.h"
22#include "utils.h"
23#include "Logger.h"
24
25#include "../../tools/iriver.h"
26#include "../../tools/mkboot.h"
27
28struct md5s {
29 const char* orig;
30 const char* patched;
31};
32
33struct md5s md5sums[] = {
34#include "irivertools/h100sums.h"
35 { nullptr, nullptr },
36#include "irivertools/h120sums.h"
37 { nullptr, nullptr },
38#include "irivertools/h300sums.h"
39 { nullptr, nullptr }
40};
41
42
43BootloaderInstallHex::BootloaderInstallHex(QObject *parent)
44 : BootloaderInstallBase(parent)
45{
46}
47
48QString BootloaderInstallHex::ofHint()
49{
50 return tr("Bootloader installation requires you to provide "
51 "a firmware file of the original firmware (hex file). "
52 "You need to download this file yourself due to legal "
53 "reasons. Please refer to the "
54 "<a href='http://www.rockbox.org/manual.shtml'>manual</a> and the "
55 "<a href='http://www.rockbox.org/wiki/IriverBoot"
56 "#Download_and_extract_a_recent_ve'>IriverBoot</a> wiki page on "
57 "how to obtain this file.<br/>"
58 "Press Ok to continue and browse your computer for the firmware "
59 "file.");
60}
61
62bool BootloaderInstallHex::install(void)
63{
64 if(m_offile.isEmpty())
65 return false;
66 m_hashindex = -1;
67
68 // md5sum hex file
69 emit logItem(tr("checking MD5 hash of input file ..."), LOGINFO);
70 QByteArray filedata;
71 // read hex file into QByteArray
72 QFile file(m_offile);
73 file.open(QIODevice::ReadOnly);
74 filedata = file.readAll();
75 file.close();
76 QString hash = QCryptographicHash::hash(filedata,
77 QCryptographicHash::Md5).toHex();
78 LOG_INFO() << "hexfile hash:" << hash;
79 if(file.error() != QFile::NoError) {
80 emit logItem(tr("Could not verify original firmware file"), LOGERROR);
81 emit done(true);
82 return false;
83 }
84 // check hash and figure model from md5sum
85 int i = sizeof(md5sums) / sizeof(struct md5s);
86 m_model = 4;
87 // 3: h300, 2: h120, 1: h100, 0:invalid
88 while(i--) {
89 if(md5sums[i].orig == nullptr)
90 m_model--;
91 if(!qstrcmp(md5sums[i].orig, hash.toLatin1()))
92 break;
93 }
94 if(i < 0) {
95 emit logItem(tr("Firmware file not recognized."), LOGERROR);
96 return false;
97 }
98 else {
99 emit logItem(tr("MD5 hash ok"), LOGOK);
100 m_hashindex = i;
101 }
102
103 // check model agains download link.
104 QString match[] = {"", "h100", "h120", "h300"};
105 if(!m_blurl.path().contains(match[m_model])) {
106 emit logItem(tr("Firmware file doesn't match selected player."),
107 LOGERROR);
108 return false;
109 }
110
111 emit logItem(tr("Descrambling file"), LOGINFO);
112 m_descrambled.open();
113 int result;
114 result = iriver_decode(m_offile.toLatin1().data(),
115 m_descrambled.fileName().toLatin1().data(), FALSE, STRIP_NONE);
116 LOG_INFO() << "iriver_decode():" << result;
117
118 if(result < 0) {
119 emit logItem(tr("Error in descramble: %1").arg(scrambleError(result)), LOGERROR);
120 return false;
121 }
122
123 // download firmware from server
124 emit logItem(tr("Downloading bootloader file"), LOGINFO);
125 connect(this, &BootloaderInstallBase::downloadDone, this, &BootloaderInstallHex::installStage2);
126
127 downloadBlStart(m_blurl);
128 return true;
129}
130
131
132void BootloaderInstallHex::installStage2(void)
133{
134 emit logItem(tr("Adding bootloader to firmware file"), LOGINFO);
135 QCoreApplication::processEvents();
136
137 // local temp file
138 QTemporaryFile tempbin;
139 tempbin.open();
140 QString tempbinName = tempbin.fileName();
141 tempbin.close();
142 // get temporary files filenames -- external tools need this.
143 m_descrambled.open();
144 QString descrambledName = m_descrambled.fileName();
145 m_descrambled.close();
146 m_tempfile.open();
147 QString tempfileName = m_tempfile.fileName();
148 m_tempfile.close();
149
150 int origin = 0;
151 switch(m_model) {
152 case 3:
153 origin = 0x3f0000;
154 break;
155 case 2:
156 case 1:
157 origin = 0x1f0000;
158 break;
159 default:
160 origin = 0;
161 break;
162 }
163
164 // iriver decode already done in stage 1
165 int result;
166 if((result = mkboot_iriver(descrambledName.toLocal8Bit().constData(),
167 tempfileName.toLocal8Bit().constData(),
168 tempbinName.toLocal8Bit().constData(), origin)) < 0)
169 {
170 QString error;
171 switch(result) {
172 case -1: error = tr("could not open input file"); break;
173 case -2: error = tr("reading header failed"); break;
174 case -3: error = tr("reading firmware failed"); break;
175 case -4: error = tr("can't open bootloader file"); break;
176 case -5: error = tr("reading bootloader file failed"); break;
177 case -6: error = tr("can't open output file"); break;
178 case -7: error = tr("writing output file failed"); break;
179 }
180 emit logItem(tr("Error in patching: %1").arg(error), LOGERROR);
181
182 emit done(true);
183 return;
184 }
185 QTemporaryFile targethex;
186 targethex.open();
187 QString targethexName = targethex.fileName();
188 if((result = iriver_encode(tempbinName.toLocal8Bit().constData(),
189 targethexName.toLocal8Bit().constData(), FALSE)) < 0)
190 {
191 emit logItem(tr("Error in scramble: %1").arg(scrambleError(result)), LOGERROR);
192 targethex.close();
193
194 emit done(true);
195 return;
196 }
197
198 // finally check the md5sum of the created file
199 QByteArray filedata;
200 filedata = targethex.readAll();
201 targethex.close();
202 QString hash = QCryptographicHash::hash(filedata,
203 QCryptographicHash::Md5).toHex();
204 LOG_INFO() << "created hexfile hash:" << hash;
205
206 emit logItem(tr("Checking modified firmware file"), LOGINFO);
207 if(hash != QString(md5sums[m_hashindex].patched)) {
208 emit logItem(tr("Error: modified file checksum wrong"), LOGERROR);
209 targethex.remove();
210 emit done(true);
211 return;
212 }
213 // finally copy file to player
214 if(!Utils::resolvePathCase(m_blfile).isEmpty()) {
215 emit logItem(tr("A firmware file is already present on player"), LOGERROR);
216 emit done(true);
217 return;
218 }
219 if(targethex.copy(m_blfile)) {
220 emit logItem(tr("Success: modified firmware file created"), LOGINFO);
221 }
222 else {
223 emit logItem(tr("Copying modified firmware file failed"), LOGERROR);
224 emit done(true);
225 return;
226 }
227
228 logInstall(LogAdd);
229 emit done(false);
230
231 return;
232}
233
234
235bool BootloaderInstallHex::uninstall(void)
236{
237 emit logItem(tr("Uninstallation not possible, only installation info removed"), LOGINFO);
238 logInstall(LogRemove);
239 emit done(true);
240 return false;
241}
242
243
244BootloaderInstallBase::BootloaderType BootloaderInstallHex::installed(void)
245{
246 return BootloaderUnknown;
247}
248
249
250BootloaderInstallBase::Capabilities BootloaderInstallHex::capabilities(void)
251{
252 return (Install | NeedsOf);
253}
254
255QString BootloaderInstallHex::scrambleError(int err)
256{
257 QString error;
258 switch(err) {
259 case -1: error = tr("Can't open input file"); break;
260 case -2: error = tr("Can't open output file"); break;
261 case -3: error = tr("invalid file: header length wrong"); break;
262 case -4: error = tr("invalid file: unrecognized header"); break;
263 case -5: error = tr("invalid file: \"length\" field wrong"); break;
264 case -6: error = tr("invalid file: \"length2\" field wrong"); break;
265 case -7: error = tr("invalid file: internal checksum error"); break;
266 case -8: error = tr("invalid file: \"length3\" field wrong"); break;
267 default: error = tr("unknown"); break;
268 }
269 return error;
270}
271
diff --git a/utils/rbutilqt/base/bootloaderinstallhex.h b/utils/rbutilqt/base/bootloaderinstallhex.h
new file mode 100644
index 0000000000..700d77447a
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallhex.h
@@ -0,0 +1,53 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef BOOTLOADERINSTALLHEX_H
20#define BOOTLOADERINSTALLHEX_H
21
22#include <QtCore>
23#include "bootloaderinstallbase.h"
24
25
26// bootloader installation derivate based on fwpatcher
27// This will patch a given hex file using (de)scramble / mkboot
28// and put it on the player.
29class BootloaderInstallHex : public BootloaderInstallBase
30{
31 Q_OBJECT
32
33 public:
34 BootloaderInstallHex(QObject *parent = nullptr);
35 bool install(void);
36 bool uninstall(void);
37 BootloaderInstallBase::BootloaderType installed(void);
38 Capabilities capabilities(void);
39 QString ofHint();
40
41 private:
42 int m_hashindex;
43 int m_model;
44 QTemporaryFile m_descrambled;
45 QString scrambleError(int);
46
47 private slots:
48 void installStage2(void);
49};
50
51
52#endif
53
diff --git a/utils/rbutilqt/base/bootloaderinstallimx.cpp b/utils/rbutilqt/base/bootloaderinstallimx.cpp
new file mode 100644
index 0000000000..7428cf10c8
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallimx.cpp
@@ -0,0 +1,193 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2011 by Jean-Louis Biasini
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include <QtDebug>
21#include "bootloaderinstallbase.h"
22#include "bootloaderinstallimx.h"
23#include "../mkimxboot/mkimxboot.h"
24#include "Logger.h"
25
26// class for running mkimxboot() in a separate thread to keep the UI responsive.
27class BootloaderThreadImx : public QThread
28{
29 public:
30 void run(void);
31 void setInputFile(QString f)
32 { m_inputfile = f; }
33 void setOutputFile(QString f)
34 { m_outputfile = f; }
35 void setBootloaderFile(QString f)
36 { m_bootfile = f; }
37 enum imx_error_t error(void)
38 { return m_error; }
39 private:
40 QString m_inputfile;
41 QString m_bootfile;
42 QString m_outputfile;
43 enum imx_error_t m_error;
44};
45
46
47void BootloaderThreadImx::run(void)
48{
49 LOG_INFO() << "Thread started.";
50 struct imx_option_t opt;
51 memset(&opt, 0, sizeof(opt));
52 opt.debug = false;
53 opt.output = IMX_DUALBOOT;
54 opt.fw_variant = VARIANT_DEFAULT;
55
56 m_error = mkimxboot(m_inputfile.toLocal8Bit().constData(),
57 m_bootfile.toLocal8Bit().constData(),
58 m_outputfile.toLocal8Bit().constData(), opt);
59 LOG_INFO() << "Thread finished, result:" << m_error;
60}
61
62
63BootloaderInstallImx::BootloaderInstallImx(QObject *parent)
64 : BootloaderInstallBase(parent)
65{
66 m_thread = nullptr;
67}
68
69
70QString BootloaderInstallImx::ofHint()
71{
72 return tr("Bootloader installation requires you to provide "
73 "a copy of the original Sandisk firmware (firmware.sb file). "
74 "This file will be patched with the Rockbox bootloader and "
75 "installed to your player. You need to download this file "
76 "yourself due to legal reasons. Please browse the "
77 "<a href='http://forums.sandisk.com/sansa/'>Sansa Forums</a> "
78 "or refer to the "
79 "<a href= 'http://www.rockbox.org/wiki/SansaFuzePlus'>SansaFuzePlus</a> "
80 "wiki page on how to obtain this file.<br/>"
81 "Press Ok to continue and browse your computer for the firmware "
82 "file.");
83}
84
85
86/** Start bootloader installation.
87 */
88bool BootloaderInstallImx::install(void)
89{
90 if(!QFileInfo(m_offile).isReadable())
91 {
92 LOG_ERROR() << "could not read original firmware file"
93 << m_offile;
94 emit logItem(tr("Could not read original firmware file"), LOGERROR);
95 return false;
96 }
97
98 LOG_INFO() << "downloading bootloader";
99 // download bootloader from server
100 emit logItem(tr("Downloading bootloader file"), LOGINFO);
101 connect(this, &BootloaderInstallBase::downloadDone, this, &BootloaderInstallImx::installStage2);
102 downloadBlStart(m_blurl);
103 return true;
104}
105
106
107void BootloaderInstallImx::installStage2(void)
108{
109 LOG_INFO() << "patching file...";
110 emit logItem(tr("Patching file..."), LOGINFO);
111 m_tempfile.open();
112
113 // we have not detailed progress on the patching so just show a busy
114 // indicator instead.
115 emit logProgress(0, 0);
116 m_patchedFile.open();
117 m_thread = new BootloaderThreadImx();
118 m_thread->setInputFile(m_offile);
119 m_thread->setBootloaderFile(m_tempfile.fileName());
120 m_thread->setOutputFile(m_patchedFile.fileName());
121 m_tempfile.close();
122 m_patchedFile.close();
123 connect(m_thread, &QThread::finished, this, &BootloaderInstallImx::installStage3);
124 connect(m_thread, SIGNAL(terminated()), this, SLOT(installStage3()));
125 m_thread->start();
126}
127
128
129void BootloaderInstallImx::installStage3(void)
130{
131 enum imx_error_t err = m_thread->error();
132 emit logProgress(1, 1);
133 // if the patch failed
134 if (err != IMX_SUCCESS)
135 {
136 LOG_ERROR() << "Could not patch the original firmware file";
137 emit logItem(tr("Patching the original firmware failed"), LOGERROR);
138 emit done(true);
139 return;
140 }
141
142 LOG_INFO() << "Original Firmware succesfully patched";
143 emit logItem(tr("Succesfully patched firmware file"), LOGINFO);
144
145 // if a bootloader is already present delete it.
146 QString fwfile(m_blfile);
147 if(QFileInfo(fwfile).isFile())
148 {
149 LOG_INFO() << "deleting old target file";
150 QFile::remove(fwfile);
151 }
152
153 // place (new) bootloader. Copy, since the temporary file will be removed
154 // automatically.
155 LOG_INFO() << "moving patched bootloader to" << fwfile;
156 if(m_patchedFile.copy(fwfile))
157 {
158 emit logItem(tr("Bootloader successful installed"), LOGOK);
159 logInstall(LogAdd);
160 emit done(false);
161 }
162 else
163 {
164 emit logItem(tr("Patched bootloader could not be installed"), LOGERROR);
165 emit done(true);
166 }
167 // clean up thread object.
168 delete m_thread;
169 return;
170}
171
172
173bool BootloaderInstallImx::uninstall(void)
174{
175 emit logItem(tr("To uninstall, perform a normal upgrade with an unmodified "
176 "original firmware."), LOGINFO);
177 logInstall(LogRemove);
178 emit done(true);
179 return false;
180}
181
182
183BootloaderInstallBase::BootloaderType BootloaderInstallImx::installed(void)
184{
185 return BootloaderUnknown;
186}
187
188
189BootloaderInstallBase::Capabilities BootloaderInstallImx::capabilities(void)
190{
191 return (Install | NeedsOf);
192}
193
diff --git a/utils/rbutilqt/base/bootloaderinstallimx.h b/utils/rbutilqt/base/bootloaderinstallimx.h
new file mode 100644
index 0000000000..1d780998ef
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallimx.h
@@ -0,0 +1,47 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2011 by Jean-Louis Biasini
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18#ifndef BOOTLOADERINSTALLIMX_H
19#define BOOTLOADERINSTALLIMX_H
20
21#include <QtCore>
22#include "bootloaderinstallbase.h"
23
24class BootloaderThreadImx;
25
26//! bootloader installation class for devices handled by mkimxboot.
27class BootloaderInstallImx : public BootloaderInstallBase
28{
29 Q_OBJECT
30 public:
31 BootloaderInstallImx(QObject *parent);
32 bool install(void);
33 bool uninstall(void);
34 BootloaderInstallBase::BootloaderType installed(void);
35 Capabilities capabilities(void);
36 QString ofHint();
37
38 private slots:
39 void installStage2(void);
40 void installStage3(void);
41
42 private:
43 BootloaderThreadImx *m_thread;
44 QTemporaryFile m_patchedFile;
45};
46
47#endif
diff --git a/utils/rbutilqt/base/bootloaderinstallipod.cpp b/utils/rbutilqt/base/bootloaderinstallipod.cpp
new file mode 100644
index 0000000000..807c6e870b
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallipod.cpp
@@ -0,0 +1,272 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include "bootloaderinstallbase.h"
21#include "bootloaderinstallipod.h"
22
23#include "../ipodpatcher/ipodpatcher.h"
24#include "utils.h"
25#include "Logger.h"
26
27
28BootloaderInstallIpod::BootloaderInstallIpod(QObject *parent)
29 : BootloaderInstallBase(parent)
30{
31 (void)parent;
32 // initialize sector buffer. The sector buffer is part of the ipod_t
33 // structure, so a second instance of this class will have its own buffer.
34 ipod_alloc_buffer(&ipod, BUFFER_SIZE);
35}
36
37
38BootloaderInstallIpod::~BootloaderInstallIpod()
39{
40 if(ipod.sectorbuf) {
41 ipod_dealloc_buffer(&ipod);
42 }
43}
44
45
46bool BootloaderInstallIpod::install(void)
47{
48 if(ipod.sectorbuf == nullptr) {
49 emit logItem(tr("Error: can't allocate buffer memory!"), LOGERROR);
50 emit done(true);
51 return false;
52 }
53 // save buffer pointer before cleaning up ipod_t structure
54 unsigned char* sb = ipod.sectorbuf;
55 memset(&ipod, 0, sizeof(struct ipod_t));
56 ipod.sectorbuf = sb;
57
58 if(!ipodInitialize(&ipod)) {
59 emit done(true);
60 return false;
61 }
62
63 if(ipod.nimages <= 0) {
64 emit logItem(tr("Failed to read firmware directory"), LOGERROR);
65 emit done(true);
66 return false;
67 }
68 if(getmodel(&ipod,(ipod.ipod_directory[ipod.ososimage].vers>>8)) < 0) {
69 emit logItem(tr("Unknown version number in firmware (%1)").arg(
70 ipod.ipod_directory[ipod.ososimage].vers), LOGERROR);
71 emit done(true);
72 return false;
73 }
74 if(ipod.macpod) {
75 emit logItem(tr("Warning: This is a MacPod, Rockbox only runs on WinPods. \n"
76 "See http://www.rockbox.org/wiki/IpodConversionToFAT32"), LOGERROR);
77 emit done(true);
78 return false;
79 }
80 emit logItem(tr("Downloading bootloader file"), LOGINFO);
81
82 downloadBlStart(m_blurl);
83 connect(this, &BootloaderInstallBase::downloadDone, this, &BootloaderInstallIpod::installStage2);
84 return true;
85}
86
87
88void BootloaderInstallIpod::installStage2(void)
89{
90 emit logItem(tr("Installing Rockbox bootloader"), LOGINFO);
91 QCoreApplication::processEvents();
92
93 if(ipod_reopen_rw(&ipod) < 0) {
94 emit logItem(tr("Could not open Ipod in R/W mode"), LOGERROR);
95 emit done(true);
96 return;
97 }
98 QCoreApplication::processEvents();
99
100 m_tempfile.open();
101 QString blfile = m_tempfile.fileName();
102 m_tempfile.close();
103 if(add_bootloader(&ipod, blfile.toLatin1().data(), FILETYPE_DOT_IPOD) == 0) {
104 emit logItem(tr("Successfull added bootloader"), LOGOK);
105 ipod_close(&ipod);
106#if defined(Q_OS_MACX)
107 m_remountDevice = ipod.diskname;
108 connect(this, SIGNAL(remounted(bool)), this, SLOT(installStage3(bool)));
109 waitRemount();
110#else
111 installStage3(true);
112#endif
113 }
114 else {
115 emit logItem(tr("Failed to add bootloader"), LOGERROR);
116 ipod_close(&ipod);
117 emit done(true);
118 return;
119 }
120}
121
122
123void BootloaderInstallIpod::installStage3(bool mounted)
124{
125 if(mounted) {
126 logInstall(LogAdd);
127 emit logItem(tr("Bootloader Installation complete."), LOGINFO);
128 emit done(false);
129 return;
130 }
131 else {
132 emit logItem(tr("Writing log aborted"), LOGERROR);
133 emit done(true);
134 }
135 LOG_INFO() << "version installed:"
136 << m_blversion.toString(Qt::ISODate);
137}
138
139
140bool BootloaderInstallIpod::uninstall(void)
141{
142 emit logItem(tr("Uninstalling bootloader"), LOGINFO);
143 QCoreApplication::processEvents();
144
145 if(!ipodInitialize(&ipod)) {
146 emit done(true);
147 return false;
148 }
149
150 if (ipod.nimages <= 0) {
151 emit logItem(tr("Failed to read firmware directory"),LOGERROR);
152 emit done(true);
153 return false;
154 }
155 if (getmodel(&ipod,(ipod.ipod_directory[ipod.ososimage].vers>>8)) < 0) {
156 emit logItem(tr("Unknown version number in firmware (%1)").arg(
157 ipod.ipod_directory[ipod.ososimage].vers), LOGERROR);
158 emit done(true);
159 return false;
160 }
161
162 if (ipod_reopen_rw(&ipod) < 0) {
163 emit logItem(tr("Could not open Ipod in R/W mode"), LOGERROR);
164 emit done(true);
165 return false;
166 }
167
168 if (ipod_has_bootloader(&ipod) == 0) {
169 emit logItem(tr("No bootloader detected."), LOGERROR);
170 emit done(true);
171 return false;
172 }
173
174 if (delete_bootloader(&ipod)==0) {
175 emit logItem(tr("Successfully removed bootloader"), LOGOK);
176 logInstall(LogRemove);
177 emit logProgress(1, 1);
178 emit done(false);
179 ipod_close(&ipod);
180 return true;
181 }
182 else {
183 emit logItem(tr("Removing bootloader failed."), LOGERROR);
184 emit done(true);
185 ipod_close(&ipod);
186 return false;
187 }
188}
189
190
191BootloaderInstallBase::BootloaderType BootloaderInstallIpod::installed(void)
192{
193 BootloaderInstallBase::BootloaderType result = BootloaderRockbox;
194
195 if(!ipodInitialize(&ipod)) {
196 LOG_INFO() << "installed: BootloaderUnknown";
197 result = BootloaderUnknown;
198 }
199 else {
200 read_directory(&ipod);
201 getmodel(&ipod,(ipod.ipod_directory[ipod.ososimage].vers>>8));
202 if(!ipod_has_bootloader(&ipod)) {
203 result = BootloaderOther;
204 }
205 else {
206 LOG_INFO() << "installed: BootloaderRockbox";
207 }
208 }
209 ipod_close(&ipod);
210
211 return result;
212}
213
214
215BootloaderInstallBase::Capabilities BootloaderInstallIpod::capabilities(void)
216{
217 return (Install | Uninstall | IsRaw);
218}
219
220
221/** @initialize Ipod by opening its file handle and checking if its an ipod.
222 * Note: the caller has to make sure the file handle gets closed!
223 */
224bool BootloaderInstallIpod::ipodInitialize(struct ipod_t *ipod)
225{
226 if(!m_blfile.isEmpty()) {
227 QString devicename = Utils::resolveDevicename(m_blfile);
228 if(devicename.isEmpty()) {
229 emit logItem(tr("Error: could not retrieve device name"), LOGERROR);
230 return false;
231 }
232#if defined(Q_OS_WIN32)
233 sprintf(ipod->diskname, "\\\\.\\PhysicalDrive%i", devicename.toInt());
234#elif defined(Q_OS_MACX)
235 sprintf(ipod->diskname, "%s",
236 qPrintable(devicename.remove(QRegExp("s[0-9]+$"))));
237#else
238 sprintf(ipod->diskname, "%s",
239 qPrintable(devicename.remove(QRegExp("[0-9]+$"))));
240#endif
241 LOG_INFO() << "ipodpatcher: overriding scan, using"
242 << ipod->diskname;
243 }
244 else {
245 emit logItem(tr("Error: no mountpoint specified!"), LOGERROR);
246 LOG_ERROR() << "no mountpoint specified!";
247 }
248 int result = ipod_open(ipod, 1);
249 if(result == -2) {
250 emit logItem(tr("Could not open Ipod: permission denied"), LOGERROR);
251 return false;
252 }
253 else if(result < 0) {
254 emit logItem(tr("Could not open Ipod"), LOGERROR);
255 return false;
256 }
257
258 if(read_partinfo(ipod, 1) < 0) {
259 emit logItem(tr("Error reading partition table - possibly not an Ipod"), LOGERROR);
260 ipod_close(ipod);
261 return false;
262 }
263
264 if(ipod->pinfo[0].start == 0) {
265 emit logItem(tr("No firmware partition on disk"), LOGERROR);
266 ipod_close(ipod);
267 return false;
268 }
269 read_directory(ipod);
270 return true;
271}
272
diff --git a/utils/rbutilqt/base/bootloaderinstallipod.h b/utils/rbutilqt/base/bootloaderinstallipod.h
new file mode 100644
index 0000000000..ac69c608d6
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallipod.h
@@ -0,0 +1,51 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef BOOTLOADERINSTALLIPOD_H
20#define BOOTLOADERINSTALLIPOD_H
21
22#include <QtCore>
23#include "bootloaderinstallbase.h"
24#include "../ipodpatcher/ipodpatcher.h"
25
26// installer class derivate for Ipod installation
27// based on ipodpatcher.
28class BootloaderInstallIpod : public BootloaderInstallBase
29{
30 Q_OBJECT
31
32 public:
33 BootloaderInstallIpod(QObject *parent);
34 ~BootloaderInstallIpod();
35 bool install(void);
36 bool uninstall(void);
37 BootloaderInstallBase::BootloaderType installed(void);
38 Capabilities capabilities(void);
39
40 private slots:
41 void installStage2(void);
42 void installStage3(bool mounted);
43
44 private:
45 bool ipodInitialize(struct ipod_t *);
46 struct ipod_t ipod;
47};
48
49
50#endif
51
diff --git a/utils/rbutilqt/base/bootloaderinstallmi4.cpp b/utils/rbutilqt/base/bootloaderinstallmi4.cpp
new file mode 100644
index 0000000000..2657347b87
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallmi4.cpp
@@ -0,0 +1,162 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include <QtDebug>
21#include <QtDebug>
22#include "bootloaderinstallmi4.h"
23#include "utils.h"
24#include "Logger.h"
25
26BootloaderInstallMi4::BootloaderInstallMi4(QObject *parent)
27 : BootloaderInstallBase(parent)
28{
29}
30
31
32bool BootloaderInstallMi4::install(void)
33{
34 emit logItem(tr("Downloading bootloader"), LOGINFO);
35 LOG_INFO() << "installing bootloader";
36 downloadBlStart(m_blurl);
37 connect(this, &BootloaderInstallBase::downloadDone, this, &BootloaderInstallMi4::installStage2);
38 return true;
39}
40
41void BootloaderInstallMi4::installStage2(void)
42{
43 emit logItem(tr("Installing Rockbox bootloader"), LOGINFO);
44 QCoreApplication::processEvents();
45
46 // move old bootloader out of the way
47 QString fwfile(Utils::resolvePathCase(m_blfile));
48 QFile oldbl(fwfile);
49 QString moved = QFileInfo(Utils::resolvePathCase(m_blfile)).absolutePath()
50 + "/OF.mi4";
51 if(!QFileInfo::exists(moved)) {
52 LOG_INFO() << "renaming" << fwfile << "to" << moved;
53 oldbl.rename(moved);
54 }
55 else {
56 LOG_INFO() << "OF.mi4 already present, not renaming again.";
57 oldbl.remove();
58 }
59
60 // place new bootloader
61 m_tempfile.open();
62 LOG_INFO() << "renaming" << m_tempfile.fileName()
63 << "to" << fwfile;
64 m_tempfile.close();
65 if(!Utils::resolvePathCase(fwfile).isEmpty()) {
66 emit logItem(tr("A firmware file is already present on player"), LOGERROR);
67 emit done(true);
68 return;
69 }
70 if(m_tempfile.copy(fwfile)) {
71 emit logItem(tr("Bootloader successful installed"), LOGOK);
72 }
73 else {
74 emit logItem(tr("Copying modified firmware file failed"), LOGERROR);
75 emit done(true);
76 return;
77 }
78
79 emit logItem(tr("Bootloader successful installed"), LOGOK);
80 logInstall(LogAdd);
81
82 emit done(false);
83}
84
85
86bool BootloaderInstallMi4::uninstall(void)
87{
88 LOG_INFO() << "Uninstalling bootloader";
89
90 // check if it's actually a Rockbox bootloader
91 emit logItem(tr("Checking for Rockbox bootloader"), LOGINFO);
92 if(installed() != BootloaderRockbox) {
93 emit logItem(tr("No Rockbox bootloader found"), LOGERROR);
94 emit done(true);
95 return false;
96 }
97
98 // check if OF file present
99 emit logItem(tr("Checking for original firmware file"), LOGINFO);
100 QString original = QFileInfo(Utils::resolvePathCase(m_blfile)).absolutePath()
101 + "/OF.mi4";
102
103 if(Utils::resolvePathCase(original).isEmpty()) {
104 emit logItem(tr("Error finding original firmware file"), LOGERROR);
105 emit done(true);
106 return false;
107 }
108
109 // finally remove RB bootloader
110 QString resolved = Utils::resolvePathCase(m_blfile);
111 QFile blfile(resolved);
112 blfile.remove();
113
114 QFile::rename(Utils::resolvePathCase(original), resolved);
115 emit logItem(tr("Rockbox bootloader successful removed"), LOGINFO);
116 logInstall(LogRemove);
117 emit logProgress(1, 1);
118 emit done(false);
119
120 return true;
121}
122
123
124//! check if a bootloader is installed and return its state.
125BootloaderInstallBase::BootloaderType BootloaderInstallMi4::installed(void)
126{
127 // for MI4 files we can check if we actually have a RB bootloader
128 // installed.
129 // RB bootloader has "RBBL" at 0x1f8 in the mi4 file.
130
131 // make sure to resolve case to prevent case issues
132 QString resolved;
133 resolved = Utils::resolvePathCase(m_blfile);
134 if(resolved.isEmpty()) {
135 LOG_INFO() << "installed: BootloaderNone";
136 return BootloaderNone;
137 }
138
139 QFile f(resolved);
140 f.open(QIODevice::ReadOnly);
141 f.seek(0x1f8);
142 char magic[4];
143 f.read(magic, 4);
144 f.close();
145
146 if(!memcmp(magic, "RBBL", 4)) {
147 LOG_INFO() << "installed: BootloaderRockbox";
148 return BootloaderRockbox;
149 }
150 else {
151 LOG_INFO() << "installed: BootloaderOther";
152 return BootloaderOther;
153 }
154}
155
156
157BootloaderInstallBase::Capabilities BootloaderInstallMi4::capabilities(void)
158{
159 LOG_INFO() << "getting capabilities";
160 return Install | Uninstall | Backup | IsFile | CanCheckInstalled | CanCheckVersion;
161}
162
diff --git a/utils/rbutilqt/base/bootloaderinstallmi4.h b/utils/rbutilqt/base/bootloaderinstallmi4.h
new file mode 100644
index 0000000000..c56669b99f
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallmi4.h
@@ -0,0 +1,48 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef BOOTLOADERINSTALLMI4_H
20#define BOOTLOADERINSTALLMI4_H
21
22#include <QtCore>
23#include "progressloggerinterface.h"
24#include "bootloaderinstallbase.h"
25
26
27// mi4 bootloader file based installation.
28// Puts the bootloader file to the correct location and
29// renames the OF to OF.mi4.
30class BootloaderInstallMi4 : public BootloaderInstallBase
31{
32 Q_OBJECT
33
34 public:
35 BootloaderInstallMi4(QObject *parent);
36 bool install(void);
37 bool uninstall(void);
38 BootloaderInstallBase::BootloaderType installed(void);
39 Capabilities capabilities(void);
40
41 private slots:
42 void installStage2(void);
43
44 private:
45};
46
47#endif
48
diff --git a/utils/rbutilqt/base/bootloaderinstallmpio.cpp b/utils/rbutilqt/base/bootloaderinstallmpio.cpp
new file mode 100644
index 0000000000..863418e591
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallmpio.cpp
@@ -0,0 +1,143 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Wenger
10 * $Id: bootloaderinstallams.cpp 24778 2010-02-19 23:45:29Z funman $
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <QtCore>
21#include "bootloaderinstallbase.h"
22#include "bootloaderinstallmpio.h"
23#include "Logger.h"
24
25#include "../mkmpioboot/mkmpioboot.h"
26
27BootloaderInstallMpio::BootloaderInstallMpio(QObject *parent)
28 : BootloaderInstallBase(parent)
29{
30}
31
32QString BootloaderInstallMpio::ofHint()
33{
34 return tr("Bootloader installation requires you to provide "
35 "a firmware file of the original firmware (bin file). "
36 "You need to download this file yourself due to legal "
37 "reasons. Please refer to the "
38 "<a href='http://www.rockbox.org/manual.shtml'>manual</a> and "
39 "the <a href='http://www.rockbox.org/wiki/MPIOHD200Port'>MPIOHD200Port</a> "
40 "wiki page on how to obtain this file.<br/>"
41 "Press Ok to continue and browse your computer for the firmware "
42 "file.");
43}
44
45bool BootloaderInstallMpio::install(void)
46{
47 if(m_offile.isEmpty())
48 return false;
49
50 LOG_INFO() << "installing bootloader";
51
52 // download firmware from server
53 emit logItem(tr("Downloading bootloader file"), LOGINFO);
54
55 connect(this, &BootloaderInstallBase::downloadDone, this, &BootloaderInstallMpio::installStage2);
56 downloadBlStart(m_blurl);
57
58 return true;
59}
60
61void BootloaderInstallMpio::installStage2(void)
62{
63 LOG_INFO() << "installStage2";
64
65 int origin = 0xe0000; /* MPIO HD200 bootloader address */
66
67 m_tempfile.open();
68 QString bootfile = m_tempfile.fileName();
69 m_tempfile.close();
70
71 int ret = mkmpioboot(m_offile.toLocal8Bit().data(),
72 bootfile.toLocal8Bit().data(), m_blfile.toLocal8Bit().data(), origin);
73
74 if(ret != 0)
75 {
76 QString error;
77 switch(ret)
78 {
79 case -1:
80 error = tr("Could not open the original firmware.");
81 break;
82 case -2:
83 error = tr("Could not read the original firmware.");
84 break;
85 case -3:
86 error = tr("Loaded firmware file does not look like MPIO original firmware file.");
87 break;
88 case -4:
89 error = tr("Could not open downloaded bootloader.");
90 break;
91 case -5:
92 error = tr("Place for bootloader in OF file not empty.");
93 break;
94 case -6:
95 error = tr("Could not read the downloaded bootloader.");
96 break;
97 case -7:
98 error = tr("Bootloader checksum error.");
99 break;
100 case -8:
101 error = tr("Could not open output file.");
102 break;
103 case -9:
104 error = tr("Could not write output file.");
105 break;
106 default:
107 error = tr("Unknown error number: %1").arg(ret);
108 break;
109 }
110
111 LOG_ERROR() << "Patching original firmware failed:" << error;
112 emit logItem(tr("Patching original firmware failed: %1").arg(error), LOGERROR);
113 emit done(true);
114 return;
115 }
116
117 //end of install
118 LOG_INFO() << "install successful";
119 emit logItem(tr("Success: modified firmware file created"), LOGINFO);
120 logInstall(LogAdd);
121 emit done(false);
122 return;
123}
124
125bool BootloaderInstallMpio::uninstall(void)
126{
127 emit logItem(tr("To uninstall, perform a normal upgrade with an unmodified "
128 "original firmware"), LOGINFO);
129 logInstall(LogRemove);
130 emit done(true);
131 return false;
132}
133
134BootloaderInstallBase::BootloaderType BootloaderInstallMpio::installed(void)
135{
136 return BootloaderUnknown;
137}
138
139BootloaderInstallBase::Capabilities BootloaderInstallMpio::capabilities(void)
140{
141 return (Install | NeedsOf);
142}
143
diff --git a/utils/rbutilqt/base/bootloaderinstallmpio.h b/utils/rbutilqt/base/bootloaderinstallmpio.h
new file mode 100644
index 0000000000..8e6c65affe
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallmpio.h
@@ -0,0 +1,43 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Wenger
10 * $Id: bootloaderinstallams.h 22317 2009-08-15 13:04:21Z Domonoky $
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#ifndef BOOTLOADERINSTALLMPIO_H
20#define BOOTLOADERINSTALLMPIO_H
21
22#include <QtCore>
23#include "bootloaderinstallbase.h"
24
25//! bootloader installation derivate based on mkmpioboot
26class BootloaderInstallMpio : public BootloaderInstallBase
27{
28 Q_OBJECT
29 public:
30 BootloaderInstallMpio(QObject *parent);
31 bool install(void);
32 bool uninstall(void);
33 BootloaderInstallBase::BootloaderType installed(void);
34 Capabilities capabilities(void);
35 QString ofHint();
36
37 private:
38
39 private slots:
40 void installStage2(void);
41};
42
43#endif
diff --git a/utils/rbutilqt/base/bootloaderinstalls5l.cpp b/utils/rbutilqt/base/bootloaderinstalls5l.cpp
new file mode 100644
index 0000000000..63a30ff2b0
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstalls5l.cpp
@@ -0,0 +1,437 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include "bootloaderinstallbase.h"
21#include "bootloaderinstalls5l.h"
22#include "Logger.h"
23#include "utils.h"
24#include "system.h"
25#include "rbsettings.h"
26#include "playerbuildinfo.h"
27
28#include "../mks5lboot/mks5lboot.h"
29
30
31BootloaderInstallS5l::BootloaderInstallS5l(QObject *parent)
32 : BootloaderInstallBase(parent)
33{
34}
35
36
37bool BootloaderInstallS5l::install(void)
38{
39 LOG_INFO() << "installing bootloader";
40 doInstall = true;
41 return installStage1();
42}
43
44
45bool BootloaderInstallS5l::uninstall(void)
46{
47 LOG_INFO() << "uninstalling bootloader";
48 doInstall = false;
49 return installStage1();
50}
51
52
53bool BootloaderInstallS5l::installStage1(void)
54{
55 LOG_INFO() << "installStage1";
56
57 mntpoint = RbSettings::value(RbSettings::Mountpoint).toString();
58
59 if (!Utils::mountpoints(Utils::MountpointsSupported).contains(mntpoint)) {
60 LOG_ERROR() << "iPod not mounted:" << mntpoint;
61 emit logItem(tr("Could not find mounted iPod."), LOGERROR);
62 emit done(true);
63 return false;
64 }
65
66 if (doInstall) {
67 // download firmware from server
68 emit logItem(tr("Downloading bootloader file..."), LOGINFO);
69 connect(this, &BootloaderInstallBase::downloadDone,
70 this, &BootloaderInstallS5l::installStageMkdfu);
71 downloadBlStart(m_blurl);
72 }
73 else {
74 installStageMkdfu();
75 }
76
77 return true;
78}
79
80
81void BootloaderInstallS5l::installStageMkdfu(void)
82{
83 int dfu_type;
84 QString dfu_arg;
85 char errstr[200];
86
87 LOG_INFO() << "installStageMkdfu";
88
89 setProgress(0);
90 aborted = false;
91 connect(this, &BootloaderInstallBase::installAborted,
92 this, &BootloaderInstallS5l::abortInstall);
93 connect(this, &BootloaderInstallBase::done,
94 this, &BootloaderInstallS5l::installDone);
95
96 if (doInstall) {
97 dfu_type = DFU_INST;
98 m_tempfile.open();
99 dfu_arg = m_tempfile.fileName();
100 m_tempfile.close();
101 }
102 else {
103 dfu_type = DFU_UNINST;
104 dfu_arg = RbSettings::value(RbSettings::Platform).toString();
105 }
106
107 // build DFU image
108 dfu_buf = mkdfu(dfu_type, dfu_arg.toLocal8Bit().data(),
109 &dfu_size, errstr, sizeof(errstr));
110 if (!dfu_buf) {
111 LOG_ERROR() << "mkdfu() failed:" << errstr;
112 emit logItem(errstr, LOGERROR);
113 emit logItem(tr("Could not make DFU image."), LOGERROR);
114 emit done(true);
115 return;
116 }
117
118 LOG_INFO() << "preparing installStageWaitForEject";
119 emit logItem(tr("Ejecting iPod..."), LOGINFO);
120 setProgress(10);
121 scanTimer.invalidate();
122 installStageWaitForEject();
123}
124
125
126void BootloaderInstallS5l::installStageWaitForEject(void)
127{
128 if (!updateProgress())
129 return; /* aborted */
130
131 if (!scanTimer.isValid() || (scanTimer.elapsed() > 3000)) {
132 scanSuccess = Utils::ejectDevice(mntpoint);
133 if (!scanSuccess) {
134 scanSuccess = !Utils::mountpoints(
135 Utils::MountpointsSupported).contains(mntpoint);
136 }
137 scanTimer.start();
138 }
139 if (!scanSuccess) {
140 if (!actionShown) {
141 emit logItem(tr("Action required:\n\n"
142 "Please make sure no programs are accessing "
143 "files on the device. If ejecting still fails "
144 "please use your computers eject functionality."),
145 LOGWARNING);
146 actionShown = true;
147 }
148 QTimer::singleShot(250, this, &BootloaderInstallS5l::installStageWaitForEject);
149 return;
150 }
151 emit logItem(tr("Device successfully ejected."), LOGINFO);
152
153 LOG_INFO() << "preparing installStageWaitForProcs";
154 setProgress(40, 18);
155 scanTimer.invalidate();
156 installStageWaitForProcs();
157}
158
159
160void BootloaderInstallS5l::installStageWaitForProcs(void)
161{
162 if (!updateProgress())
163 return; /* aborted */
164
165 if (!scanTimer.isValid() || (scanTimer.elapsed() > 1000)) {
166 scanSuccess = Utils::findRunningProcess(QStringList("iTunes")).isEmpty();
167 scanTimer.start();
168 }
169 if (!scanSuccess) {
170 if (!actionShown) {
171 emit logItem(tr("Action required:\n\n"
172 "Quit iTunes application."), LOGWARNING);
173 actionShown = true;
174 }
175 QTimer::singleShot(250, this, &BootloaderInstallS5l::installStageWaitForProcs);
176 return;
177 }
178 if (actionShown) {
179 emit logItem(tr("iTunes closed."), LOGINFO);
180 if (!updateProgress())
181 return; /* aborted */
182 }
183
184 QList<int> helperPids = Utils::findRunningProcess(
185#if defined(Q_OS_WIN32)
186 QStringList("iTunesHelper"))["iTunesHelper.exe"];
187#else
188 QStringList("iTunesHelper"))["iTunesHelper"];
189#endif
190 suspendedPids = Utils::suspendProcess(helperPids, true);
191 if (suspendedPids.size() != helperPids.size()) {
192 emit logItem(tr("Could not suspend iTunesHelper. Stop it "
193 "using the Task Manager, and try again."), LOGERROR);
194 emit done(true);
195 return;
196 }
197
198 LOG_INFO() << "preparing installStageWaitForSpindown";
199 // for Windows: skip waiting if the HDD was ejected a time ago
200 if (progressTimer.elapsed() < progressTimeout)
201 emit logItem(tr("Waiting for HDD spin-down..."), LOGINFO);
202 installStageWaitForSpindown();
203}
204
205
206void BootloaderInstallS5l::installStageWaitForSpindown(void)
207{
208 if (!updateProgress())
209 return; /* aborted */
210
211 if (progressTimer.elapsed() < progressTimeout) {
212 QTimer::singleShot(250, this, &BootloaderInstallS5l::installStageWaitForSpindown);
213 return;
214 }
215
216 LOG_INFO() << "preparing installStageWaitForDfu";
217 emit logItem(tr("Waiting for DFU mode..."), LOGINFO);
218 emit logItem(tr("Action required:\n\n"
219 "Press and hold SELECT+MENU buttons, after "
220 "about 12 seconds a new action will require "
221 "you to release the buttons, DO IT QUICKLY, "
222 "otherwise the process could fail."), LOGWARNING);
223 scanTimer.invalidate();
224 installStageWaitForDfu();
225}
226
227
228void BootloaderInstallS5l::installStageWaitForDfu(void)
229{
230 if (!updateProgress())
231 return; /* aborted */
232
233 if (!scanTimer.isValid() || (scanTimer.elapsed() > 2000)) {
234 scanSuccess = System::listUsbIds().contains(0x05ac1223);
235 scanTimer.start();
236 }
237 if (!scanSuccess) {
238 QTimer::singleShot(250, this, &BootloaderInstallS5l::installStageWaitForDfu);
239 return;
240 }
241 emit logItem(tr("DFU mode detected."), LOGINFO);
242
243 emit logItem(tr("Action required:\n\n"
244 "Release SELECT+MENU buttons and wait..."), LOGWARNING);
245
246 // Once the iPod enters DFU mode, the device will reset again if
247 // SELECT+MENU remains pressed for another 8 seconds. To avoid a
248 // reset while the NOR is being written, we wait ~10 seconds
249 // before sending the DFU image.
250 LOG_INFO() << "preparing installStageSendDfu";
251 setProgress(60, 10);
252 installStageSendDfu();
253}
254
255
256void BootloaderInstallS5l::installStageSendDfu(void)
257{
258 if (!updateProgress())
259 return; /* aborted */
260
261 if (progressTimer.elapsed() < progressTimeout) {
262 QTimer::singleShot(250, this, &BootloaderInstallS5l::installStageSendDfu);
263 return;
264 }
265
266 if (!System::listUsbIds().contains(0x05ac1223)) {
267 LOG_ERROR() << "device not in DFU mode";
268 emit logItem(tr("Device is not in DFU mode. It seems that "
269 "the previous required action failed, please "
270 "try again."), LOGERROR);
271 emit done(true);
272 return;
273 }
274
275 emit logItem(tr("Transfering DFU image..."), LOGINFO);
276 if (!updateProgress())
277 return; /* aborted */
278
279 char errstr[200];
280 if (!ipoddfu_send(0x1223, dfu_buf, dfu_size, errstr, sizeof(errstr))) {
281 LOG_ERROR() << "ipoddfu_send() failed:" << errstr;
282#if defined(Q_OS_WIN32)
283 if (strstr(errstr, "DFU device not found"))
284 {
285 emit logItem(tr("No valid DFU USB driver found.\n\n"
286 "Install iTunes (or the Apple Device Driver) "
287 "and try again."),
288 LOGERROR);
289 }
290 else
291#endif
292 {
293 emit logItem(errstr, LOGERROR);
294 emit logItem(tr("Could not transfer DFU image."), LOGERROR);
295 }
296 emit done(true);
297 return;
298 }
299 emit logItem(tr("DFU transfer completed."), LOGINFO);
300
301 LOG_INFO() << "preparing installStageWaitForRemount";
302 emit logItem(tr("Restarting iPod, waiting for remount..."), LOGINFO);
303 setProgress(99, 45);
304 scanTimer.invalidate();
305 installStageWaitForRemount();
306}
307
308
309void BootloaderInstallS5l::installStageWaitForRemount(void)
310{
311 if (!updateProgress())
312 return; /* aborted */
313
314 if (!scanTimer.isValid() || (scanTimer.elapsed() > 5000)) {
315 scanSuccess = Utils::mountpoints(
316 Utils::MountpointsSupported).contains(mntpoint);
317 scanTimer.start();
318 }
319 if (!scanSuccess) {
320 if (!actionShown && (progressTimer.elapsed() > progressTimeout)) {
321 emit logItem(tr("Action required:\n\n"
322 "Could not remount the device, try to do it "
323 "manually. If the iPod didn't restart, force "
324 "a reset by pressing SELECT+MENU buttons "
325 "for about 5 seconds. If the problem could "
326 "not be solved then click 'Abort' to cancel."),
327 LOGWARNING);
328 actionShown = true;
329 }
330 QTimer::singleShot(250, this, &BootloaderInstallS5l::installStageWaitForRemount);
331 return;
332 }
333 emit logItem(tr("Device remounted."), LOGINFO);
334
335 if (doInstall)
336 emit logItem(tr("Bootloader successfully installed."), LOGOK);
337 else
338 emit logItem(tr("Bootloader successfully uninstalled."), LOGOK);
339
340 logInstall(doInstall ? LogAdd : LogRemove);
341 emit logProgress(1, 1);
342 emit done(false);
343}
344
345
346void BootloaderInstallS5l::installDone(bool status)
347{
348 LOG_INFO() << "installDone, status:" << status;
349 if (Utils::suspendProcess(suspendedPids, false).size() != suspendedPids.size())
350 emit logItem(tr("Could not resume iTunesHelper."), LOGWARNING);
351}
352
353
354void BootloaderInstallS5l::abortInstall(void)
355{
356 LOG_INFO() << "abortInstall";
357 aborted = true;
358 disconnect(this, &BootloaderInstallBase::installAborted,
359 this, &BootloaderInstallS5l::abortInstall);
360}
361
362
363bool BootloaderInstallS5l::abortDetected(void)
364{
365 if (aborted) {
366 LOG_ERROR() << "abortDetected";
367 if (doInstall)
368 emit logItem(tr("Install aborted by user."), LOGERROR);
369 else
370 emit logItem(tr("Uninstall aborted by user."), LOGERROR);
371 emit done(true);
372 return true;
373 }
374 return false;
375}
376
377
378void BootloaderInstallS5l::setProgress(int progress, int secondsTimeout)
379{
380 progressTimer.start();
381 progressTimeout = secondsTimeout * 1000;
382 progOrigin = progTarget;
383 progTarget = progress;
384 actionShown = false;
385}
386
387
388bool BootloaderInstallS5l::updateProgress(void)
389{
390 if (progressTimeout) {
391 progCurrent = qMin(progTarget, progOrigin +
392 static_cast<int>(progressTimer.elapsed())
393 * (progTarget - progOrigin) / progressTimeout);
394 }
395 else {
396 progCurrent = progTarget;
397 }
398 emit logProgress(progCurrent, 100);
399 QCoreApplication::sendPostedEvents();
400 QCoreApplication::processEvents();
401 return !abortDetected();
402}
403
404
405BootloaderInstallBase::BootloaderType BootloaderInstallS5l::installed(void)
406{
407 bool rbblInstalled;
408
409 QString device = Utils::resolveDevicename(m_blfile);
410 if (device.isEmpty()) {
411 LOG_INFO() << "installed: BootloaderUnknown";
412 return BootloaderUnknown;
413 }
414
415 // rely on logfile
416 QString logfile = RbSettings::value(RbSettings::Mountpoint).toString()
417 + "/.rockbox/rbutil.log";
418 QSettings s(logfile, QSettings::IniFormat, this);
419 QString section = PlayerBuildInfo::instance()->value(
420 PlayerBuildInfo::BootloaderName).toString().section('/', -1);
421 rbblInstalled = s.contains("Bootloader/" + section);
422
423 if (rbblInstalled) {
424 LOG_INFO() << "installed: BootloaderRockbox";
425 return BootloaderRockbox;
426 }
427 else {
428 LOG_INFO() << "installed: BootloaderOther";
429 return BootloaderOther;
430 }
431}
432
433
434BootloaderInstallBase::Capabilities BootloaderInstallS5l::capabilities(void)
435{
436 return (Install | Uninstall);
437}
diff --git a/utils/rbutilqt/base/bootloaderinstalls5l.h b/utils/rbutilqt/base/bootloaderinstalls5l.h
new file mode 100644
index 0000000000..e2a44a031f
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstalls5l.h
@@ -0,0 +1,71 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef BOOTLOADERINSTALLS5L_H
20#define BOOTLOADERINSTALLS5L_H
21
22#include <QtCore>
23#include "bootloaderinstallbase.h"
24
25
26//! bootloader installation derivate based on mks5lboot
27class BootloaderInstallS5l : public BootloaderInstallBase
28{
29 Q_OBJECT
30
31 public:
32 BootloaderInstallS5l(QObject *parent);
33 bool install(void);
34 bool uninstall(void);
35 BootloaderInstallBase::BootloaderType installed(void);
36 Capabilities capabilities(void);
37
38 private slots:
39 bool installStage1(void);
40 void installStageMkdfu(void);
41 void installStageWaitForEject(void);
42 void installStageWaitForSpindown(void);
43 void installStageWaitForProcs(void);
44 void installStageWaitForDfu(void);
45 void installStageSendDfu(void);
46 void installStageWaitForRemount(void);
47 void abortInstall(void);
48 void installDone(bool);
49
50 private:
51 bool doInstall;
52 QString mntpoint;
53 unsigned char* dfu_buf;
54 int dfu_size;
55 QList<int> suspendedPids;
56 bool aborted;
57 bool abortDetected(void);
58 QElapsedTimer scanTimer;
59 bool scanSuccess;
60 // progress
61 QElapsedTimer progressTimer;
62 int progressTimeout;
63 int progCurrent;
64 int progOrigin;
65 int progTarget;
66 bool actionShown;
67 void setProgress(int, int=0);
68 bool updateProgress(void);
69};
70
71#endif
diff --git a/utils/rbutilqt/base/bootloaderinstallsansa.cpp b/utils/rbutilqt/base/bootloaderinstallsansa.cpp
new file mode 100644
index 0000000000..b1f0167e42
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallsansa.cpp
@@ -0,0 +1,286 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include "bootloaderinstallbase.h"
21#include "bootloaderinstallsansa.h"
22#include "Logger.h"
23
24#include "../sansapatcher/sansapatcher.h"
25#include "utils.h"
26
27BootloaderInstallSansa::BootloaderInstallSansa(QObject *parent)
28 : BootloaderInstallBase(parent)
29{
30 (void)parent;
31 // initialize sector buffer. The sector buffer is part of the sansa_t
32 // structure, so a second instance of this class will have its own buffer.
33 sansa_alloc_buffer(&sansa, BUFFER_SIZE);
34}
35
36
37BootloaderInstallSansa::~BootloaderInstallSansa()
38{
39 if(sansa.sectorbuf) {
40 sansa_dealloc_buffer(&sansa);
41 }
42}
43
44
45/** Start bootloader installation.
46 */
47bool BootloaderInstallSansa::install(void)
48{
49 if(sansa.sectorbuf == nullptr) {
50 emit logItem(tr("Error: can't allocate buffer memory!"), LOGERROR);
51 return false;
52 emit done(true);
53 }
54
55 emit logItem(tr("Searching for Sansa"), LOGINFO);
56
57 int n = sansa_scan(&sansa);
58 if(n == -1) {
59 emit logItem(tr("Permission for disc access denied!\n"
60 "This is required to install the bootloader"),
61 LOGERROR);
62 emit done(true);
63 return false;
64 }
65 if(n == 0) {
66 emit logItem(tr("No Sansa detected!"), LOGERROR);
67 emit done(true);
68 return false;
69 }
70 if(sansa.hasoldbootloader) {
71 emit logItem(tr("OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
72 "You must reinstall the original Sansa firmware before running\n"
73 "sansapatcher for the first time.\n"
74 "See http://www.rockbox.org/wiki/SansaE200Install\n"),
75 LOGERROR);
76 emit done(true);
77 return false;
78 }
79 emit logItem(tr("Downloading bootloader file"), LOGINFO);
80
81 downloadBlStart(m_blurl);
82 connect(this, &BootloaderInstallBase::downloadDone, this, &BootloaderInstallSansa::installStage2);
83 return true;
84}
85
86
87/** Finish bootloader installation.
88 */
89void BootloaderInstallSansa::installStage2(void)
90{
91 unsigned char* buf = nullptr;
92 unsigned int len;
93
94 emit logItem(tr("Installing Rockbox bootloader"), LOGINFO);
95 QCoreApplication::processEvents();
96 if(!sansaInitialize(&sansa)) {
97 emit done(true);
98 return;
99 }
100
101 if(sansa_reopen_rw(&sansa) < 0) {
102 emit logItem(tr("Could not open Sansa in R/W mode"), LOGERROR);
103 emit done(true);
104 return;
105 }
106
107 // check model -- if sansapatcher reports a c200 don't install an e200
108 // bootloader and vice versa.
109 // The model is available in the mi4 file at offset 0x1fc and matches
110 // the targetname set by sansapatcher.
111 emit logItem(tr("Checking downloaded bootloader"), LOGINFO);
112 m_tempfile.open();
113 QString blfile = m_tempfile.fileName();
114 char magic[4];
115 m_tempfile.seek(0x1fc);
116 m_tempfile.read(magic, 4);
117 m_tempfile.close();
118 if(memcmp(sansa.targetname, magic, 4) != 0) {
119 emit logItem(tr("Bootloader mismatch! Aborting."), LOGERROR);
120 LOG_INFO("Targetname: %s, mi4 magic: %c%c%c%c",
121 sansa.targetname, magic[0], magic[1], magic[2], magic[3]);
122 emit done(true);
123 sansa_close(&sansa);
124 return;
125 }
126
127 len = sansa_read_bootloader(&sansa, blfile.toLatin1().data(), &buf);
128 if(sansa_add_bootloader(&sansa, buf, len) == 0) {
129 emit logItem(tr("Successfully installed bootloader"), LOGOK);
130 sansa_close(&sansa);
131#if defined(Q_OS_MACX)
132 m_remountDevice = sansa.diskname;
133 connect(this, SIGNAL(remounted(bool)), this, SLOT(installStage3(bool)));
134 waitRemount();
135#else
136 installStage3(true);
137#endif
138 }
139 else {
140 emit logItem(tr("Failed to install bootloader"), LOGERROR);
141 sansa_close(&sansa);
142 emit done(true);
143 return;
144 }
145
146}
147
148
149void BootloaderInstallSansa::installStage3(bool mounted)
150{
151 if(mounted) {
152 logInstall(LogAdd);
153 emit logItem(tr("Bootloader Installation complete."), LOGINFO);
154 emit done(false);
155 return;
156 }
157 else {
158 emit logItem(tr("Writing log aborted"), LOGERROR);
159 emit done(true);
160 }
161 LOG_INFO() << "version installed:"
162 << m_blversion.toString(Qt::ISODate);
163}
164
165
166/** Uninstall the bootloader.
167 */
168bool BootloaderInstallSansa::uninstall(void)
169{
170 emit logItem(tr("Uninstalling bootloader"), LOGINFO);
171 QCoreApplication::processEvents();
172
173 if(!sansaInitialize(&sansa)) {
174 emit done(true);
175 return false;
176 }
177
178 if (sansa.hasoldbootloader) {
179 emit logItem(tr("OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
180 "You must reinstall the original Sansa firmware before running\n"
181 "sansapatcher for the first time.\n"
182 "See http://www.rockbox.org/wiki/SansaE200Install\n"),
183 LOGERROR);
184 emit done(true);
185 return false;
186 }
187
188 if (sansa_reopen_rw(&sansa) < 0) {
189 emit logItem(tr("Could not open Sansa in R/W mode"), LOGERROR);
190 emit done(true);
191 return false;
192 }
193
194 if (sansa_delete_bootloader(&sansa)==0) {
195 emit logItem(tr("Successfully removed bootloader"), LOGOK);
196 logInstall(LogRemove);
197 emit logProgress(1, 1);
198 emit done(false);
199 sansa_close(&sansa);
200 return true;
201 }
202 else {
203 emit logItem(tr("Removing bootloader failed."),LOGERROR);
204 emit done(true);
205 sansa_close(&sansa);
206 return false;
207 }
208
209 return false;
210}
211
212
213/** Check if bootloader is already installed
214 */
215BootloaderInstallBase::BootloaderType BootloaderInstallSansa::installed(void)
216{
217 int num;
218
219 if(!sansaInitialize(&sansa)) {
220 return BootloaderUnknown;
221 }
222 if((num = sansa_list_images(&sansa)) == 2) {
223 sansa_close(&sansa);
224 return BootloaderRockbox;
225 }
226 else if(num == 1) {
227 sansa_close(&sansa);
228 return BootloaderOther;
229 }
230 return BootloaderUnknown;
231
232}
233
234bool BootloaderInstallSansa::sansaInitialize(struct sansa_t *sansa)
235{
236 if(!m_blfile.isEmpty()) {
237 QString devicename = Utils::resolveDevicename(m_blfile);
238 if(devicename.isEmpty()) {
239 emit logItem(tr("Error: could not retrieve device name"), LOGERROR);
240 return false;
241 }
242#if defined(Q_OS_WIN32)
243 sprintf(sansa->diskname, "\\\\.\\PhysicalDrive%i", devicename.toInt());
244#elif defined(Q_OS_MACX)
245 sprintf(sansa->diskname,
246 "%s", qPrintable(devicename.remove(QRegExp("s[0-9]+$"))));
247#else
248 sprintf(sansa->diskname,
249 "%s", qPrintable(devicename.remove(QRegExp("[0-9]+$"))));
250#endif
251 LOG_INFO() << "sansapatcher: overriding scan, using"
252 << sansa->diskname;
253 }
254 else if(sansa_scan(sansa) != 1) {
255 emit logItem(tr("Can't find Sansa"), LOGERROR);
256 return false;
257 }
258
259 if (sansa_open(sansa, 0) < 0) {
260 emit logItem(tr("Could not open Sansa"), LOGERROR);
261 return false;
262 }
263
264 if (sansa_read_partinfo(sansa,0) < 0) {
265 emit logItem(tr("Could not read partition table"), LOGERROR);
266 sansa_close(sansa);
267 return false;
268 }
269
270 int i = is_sansa(sansa);
271 if(i < 0) {
272 emit logItem(tr("Disk is not a Sansa (Error %1), aborting.").arg(i), LOGERROR);
273 sansa_close(sansa);
274 return false;
275 }
276 return true;
277}
278
279
280/** Get capabilities of subclass installer.
281 */
282BootloaderInstallBase::Capabilities BootloaderInstallSansa::capabilities(void)
283{
284 return (Install | Uninstall | IsRaw | CanCheckInstalled);
285}
286
diff --git a/utils/rbutilqt/base/bootloaderinstallsansa.h b/utils/rbutilqt/base/bootloaderinstallsansa.h
new file mode 100644
index 0000000000..45837f0ac3
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallsansa.h
@@ -0,0 +1,51 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef BOOTLOADERINSTALLSANSA_H
20#define BOOTLOADERINSTALLSANSA_H
21
22#include <QtCore>
23#include "bootloaderinstallbase.h"
24#include "sansapatcher.h"
25
26
27// bootloader installation class for devices handled by sansapatcher.
28class BootloaderInstallSansa : public BootloaderInstallBase
29{
30 Q_OBJECT
31
32 public:
33 BootloaderInstallSansa(QObject *parent = nullptr);
34 ~BootloaderInstallSansa();
35 bool install(void);
36 bool uninstall(void);
37 BootloaderInstallBase::BootloaderType installed(void);
38 Capabilities capabilities(void);
39
40 private:
41 bool sansaInitialize(struct sansa_t *);
42 struct sansa_t sansa;
43
44 private slots:
45 void installStage2(void);
46 void installStage3(bool);
47};
48
49
50#endif
51
diff --git a/utils/rbutilqt/base/bootloaderinstalltcc.cpp b/utils/rbutilqt/base/bootloaderinstalltcc.cpp
new file mode 100644
index 0000000000..ffc8555733
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstalltcc.cpp
@@ -0,0 +1,165 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2009 by Tomer Shalev
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 * This file is a modified version of the AMS installer by Dominik Wenger
18 *
19 ****************************************************************************/
20
21#include <QtCore>
22#include "bootloaderinstallbase.h"
23#include "bootloaderinstalltcc.h"
24#include "../mktccboot/mktccboot.h"
25
26BootloaderInstallTcc::BootloaderInstallTcc(QObject *parent)
27 : BootloaderInstallBase(parent)
28{
29}
30
31QString BootloaderInstallTcc::ofHint()
32{
33 return tr("Bootloader installation requires you to provide "
34 "a firmware file of the original firmware (bin file). "
35 "You need to download this file yourself due to legal "
36 "reasons. Please refer to the "
37 "<a href='http://www.rockbox.org/manual.shtml'>manual</a> and the "
38 "<a href='http://www.rockbox.org/wiki/CowonD2Info'>CowonD2Info</a> "
39 "wiki page on how to obtain the file.<br/>"
40 "Press Ok to continue and browse your computer for the firmware "
41 "file.");
42}
43
44bool BootloaderInstallTcc::install(void)
45{
46 if(m_offile.isEmpty())
47 return false;
48
49 // Download firmware from server
50 emit logItem(tr("Downloading bootloader file"), LOGINFO);
51
52 connect(this, &BootloaderInstallBase::downloadDone, this, &BootloaderInstallTcc::installStage2);
53 downloadBlStart(m_blurl);
54
55 return true;
56}
57
58void BootloaderInstallTcc::installStage2(void)
59{
60 unsigned char *of_buf, *boot_buf = nullptr, *patched_buf = nullptr;
61 int n, of_size, boot_size, patched_size;
62 char errstr[200];
63 bool ret = false;
64
65 m_tempfile.open();
66 QString bootfile = m_tempfile.fileName();
67 m_tempfile.close();
68
69 /* Construct path for write out.
70 * Combine path of m_blfile with filename from OF */
71 QString outfilename = QFileInfo(m_blfile).absolutePath() + "/" +
72 QFileInfo(m_offile).fileName();
73
74 /* Write out file */
75 QFile out(outfilename);
76
77 /* Load original firmware file */
78 of_buf = file_read(m_offile.toLocal8Bit().data(), &of_size);
79 if (of_buf == nullptr)
80 {
81 emit logItem(errstr, LOGERROR);
82 emit logItem(tr("Could not load %1").arg(m_offile), LOGERROR);
83 goto exit;
84 }
85
86 /* A CRC test in order to reject non OF file */
87 if (test_firmware_tcc(of_buf, of_size))
88 {
89 emit logItem(errstr, LOGERROR);
90 emit logItem(tr("Unknown OF file used: %1").arg(m_offile), LOGERROR);
91 goto exit;
92 }
93
94 /* Load bootloader file */
95 boot_buf = file_read(bootfile.toLocal8Bit().data(), &boot_size);
96 if (boot_buf == nullptr)
97 {
98 emit logItem(errstr, LOGERROR);
99 emit logItem(tr("Could not load %1").arg(bootfile), LOGERROR);
100 goto exit;
101 }
102
103 /* Patch the firmware */
104 emit logItem(tr("Patching Firmware..."), LOGINFO);
105
106 patched_buf = patch_firmware_tcc(of_buf, of_size, boot_buf, boot_size,
107 &patched_size);
108 if (patched_buf == nullptr)
109 {
110 emit logItem(errstr, LOGERROR);
111 emit logItem(tr("Could not patch firmware"), LOGERROR);
112 goto exit;
113 }
114
115 if(!out.open(QIODevice::WriteOnly | QIODevice::Truncate))
116 {
117 emit logItem(tr("Could not open %1 for writing").arg(m_blfile),
118 LOGERROR);
119 goto exit;
120 }
121
122 n = out.write((char*)patched_buf, patched_size);
123 out.close();
124 if (n != patched_size)
125 {
126 emit logItem(tr("Could not write firmware file"), LOGERROR);
127 goto exit;
128 }
129
130 /* End of install */
131 emit logItem(tr("Success: modified firmware file created"), LOGINFO);
132 logInstall(LogAdd);
133
134 ret = true;
135
136exit:
137 if (of_buf)
138 free(of_buf);
139
140 if (boot_buf)
141 free(boot_buf);
142
143 if (patched_buf)
144 free(patched_buf);
145
146 emit done(ret);
147}
148
149bool BootloaderInstallTcc::uninstall(void)
150{
151 emit logItem(tr("To uninstall, perform a normal upgrade with an unmodified original firmware"), LOGINFO);
152 logInstall(LogRemove);
153 emit done(true);
154 return false;
155}
156
157BootloaderInstallBase::BootloaderType BootloaderInstallTcc::installed(void)
158{
159 return BootloaderUnknown;
160}
161
162BootloaderInstallBase::Capabilities BootloaderInstallTcc::capabilities(void)
163{
164 return (Install | NeedsOf);
165}
diff --git a/utils/rbutilqt/base/bootloaderinstalltcc.h b/utils/rbutilqt/base/bootloaderinstalltcc.h
new file mode 100644
index 0000000000..cc1fd45802
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstalltcc.h
@@ -0,0 +1,44 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2009 by Tomer Shalev
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 * This file is a modified version of the AMS installer by Dominik Wenger
18 *
19 ****************************************************************************/
20#ifndef BOOTLOADERINSTALLTCC_H
21#define BOOTLOADERINSTALLTCC_H
22
23#include <QtCore>
24#include "bootloaderinstallbase.h"
25
26//! bootloader installation derivate based on mktccboot
27class BootloaderInstallTcc : public BootloaderInstallBase
28{
29 Q_OBJECT
30 public:
31 BootloaderInstallTcc(QObject *parent);
32 bool install(void);
33 bool uninstall(void);
34 BootloaderInstallBase::BootloaderType installed(void);
35 Capabilities capabilities(void);
36 QString ofHint();
37
38 private:
39
40 private slots:
41 void installStage2(void);
42};
43
44#endif
diff --git a/utils/rbutilqt/base/encoderbase.cpp b/utils/rbutilqt/base/encoderbase.cpp
new file mode 100644
index 0000000000..fe45eee49b
--- /dev/null
+++ b/utils/rbutilqt/base/encoderbase.cpp
@@ -0,0 +1,86 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include "encoderbase.h"
20#include "utils.h"
21#include "rbsettings.h"
22#include "encoderrbspeex.h"
23#include "encoderlame.h"
24#include "encoderexe.h"
25
26#include "Logger.h"
27
28/*********************************************************************
29* Encoder Base
30**********************************************************************/
31QMap<QString,QString> EncoderBase::encoderList;
32
33EncoderBase::EncoderBase(QObject *parent): EncTtsSettingInterface(parent)
34{
35
36}
37
38// initialize list of encoders
39void EncoderBase::initEncodernamesList()
40{
41 encoderList["rbspeex"] = "Rockbox Speex Encoder";
42 encoderList["lame"] = "Lame Mp3 Encoder";
43}
44
45
46// get nice name for a specific encoder
47QString EncoderBase::getEncoderName(QString encoder)
48{
49 if(encoderList.isEmpty())
50 initEncodernamesList();
51 return encoderList.value(encoder);
52}
53
54
55// get a specific encoder object
56EncoderBase* EncoderBase::getEncoder(QObject* parent,QString encoder)
57{
58 EncoderBase* enc;
59 if(encoder == "lame")
60 {
61 enc = new EncoderLame(parent);
62 if (!enc->configOk())
63 {
64 LOG_WARNING() << "Could not load lame dll, falling back to command "
65 "line lame. This is notably slower.";
66 delete enc;
67 enc = new EncoderExe(encoder, parent);
68
69 }
70 return enc;
71 }
72 else // rbspeex is default
73 {
74 enc = new EncoderRbSpeex(parent);
75 return enc;
76 }
77}
78
79
80QStringList EncoderBase::getEncoderList()
81{
82 if(encoderList.isEmpty())
83 initEncodernamesList();
84 return encoderList.keys();
85}
86
diff --git a/utils/rbutilqt/base/encoderbase.h b/utils/rbutilqt/base/encoderbase.h
new file mode 100644
index 0000000000..810b38aa9e
--- /dev/null
+++ b/utils/rbutilqt/base/encoderbase.h
@@ -0,0 +1,63 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#ifndef ENCODERS_H
22#define ENCODERS_H
23
24#include <QtCore>
25
26#include "encttssettings.h"
27
28
29class EncoderBase : public EncTtsSettingInterface
30{
31 Q_OBJECT
32 public:
33 EncoderBase(QObject *parent );
34
35 //! Child class should encode a wav file
36 virtual bool encode(QString input,QString output) =0;
37 //! Child class should do startup
38 virtual bool start()=0;
39 //! Child class should stop
40 virtual bool stop()=0;
41
42 // settings
43 //! Child class should return true when configuration is ok
44 virtual bool configOk()=0;
45 //! Child class should fill in settingsList
46 virtual void generateSettings() = 0;
47 //! Child class should commit from SettingsList to permanent storage
48 virtual void saveSettings() = 0;
49
50 // static functions
51 static QString getEncoderName(QString name);
52 static EncoderBase* getEncoder(QObject* parent,QString name);
53 static QStringList getEncoderList(void);
54
55 private:
56 static void initEncodernamesList(void);
57
58 protected:
59 static QMap<QString,QString> encoderList;
60};
61
62#endif
63
diff --git a/utils/rbutilqt/base/encoderexe.cpp b/utils/rbutilqt/base/encoderexe.cpp
new file mode 100644
index 0000000000..331b5fb2a4
--- /dev/null
+++ b/utils/rbutilqt/base/encoderexe.cpp
@@ -0,0 +1,78 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include "encoderexe.h"
21#include "rbsettings.h"
22#include "utils.h"
23#include "Logger.h"
24
25EncoderExe::EncoderExe(QString name, QObject *parent) : EncoderBase(parent),
26 m_name(name)
27{
28}
29
30
31void EncoderExe::generateSettings()
32{
33 QString exepath = RbSettings::subValue(m_name,RbSettings::EncoderPath).toString();
34 if(exepath.isEmpty()) exepath = Utils::findExecutable(m_name);
35
36 insertSetting(eEXEPATH, new EncTtsSetting(this, EncTtsSetting::eSTRING,
37 tr("Path to Encoder:"), exepath, EncTtsSetting::eBROWSEBTN));
38 insertSetting(eEXEOPTIONS, new EncTtsSetting(this, EncTtsSetting::eSTRING,
39 tr("Encoder options:"), RbSettings::subValue(m_name, RbSettings::EncoderOptions)));
40}
41
42void EncoderExe::saveSettings()
43{
44 RbSettings::setSubValue(m_name, RbSettings::EncoderPath, getSetting(eEXEPATH)->current().toString());
45 RbSettings::setSubValue(m_name, RbSettings::EncoderOptions, getSetting(eEXEOPTIONS)->current().toString());
46 RbSettings::sync();
47}
48
49bool EncoderExe::start()
50{
51 m_EncExec = RbSettings::subValue(m_name, RbSettings::EncoderPath).toString();
52 m_EncOpts = RbSettings::subValue(m_name, RbSettings::EncoderOptions).toString();
53
54 QFileInfo enc(m_EncExec);
55 return enc.exists();
56}
57
58bool EncoderExe::encode(QString input,QString output)
59{
60 if (!configOk())
61 return false;
62
63 QStringList args;
64 args << m_EncOpts;
65 args << input;
66 args << output;
67 int result = QProcess::execute(m_EncExec, args);
68 return result == 0;
69}
70
71
72bool EncoderExe::configOk()
73{
74 QString path = RbSettings::subValue(m_name, RbSettings::EncoderPath).toString();
75
76 return QFileInfo::exists(path);
77}
78
diff --git a/utils/rbutilqt/base/encoderexe.h b/utils/rbutilqt/base/encoderexe.h
new file mode 100644
index 0000000000..4008689167
--- /dev/null
+++ b/utils/rbutilqt/base/encoderexe.h
@@ -0,0 +1,53 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#ifndef ENCODEREXES_H
22#define ENCODEREXES_H
23
24#include <QtCore>
25#include "encoderbase.h"
26
27class EncoderExe : public EncoderBase
28{
29 enum ESettings
30 {
31 eEXEPATH,
32 eEXEOPTIONS
33 };
34
35 Q_OBJECT
36 public:
37 EncoderExe(QString name,QObject *parent = nullptr);
38 bool encode(QString input,QString output);
39 bool start();
40 bool stop() {return true;}
41
42 // setting
43 bool configOk();
44 void generateSettings();
45 void saveSettings();
46
47 private:
48 QString m_name;
49 QString m_EncExec;
50 QString m_EncOpts;
51};
52#endif
53
diff --git a/utils/rbutilqt/base/encoderlame.cpp b/utils/rbutilqt/base/encoderlame.cpp
new file mode 100644
index 0000000000..1658a7092d
--- /dev/null
+++ b/utils/rbutilqt/base/encoderlame.cpp
@@ -0,0 +1,312 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2012 Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include "encoderlame.h"
21#include "rbsettings.h"
22#include "lame/lame.h"
23#include "Logger.h"
24
25/** Resolve a symbol from loaded library.
26 */
27#define SYMBOLRESOLVE(symbol, type) \
28 do { m_##symbol = (type)lib.resolve(#symbol); \
29 if(!m_##symbol) return; \
30 LOG_INFO() << "Resolved symbol " #symbol; } \
31 while(0)
32
33EncoderLame::EncoderLame(QObject *parent) : EncoderBase(parent),
34 lib("libmp3lame", this), m_symbolsResolved(false)
35{
36 lib.load();
37 if (!lib.isLoaded()) {
38 LOG_WARNING() << "Loading mp3lame lib failed:" << lib.errorString();
39 return;
40 }
41
42 SYMBOLRESOLVE(get_lame_short_version, const char* (*)());
43 SYMBOLRESOLVE(lame_set_out_samplerate, int (*)(lame_global_flags*, int));
44 SYMBOLRESOLVE(lame_set_in_samplerate, int (*)(lame_global_flags*, int));
45 SYMBOLRESOLVE(lame_set_num_channels, int (*)(lame_global_flags*, int));
46 SYMBOLRESOLVE(lame_set_scale, int (*)(lame_global_flags*, float));
47 SYMBOLRESOLVE(lame_set_mode, int (*)(lame_global_flags*, MPEG_mode));
48 SYMBOLRESOLVE(lame_set_VBR, int (*)(lame_global_flags*, vbr_mode));
49 SYMBOLRESOLVE(lame_set_VBR_quality, int (*)(lame_global_flags*, float));
50 SYMBOLRESOLVE(lame_set_VBR_max_bitrate_kbps, int (*)(lame_global_flags*, int));
51 SYMBOLRESOLVE(lame_set_bWriteVbrTag, int (*)(lame_global_flags*, int));
52 SYMBOLRESOLVE(lame_init, lame_global_flags* (*)());
53 SYMBOLRESOLVE(lame_init_params, int (*)(lame_global_flags*));
54 SYMBOLRESOLVE(lame_encode_buffer, int (*)(lame_global_flags*, short int*, short int*, int, unsigned char*, int));
55 SYMBOLRESOLVE(lame_encode_flush, int (*)(lame_global_flags*, unsigned char*, int));
56 SYMBOLRESOLVE(lame_close, int (*)(lame_global_flags*));
57
58 m_encoderVolume = RbSettings::subValue("lame", RbSettings::EncoderVolume).toDouble();
59 m_encoderQuality = RbSettings::subValue("lame", RbSettings::EncoderQuality).toDouble();
60 m_symbolsResolved = true;
61}
62
63void EncoderLame::generateSettings()
64{
65 // no settings for now.
66 // show lame version.
67 if(m_symbolsResolved) {
68 double quality = RbSettings::subValue("lame",
69 RbSettings::EncoderQuality).toDouble();
70 // default quality is 0.999.
71 if(quality < 0) {
72 quality = 0.99;
73 }
74 insertSetting(LAMEVERSION, new EncTtsSetting(this, EncTtsSetting::eREADONLYSTRING,
75 tr("LAME"), QString(m_get_lame_short_version())));
76 insertSetting(VOLUME, new EncTtsSetting(this, EncTtsSetting::eDOUBLE,
77 tr("Volume"),
78 RbSettings::subValue("lame", RbSettings::EncoderVolume).toDouble(),
79 0.0, 2.0));
80 insertSetting(QUALITY, new EncTtsSetting(this, EncTtsSetting::eDOUBLE,
81 tr("Quality"), quality, 0.0, 1.0));
82 }
83 else {
84 insertSetting(LAMEVERSION, new EncTtsSetting(this, EncTtsSetting::eREADONLYSTRING,
85 tr("LAME"), tr("Could not find libmp3lame!")));
86 }
87}
88
89void EncoderLame::saveSettings()
90{
91 if(m_symbolsResolved) {
92 RbSettings::setSubValue("lame", RbSettings::EncoderVolume,
93 getSetting(VOLUME)->current().toDouble());
94 RbSettings::setSubValue("lame", RbSettings::EncoderQuality,
95 getSetting(QUALITY)->current().toDouble());
96 m_encoderVolume =
97 RbSettings::subValue("lame", RbSettings::EncoderVolume).toDouble();
98 m_encoderQuality =
99 RbSettings::subValue("lame", RbSettings::EncoderQuality).toDouble();
100 }
101}
102
103bool EncoderLame::start()
104{
105 if(!m_symbolsResolved) {
106 return false;
107 }
108 // try to get config from settings
109 return true;
110}
111
112bool EncoderLame::encode(QString input,QString output)
113{
114 LOG_INFO() << "Encoding" << QDir::cleanPath(input);
115 if(!m_symbolsResolved) {
116 LOG_ERROR() << "Symbols not successfully resolved, cannot run!";
117 return false;
118 }
119
120 QFile fin(input);
121 QFile fout(output);
122 // initialize encoder
123 lame_global_flags *gfp;
124 unsigned char header[12];
125 unsigned char chunkheader[8];
126 unsigned int datalength = 0;
127 unsigned int channels = 0;
128 unsigned int samplerate = 0;
129 unsigned int samplesize = 0;
130 int num_samples = 0;
131 int ret;
132 unsigned char* mp3buf;
133 int mp3buflen;
134 short int* wavbuf;
135 int wavbuflen;
136
137
138 gfp = m_lame_init();
139 m_lame_set_out_samplerate(gfp, 12000); // resample to 12kHz
140 // scale input volume
141 m_lame_set_scale(gfp, m_encoderVolume);
142 m_lame_set_mode(gfp, MONO); // mono output mode
143 m_lame_set_VBR(gfp, vbr_default); // enable default VBR mode
144 // VBR quality
145 m_lame_set_VBR_quality(gfp, m_encoderQuality);
146 m_lame_set_VBR_max_bitrate_kbps(gfp, 64); // maximum bitrate 64kbps
147 m_lame_set_bWriteVbrTag(gfp, 0); // disable LAME tag.
148
149 if(!fin.open(QIODevice::ReadOnly)) {
150 LOG_ERROR() << "Could not open input file" << input;
151 return false;
152 }
153
154 // read RIFF header
155 fin.read((char*)header, 12);
156 if(memcmp("RIFF", header, 4) != 0) {
157 LOG_ERROR() << "RIFF header not found!"
158 << header[0] << header[1] << header[2] << header[3];
159 fin.close();
160 return false;
161 }
162 if(memcmp("WAVE", &header[8], 4) != 0) {
163 LOG_ERROR() << "WAVE FOURCC not found!"
164 << header[8] << header[9] << header[10] << header[11];
165 fin.close();
166 return false;
167 }
168
169 // search for fmt chunk
170 do {
171 // read fmt
172 fin.read((char*)chunkheader, 8);
173 int chunkdatalen = chunkheader[4] | chunkheader[5]<<8
174 | chunkheader[6]<<16 | chunkheader[7]<<24;
175 if(memcmp("fmt ", chunkheader, 4) == 0) {
176 // fmt found, read rest of chunk.
177 // NOTE: This code ignores the format tag value.
178 // Ideally this should be checked as well. However, rbspeex doesn't
179 // check the format tag either when reading wave files, so if
180 // problems arise we should notice pretty soon. Furthermore, the
181 // input format used should be known. In case some TTS uses a
182 // different wave encoding some time this needs to get adjusted.
183 if(chunkdatalen < 16) {
184 LOG_ERROR() << "fmt chunk too small!";
185 }
186 else {
187 unsigned char *buf = new unsigned char[chunkdatalen];
188 fin.read((char*)buf, chunkdatalen);
189 channels = buf[2] | buf[3]<<8;
190 samplerate = buf[4] | buf[5]<<8 | buf[6]<<16 | buf[7]<<24;
191 samplesize = buf[14] | buf[15]<<8;
192 delete[] buf;
193 }
194 }
195 // read data
196 else if(memcmp("data", chunkheader, 4) == 0) {
197 datalength = chunkdatalen;
198 break;
199 }
200 else {
201 // unknown chunk, just skip its data.
202 LOG_WARNING() << "unknown chunk, skipping."
203 << chunkheader[0] << chunkheader[1]
204 << chunkheader[2] << chunkheader[3];
205 fin.seek(fin.pos() + chunkdatalen);
206 }
207 } while(!fin.atEnd());
208
209 // check format
210 if(channels == 0 || samplerate == 0 || samplesize == 0 || datalength == 0) {
211 LOG_ERROR() << "invalid format. Channels:" << channels
212 << "Samplerate:" << samplerate << "Samplesize:" << samplesize
213 << "Data chunk length:" << datalength;
214 fin.close();
215 return false;
216 }
217 num_samples = (datalength / channels / (samplesize/8));
218
219 // set input format values
220 m_lame_set_in_samplerate(gfp, samplerate);
221 m_lame_set_num_channels(gfp, channels);
222
223 // initialize encoder.
224 ret = m_lame_init_params(gfp);
225 if(ret != 0) {
226 LOG_ERROR() << "lame_init_params() failed with" << ret;
227 fin.close();
228 return false;
229 }
230
231 // we're dealing with rather small files here (100kB-ish), so don't care
232 // about the possible output size and simply allocate the same number of
233 // bytes the input file has. This wastes space but should be ok.
234 // Put an upper limit of 8MiB.
235 if(datalength > 8*1024*1024) {
236 LOG_ERROR() << "Input file too large:" << datalength;
237 fin.close();
238 return false;
239 }
240 mp3buflen = datalength;
241 wavbuflen = datalength;
242 mp3buf = new unsigned char[mp3buflen];
243 wavbuf = new short int[wavbuflen];
244#if defined(Q_OS_MACX)
245 // handle byte order -- the host might not be LE.
246 if(samplesize == 8) {
247 // no need to convert.
248 fin.read((char*)wavbuf, wavbuflen);
249 }
250 else if(samplesize == 16) {
251 // read LE 16bit words. Since the input format is either mono or
252 // interleaved there's no need to care for that.
253 unsigned int pos = 0;
254 char word[2];
255 while(pos < datalength) {
256 fin.read(word, 2);
257 wavbuf[pos++] = (word[0]&0xff) | ((word[1]<<8)&0xff00);
258 }
259 }
260 else {
261 LOG_ERROR() << "Unknown samplesize:" << samplesize;
262 fin.close();
263 delete[] mp3buf;
264 delete[] wavbuf;
265 return false;
266 }
267#else
268 // all systems but OS X are considered LE.
269 fin.read((char*)wavbuf, wavbuflen);
270#endif
271 fin.close();
272 // encode data.
273 fout.open(QIODevice::ReadWrite);
274 ret = m_lame_encode_buffer(gfp, wavbuf, wavbuf, num_samples, mp3buf, mp3buflen);
275 if(ret < 0) {
276 LOG_ERROR() << "Error during encoding:" << ret;
277 }
278 if(fout.write((char*)mp3buf, ret) != (unsigned int)ret) {
279 LOG_ERROR() << "Writing mp3 data failed!" << ret;
280 fout.close();
281 delete[] mp3buf;
282 delete[] wavbuf;
283 return false;
284 }
285 // flush remaining data
286 ret = m_lame_encode_flush(gfp, mp3buf, mp3buflen);
287 if(fout.write((char*)mp3buf, ret) != (unsigned int)ret) {
288 LOG_ERROR() << "Writing final mp3 data failed!";
289 fout.close();
290 delete[] mp3buf;
291 delete[] wavbuf;
292 return false;
293 }
294 // shut down encoder and clean up.
295 m_lame_close(gfp);
296 fout.close();
297 delete[] mp3buf;
298 delete[] wavbuf;
299
300 return true;
301}
302
303/** Check if the current configuration is usable.
304 * Since we're loading a library dynamically in the constructor test if that
305 * succeeded. Otherwise the "configuration" is not usable, even though the
306 * problem is not necessarily related to configuration values set by the user.
307 */
308bool EncoderLame::configOk()
309{
310 return m_symbolsResolved;
311}
312
diff --git a/utils/rbutilqt/base/encoderlame.h b/utils/rbutilqt/base/encoderlame.h
new file mode 100644
index 0000000000..a5f1b2d3f4
--- /dev/null
+++ b/utils/rbutilqt/base/encoderlame.h
@@ -0,0 +1,72 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2012 Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef ENCODERLAME_H
20#define ENCODERLAME_H
21
22#include <QtCore>
23#include "encoderbase.h"
24#include "lame/lame.h"
25
26class EncoderLame : public EncoderBase
27{
28 enum ESettings
29 {
30 LAMEVERSION,
31 VOLUME,
32 QUALITY,
33 };
34
35 Q_OBJECT
36 public:
37 EncoderLame(QObject *parent = nullptr);
38 bool encode(QString input,QString output);
39 bool start();
40 bool stop() {return true;}
41
42 // for settings view
43 bool configOk();
44 void generateSettings();
45 void saveSettings();
46
47 private:
48 QLibrary lib;
49 const char*(*m_get_lame_short_version)(void);
50 int (*m_lame_set_out_samplerate)(lame_global_flags*, int);
51 int (*m_lame_set_in_samplerate)(lame_global_flags*, int);
52 int (*m_lame_set_num_channels)(lame_global_flags*, int);
53 int (*m_lame_set_scale)(lame_global_flags*, float);
54 int (*m_lame_set_mode)(lame_global_flags*, MPEG_mode);
55 int (*m_lame_set_VBR)(lame_global_flags*, vbr_mode);
56 int (*m_lame_set_VBR_quality)(lame_global_flags*, float);
57 int (*m_lame_set_VBR_max_bitrate_kbps)(lame_global_flags*, int);
58 int (*m_lame_set_bWriteVbrTag)(lame_global_flags*, int);
59 lame_global_flags*(*m_lame_init)(void);
60 int (*m_lame_init_params)(lame_global_flags*);
61 int (*m_lame_encode_buffer)(lame_global_flags*, short int[], short
62 int[], int, unsigned char*, int);
63 int (*m_lame_encode_flush)(lame_global_flags*, unsigned char*, int);
64 int (*m_lame_close)(lame_global_flags*);
65
66 bool m_symbolsResolved;
67 double m_encoderVolume;
68 double m_encoderQuality;
69};
70
71#endif
72
diff --git a/utils/rbutilqt/base/encoderrbspeex.cpp b/utils/rbutilqt/base/encoderrbspeex.cpp
new file mode 100644
index 0000000000..2bee66028a
--- /dev/null
+++ b/utils/rbutilqt/base/encoderrbspeex.cpp
@@ -0,0 +1,119 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include "encoderrbspeex.h"
21#include "rbsettings.h"
22#include "rbspeex.h"
23#include "Logger.h"
24
25EncoderRbSpeex::EncoderRbSpeex(QObject *parent) : EncoderBase(parent)
26{
27
28}
29
30void EncoderRbSpeex::generateSettings()
31{
32 loadSettings();
33 insertSetting(eVOLUME, new EncTtsSetting(this, EncTtsSetting::eDOUBLE,
34 tr("Volume:"), volume, 0.0, 2.0));
35 insertSetting(eQUALITY, new EncTtsSetting(this, EncTtsSetting::eDOUBLE,
36 tr("Quality:"), quality, 0, 10.0));
37 insertSetting(eCOMPLEXITY, new EncTtsSetting(this, EncTtsSetting::eINT,
38 tr("Complexity:"), complexity, 0, 10));
39 insertSetting(eNARROWBAND,new EncTtsSetting(this, EncTtsSetting::eBOOL,
40 tr("Use Narrowband:"), narrowband));
41}
42
43void EncoderRbSpeex::saveSettings()
44{
45 //save settings in user config
46 RbSettings::setSubValue("rbspeex",RbSettings::EncoderVolume,
47 getSetting(eVOLUME)->current().toDouble());
48 RbSettings::setSubValue("rbspeex",RbSettings::EncoderQuality,
49 getSetting(eQUALITY)->current().toDouble());
50 RbSettings::setSubValue("rbspeex",RbSettings::EncoderComplexity,
51 getSetting(eCOMPLEXITY)->current().toInt());
52 RbSettings::setSubValue("rbspeex",RbSettings::EncoderNarrowBand,
53 getSetting(eNARROWBAND)->current().toBool());
54
55 RbSettings::sync();
56}
57
58
59void EncoderRbSpeex::loadSettings(void)
60{
61 // try to get config from settings
62 quality = RbSettings::subValue("rbspeex", RbSettings::EncoderQuality).toDouble();
63 if(quality < 0) {
64 quality = 8.0;
65 }
66 complexity = RbSettings::subValue("rbspeex", RbSettings::EncoderComplexity).toInt();
67 volume = RbSettings::subValue("rbspeex", RbSettings::EncoderVolume).toDouble();
68 narrowband = RbSettings::subValue("rbspeex", RbSettings::EncoderNarrowBand).toBool();
69}
70
71
72bool EncoderRbSpeex::start()
73{
74
75 // make sure configuration parameters are set.
76 loadSettings();
77 return true;
78}
79
80bool EncoderRbSpeex::encode(QString input,QString output)
81{
82 LOG_INFO() << "Encoding " << input << " to "<< output;
83 char errstr[512];
84
85 FILE *fin,*fout;
86 if ((fin = fopen(input.toLocal8Bit(), "rb")) == nullptr) {
87 LOG_ERROR() << "Error: could not open input file\n";
88 return false;
89 }
90 if ((fout = fopen(output.toLocal8Bit(), "wb")) == nullptr) {
91 LOG_ERROR() << "Error: could not open output file\n";
92 fclose(fin);
93 return false;
94 }
95
96 int ret = encode_file(fin, fout, quality, complexity, narrowband, volume,
97 errstr, sizeof(errstr));
98 fclose(fout);
99 fclose(fin);
100
101 if (!ret) {
102 /* Attempt to delete unfinished output */
103 LOG_ERROR() << "Error:" << errstr;
104 QFile(output).remove();
105 return false;
106 }
107 return true;
108}
109
110bool EncoderRbSpeex::configOk()
111{
112 // check config. Make sure current settings are loaded.
113 loadSettings();
114 if(volume <= 0 || quality <= 0 || complexity <= 0)
115 return false;
116 else
117 return true;
118}
119
diff --git a/utils/rbutilqt/base/encoderrbspeex.h b/utils/rbutilqt/base/encoderrbspeex.h
new file mode 100644
index 0000000000..6ad41c38a3
--- /dev/null
+++ b/utils/rbutilqt/base/encoderrbspeex.h
@@ -0,0 +1,61 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef ENCODERRBSPEEX_H
20#define ENCODERRBSPEEX_H
21
22#include <QtCore>
23#include "encoderbase.h"
24
25class EncoderRbSpeex : public EncoderBase
26{
27 enum ESettings
28 {
29 eVOLUME,
30 eQUALITY,
31 eCOMPLEXITY,
32 eNARROWBAND
33 };
34
35 Q_OBJECT
36 public:
37 EncoderRbSpeex(QObject *parent = nullptr);
38 bool encode(QString input,QString output);
39 bool start();
40 bool stop() {return true;}
41
42 // for settings view
43 bool configOk();
44 void generateSettings();
45 void saveSettings();
46
47 private:
48 void loadSettings(void);
49 float quality;
50 float volume;
51 int complexity;
52 bool narrowband;
53
54 float defaultQuality;
55 float defaultVolume;
56 int defaultComplexity;
57 bool defaultBand;
58};
59
60#endif
61
diff --git a/utils/rbutilqt/base/encttssettings.cpp b/utils/rbutilqt/base/encttssettings.cpp
new file mode 100644
index 0000000000..9c8c2e57fd
--- /dev/null
+++ b/utils/rbutilqt/base/encttssettings.cpp
@@ -0,0 +1,70 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 * $Id: encoders.h 17902 2008-06-30 22:09:45Z bluebrother $
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "encttssettings.h"
23
24
25EncTtsSetting::EncTtsSetting(QObject* parent,ESettingType type,QString name,QVariant current, EButton btn) : QObject(parent)
26{
27 m_btn = btn;
28 m_name =name;
29 m_type =type;
30 m_currentValue = current;
31}
32
33EncTtsSetting::EncTtsSetting(QObject* parent,ESettingType type,QString name,QVariant current,QStringList list,EButton btn) : QObject(parent)
34{
35 m_btn = btn;
36 m_name =name;
37 m_type =type;
38 m_currentValue = current;
39 m_list = list;
40}
41
42EncTtsSetting::EncTtsSetting(QObject* parent,ESettingType type,QString name,QVariant current,QVariant min,QVariant max, EButton btn) : QObject(parent)
43{
44 m_btn = btn;
45 m_name =name;
46 m_type =type;
47 m_currentValue = current;
48 m_minValue = min;
49 m_maxValue = max;
50}
51
52void EncTtsSetting::setCurrent(QVariant current,bool noticeGui)
53{
54 m_currentValue = current;
55 emit dataChanged();
56
57 if(noticeGui) emit updateGui();
58}
59
60//! insert a setting
61void EncTtsSettingInterface::insertSetting(int id,EncTtsSetting* setting)
62{
63 settingsList.insert(id,setting);
64}
65
66//! retrieve a specific setting
67EncTtsSetting* EncTtsSettingInterface::getSetting(int id)
68{
69 return settingsList.at(id);
70}
diff --git a/utils/rbutilqt/base/encttssettings.h b/utils/rbutilqt/base/encttssettings.h
new file mode 100644
index 0000000000..1258d81d57
--- /dev/null
+++ b/utils/rbutilqt/base/encttssettings.h
@@ -0,0 +1,128 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#ifndef ENCTTSSETTINGS_H
22#define ENCTTSSETTINGS_H
23
24#include <QtCore>
25
26//! \brief This class stores everything needed to display a Setting.
27//!
28class EncTtsSetting : public QObject
29{
30 Q_OBJECT
31public:
32 enum ESettingType
33 {
34 eBASE,
35 eBOOL,
36 eDOUBLE,
37 eINT,
38 eSTRING,
39 eREADONLYSTRING,
40 eSTRINGLIST,
41 };
42 enum EButton
43 {
44 eNOBTN,
45 eBROWSEBTN,
46 eREFRESHBTN
47 };
48
49 //! constructor for a String or Bool setting
50 EncTtsSetting(QObject* parent,ESettingType type,QString name,QVariant current,EButton btn = eNOBTN);
51 //! contructor for a Stringlist setting, ie a enumeration
52 EncTtsSetting(QObject* parent,ESettingType type,QString name,QVariant current,QStringList list,EButton btn = eNOBTN);
53 //! constructor for a setting with a min-max range
54 EncTtsSetting(QObject* parent,ESettingType type,QString name,QVariant current,QVariant min,QVariant max,EButton = eNOBTN);
55
56 //! get currentValue
57 QVariant current() {return m_currentValue;}
58 //! set currentValue
59 void setCurrent(QVariant current,bool noticeGui=true);
60
61 //! get name of the Setting
62 QString name() {return m_name;}
63 //! get the type of the setting
64 ESettingType type() {return m_type;}
65 //! get what type of button this setting needs
66 EButton button() {return m_btn;}
67 //! get the minValue (only valid for a range setting, ie eDOUBLE or eINT)
68 QVariant min() {return m_minValue; }
69 //! get the maxValue (only valid for a range setting, ie eDOUBLE or eINT)
70 QVariant max() {return m_maxValue; }
71 //! get the enumerationlist (only valid for eSTRINGLIST settings)
72 QStringList list() {return m_list;}
73 //! set the enumeration list
74 void setList(QStringList list){m_list = list;}
75
76signals:
77 //! connect to this signal if you want to get noticed when the data changes
78 void dataChanged();
79 //! connect to this if you want to react on refresh button
80 void refresh();
81 //! will be emited when the gui should update this setting
82 void updateGui();
83
84private:
85 ESettingType m_type;
86 EButton m_btn;
87 QString m_name;
88 QVariant m_currentValue;
89 QVariant m_minValue;
90 QVariant m_maxValue;
91 QStringList m_list;
92};
93
94
95//! \brief this class is the Interface for Encoder and TTS engines, to display settings
96//! It wraps nearly everything needed, only updateModel() and commitModel() needs to be reimplemented
97//!
98class EncTtsSettingInterface : public QObject
99{
100 Q_OBJECT
101public:
102 EncTtsSettingInterface(QObject* parent) : QObject(parent) {}
103
104 //! get the Settings list
105 QList<EncTtsSetting*> getSettings() {generateSettings(); return settingsList;}
106
107 //! Chlid class should commit the from SettingsList to permanent storage
108 virtual void saveSettings() = 0;
109
110signals:
111 void busy(); // emit this if a operation takes time
112 void busyEnd(); // emit this at the end of a busy section
113
114protected:
115 //! Child class should fill in the setttingsList
116 virtual void generateSettings() = 0;
117
118 //! insert a setting
119 void insertSetting(int id,EncTtsSetting* setting);
120 //! retrieve a specific setting
121 EncTtsSetting* getSetting(int id);
122
123private:
124 //! The setting storage.
125 QList<EncTtsSetting*> settingsList;
126
127};
128#endif
diff --git a/utils/rbutilqt/base/httpget.cpp b/utils/rbutilqt/base/httpget.cpp
new file mode 100644
index 0000000000..2df9501fd6
--- /dev/null
+++ b/utils/rbutilqt/base/httpget.cpp
@@ -0,0 +1,256 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2013 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtNetwork>
20
21#include <QNetworkAccessManager>
22#include <QNetworkRequest>
23
24#include "httpget.h"
25#include "Logger.h"
26
27QString HttpGet::m_globalUserAgent; //< globally set user agent for requests
28QDir HttpGet::m_globalCache; //< global cach path value for new objects
29QNetworkProxy HttpGet::m_globalProxy;
30
31HttpGet::HttpGet(QObject *parent)
32 : QObject(parent),
33 m_mgr(this),
34 m_reply(nullptr),
35 m_cache(nullptr),
36 m_cachedir(m_globalCache),
37 m_outputFile(nullptr),
38 m_proxy(QNetworkProxy::NoProxy)
39{
40 setCache(true);
41 connect(&m_mgr, &QNetworkAccessManager::finished, this,
42 static_cast<void (HttpGet::*)(QNetworkReply*)>(&HttpGet::requestFinished));
43 m_lastServerTimestamp = QDateTime();
44}
45
46
47/** @brief set cache path
48 * @param d new directory to use as cache path
49 */
50void HttpGet::setCache(const QDir& d)
51{
52 if(m_cache && m_cachedir == d.absolutePath())
53 return;
54 m_cachedir.setPath(d.absolutePath());
55 setCache(true);
56}
57
58
59/** @brief enable / disable cache useage
60 * @param c set cache usage
61 */
62void HttpGet::setCache(bool c)
63{
64 // don't change cache if it's already (un)set.
65 if(c && m_cache) return;
66 if(!c && !m_cache) return;
67 // don't delete the old cache directly, it might still be in use. Just
68 // instruct it to delete itself later.
69 if(m_cache) m_cache->deleteLater();
70 m_cache = nullptr;
71
72 QString path = m_cachedir.absolutePath();
73
74 if(!c || m_cachedir.absolutePath().isEmpty()) {
75 LOG_INFO() << "disabling download cache";
76 }
77 else {
78 // append the cache path to make it unique in case the path points to
79 // the system temporary path. In that case using it directly might
80 // cause problems. Extra path also used in configure dialog.
81 path += "/rbutil-cache";
82 LOG_INFO() << "setting cache folder to" << path;
83 m_cache = new QNetworkDiskCache(this);
84 m_cache->setCacheDirectory(path);
85 }
86 m_mgr.setCache(m_cache);
87}
88
89
90/** @brief read all downloaded data into a buffer
91 * @return data
92 */
93QByteArray HttpGet::readAll()
94{
95 return m_data;
96}
97
98
99/** @brief Set and enable Proxy to use.
100 * @param proxy Proxy URL.
101 */
102void HttpGet::setProxy(const QUrl &proxy)
103{
104 LOG_INFO() << "Proxy set to" << proxy;
105 m_proxy.setType(QNetworkProxy::HttpProxy);
106 m_proxy.setHostName(proxy.host());
107 m_proxy.setPort(proxy.port());
108 m_proxy.setUser(proxy.userName());
109 m_proxy.setPassword(proxy.password());
110 m_mgr.setProxy(m_proxy);
111}
112
113
114/** @brief Enable or disable use of previously set proxy.
115 * @param enable Enable proxy.
116 */
117void HttpGet::setProxy(bool enable)
118{
119 if(enable) m_mgr.setProxy(m_proxy);
120 else m_mgr.setProxy(QNetworkProxy::NoProxy);
121}
122
123
124/** @brief Set output file.
125 *
126 * Set filename for storing the downloaded file to. If no file is set the
127 * downloaded file will not be stored to disk but kept in memory. The result
128 * can then be retrieved using readAll().
129 *
130 * @param file Output file.
131 */
132void HttpGet::setFile(QFile *file)
133{
134 m_outputFile = file;
135}
136
137
138void HttpGet::abort()
139{
140 if(m_reply) m_reply->abort();
141}
142
143
144void HttpGet::requestFinished(QNetworkReply* reply)
145{
146 m_lastStatusCode
147 = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
148 LOG_INFO() << "Request finished, status code:" << m_lastStatusCode;
149 m_lastServerTimestamp
150 = reply->header(QNetworkRequest::LastModifiedHeader).toDateTime().toLocalTime();
151 LOG_INFO() << "Data from cache:"
152 << reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool();
153 m_lastRequestCached =
154 reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool();
155 if(reply->attribute(QNetworkRequest::RedirectionTargetAttribute).isValid()) {
156 // handle relative URLs using QUrl::resolved()
157 QUrl org = reply->request().url();
158 QUrl url = QUrl(org).resolved(
159 reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl());
160 // reconstruct query
161#if QT_VERSION < 0x050000
162 QList<QPair<QByteArray, QByteArray> > qitms = org.encodedQueryItems();
163 for(int i = 0; i < qitms.size(); ++i)
164 url.addEncodedQueryItem(qitms.at(i).first, qitms.at(i).second);
165#else
166 url.setQuery(org.query());
167#endif
168 LOG_INFO() << "Redirected to" << url;
169 startRequest(url);
170 return;
171 }
172 else if(m_lastStatusCode == 200 ||
173 (reply->url().scheme() == "file" && reply->error() == 0)) {
174 // callers might not be aware if the request is file:// so fake 200.
175 m_lastStatusCode = 200;
176 m_data = reply->readAll();
177 if(m_outputFile && m_outputFile->open(QIODevice::WriteOnly)) {
178 m_outputFile->write(m_data);
179 m_outputFile->close();
180 }
181 emit done(false);
182 }
183 else {
184 m_data.clear();
185 emit done(true);
186 }
187 reply->deleteLater();
188 m_reply = nullptr;
189}
190
191
192void HttpGet::downloadProgress(qint64 received, qint64 total)
193{
194 emit dataReadProgress((int)received, (int)total);
195}
196
197
198void HttpGet::startRequest(QUrl url)
199{
200 LOG_INFO() << "Request started";
201 QNetworkRequest req(url);
202 if(!m_globalUserAgent.isEmpty())
203 req.setRawHeader("User-Agent", m_globalUserAgent.toLatin1());
204
205 m_reply = m_mgr.get(req);
206#if QT_VERSION < 0x050f00
207 connect(m_reply,
208 static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
209 this, &HttpGet::networkError);
210#else
211 connect(m_reply, &QNetworkReply::errorOccurred, this, &HttpGet::networkError);
212#endif
213 connect(m_reply, &QNetworkReply::downloadProgress, this, &HttpGet::downloadProgress);
214}
215
216
217void HttpGet::networkError(QNetworkReply::NetworkError error)
218{
219 LOG_ERROR() << "NetworkError occured:" << error << m_reply->errorString();
220 m_lastErrorString = m_reply->errorString();
221}
222
223
224/** @brief Retrieve the file pointed to by url.
225 *
226 * Note: This also handles file:// URLs. Be aware that QUrl requires file://
227 * URLs to be absolute, i.e. file://filename.txt doesn't work. Use
228 * QDir::absoluteFilePath() to convert to an absolute path first.
229 *
230 * @param url URL to download.
231 */
232void HttpGet::getFile(const QUrl &url)
233{
234 LOG_INFO() << "Get URI" << url.toString();
235 m_data.clear();
236 startRequest(url);
237}
238
239
240/** @brief Retrieve string representation for most recent error.
241 * @return Error string.
242 */
243QString HttpGet::errorString(void)
244{
245 return m_lastErrorString;
246}
247
248
249/** @brief Return last HTTP response code.
250 * @return Response code.
251 */
252int HttpGet::httpResponse(void)
253{
254 return m_lastStatusCode;
255}
256
diff --git a/utils/rbutilqt/base/httpget.h b/utils/rbutilqt/base/httpget.h
new file mode 100644
index 0000000000..dfd7b87c89
--- /dev/null
+++ b/utils/rbutilqt/base/httpget.h
@@ -0,0 +1,111 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Riebeling
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21
22#ifndef HTTPGET_H
23#define HTTPGET_H
24
25#include <QtCore>
26#include <QtNetwork>
27#include <QNetworkAccessManager>
28#include "Logger.h"
29
30class HttpGet : public QObject
31{
32 Q_OBJECT
33
34 public:
35 HttpGet(QObject *parent = nullptr);
36
37 void getFile(const QUrl &url);
38 void setProxy(const QUrl &url);
39 void setProxy(bool);
40 QString errorString(void);
41 void setFile(QFile*);
42 void setCache(const QDir&);
43 void setCache(bool);
44 int httpResponse(void);
45 QByteArray readAll(void);
46 bool isCached()
47 { return m_lastRequestCached; }
48 QDateTime timestamp(void)
49 { return m_lastServerTimestamp; }
50 //< set global cache path
51 static void setGlobalCache(const QDir& d)
52 {
53 LOG_INFO() << "Global cache set to" << d.absolutePath();
54 m_globalCache = d;
55 }
56 //< set global proxy value
57 static void setGlobalProxy(const QUrl& p)
58 {
59 LOG_INFO() << "setting global proxy" << p;
60 if(!p.isValid() || p.isEmpty()) {
61 HttpGet::m_globalProxy.setType(QNetworkProxy::NoProxy);
62 }
63 else {
64 HttpGet::m_globalProxy.setType(QNetworkProxy::HttpProxy);
65 HttpGet::m_globalProxy.setHostName(p.host());
66 HttpGet::m_globalProxy.setPort(p.port());
67 HttpGet::m_globalProxy.setUser(p.userName());
68 HttpGet::m_globalProxy.setPassword(p.password());
69 }
70 QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
71 QNetworkProxy::setApplicationProxy(HttpGet::m_globalProxy);
72 }
73 //< set global user agent string
74 static void setGlobalUserAgent(const QString& u)
75 { m_globalUserAgent = u; }
76
77 public slots:
78 void abort(void);
79
80 signals:
81 void done(bool);
82 void dataReadProgress(int, int);
83 void requestFinished(int, bool);
84 void headerFinished(void);
85
86 private slots:
87 void requestFinished(QNetworkReply* reply);
88 void startRequest(QUrl url);
89 void downloadProgress(qint64 received, qint64 total);
90 void networkError(QNetworkReply::NetworkError error);
91
92 private:
93 static QString m_globalUserAgent;
94 static QNetworkProxy m_globalProxy;
95 QNetworkAccessManager m_mgr;
96 QNetworkReply *m_reply;
97 QNetworkDiskCache *m_cache;
98 QDir m_cachedir;
99 static QDir m_globalCache; //< global cache path value
100 QByteArray m_data;
101 QFile *m_outputFile;
102 int m_lastStatusCode;
103 QString m_lastErrorString;
104 QDateTime m_lastServerTimestamp;
105 bool m_lastRequestCached;
106 QNetworkProxy m_proxy;
107};
108
109
110#endif
111
diff --git a/utils/rbutilqt/base/mspackutil.cpp b/utils/rbutilqt/base/mspackutil.cpp
new file mode 100644
index 0000000000..b794272199
--- /dev/null
+++ b/utils/rbutilqt/base/mspackutil.cpp
@@ -0,0 +1,164 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2013 Amaury Pouly
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include "Logger.h"
21#include "mspackutil.h"
22#include "progressloggerinterface.h"
23
24MsPackUtil::MsPackUtil(QObject* parent)
25 :ArchiveUtil(parent)
26{
27 m_cabd = mspack_create_cab_decompressor(nullptr);
28 m_cabinet = nullptr;
29 if(!m_cabd)
30 LOG_ERROR() << "CAB decompressor creation failed!";
31}
32
33MsPackUtil::~MsPackUtil()
34{
35 close();
36 if(m_cabd)
37 mspack_destroy_cab_decompressor(m_cabd);
38}
39
40bool MsPackUtil::open(QString& mspackfile)
41{
42 close();
43
44 if(m_cabd == nullptr)
45 {
46 LOG_ERROR() << "No CAB decompressor available: cannot open file!";
47 return false;
48 }
49 m_cabinet = m_cabd->search(m_cabd, QFile::encodeName(mspackfile).constData());
50 return m_cabinet != nullptr;
51}
52
53bool MsPackUtil::close(void)
54{
55 if(m_cabd && m_cabinet)
56 m_cabd->close(m_cabd, m_cabinet);
57 m_cabinet = nullptr;
58 return true;
59}
60
61bool MsPackUtil::extractArchive(const QString& dest, QString file)
62{
63 LOG_INFO() << "extractArchive" << dest << file;
64 if(!m_cabinet)
65 {
66 LOG_ERROR() << "CAB file not open!";
67 return false;
68 }
69
70 // construct the filename when extracting a single file from an archive.
71 // if the given destination is a full path use it as output name,
72 // otherwise use it as path to place the file as named in the archive.
73 QString singleoutfile;
74 if(!file.isEmpty() && QFileInfo(dest).isDir())
75 singleoutfile = dest + "/" + file;
76 else if(!file.isEmpty())
77 singleoutfile = dest;
78 struct mscabd_file *f = m_cabinet->files;
79 if(f == nullptr)
80 {
81 LOG_WARNING() << "CAB doesn't contain file" << file;
82 return true;
83 }
84 bool found = false;
85 while(f)
86 {
87 QString name = QFile::decodeName(f->filename);
88 name.replace("\\", "/");
89 if(name.at(0) == '/')
90 name.remove(0, 1);
91 if(name == file || file.isEmpty())
92 {
93 QString path;
94 if(!singleoutfile.isEmpty())
95 path = singleoutfile;
96 else
97 path = dest + "/" + name;
98 // make sure the output path exists
99 if(!QDir().mkpath(QFileInfo(path).absolutePath()))
100 {
101 emit logItem(tr("Creating output path failed"), LOGERROR);
102 LOG_ERROR() << "creating output path failed for:" << path;
103 emit logProgress(1, 1);
104 return false;
105 }
106 int ret = m_cabd->extract(m_cabd, f, QFile::encodeName(path).constData());
107 if(ret != MSPACK_ERR_OK)
108 {
109 emit logItem(tr("Error during CAB operation"), LOGERROR);
110 LOG_ERROR() << "mspack error: " << ret
111 << "(" << errorStringMsPack(ret) << ")";
112 emit logProgress(1, 1);
113 return false;
114 }
115 found = true;
116 }
117 f = f->next;
118 }
119 emit logProgress(1, 1);
120
121 return found;
122}
123
124QStringList MsPackUtil::files(void)
125{
126 QStringList list;
127 if(!m_cabinet)
128 {
129 LOG_WARNING() << "CAB file not open!";
130 return list;
131 }
132 struct mscabd_file *file = m_cabinet->files;
133 while(file)
134 {
135 QString name = QFile::decodeName(file->filename);
136 name.replace("\\", "/");
137 if(name.at(0) == '/')
138 name.remove(0, 1);
139 list.append(name);
140 file = file->next;
141 }
142
143 return list;
144}
145
146QString MsPackUtil::errorStringMsPack(int error) const
147{
148 switch(error)
149 {
150 case MSPACK_ERR_OK: return "Ok";
151 case MSPACK_ERR_ARGS: return "Bad arguments";
152 case MSPACK_ERR_OPEN: return "Open error";
153 case MSPACK_ERR_READ: return "Read error";
154 case MSPACK_ERR_WRITE: return "Write error";
155 case MSPACK_ERR_SEEK: return "Seek error";
156 case MSPACK_ERR_NOMEMORY: return "Out of memory";
157 case MSPACK_ERR_SIGNATURE: return "Bad signature";
158 case MSPACK_ERR_DATAFORMAT: return "Bad data format";
159 case MSPACK_ERR_CHECKSUM: return "Checksum error";
160 case MSPACK_ERR_CRUNCH: return "Compression error";
161 case MSPACK_ERR_DECRUNCH: return "Decompression error";
162 default: return "Unknown";
163 }
164}
diff --git a/utils/rbutilqt/base/mspackutil.h b/utils/rbutilqt/base/mspackutil.h
new file mode 100644
index 0000000000..1cb4350b13
--- /dev/null
+++ b/utils/rbutilqt/base/mspackutil.h
@@ -0,0 +1,51 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2013 Amaury Pouly
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef MSPACKUTIL_H
20#define MSPACKUTIL_H
21
22#include <QtCore>
23#include "archiveutil.h"
24#include "mspack/mspack.h"
25
26class MsPackUtil : public ArchiveUtil
27{
28 Q_OBJECT
29
30 public:
31 // archive types can be ORed
32 MsPackUtil(QObject* parent);
33 ~MsPackUtil();
34 bool open(QString& mspackfile);
35 virtual bool close(void);
36 virtual bool extractArchive(const QString& dest, QString file = "");
37 virtual QStringList files(void);
38
39 signals:
40 void logProgress(int, int);
41 void logItem(QString, int);
42
43 private:
44 QString errorStringMsPack(int error) const;
45 struct mscab_decompressor* m_cabd;
46 struct mscabd_cabinet *m_cabinet;
47
48};
49#endif
50
51
diff --git a/utils/rbutilqt/base/playerbuildinfo.cpp b/utils/rbutilqt/base/playerbuildinfo.cpp
new file mode 100644
index 0000000000..f118a9fd7a
--- /dev/null
+++ b/utils/rbutilqt/base/playerbuildinfo.cpp
@@ -0,0 +1,362 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2020 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include "playerbuildinfo.h"
20#include "rbsettings.h"
21#include "Logger.h"
22
23PlayerBuildInfo* PlayerBuildInfo::infoInstance = nullptr;
24
25PlayerBuildInfo* PlayerBuildInfo::instance()
26{
27 if (infoInstance == nullptr) {
28 infoInstance = new PlayerBuildInfo();
29 }
30 return infoInstance;
31}
32
33// server infos
34const static struct {
35 PlayerBuildInfo::BuildInfo item;
36 const char* name;
37} ServerInfoList[] = {
38 { PlayerBuildInfo::BuildVoiceLangs, "voices/:version:" },
39 { PlayerBuildInfo::BuildVersion, ":build:/:target:" },
40 { PlayerBuildInfo::BuildUrl, ":build:/build_url" },
41 { PlayerBuildInfo::BuildVoiceUrl, ":build:/voice_url" },
42 { PlayerBuildInfo::BuildManualUrl, ":build:/manual_url" },
43 { PlayerBuildInfo::BuildSourceUrl, ":build:/source_url" },
44 { PlayerBuildInfo::BuildFontUrl, ":build:/font_url" },
45
46 // other URLs -- those are not directly related to the build, but handled here.
47 { PlayerBuildInfo::DoomUrl, "other/doom_url" },
48 { PlayerBuildInfo::Duke3DUrl, "other/duke3d_url" },
49 { PlayerBuildInfo::PuzzFontsUrl, "other/puzzfonts_url" },
50 { PlayerBuildInfo::QuakeUrl, "other/quake_url" },
51 { PlayerBuildInfo::Wolf3DUrl, "other/wolf3d_url" },
52 { PlayerBuildInfo::XWorldUrl, "other/xworld_url" },
53 { PlayerBuildInfo::MidiPatchsetUrl, "other/patcheset_url" },
54};
55
56const static struct {
57 PlayerBuildInfo::DeviceInfo item;
58 const char* name;
59} PlayerInfoList[] = {
60 { PlayerBuildInfo::BuildStatus, "status/:target:" },
61 { PlayerBuildInfo::DisplayName, ":target:/name" },
62 { PlayerBuildInfo::BootloaderMethod, ":target:/bootloadermethod" },
63 { PlayerBuildInfo::BootloaderName, ":target:/bootloadername" },
64 { PlayerBuildInfo::BootloaderFile, ":target:/bootloaderfile" },
65 { PlayerBuildInfo::BootloaderFilter, ":target:/bootloaderfilter" },
66 { PlayerBuildInfo::Encoder, ":target:/encoder" },
67 { PlayerBuildInfo::Brand, ":target:/brand" },
68 { PlayerBuildInfo::PlayerPicture, ":target:/playerpic" },
69 { PlayerBuildInfo::TargetNamesAll, "_targets/all" },
70 { PlayerBuildInfo::TargetNamesEnabled, "_targets/enabled" },
71 { PlayerBuildInfo::LanguageInfo, "languages/:target:" },
72 { PlayerBuildInfo::LanguageList, "_languages/list" },
73 { PlayerBuildInfo::UsbIdErrorList, "_usb/error" },
74 { PlayerBuildInfo::UsbIdTargetList, "_usb/target" },
75};
76
77const static struct {
78 PlayerBuildInfo::SystemUrl item;
79 const char* name;
80} PlayerSystemUrls[] = {
81 { PlayerBuildInfo::BootloaderUrl, "bootloader/download_url" },
82 { PlayerBuildInfo::BuildInfoUrl, "build_info_url" },
83 { PlayerBuildInfo::GenlangUrl, "genlang_url" },
84 { PlayerBuildInfo::ThemesUrl, "themes_url" },
85 { PlayerBuildInfo::ThemesInfoUrl, "themes_info_url" },
86 { PlayerBuildInfo::RbutilUrl, "rbutil_url" },
87};
88
89PlayerBuildInfo::PlayerBuildInfo() :
90 serverInfo(nullptr),
91 playerInfo(":/ini/rbutil.ini", QSettings::IniFormat)
92{
93
94}
95
96void PlayerBuildInfo::setBuildInfo(QString file)
97{
98 if (serverInfo)
99 delete serverInfo;
100 LOG_INFO() << "updated:" << file;
101 serverInfo = new QSettings(file, QSettings::IniFormat);
102}
103
104QVariant PlayerBuildInfo::value(BuildInfo item, BuildType type)
105{
106 // locate setting item in server info file
107 int i = 0;
108 while(ServerInfoList[i].item != item)
109 i++;
110
111 // split of variant for target.
112 // we can have an optional variant part in the target string.
113 // For build info we don't use that.
114 QString target = RbSettings::value(RbSettings::CurrentPlatform).toString().split('.').at(0);
115
116 QString s = ServerInfoList[i].name;
117 s.replace(":target:", target);
118 QString v;
119 switch(type) {
120 case TypeRelease:
121 v = "release";
122 break;
123 case TypeCandidate:
124 v = "release-candidate";
125 break;
126 case TypeDaily:
127 v = "daily";
128 break;
129 case TypeDevel:
130 v = "development";
131 break;
132 }
133
134 QVariant result = QString();
135 if (!serverInfo)
136 return result;
137 QStringList version = serverInfo->value(v + "/" + target, "").toStringList();
138 s.replace(":build:", v);
139 s.replace(":version:", version.at(0));
140
141 // get value from server build-info
142 // we need to get a version string, otherwise the data is invalid.
143 // For invalid data return an empty string.
144 if(version.at(0).isEmpty()) {
145 LOG_INFO() << s << "(version invalid)";
146 return result;
147 }
148 if(!s.isEmpty())
149 result = serverInfo->value(s);
150
151 // depending on the actual value we need more replacements.
152 switch(item) {
153 case BuildVersion:
154 result = result.toStringList().at(0);
155 break;
156
157 case BuildUrl:
158 if(version.size() > 1) {
159 // version info has an URL appended. Takes precendence.
160 result = version.at(1);
161 }
162 break;
163
164 case BuildVoiceLangs:
165 if (type == TypeDaily)
166 s = "voices/daily";
167 result = serverInfo->value(s);
168 break;
169
170 case BuildManualUrl:
171 {
172 // special case: if playerInfo has a non-empty manualname entry for the
173 // target, use that as target for the manual name.
174 QString manualtarget = playerInfo.value(target + "/manualname", "").toString();
175 if(!manualtarget.isEmpty())
176 target = manualtarget;
177 break;
178 }
179
180 default:
181 break;
182 }
183 // if the value is a string we can replace some patterns.
184 // if we cannot convert it (f.e. for a QStringList) we leave as-is, since
185 // the conversion would return an empty type.
186 if (result.canConvert(QMetaType::QString))
187 result = result.toString()
188 .replace("%TARGET%", target)
189 .replace("%VERSION%", version.at(0));
190
191 LOG_INFO() << "B:" << s << result;
192 return result;
193}
194
195QVariant PlayerBuildInfo::value(DeviceInfo item, QString target)
196{
197 // locate setting item in server info file
198 int i = 0;
199 while(PlayerInfoList[i].item != item)
200 i++;
201
202 // split of variant for target.
203 // we can have an optional variant part in the target string.
204 // For device info we use this.
205 if (target.isEmpty())
206 target = RbSettings::value(RbSettings::CurrentPlatform).toString();
207
208 QVariant result = QString();
209
210 QString s = PlayerInfoList[i].name;
211 s.replace(":target:", target);
212
213 switch(item) {
214 case BuildStatus:
215 {
216 // build status is the only value that doesn't depend on the version
217 // but the selected target instead.
218 bool ok = false;
219 if (serverInfo)
220 result = serverInfo->value(s).toInt(&ok);
221 if (!ok)
222 result = -1;
223 break;
224 }
225 case TargetNamesAll:
226 // list of all internal target names. Doesn't depend on the passed target.
227 result = targetNames(true);
228 break;
229 case TargetNamesEnabled:
230 // list of all non-disabled target names. Doesn't depend on the passed target.
231 result = targetNames(false);
232 break;
233
234 case LanguageList:
235 // Return a map (language, display string).
236 {
237 // need to use (QString, QVariant) here, so we can put the map into
238 // a QVariant by itself.
239 QMap<QString, QVariant> m;
240
241 playerInfo.beginGroup("languages");
242 QStringList a = playerInfo.childKeys();
243
244 for(int i = 0; i < a.size(); i++) {
245 QStringList v = playerInfo.value(a.at(i)).toStringList();
246 m[v.at(0)] = v.at(1);
247 }
248 playerInfo.endGroup();
249 result = m;
250 }
251 break;
252
253 default:
254 result = playerInfo.value(s);
255 break;
256 }
257
258 LOG_INFO() << "T:" << s << result;
259 return result;
260}
261
262QVariant PlayerBuildInfo::value(DeviceInfo item, unsigned int match)
263{
264 QStringList result;
265 int i = 0;
266 while(PlayerInfoList[i].item != item)
267 i++;
268 QString s = PlayerInfoList[i].name;
269
270 switch(item) {
271 case UsbIdErrorList:
272 {
273 // go through all targets and find the one indicated by the usb id "target".
274 // return list of matching players (since it could be more than one)
275 QStringList targets = targetNames(true);
276 for(int i = 0; i < targets.size(); i++) {
277 QStringList usbids = playerInfo.value(targets.at(i) + "/usberror").toStringList();
278 for(int j = 0; j < usbids.size(); j++) {
279 if(usbids.at(j).toUInt(nullptr, 0) == match) {
280 result << targets.at(i);
281 }
282 }
283 }
284 break;
285 }
286
287 case UsbIdTargetList:
288 {
289 QStringList targets = targetNames(true);
290 for(int i = 0; i < targets.size(); i++) {
291 QStringList usbids = playerInfo.value(targets.at(i) + "/usbid").toStringList();
292 for(int j = 0; j < usbids.size(); j++) {
293 if(usbids.at(j).toUInt(nullptr, 0) == match) {
294 result << targets.at(i);
295 }
296 }
297 }
298 break;
299 }
300
301 default:
302 break;
303 }
304 LOG_INFO() << "T:" << s << result;
305 return result;
306}
307
308QVariant PlayerBuildInfo::value(SystemUrl item)
309{
310 // locate setting item in server info file
311 int i = 0;
312 while(PlayerSystemUrls[i].item != item)
313 i++;
314
315 QVariant result = playerInfo.value(PlayerSystemUrls[i].name);
316 LOG_INFO() << "U:" << PlayerSystemUrls[i].name << result;
317 return result;
318}
319
320
321QString PlayerBuildInfo::statusAsString(QString platform)
322{
323 QString result;
324 switch(value(BuildStatus, platform).toInt())
325 {
326 case STATUS_RETIRED:
327 result = tr("Stable (Retired)");
328 break;
329 case STATUS_UNUSABLE:
330 result = tr("Unusable");
331 break;
332 case STATUS_UNSTABLE:
333 result = tr("Unstable");
334 break;
335 case STATUS_STABLE:
336 result = tr("Stable");
337 break;
338 default:
339 result = tr("Unknown");
340 break;
341 }
342
343 return result;
344}
345
346
347QStringList PlayerBuildInfo::targetNames(bool all)
348{
349 QStringList result;
350 playerInfo.beginGroup("platforms");
351 QStringList a = playerInfo.childKeys();
352 playerInfo.endGroup();
353 for(int i = 0; i < a.size(); i++)
354 {
355 QString target = playerInfo.value("platforms/" + a.at(i), "null").toString();
356 if(playerInfo.value(target + "/status").toString() != "disabled" || all) {
357 result.append(target);
358 }
359 }
360 return result;
361}
362
diff --git a/utils/rbutilqt/base/playerbuildinfo.h b/utils/rbutilqt/base/playerbuildinfo.h
new file mode 100644
index 0000000000..6a88f750ed
--- /dev/null
+++ b/utils/rbutilqt/base/playerbuildinfo.h
@@ -0,0 +1,123 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2020 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef PLAYERBUILDINFO_H
20#define PLAYERBUILDINFO_H
21
22#include <QSettings>
23
24#define STATUS_RETIRED 0
25#define STATUS_UNUSABLE 1
26#define STATUS_UNSTABLE 2
27#define STATUS_STABLE 3
28
29// Provide information about both player and builds.
30// For build info data retrieved from the build server has to be passed.
31class PlayerBuildInfo : public QObject
32{
33 Q_OBJECT
34
35public:
36
37 enum BuildType {
38 TypeRelease,
39 TypeCandidate,
40 TypeDaily,
41 TypeDevel,
42 };
43 enum BuildInfo {
44 BuildUrl,
45 BuildVersion,
46 BuildManualUrl,
47 BuildVoiceUrl,
48 BuildVoiceLangs,
49 BuildSourceUrl,
50 BuildFontUrl,
51
52 DoomUrl,
53 Duke3DUrl,
54 PuzzFontsUrl,
55 QuakeUrl,
56 Wolf3DUrl,
57 XWorldUrl,
58 MidiPatchsetUrl,
59 };
60 enum DeviceInfo {
61 BuildStatus,
62
63 DisplayName,
64 BootloaderMethod,
65 BootloaderName,
66 BootloaderFile,
67 BootloaderFilter,
68 Encoder,
69 Brand,
70 PlayerPicture,
71
72 TargetNamesAll,
73 TargetNamesEnabled,
74 LanguageInfo,
75 LanguageList,
76 UsbIdErrorList,
77 UsbIdTargetList,
78 };
79
80 enum SystemUrl {
81 BootloaderUrl,
82 BuildInfoUrl,
83 GenlangUrl,
84 ThemesUrl,
85 ThemesInfoUrl,
86 RbutilUrl,
87 };
88
89 static PlayerBuildInfo* instance();
90
91 //! Update with build information from server
92 void setBuildInfo(QString file);
93
94 // Get information about a device. This data does not depend on the build type.
95 QVariant value(DeviceInfo item, QString target = "");
96
97 // Get information about a device. Make a numeric match
98 // (only sensible implementation for USB IDs)
99 QVariant value(DeviceInfo item, unsigned int match);
100
101 // Get build information for currently selected player.
102 QVariant value(BuildInfo item, BuildType type);
103
104 // Get fixed download URL information
105 QVariant value(SystemUrl item);
106
107 QString statusAsString(QString target = "");
108
109protected:
110 explicit PlayerBuildInfo();
111
112private:
113 //! Return a list with all target names (as used internally).
114 //! @all false filter out all targets with status = disabled.
115 QStringList targetNames(bool all);
116
117 static PlayerBuildInfo* infoInstance;
118 QSettings* serverInfo;
119 QSettings playerInfo;
120
121};
122
123#endif
diff --git a/utils/rbutilqt/base/progressloggerinterface.h b/utils/rbutilqt/base/progressloggerinterface.h
new file mode 100644
index 0000000000..ae4270ae6b
--- /dev/null
+++ b/utils/rbutilqt/base/progressloggerinterface.h
@@ -0,0 +1,60 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#ifndef PROGRESSLOGGERINTERFACE_H
22#define PROGRESSLOGGERINTERFACE_H
23
24#include <QtCore>
25
26enum {
27 LOGNOICON, LOGOK, LOGINFO, LOGWARNING, LOGERROR
28};
29
30
31
32class ProgressloggerInterface : public QObject
33{
34 Q_OBJECT
35
36public:
37 ProgressloggerInterface(QObject* parent) : QObject(parent) {}
38
39 virtual void setProgressValue(int value)=0;
40 virtual void setProgressMax(int max)=0;
41 virtual int getProgressMax()=0;
42
43signals:
44 void aborted();
45
46
47public slots:
48 virtual void addItem(const QString &text, int flag)=0; //! add a string to the list, with icon
49
50 virtual void close()=0;
51 virtual void show()=0;
52 virtual void setRunning()=0;
53 virtual void setFinished()=0;
54
55private:
56
57};
58
59#endif
60
diff --git a/utils/rbutilqt/base/rbsettings.cpp b/utils/rbutilqt/base/rbsettings.cpp
new file mode 100644
index 0000000000..8eaa01f7f6
--- /dev/null
+++ b/utils/rbutilqt/base/rbsettings.cpp
@@ -0,0 +1,207 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include "rbsettings.h"
20#include "playerbuildinfo.h"
21#include <QSettings>
22#include "Logger.h"
23
24#if defined(Q_OS_LINUX)
25#include <unistd.h>
26#endif
27
28// user settings
29const static struct {
30 RbSettings::UserSettings setting;
31 const char* name;
32 const char* def;
33} UserSettingsList[] = {
34 { RbSettings::RbutilVersion, "rbutil_version", "" },
35 { RbSettings::ShowChangelog, "show_changelog", "false" },
36 { RbSettings::CurrentPlatform, "platform", "" },
37 { RbSettings::Mountpoint, "mountpoint", "" },
38 { RbSettings::CachePath, "cachepath", "" },
39 { RbSettings::Build, "build", "" },
40 { RbSettings::ProxyType, "proxytype", "" },
41 { RbSettings::Proxy, "proxy", "" },
42 { RbSettings::OfPath, "ofpath", "" },
43 { RbSettings::Platform, "platform", "" },
44 { RbSettings::Language, "lang", "" },
45 { RbSettings::BackupPath, "backuppath", "" },
46 { RbSettings::InstallRockbox, "install_rockbox", "true" },
47 { RbSettings::InstallFonts, "install_fonts", "true" },
48 { RbSettings::InstallThemes, "install_themes", "false" },
49 { RbSettings::InstallPluginData, "install_plugin_data", "true" },
50 { RbSettings::InstallVoice, "install_voice", "false" },
51 { RbSettings::InstallManual, "install_manual", "false" },
52#if defined(Q_OS_WIN32)
53 { RbSettings::Tts, "tts", "sapi" },
54#elif defined(Q_OS_MACX)
55 { RbSettings::Tts, "tts", "carbon" },
56#else
57 { RbSettings::Tts, "tts", "espeak" },
58#endif
59 { RbSettings::UseTtsCorrections, "use_tts_corrections", "true" },
60 { RbSettings::TalkFolders, "talk_folders", "" },
61 { RbSettings::TalkProcessFiles, "talk_process_files", "true" },
62 { RbSettings::TalkProcessFolders, "talk_process_folders", "true" },
63 { RbSettings::TalkRecursive, "talk_recursive", "true" },
64 { RbSettings::TalkSkipExisting, "talk_skip_existing", "true" },
65 { RbSettings::TalkStripExtensions, "talk_strip_extensions","true" },
66 { RbSettings::TalkIgnoreFiles, "talk_ignore_files", "false" },
67 { RbSettings::TalkIgnoreWildcards, "talk_ignore_wildcards","" },
68 { RbSettings::VoiceLanguage, "voicelanguage", "" },
69 { RbSettings::TtsLanguage, ":tts:/language", "" },
70 { RbSettings::TtsOptions, ":tts:/options", "" },
71 { RbSettings::TtsPitch, ":tts:/pitch", "0" },
72 { RbSettings::TtsPath, ":tts:/path", "" },
73 { RbSettings::TtsVoice, ":tts:/voice", "" },
74 { RbSettings::EncoderPath, ":encoder:/encoderpath", "" },
75 { RbSettings::EncoderOptions, ":encoder:/encoderoptions", "" },
76 { RbSettings::CacheDisabled, "cachedisable", "false" },
77 { RbSettings::TtsUseSapi4, "sapi/useSapi4", "false" },
78 { RbSettings::EncoderNarrowBand, ":encoder:/narrowband", "false" },
79 { RbSettings::WavtrimThreshold, "wavtrimthreshold", "500"},
80 { RbSettings::TtsSpeed, ":tts:/speed", "175" },
81 { RbSettings::EncoderComplexity, ":encoder:/complexity", "10" },
82 { RbSettings::EncoderQuality, ":encoder:/quality", "-1.0" },
83 { RbSettings::EncoderVolume, ":encoder:/volume", "1.0" },
84};
85
86//! pointer to setting object to NULL
87QSettings* RbSettings::userSettings = nullptr;
88
89void RbSettings::ensureRbSettingsExists()
90{
91 if(userSettings == nullptr)
92 {
93 // portable installation:
94 // check for a configuration file in the program folder.
95 QFileInfo config;
96 config.setFile(QCoreApplication::instance()->applicationDirPath()
97 + "/RockboxUtility.ini");
98 if(config.isFile())
99 {
100 userSettings = new QSettings(QCoreApplication::instance()->applicationDirPath()
101 + "/RockboxUtility.ini", QSettings::IniFormat, nullptr);
102 LOG_INFO() << "configuration: portable";
103 }
104 else
105 {
106 userSettings = new QSettings(QSettings::IniFormat,
107 QSettings::UserScope, "rockbox.org", "RockboxUtility",nullptr);
108 LOG_INFO() << "configuration: system";
109 }
110 }
111}
112
113void RbSettings::sync()
114{
115 ensureRbSettingsExists();
116
117 userSettings->sync();
118#if defined(Q_OS_LINUX)
119 // when using sudo it runs rbutil with uid 0 but unfortunately without a
120 // proper login shell, thus the configuration file gets placed in the
121 // calling users $HOME. This in turn will cause issues if trying to
122 // run rbutil later as user. Try to detect this case via the environment
123 // variable SUDO_UID and SUDO_GID and if set chown the user config file.
124 if(getuid() == 0)
125 {
126 char* realuser = getenv("SUDO_UID");
127 char* realgroup = getenv("SUDO_GID");
128 if(realuser != nullptr && realgroup != nullptr)
129 {
130 int realuid = atoi(realuser);
131 int realgid = atoi(realgroup);
132 // chown is attribute warn_unused_result, but in case this fails
133 // we can't do anything useful about it. Notifying the user
134 // is somewhat pointless. Add hack to suppress compiler warning.
135 if(chown(qPrintable(userSettings->fileName()), realuid, realgid))
136 { }
137 }
138 }
139#endif
140}
141
142QString RbSettings::userSettingFilename()
143{
144 ensureRbSettingsExists();
145 return userSettings->fileName();
146}
147
148QVariant RbSettings::value(enum UserSettings setting)
149{
150 QString empty;
151 return subValue(empty, setting);
152}
153
154QVariant RbSettings::subValue(QString sub, enum UserSettings setting)
155{
156 ensureRbSettingsExists();
157
158 // locate setting item
159 int i = 0;
160 while(UserSettingsList[i].setting != setting)
161 i++;
162
163 QString s = constructSettingPath(UserSettingsList[i].name, sub);
164 LOG_INFO() << "GET U:" << s << userSettings->value(s).toString();
165 return userSettings->value(s, UserSettingsList[i].def);
166}
167
168void RbSettings::setValue(enum UserSettings setting , QVariant value)
169{
170 QString empty;
171 return setSubValue(empty, setting, value);
172}
173
174void RbSettings::setSubValue(QString sub, enum UserSettings setting, QVariant value)
175{
176 ensureRbSettingsExists();
177
178 // locate setting item
179 int i = 0;
180 while(UserSettingsList[i].setting != setting)
181 i++;
182
183 QString s = constructSettingPath(UserSettingsList[i].name, sub);
184 userSettings->setValue(s, value);
185 LOG_INFO() << "SET U:" << s << userSettings->value(s).toString();
186}
187
188QString RbSettings::constructSettingPath(QString path, QString substitute)
189{
190 // anything to substitute?
191 if(path.contains(':')) {
192 QString platform = userSettings->value("platform").toString();
193 if(!substitute.isEmpty()) {
194 path.replace(":tts:", substitute);
195 path.replace(":encoder:", substitute);
196 }
197 else {
198 path.replace(":tts:", userSettings->value("tts").toString());
199 path.replace(":encoder:", PlayerBuildInfo::instance()->value(
200 PlayerBuildInfo::Encoder, platform).toString());
201 }
202 path.replace(":platform:", platform);
203 }
204
205 return path;
206}
207
diff --git a/utils/rbutilqt/base/rbsettings.h b/utils/rbutilqt/base/rbsettings.h
new file mode 100644
index 0000000000..ef0c4eb134
--- /dev/null
+++ b/utils/rbutilqt/base/rbsettings.h
@@ -0,0 +1,105 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#ifndef RBSETTINGS_H
22#define RBSETTINGS_H
23
24#include <QtCore>
25
26class RbSettings : public QObject
27{
28 Q_OBJECT
29 public:
30
31 //! All user settings
32 enum UserSettings {
33 RbutilVersion,
34 ShowChangelog,
35 CurrentPlatform,
36 Mountpoint,
37 CachePath,
38 Build,
39 ProxyType,
40 Proxy,
41 OfPath,
42 Platform,
43 Language,
44 BackupPath,
45 InstallRockbox,
46 InstallFonts,
47 InstallThemes,
48 InstallPluginData,
49 InstallVoice,
50 InstallManual,
51 Tts,
52 UseTtsCorrections,
53 TalkFolders,
54 TalkProcessFiles,
55 TalkProcessFolders,
56 TalkRecursive,
57 TalkSkipExisting,
58 TalkStripExtensions,
59 TalkIgnoreFiles,
60 TalkIgnoreWildcards,
61 VoiceLanguage,
62 TtsLanguage,
63 TtsOptions,
64 TtsPath,
65 TtsVoice,
66 TtsPitch,
67 EncoderPath,
68 EncoderOptions,
69 WavtrimThreshold,
70 EncoderComplexity,
71 TtsSpeed,
72 CacheDisabled,
73 TtsUseSapi4,
74 EncoderNarrowBand,
75 EncoderQuality,
76 EncoderVolume,
77 };
78
79 //! call this to flush the user Settings
80 static void sync();
81 //! returns the filename of the usersettings file
82 static QString userSettingFilename();
83 //! get a value from user settings
84 static QVariant value(enum UserSettings setting);
85 //! set a user setting value
86 static void setValue(enum UserSettings setting , QVariant value);
87 //! get a user setting from a subvalue (ie for encoders and tts engines)
88 static QVariant subValue(QString sub, enum UserSettings setting);
89 //! set a user setting from a subvalue (ie for encoders and tts engines)
90 static void setSubValue(QString sub, enum UserSettings setting, QVariant value);
91
92 private:
93 //! you shouldnt call this, its a fully static calls
94 RbSettings() {}
95 //! create the setting objects if neccessary
96 static void ensureRbSettingsExists();
97 //! create a settings path, substitute platform, tts and encoder
98 static QString constructSettingPath(QString path, QString substitute = QString());
99
100 //! pointers to our setting object
101 static QSettings *userSettings;
102};
103
104#endif
105
diff --git a/utils/rbutilqt/base/rockboxinfo.cpp b/utils/rbutilqt/base/rockboxinfo.cpp
new file mode 100644
index 0000000000..f34adbfc2f
--- /dev/null
+++ b/utils/rbutilqt/base/rockboxinfo.cpp
@@ -0,0 +1,83 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include "rockboxinfo.h"
20
21#include <QtCore>
22#include <QDebug>
23#include "Logger.h"
24
25RockboxInfo::RockboxInfo(QString mountpoint, QString fname)
26{
27 LOG_INFO() << "Getting version info from rockbox-info.txt";
28 QFile file(mountpoint + "/" + fname);
29 m_success = false;
30 m_voicefmt = 400; // default value for compatibility
31 if(!file.exists())
32 return;
33
34 if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
35 return;
36
37 // read file contents
38 QRegExp hash("^Version:\\s+(r?)([0-9a-fM]+)");
39 QRegExp version("^Version:\\s+(\\S.*)");
40 QRegExp release("^Version:\\s+([0-9\\.]+)\\s*$");
41 QRegExp target("^Target:\\s+(\\S.*)");
42 QRegExp features("^Features:\\s+(\\S.*)");
43 QRegExp targetid("^Target id:\\s+(\\S.*)");
44 QRegExp memory("^Memory:\\s+(\\S.*)");
45 QRegExp voicefmt("^Voice format:\\s+(\\S.*)");
46 while (!file.atEnd())
47 {
48 QString line = file.readLine().trimmed();
49
50 if(version.indexIn(line) >= 0) {
51 m_version = version.cap(1);
52 }
53 if(release.indexIn(line) >= 0) {
54 m_release = release.cap(1);
55 }
56 if(hash.indexIn(line) >= 0) {
57 // git hashes are usually at least 7 characters.
58 // svn revisions are expected to be at least 4 digits.
59 if(hash.cap(2).size() > 3)
60 m_revision = hash.cap(2);
61 }
62 else if(target.indexIn(line) >= 0) {
63 m_target = target.cap(1);
64 }
65 else if(features.indexIn(line) >= 0) {
66 m_features = features.cap(1);
67 }
68 else if(targetid.indexIn(line) >= 0) {
69 m_targetid = targetid.cap(1);
70 }
71 else if(memory.indexIn(line) >= 0) {
72 m_ram = memory.cap(1).toInt();
73 }
74 else if(voicefmt.indexIn(line) >= 0) {
75 m_voicefmt = voicefmt.cap(1).toInt();
76 }
77 }
78
79 file.close();
80 m_success = true;
81 return;
82}
83
diff --git a/utils/rbutilqt/base/rockboxinfo.h b/utils/rbutilqt/base/rockboxinfo.h
new file mode 100644
index 0000000000..af5cf227f7
--- /dev/null
+++ b/utils/rbutilqt/base/rockboxinfo.h
@@ -0,0 +1,54 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21
22#ifndef ROCKBOXINFO_H
23#define ROCKBOXINFO_H
24
25#include <QString>
26
27class RockboxInfo
28{
29public:
30 RockboxInfo(QString mountpoint, QString fname = "/.rockbox/rockbox-info.txt");
31
32 QString version() {return m_version;}
33 QString features(){return m_features;}
34 QString targetID() {return m_targetid;}
35 QString target() {return m_target;}
36 int ram() { return m_ram; }
37 int voicefmt() { return m_voicefmt; }
38 bool success() { return m_success; }
39 QString revision(void) { return m_revision; }
40 QString release(void) { return m_release; }
41private:
42 QString m_version;
43 QString m_revision;
44 QString m_release;
45 QString m_features;
46 QString m_targetid;
47 QString m_target;
48 int m_ram;
49 int m_voicefmt;
50 bool m_success;
51};
52
53#endif
54
diff --git a/utils/rbutilqt/base/system.cpp b/utils/rbutilqt/base/system.cpp
new file mode 100644
index 0000000000..dafab971ec
--- /dev/null
+++ b/utils/rbutilqt/base/system.cpp
@@ -0,0 +1,519 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19
20#include "system.h"
21
22#include <QtCore>
23#include <QDebug>
24
25#include <cstdlib>
26#include <stdio.h>
27
28// Windows Includes
29#if defined(Q_OS_WIN32)
30#if defined(UNICODE)
31#define _UNICODE
32#endif
33#include <windows.h>
34#include <tchar.h>
35#include <lm.h>
36#include <windows.h>
37#include <setupapi.h>
38#endif
39
40// Linux and Mac includes
41#if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
42#include <sys/utsname.h>
43#include <unistd.h>
44#include <pwd.h>
45#endif
46
47// Linux includes
48#if defined(Q_OS_LINUX)
49#include <libusb-1.0/libusb.h>
50#include <mntent.h>
51#endif
52
53// Mac includes
54#if defined(Q_OS_MACX)
55#include <sys/param.h>
56#include <sys/ucred.h>
57#include <sys/mount.h>
58
59#include <CoreFoundation/CoreFoundation.h>
60#include <SystemConfiguration/SystemConfiguration.h>
61#include <CoreServices/CoreServices.h>
62#include <IOKit/IOKitLib.h>
63#include <IOKit/usb/IOUSBLib.h>
64#endif
65
66#include "utils.h"
67#include "rbsettings.h"
68#include "Logger.h"
69
70/** @brief detect permission of user (only Windows at moment).
71 * @return enum userlevel.
72 */
73#if defined(Q_OS_WIN32)
74enum System::userlevel System::userPermissions(void)
75{
76 LPUSER_INFO_1 buf = NULL;
77 wchar_t userbuf[UNLEN];
78 DWORD usersize = UNLEN;
79 BOOL status;
80 enum userlevel result = ERR;
81
82 status = GetUserNameW(userbuf, &usersize);
83 if(!status)
84 return ERR;
85
86 if(NetUserGetInfo(NULL, userbuf, (DWORD)1, (LPBYTE*)&buf) == NERR_Success) {
87 switch(buf->usri1_priv) {
88 case USER_PRIV_GUEST:
89 result = GUEST;
90 break;
91 case USER_PRIV_USER:
92 result = USER;
93 break;
94 case USER_PRIV_ADMIN:
95 result = ADMIN;
96 break;
97 default:
98 result = ERR;
99 break;
100 }
101 }
102 if(buf != NULL)
103 NetApiBufferFree(buf);
104
105 return result;
106}
107
108/** @brief detects user permissions (only Windows at moment).
109 * @return a user readable string with the permission.
110 */
111QString System::userPermissionsString(void)
112{
113 QString result;
114 int perm = userPermissions();
115 switch(perm) {
116 case GUEST:
117 result = tr("Guest");
118 break;
119 case ADMIN:
120 result = tr("Admin");
121 break;
122 case USER:
123 result = tr("User");
124 break;
125 default:
126 result = tr("Error");
127 break;
128 }
129 return result;
130}
131#endif
132
133
134/** @brief detects current Username.
135 * @return string with Username.
136 */
137QString System::userName(void)
138{
139#if defined(Q_OS_WIN32)
140 wchar_t userbuf[UNLEN];
141 DWORD usersize = UNLEN;
142
143 if(GetUserNameW(userbuf, &usersize) == 0)
144 return QString();
145
146 return QString::fromWCharArray(userbuf);
147#endif
148#if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
149 struct passwd *user;
150 user = getpwuid(geteuid());
151 return QString(user->pw_name);
152#endif
153}
154
155
156/** @brief detects the OS Version
157 * @return String with OS Version.
158 */
159QString System::osVersionString(void)
160{
161 QString result;
162#if defined(Q_OS_WIN32)
163 SYSTEM_INFO sysinfo;
164 OSVERSIONINFO osvi;
165 ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
166 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
167 GetVersionEx(&osvi);
168 GetSystemInfo(&sysinfo);
169
170 result = QString("Windows version %1.%2, ").arg(osvi.dwMajorVersion).arg(osvi.dwMinorVersion);
171 if(osvi.szCSDVersion)
172 result += QString("build %1 (%2)").arg(osvi.dwBuildNumber)
173 .arg(QString::fromWCharArray(osvi.szCSDVersion));
174 else
175 result += QString("build %1").arg(osvi.dwBuildNumber);
176 result += QString("<br/>CPU: %1, %2 processor(s)").arg(sysinfo.dwProcessorType)
177 .arg(sysinfo.dwNumberOfProcessors);
178#endif
179#if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
180 struct utsname u;
181 int ret;
182 ret = uname(&u);
183
184#if defined(Q_OS_MACX)
185 SInt32 cores;
186 Gestalt(gestaltCountOfCPUs, &cores);
187#else
188 long cores = sysconf(_SC_NPROCESSORS_ONLN);
189#endif
190 if(ret != -1) {
191 result = QString("CPU: %1, %2 processor(s)").arg(u.machine).arg(cores);
192 result += QString("<br/>System: %2<br/>Release: %3<br/>Version: %4")
193 .arg(u.sysname).arg(u.release).arg(u.version);
194 }
195 else {
196 result = QString("(Error when retrieving system information)");
197 }
198#if defined(Q_OS_MACX)
199 SInt32 major;
200 SInt32 minor;
201 SInt32 bugfix;
202 Gestalt(gestaltSystemVersionMajor, &major);
203 Gestalt(gestaltSystemVersionMinor, &minor);
204 Gestalt(gestaltSystemVersionBugFix, &bugfix);
205
206 result += QString("<br/>OS X %1.%2.%3 ").arg(major).arg(minor).arg(bugfix);
207 // 1: 86k, 2: ppc, 10: i386
208 SInt32 arch;
209 Gestalt(gestaltSysArchitecture, &arch);
210 switch(arch) {
211 case 1:
212 result.append("(86k)");
213 break;
214 case 2:
215 result.append("(ppc)");
216 break;
217 case 10:
218 result.append("(x86)");
219 break;
220 default:
221 result.append("(unknown)");
222 break;
223 }
224#endif
225#endif
226 result += QString("<br/>Qt version %1").arg(qVersion());
227 return result;
228}
229
230QList<uint32_t> System::listUsbIds(void)
231{
232 return listUsbDevices().keys();
233}
234
235/** @brief detect devices based on usb pid / vid.
236 * @return list with usb VID / PID values.
237 */
238QMultiMap<uint32_t, QString> System::listUsbDevices(void)
239{
240 QMultiMap<uint32_t, QString> usbids;
241 // usb pid detection
242 LOG_INFO() << "Searching for USB devices";
243#if defined(Q_OS_LINUX)
244 libusb_device **devs;
245 if(libusb_init(nullptr) != 0) {
246 LOG_ERROR() << "Initializing libusb-1 failed.";
247 return usbids;
248 }
249
250 if(libusb_get_device_list(nullptr, &devs) < 1) {
251 LOG_ERROR() << "Error getting device list.";
252 return usbids;
253 }
254 libusb_device *dev;
255 int i = 0;
256 while((dev = devs[i++]) != nullptr) {
257 QString name;
258 unsigned char buf[256];
259 uint32_t id;
260 struct libusb_device_descriptor descriptor;
261 if(libusb_get_device_descriptor(dev, &descriptor) == 0) {
262 id = descriptor.idVendor << 16 | descriptor.idProduct;
263
264 libusb_device_handle *dh;
265 if(libusb_open(dev, &dh) == 0) {
266 libusb_get_string_descriptor_ascii(dh, descriptor.iManufacturer, buf, 256);
267 name += QString::fromLatin1((char*)buf) + " ";
268 libusb_get_string_descriptor_ascii(dh, descriptor.iProduct, buf, 256);
269 name += QString::fromLatin1((char*)buf);
270 libusb_close(dh);
271 }
272 if(name.isEmpty())
273 name = tr("(no description available)");
274 if(id) {
275 usbids.insert(id, name);
276 LOG_INFO("USB: 0x%08x, %s", id, name.toLocal8Bit().data());
277 }
278 }
279 }
280
281 libusb_free_device_list(devs, 1);
282 libusb_exit(nullptr);
283#endif
284
285#if defined(Q_OS_MACX)
286 kern_return_t result = KERN_FAILURE;
287 CFMutableDictionaryRef usb_matching_dictionary;
288 io_iterator_t usb_iterator = IO_OBJECT_NULL;
289 usb_matching_dictionary = IOServiceMatching(kIOUSBDeviceClassName);
290 result = IOServiceGetMatchingServices(kIOMasterPortDefault, usb_matching_dictionary,
291 &usb_iterator);
292 if(result) {
293 LOG_ERROR() << "USB: IOKit: Could not get matching services.";
294 return usbids;
295 }
296
297 io_object_t usbCurrentObj;
298 while((usbCurrentObj = IOIteratorNext(usb_iterator))) {
299 uint32_t id;
300 QString name;
301 /* get vendor ID */
302 CFTypeRef vidref = NULL;
303 int vid = 0;
304 vidref = IORegistryEntryCreateCFProperty(usbCurrentObj, CFSTR("idVendor"),
305 kCFAllocatorDefault, 0);
306 CFNumberGetValue((CFNumberRef)vidref, kCFNumberIntType, &vid);
307 CFRelease(vidref);
308
309 /* get product ID */
310 CFTypeRef pidref = NULL;
311 int pid = 0;
312 pidref = IORegistryEntryCreateCFProperty(usbCurrentObj, CFSTR("idProduct"),
313 kCFAllocatorDefault, 0);
314 CFNumberGetValue((CFNumberRef)pidref, kCFNumberIntType, &pid);
315 CFRelease(pidref);
316 id = vid << 16 | pid;
317
318 /* get product vendor */
319 char vendor_buf[256];
320 CFIndex vendor_buflen = 256;
321 CFTypeRef vendor_name_ref = NULL;
322
323 vendor_name_ref = IORegistryEntrySearchCFProperty(usbCurrentObj,
324 kIOServicePlane, CFSTR("USB Vendor Name"),
325 kCFAllocatorDefault, 0);
326 if(vendor_name_ref != NULL) {
327 CFStringGetCString((CFStringRef)vendor_name_ref, vendor_buf, vendor_buflen,
328 kCFStringEncodingUTF8);
329 name += QString::fromUtf8(vendor_buf) + " ";
330 CFRelease(vendor_name_ref);
331 }
332 else {
333 name += QObject::tr("(unknown vendor name) ");
334 }
335
336 /* get product name */
337 char product_buf[256];
338 CFIndex product_buflen = 256;
339 CFTypeRef product_name_ref = NULL;
340
341 product_name_ref = IORegistryEntrySearchCFProperty(usbCurrentObj,
342 kIOServicePlane, CFSTR("USB Product Name"),
343 kCFAllocatorDefault, 0);
344 if(product_name_ref != NULL) {
345 CFStringGetCString((CFStringRef)product_name_ref, product_buf, product_buflen,
346 kCFStringEncodingUTF8);
347 name += QString::fromUtf8(product_buf);
348 CFRelease(product_name_ref);
349 }
350 else {
351 name += QObject::tr("(unknown product name)");
352 }
353
354 if(id) {
355 usbids.insertMulti(id, name);
356 LOG_INFO() << "USB:" << QString("0x%1").arg(id, 8, 16) << name;
357 }
358
359 }
360 IOObjectRelease(usb_iterator);
361#endif
362
363#if defined(Q_OS_WIN32)
364 HDEVINFO deviceInfo;
365 SP_DEVINFO_DATA infoData;
366 DWORD i;
367
368 // Iterate over all devices
369 // by doing it this way it's unneccessary to use GUIDs which might be not
370 // present in current MinGW. It also seemed to be more reliably than using
371 // a GUID.
372 // See KB259695 for an example.
373 deviceInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
374
375 infoData.cbSize = sizeof(SP_DEVINFO_DATA);
376
377 for(i = 0; SetupDiEnumDeviceInfo(deviceInfo, i, &infoData); i++) {
378 DWORD data;
379 LPTSTR buffer = NULL;
380 DWORD buffersize = 0;
381 QString description;
382
383 // get device descriptor first
384 // for some reason not doing so results in bad things (tm)
385 while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData,
386 SPDRP_DEVICEDESC, &data, (PBYTE)buffer, buffersize, &buffersize)) {
387 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
388 if(buffer) free(buffer);
389 // double buffer size to avoid problems as per KB888609
390 buffer = (LPTSTR)malloc(buffersize * 2);
391 }
392 else {
393 break;
394 }
395 }
396 if(!buffer) {
397 LOG_WARNING() << "Got no device description"
398 << "(SetupDiGetDeviceRegistryProperty), item" << i;
399 continue;
400 }
401 description = QString::fromWCharArray(buffer);
402
403 // now get the hardware id, which contains PID and VID.
404 while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData,
405 SPDRP_HARDWAREID, &data, (PBYTE)buffer, buffersize, &buffersize)) {
406 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
407 if(buffer) free(buffer);
408 // double buffer size to avoid problems as per KB888609
409 buffer = (LPTSTR)malloc(buffersize * 2);
410 }
411 else {
412 break;
413 }
414 }
415
416 if(buffer) {
417 // convert buffer text to upper case to avoid depending on the case of
418 // the keys (W7 uses different casing than XP at least), in addition
419 // XP may use "Vid_" and "Pid_".
420 QString data = QString::fromWCharArray(buffer).toUpper();
421 QRegExp rex("USB\\\\VID_([0-9A-F]{4})&PID_([0-9A-F]{4}).*");
422 if(rex.indexIn(data) >= 0) {
423 uint32_t id;
424 id = rex.cap(1).toUInt(0, 16) << 16 | rex.cap(2).toUInt(0, 16);
425 usbids.insert(id, description);
426 LOG_INFO() << "USB:" << QString("0x%1").arg(id, 8, 16);
427 }
428 free(buffer);
429 }
430 }
431 SetupDiDestroyDeviceInfoList(deviceInfo);
432
433#endif
434 return usbids;
435}
436
437
438/** @brief detects current system proxy
439 * @return QUrl with proxy or empty
440 */
441QUrl System::systemProxy(void)
442{
443#if defined(Q_OS_LINUX)
444 return QUrl(getenv("http_proxy"));
445#elif defined(Q_OS_WIN32)
446 HKEY hk;
447 wchar_t proxyval[80];
448 DWORD buflen = 80;
449 long ret;
450 DWORD enable;
451 DWORD enalen = sizeof(DWORD);
452
453 ret = RegOpenKeyEx(HKEY_CURRENT_USER,
454 _TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"),
455 0, KEY_QUERY_VALUE, &hk);
456 if(ret != ERROR_SUCCESS) return QUrl("");
457
458 ret = RegQueryValueEx(hk, _TEXT("ProxyServer"), NULL, NULL, (LPBYTE)proxyval, &buflen);
459 if(ret != ERROR_SUCCESS) return QUrl("");
460
461 ret = RegQueryValueEx(hk, _TEXT("ProxyEnable"), NULL, NULL, (LPBYTE)&enable, &enalen);
462 if(ret != ERROR_SUCCESS) return QUrl("");
463
464 RegCloseKey(hk);
465
466 //LOG_INFO() << QString::fromWCharArray(proxyval) << QString("%1").arg(enable);
467 if(enable != 0)
468 return QUrl("http://" + QString::fromWCharArray(proxyval));
469 else
470 return QUrl("");
471#elif defined(Q_OS_MACX)
472
473 CFDictionaryRef dictref;
474 CFStringRef stringref;
475 CFNumberRef numberref;
476 int enable = 0;
477 int port = 0;
478 unsigned int bufsize = 0;
479 char *buf;
480 QUrl proxy;
481
482 dictref = SCDynamicStoreCopyProxies(NULL);
483 if(dictref == NULL)
484 return proxy;
485 numberref = (CFNumberRef)CFDictionaryGetValue(dictref, kSCPropNetProxiesHTTPEnable);
486 if(numberref != NULL)
487 CFNumberGetValue(numberref, kCFNumberIntType, &enable);
488 if(enable == 1) {
489 // get proxy string
490 stringref = (CFStringRef)CFDictionaryGetValue(dictref, kSCPropNetProxiesHTTPProxy);
491 if(stringref != NULL) {
492 // get number of characters. CFStringGetLength uses UTF-16 code pairs
493 bufsize = CFStringGetLength(stringref) * 2 + 1;
494 buf = (char*)malloc(sizeof(char) * bufsize);
495 if(buf == NULL) {
496 LOG_ERROR() << "can't allocate memory for proxy string!";
497 CFRelease(dictref);
498 return QUrl("");
499 }
500 CFStringGetCString(stringref, buf, bufsize, kCFStringEncodingUTF16);
501 numberref = (CFNumberRef)CFDictionaryGetValue(dictref, kSCPropNetProxiesHTTPPort);
502 if(numberref != NULL)
503 CFNumberGetValue(numberref, kCFNumberIntType, &port);
504 proxy.setScheme("http");
505 proxy.setHost(QString::fromUtf16((unsigned short*)buf));
506 proxy.setPort(port);
507
508 free(buf);
509 }
510 }
511 CFRelease(dictref);
512
513 return proxy;
514#else
515 return QUrl("");
516#endif
517}
518
519
diff --git a/utils/rbutilqt/base/system.h b/utils/rbutilqt/base/system.h
new file mode 100644
index 0000000000..61f0a6f1a9
--- /dev/null
+++ b/utils/rbutilqt/base/system.h
@@ -0,0 +1,53 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21
22#ifndef SYSTEM_H
23#define SYSTEM_H
24
25#include <QtCore/QObject>
26
27#include <inttypes.h>
28
29#include <QMultiMap>
30#include <QString>
31#include <QUrl>
32
33class System : public QObject
34{
35public:
36 System() {}
37
38#if defined(Q_OS_WIN32)
39 enum userlevel { ERR, GUEST, USER, ADMIN };
40 static enum userlevel userPermissions(void);
41 static QString userPermissionsString(void);
42#endif
43
44 static QString userName(void);
45 static QString osVersionString(void);
46 static QList<uint32_t> listUsbIds(void);
47 static QMultiMap<uint32_t, QString> listUsbDevices(void);
48
49 static QUrl systemProxy(void);
50
51};
52#endif
53
diff --git a/utils/rbutilqt/base/talkfile.cpp b/utils/rbutilqt/base/talkfile.cpp
new file mode 100644
index 0000000000..cef53c852b
--- /dev/null
+++ b/utils/rbutilqt/base/talkfile.cpp
@@ -0,0 +1,300 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include "talkfile.h"
20#include "rbsettings.h"
21#include "Logger.h"
22
23TalkFileCreator::TalkFileCreator(QObject* parent): QObject(parent)
24{
25
26}
27
28//! \brief Creates Talkfiles.
29//!
30//! \param logger A pointer to a Loggerobject
31bool TalkFileCreator::createTalkFiles()
32{
33 m_abort = false;
34 QString errStr;
35
36 emit logItem(tr("Starting Talk file generation for folder %1")
37 .arg(m_dir), LOGINFO);
38 emit logProgress(0,0);
39 QCoreApplication::processEvents();
40
41 // read in Maps of paths - file/dirnames
42 emit logItem(tr("Reading Filelist..."),LOGINFO);
43 if(createTalkList(m_mountpoint + "/" + m_dir) == false)
44 {
45 emit logItem(tr("Talk file creation aborted"),LOGERROR);
46 doAbort();
47 return false;
48 }
49 QCoreApplication::processEvents();
50
51 // generate entries
52 TalkGenerator generator(this);
53 // no string corrections yet: do not set language for TalkGenerator.
54 connect(&generator, &TalkGenerator::done, this, &TalkFileCreator::done);
55 connect(&generator, &TalkGenerator::logItem, this, &TalkFileCreator::logItem);
56 connect(&generator, &TalkGenerator::logProgress, this, &TalkFileCreator::logProgress);
57 connect(this, &TalkFileCreator::aborted, &generator, &TalkGenerator::abort);
58
59 if(generator.process(&m_talkList) == TalkGenerator::eERROR)
60 {
61 doAbort();
62 return false;
63 }
64
65 // Copying talk files
66 emit logItem(tr("Copying Talkfiles..."),LOGINFO);
67 if(copyTalkFiles(&errStr) == false)
68 {
69 emit logItem(errStr,LOGERROR);
70 doAbort();
71 return false;
72 }
73
74 // Deleting left overs
75 if( !cleanup())
76 return false;
77
78 emit logItem(tr("Finished creating Talk files"),LOGOK);
79 emit logProgress(1,1);
80 emit done(false);
81
82 return true;
83}
84
85//! \brief Strips everything after and including the last dot in a string. If there is no dot, nothing is changed
86//!
87//! \param filename The filename from which to strip the Extension
88//! \returns the modified string
89QString TalkFileCreator::stripExtension(QString filename)
90{
91 // only strip extension if there is a dot in the filename and there are chars before the dot
92 if(filename.lastIndexOf(".") != -1 && filename.left(filename.lastIndexOf(".")) != "")
93 return filename.left(filename.lastIndexOf("."));
94 else
95 return filename;
96}
97
98//! \brief Does needed Tasks when we need to abort. Cleans up Files. Stops the Logger, Stops TTS and Encoder
99//!
100void TalkFileCreator::doAbort()
101{
102 cleanup();
103 emit logProgress(0,1);
104 emit done(true);
105}
106//! \brief creates a list of what to generate
107//!
108//! \param startDir The directory from which to start scanning
109bool TalkFileCreator::createTalkList(QDir startDir)
110{
111 LOG_INFO() << "generating list of files" << startDir;
112 m_talkList.clear();
113
114 // create Iterator
115 QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags;
116 if(m_recursive)
117 flags = QDirIterator::Subdirectories;
118
119 QDirIterator it(startDir,flags);
120
121 //create temp directory
122 QDir tempDir(QDir::tempPath()+ "/talkfiles/");
123 if(!tempDir.exists())
124 tempDir.mkpath(QDir::tempPath()+ "/talkfiles/");
125
126 // read in Maps of paths - file/dirnames
127 while (it.hasNext())
128 {
129 it.next();
130 if(m_abort)
131 {
132 return false;
133 }
134
135 QFileInfo fileInf = it.fileInfo();
136
137 // its a dir
138 if(fileInf.isDir())
139 {
140 QDir dir = fileInf.dir();
141
142 // insert into List
143 if(!dir.dirName().isEmpty() && m_talkFolders)
144 {
145 // check if we should ignore it
146 if(m_generateOnlyNew && QFileInfo::exists(dir.path() + "/_dirname.talk"))
147 {
148 continue;
149 }
150
151 //generate entry
152 TalkGenerator::TalkEntry entry;
153 entry.toSpeak = dir.dirName();
154 entry.wavfilename = QDir::tempPath() + "/talkfiles/"
155 + QCryptographicHash::hash(entry.toSpeak.toUtf8(),
156 QCryptographicHash::Md5).toHex() + ".wav";
157 entry.talkfilename = QDir::tempPath() + "/talkfiles/"
158 + QCryptographicHash::hash(entry.toSpeak.toUtf8(),
159 QCryptographicHash::Md5).toHex() + ".talk";
160 entry.target = dir.path() + "/_dirname.talk";
161 entry.voiced = false;
162 entry.encoded = false;
163 LOG_INFO() << "toSpeak:" << entry.toSpeak
164 << "target:" << entry.target
165 << "intermediates:" << entry.wavfilename << entry.talkfilename;
166 m_talkList.append(entry);
167 }
168 }
169 else // its a File
170 {
171 // insert into List
172 if( !fileInf.fileName().isEmpty() && !fileInf.fileName().endsWith(".talk") && m_talkFiles)
173 {
174 //test if we should ignore this file
175 bool match = false;
176 for(int i=0; i < m_ignoreFiles.size();i++)
177 {
178 QRegExp rx(m_ignoreFiles[i].trimmed());
179 rx.setPatternSyntax(QRegExp::Wildcard);
180 if(rx.exactMatch(fileInf.fileName()))
181 match = true;
182 }
183 if(match)
184 continue;
185
186 // check if we should ignore it
187 if(m_generateOnlyNew && QFileInfo::exists(fileInf.path() + "/" + fileInf.fileName() + ".talk"))
188 {
189 continue;
190 }
191
192 //generate entry
193 TalkGenerator::TalkEntry entry;
194 if(m_stripExtensions)
195 entry.toSpeak = stripExtension(fileInf.fileName());
196 else
197 entry.toSpeak = fileInf.fileName();
198 entry.wavfilename = QDir::tempPath() + "/talkfiles/"
199 + QCryptographicHash::hash(entry.toSpeak.toUtf8(),
200 QCryptographicHash::Md5).toHex() + ".wav";
201 entry.talkfilename = QDir::tempPath() + "/talkfiles/"
202 + QCryptographicHash::hash(entry.toSpeak.toUtf8(),
203 QCryptographicHash::Md5).toHex() + ".talk";
204 entry.target = fileInf.path() + "/" + fileInf.fileName() + ".talk";
205 entry.voiced = false;
206 entry.encoded = false;
207 LOG_INFO() << "toSpeak:" << entry.toSpeak
208 << "target:" << entry.target
209 << "intermediates:"
210 << entry.wavfilename << entry.talkfilename;
211 m_talkList.append(entry);
212 }
213 }
214 QCoreApplication::processEvents();
215 }
216 LOG_INFO() << "list created, entries:" << m_talkList.size();
217 return true;
218}
219
220
221//! \brief copys Talkfiles from the temp dir to the target. Progress and installlog is handled inside
222//!
223//! \param errString Pointer to a QString where the error cause is written.
224//! \returns true on success, false on error or user abort
225bool TalkFileCreator::copyTalkFiles(QString* errString)
226{
227 int progressMax = m_talkList.size();
228 int m_progress = 0;
229 emit logProgress(m_progress,progressMax);
230
231 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, nullptr);
232 installlog.beginGroup("talkfiles");
233
234 for(int i=0; i < m_talkList.size(); i++)
235 {
236 if(m_abort)
237 {
238 *errString = tr("File copy aborted");
239 return false;
240 }
241
242 // skip not encoded files
243 if(m_talkList[i].encoded == false)
244 {
245 emit logProgress(++m_progress,progressMax);
246 continue; // this file was skipped in one of the previous steps
247 }
248 // remove target if it exists, and if we should overwrite it
249 if(QFile::exists(m_talkList[i].target))
250 QFile::remove(m_talkList[i].target);
251
252 // copying
253 LOG_INFO() << "copying" << m_talkList[i].talkfilename
254 << "to" << m_talkList[i].target;
255 if(!QFile::copy(m_talkList[i].talkfilename,m_talkList[i].target))
256 {
257 *errString = tr("Copying of %1 to %2 failed").arg(m_talkList[i].talkfilename).arg(m_talkList[i].target);
258 return false;
259 }
260
261 // add to installlog
262 QString now = QDate::currentDate().toString("yyyyMMdd");
263 installlog.setValue(m_talkList[i].target.remove(0,m_mountpoint.length()),now);
264
265 emit logProgress(++m_progress,progressMax);
266 QCoreApplication::processEvents();
267 }
268 installlog.endGroup();
269 installlog.sync();
270 return true;
271}
272
273
274//! \brief Cleans up Files potentially left in the temp dir
275//!
276bool TalkFileCreator::cleanup()
277{
278 emit logItem(tr("Cleaning up..."),LOGINFO);
279
280 for(int i=0; i < m_talkList.size(); i++)
281 {
282 if(QFile::exists(m_talkList[i].wavfilename))
283 QFile::remove(m_talkList[i].wavfilename);
284 if(QFile::exists(m_talkList[i].talkfilename))
285 QFile::remove(m_talkList[i].talkfilename);
286
287 QCoreApplication::processEvents();
288 }
289 emit logItem(tr("Finished"),LOGINFO);
290 return true;
291}
292
293//! \brief slot, which is connected to the abort of the Logger. Sets a flag, so Creating Talkfiles ends at the next possible position
294//!
295void TalkFileCreator::abort()
296{
297 m_abort = true;
298 emit aborted();
299}
300
diff --git a/utils/rbutilqt/base/talkfile.h b/utils/rbutilqt/base/talkfile.h
new file mode 100644
index 0000000000..11dd95ca14
--- /dev/null
+++ b/utils/rbutilqt/base/talkfile.h
@@ -0,0 +1,83 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21
22#ifndef TALKFILE_H
23#define TALKFILE_H
24
25#include <QtCore>
26#include "progressloggerinterface.h"
27
28#include "talkgenerator.h"
29
30class TalkFileCreator :public QObject
31{
32 Q_OBJECT
33
34public:
35 TalkFileCreator(QObject* parent);
36
37 bool createTalkFiles();
38
39 void setDir(QString dir) {m_dir = dir;}
40 void setMountPoint(QString mountpoint) {m_mountpoint = mountpoint;}
41
42 void setGenerateOnlyNew(bool ov) {m_generateOnlyNew = ov;}
43 void setRecursive(bool ov) {m_recursive = ov;}
44 void setStripExtensions(bool ov) {m_stripExtensions = ov;}
45 void setTalkFolders(bool ov) {m_talkFolders = ov;}
46 void setTalkFiles(bool ov) {m_talkFiles = ov;}
47 void setIgnoreFiles(QStringList wildcards) {m_ignoreFiles = wildcards;}
48public slots:
49 void abort();
50
51signals:
52 void done(bool);
53 void aborted();
54 void logItem(QString, int); //! set logger item
55 void logProgress(int, int); //! set progress bar.
56
57private:
58 bool cleanup();
59 QString stripExtension(QString filename);
60 void doAbort();
61 void resetProgress(int max);
62 bool copyTalkFiles(QString* errString);
63
64 bool createTalkList(QDir startDir);
65
66 QString m_dir;
67 QString m_mountpoint;
68
69 bool m_generateOnlyNew;
70 bool m_recursive;
71 bool m_stripExtensions;
72 bool m_talkFolders;
73 bool m_talkFiles;
74 QStringList m_ignoreFiles;
75
76 bool m_abort;
77
78 QList<TalkGenerator::TalkEntry> m_talkList;
79};
80
81
82#endif
83
diff --git a/utils/rbutilqt/base/talkgenerator.cpp b/utils/rbutilqt/base/talkgenerator.cpp
new file mode 100644
index 0000000000..9139ceb274
--- /dev/null
+++ b/utils/rbutilqt/base/talkgenerator.cpp
@@ -0,0 +1,337 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include "talkgenerator.h"
20#include "rbsettings.h"
21#include "playerbuildinfo.h"
22#include "wavtrim.h"
23#include "Logger.h"
24
25TalkGenerator::TalkGenerator(QObject* parent): QObject(parent)
26{
27
28}
29
30//! \brief Creates Talkfiles.
31//!
32TalkGenerator::Status TalkGenerator::process(QList<TalkEntry>* list,int wavtrimth)
33{
34 m_abort = false;
35 QString errStr;
36 bool warnings = false;
37
38 //tts
39 emit logItem(tr("Starting TTS Engine"), LOGINFO);
40 m_tts = TTSBase::getTTS(this, RbSettings::value(RbSettings::Tts).toString());
41 if(!m_tts)
42 {
43 LOG_ERROR() << "getting the TTS object failed!";
44 emit logItem(tr("Init of TTS engine failed"), LOGERROR);
45 emit done(true);
46 return eERROR;
47 }
48 if(!m_tts->start(&errStr))
49 {
50 emit logItem(errStr.trimmed(),LOGERROR);
51 emit logItem(tr("Init of TTS engine failed"), LOGERROR);
52 emit done(true);
53 return eERROR;
54 }
55 QCoreApplication::processEvents();
56
57 // Encoder
58 emit logItem(tr("Starting Encoder Engine"),LOGINFO);
59 m_enc = EncoderBase::getEncoder(this, PlayerBuildInfo::instance()->value(
60 PlayerBuildInfo::Encoder).toString());
61 if(!m_enc->start())
62 {
63 emit logItem(tr("Init of Encoder engine failed"),LOGERROR);
64 emit done(true);
65 m_tts->stop();
66 return eERROR;
67 }
68 QCoreApplication::processEvents();
69
70 emit logProgress(0,0);
71
72 // Voice entries
73 emit logItem(tr("Voicing entries..."),LOGINFO);
74 Status voiceStatus= voiceList(list,wavtrimth);
75 if(voiceStatus == eERROR)
76 {
77 m_tts->stop();
78 m_enc->stop();
79 emit done(true);
80 return eERROR;
81 }
82 else if( voiceStatus == eWARNING)
83 warnings = true;
84
85 QCoreApplication::processEvents();
86
87 // Encoding Entries
88 emit logItem(tr("Encoding files..."),LOGINFO);
89 Status encoderStatus = encodeList(list);
90 if( encoderStatus == eERROR)
91 {
92 m_tts->stop();
93 m_enc->stop();
94 emit done(true);
95 return eERROR;
96 }
97 else if( voiceStatus == eWARNING)
98 warnings = true;
99
100 QCoreApplication::processEvents();
101
102 m_tts->stop();
103 m_enc->stop();
104 emit logProgress(1,1);
105
106 if(warnings)
107 return eWARNING;
108 return eOK;
109}
110
111//! \brief Voices a List of string
112//!
113TalkGenerator::Status TalkGenerator::voiceList(QList<TalkEntry>* list,int wavtrimth)
114{
115 int progressMax = list->size();
116 int m_progress = 0;
117 emit logProgress(m_progress,progressMax);
118
119 QStringList errors;
120 QStringList duplicates;
121
122 bool warnings = false;
123 for(int i=0; i < list->size(); i++)
124 {
125 if(m_abort)
126 {
127 emit logItem(tr("Voicing aborted"), LOGERROR);
128 return eERROR;
129 }
130
131 // skip duplicated wav entrys
132 if(!duplicates.contains(list->at(i).wavfilename))
133 duplicates.append(list->at(i).wavfilename);
134 else
135 {
136 LOG_INFO() << "duplicate skipped";
137 (*list)[i].voiced = true;
138 emit logProgress(++m_progress,progressMax);
139 continue;
140 }
141
142 // skip already voiced entrys
143 if(list->at(i).voiced == true)
144 {
145 emit logProgress(++m_progress,progressMax);
146 continue;
147 }
148 // skip entry whith empty text
149 if(list->at(i).toSpeak == "")
150 {
151 emit logProgress(++m_progress,progressMax);
152 continue;
153 }
154
155 // voice entry
156 QString error;
157 LOG_INFO() << "voicing: " << list->at(i).toSpeak
158 << "to" << list->at(i).wavfilename;
159 TTSStatus status = m_tts->voice(list->at(i).toSpeak,
160 list->at(i).wavfilename, &error);
161 if(status == Warning)
162 {
163 warnings = true;
164 emit logItem(tr("Voicing of %1 failed: %2").arg(list->at(i).toSpeak).arg(error),
165 LOGWARNING);
166 }
167 else if (status == FatalError)
168 {
169 emit logItem(tr("Voicing of %1 failed: %2").arg(list->at(i).toSpeak).arg(error),
170 LOGERROR);
171 return eERROR;
172 }
173 else
174 (*list)[i].voiced = true;
175
176 // wavtrim if needed
177 if(wavtrimth != -1)
178 {
179 char buffer[255];
180 if(wavtrim(list->at(i).wavfilename.toLocal8Bit().data(),
181 wavtrimth, buffer, 255))
182 {
183 LOG_ERROR() << "wavtrim returned error on"
184 << list->at(i).wavfilename;
185 return eERROR;
186 }
187 }
188
189 emit logProgress(++m_progress,progressMax);
190 QCoreApplication::processEvents();
191 }
192 if(warnings)
193 return eWARNING;
194 else
195 return eOK;
196}
197
198
199//! \brief Encodes a List of strings
200//!
201TalkGenerator::Status TalkGenerator::encodeList(QList<TalkEntry>* list)
202{
203 QStringList duplicates;
204
205 int progressMax = list->size();
206 int m_progress = 0;
207 emit logProgress(m_progress,progressMax);
208
209 for(int i=0; i < list->size(); i++)
210 {
211 if(m_abort)
212 {
213 emit logItem(tr("Encoding aborted"), LOGERROR);
214 return eERROR;
215 }
216
217 //skip non-voiced entrys
218 if(list->at(i).voiced == false)
219 {
220 LOG_WARNING() << "non voiced entry detected:"
221 << list->at(i).toSpeak;
222 emit logProgress(++m_progress,progressMax);
223 continue;
224 }
225 //skip duplicates
226 if(!duplicates.contains(list->at(i).talkfilename))
227 duplicates.append(list->at(i).talkfilename);
228 else
229 {
230 LOG_INFO() << "duplicate skipped";
231 (*list)[i].encoded = true;
232 emit logProgress(++m_progress,progressMax);
233 continue;
234 }
235
236 //encode entry
237 LOG_INFO() << "encoding " << list->at(i).wavfilename
238 << "to" << list->at(i).talkfilename;
239 if(!m_enc->encode(list->at(i).wavfilename,list->at(i).talkfilename))
240 {
241 emit logItem(tr("Encoding of %1 failed").arg(
242 QFileInfo(list->at(i).wavfilename).baseName()), LOGERROR);
243 return eERROR;
244 }
245 (*list)[i].encoded = true;
246 emit logProgress(++m_progress,progressMax);
247 QCoreApplication::processEvents();
248 }
249 return eOK;
250}
251
252//! \brief slot, which is connected to the abort of the Logger.
253//Sets a flag, so Creating Talkfiles ends at the next possible position
254//!
255void TalkGenerator::abort()
256{
257 m_abort = true;
258}
259
260QString TalkGenerator::correctString(QString s)
261{
262 QString corrected = s;
263 int i = 0;
264 int max = m_corrections.size();
265 while(i < max) {
266 corrected = corrected.replace(QRegExp(m_corrections.at(i).search,
267 m_corrections.at(i).modifier.contains("i")
268 ? Qt::CaseInsensitive : Qt::CaseSensitive),
269 m_corrections.at(i).replace);
270 i++;
271 }
272
273 if(corrected != s)
274 LOG_INFO() << "corrected string" << s << "to" << corrected;
275
276 return corrected;
277 m_abort = true;
278}
279
280void TalkGenerator::setLang(QString name)
281{
282 m_lang = name;
283
284 // re-initialize corrections list
285 m_corrections.clear();
286 QFile correctionsFile(":/builtin/voice-corrections.txt");
287 correctionsFile.open(QIODevice::ReadOnly);
288
289 QString engine = RbSettings::value(RbSettings::Tts).toString();
290 TTSBase* tts = TTSBase::getTTS(this,RbSettings::value(RbSettings::Tts).toString());
291 if(!tts)
292 {
293 LOG_ERROR() << "getting the TTS object failed!";
294 return;
295 }
296 QString vendor = tts->voiceVendor();
297 delete tts;
298
299 if(m_lang.isEmpty())
300 m_lang = "english";
301 LOG_INFO() << "building string corrections list for"
302 << m_lang << engine << vendor;
303 QTextStream stream(&correctionsFile);
304 while(!stream.atEnd()) {
305 QString line = stream.readLine();
306 if(line.startsWith(" ") || line.length() < 10)
307 continue;
308 // separator is first character
309 QString separator = line.at(0);
310 line.remove(0, 1);
311 QStringList items = line.split(separator);
312 // we need to have at least 6 separate entries.
313 if(items.size() < 6)
314 continue;
315
316 QRegExp re_lang(items.at(0));
317 QRegExp re_engine(items.at(1));
318 QRegExp re_vendor(items.at(2));
319 if(!re_lang.exactMatch(m_lang)) {
320 continue;
321 }
322 if(!re_vendor.exactMatch(vendor)) {
323 continue;
324 }
325 if(!re_engine.exactMatch(engine)) {
326 continue;
327 }
328 struct CorrectionItems co;
329 co.search = items.at(3);
330 co.replace = items.at(4);
331 // Qt uses backslash for back references, Perl uses dollar sign.
332 co.replace.replace(QRegExp("\\$(\\d+)"), "\\\\1");
333 co.modifier = items.at(5);
334 m_corrections.append(co);
335 }
336 correctionsFile.close();
337}
diff --git a/utils/rbutilqt/base/talkgenerator.h b/utils/rbutilqt/base/talkgenerator.h
new file mode 100644
index 0000000000..3e2f9394fb
--- /dev/null
+++ b/utils/rbutilqt/base/talkgenerator.h
@@ -0,0 +1,91 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21
22#ifndef TALKGENERATOR_H
23#define TALKGENERATOR_H
24
25#include <QtCore>
26#include "progressloggerinterface.h"
27
28#include "encoderbase.h"
29#include "ttsbase.h"
30
31//! \brief Talk generator, generates .wav and .talk files out of a list.
32class TalkGenerator :public QObject
33{
34 Q_OBJECT
35public:
36 enum Status
37 {
38 eOK,
39 eWARNING,
40 eERROR
41 };
42
43 struct TalkEntry
44 {
45 QString toSpeak;
46 QString wavfilename;
47 QString talkfilename;
48 QString target;
49 bool voiced;
50 bool encoded;
51 };
52
53 TalkGenerator(QObject* parent);
54
55 Status process(QList<TalkEntry>* list,int wavtrimth = -1);
56 QString correctString(QString s);
57
58public slots:
59 void abort();
60 void setLang(QString name);
61
62signals:
63 void done(bool);
64 void logItem(QString, int); //! set logger item
65 void logProgress(int, int); //! set progress bar.
66
67private:
68 Status voiceList(QList<TalkEntry>* list,int wavetrimth);
69 Status encodeList(QList<TalkEntry>* list);
70
71 TTSBase* m_tts;
72 EncoderBase* m_enc;
73
74 QString m_lang;
75
76 struct CorrectionItems
77 {
78 QString search;
79 QString replace;
80 QString modifier;
81 };
82 QList<struct CorrectionItems> m_corrections;
83
84 bool m_abort;
85
86
87};
88
89
90#endif
91
diff --git a/utils/rbutilqt/base/ttsbase.cpp b/utils/rbutilqt/base/ttsbase.cpp
new file mode 100644
index 0000000000..0102d215a6
--- /dev/null
+++ b/utils/rbutilqt/base/ttsbase.cpp
@@ -0,0 +1,122 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include "ttsbase.h"
21
22#include "ttsfestival.h"
23#include "ttssapi.h"
24#include "ttssapi4.h"
25#include "ttsmssp.h"
26#include "ttsexes.h"
27#include "ttsespeak.h"
28#include "ttsespeakng.h"
29#include "ttsflite.h"
30#include "ttsmimic.h"
31#include "ttsswift.h"
32#if defined(Q_OS_MACX)
33#include "ttscarbon.h"
34#endif
35
36// list of tts names and identifiers
37QMap<QString,QString> TTSBase::ttsList;
38
39TTSBase::TTSBase(QObject* parent): EncTtsSettingInterface(parent)
40{
41}
42
43// static functions
44void TTSBase::initTTSList()
45{
46#if !defined(Q_OS_WIN)
47 ttsList["espeak"] = tr("Espeak TTS Engine");
48 ttsList["espeakng"] = tr("Espeak-ng TTS Engine");
49 ttsList["mimic"] = tr("Mimic TTS Engine");
50#endif
51 ttsList["flite"] = tr("Flite TTS Engine");
52 ttsList["swift"] = tr("Swift TTS Engine");
53#if defined(Q_OS_WIN)
54#if 0 /* SAPI4 has been disabled since long. Keep support for now. */
55 ttsList["sapi4"] = tr("SAPI4 TTS Engine");
56#endif
57 ttsList["sapi"] = tr("SAPI5 TTS Engine");
58 ttsList["mssp"] = tr("MS Speech Platform");
59#endif
60#if defined(Q_OS_LINUX)
61 ttsList["festival"] = tr("Festival TTS Engine");
62#endif
63#if defined(Q_OS_MACX)
64 ttsList["carbon"] = tr("OS X System Engine");
65#endif
66}
67
68// function to get a specific encoder
69TTSBase* TTSBase::getTTS(QObject* parent,QString ttsName)
70{
71
72 TTSBase* tts = nullptr;
73#if defined(Q_OS_WIN)
74 if(ttsName == "sapi")
75 tts = new TTSSapi(parent);
76 else if (ttsName == "sapi4")
77 tts = new TTSSapi4(parent);
78 else if (ttsName == "mssp")
79 tts = new TTSMssp(parent);
80 else
81#elif defined(Q_OS_LINUX)
82 if (ttsName == "festival")
83 tts = new TTSFestival(parent);
84 else
85#elif defined(Q_OS_MACX)
86 if(ttsName == "carbon")
87 tts = new TTSCarbon(parent);
88 else
89#endif
90 if(ttsName == "espeak")
91 tts = new TTSEspeak(parent);
92 else if(ttsName == "espeakng")
93 tts = new TTSEspeakNG(parent);
94 else if(ttsName == "mimic")
95 tts = new TTSMimic(parent);
96 else if(ttsName == "flite")
97 tts = new TTSFlite(parent);
98 else if(ttsName == "swift")
99 tts = new TTSSwift(parent);
100 else if(ttsName == "user")
101 tts = new TTSExes(parent);
102
103 return tts;
104}
105
106// get the list of encoders, nice names
107QStringList TTSBase::getTTSList()
108{
109 // init list if its empty
110 if(ttsList.count() == 0)
111 initTTSList();
112
113 return ttsList.keys();
114}
115
116// get nice name of a specific tts
117QString TTSBase::getTTSName(QString tts)
118{
119 if(ttsList.isEmpty())
120 initTTSList();
121 return ttsList.value(tts);
122}
diff --git a/utils/rbutilqt/base/ttsbase.h b/utils/rbutilqt/base/ttsbase.h
new file mode 100644
index 0000000000..125fe49ff4
--- /dev/null
+++ b/utils/rbutilqt/base/ttsbase.h
@@ -0,0 +1,70 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21
22#ifndef TTSBASE_H
23#define TTSBASE_H
24
25#include <QtCore>
26
27#include "encttssettings.h"
28
29enum TTSStatus{ FatalError, NoError, Warning };
30class TTSBase : public EncTtsSettingInterface
31{
32 Q_OBJECT
33 public:
34 enum Capability { None = 0, RunInParallel = 1, CanSpeak = 2 };
35 Q_DECLARE_FLAGS(Capabilities, Capability)
36
37 TTSBase(QObject *parent);
38 //! Child class should generate a clip
39 virtual TTSStatus voice(QString text,QString wavfile, QString* errStr) =0;
40 //! Child class should do startup
41 virtual bool start(QString *errStr) =0;
42 //! child class should stop
43 virtual bool stop() =0;
44
45 virtual QString voiceVendor(void) = 0;
46 // configuration
47 //! Child class should return true, when configuration is good
48 virtual bool configOk()=0;
49 //! Child class should generate and insertSetting(..) its settings
50 virtual void generateSettings() = 0;
51 //! Chlid class should commit the Settings to permanent storage
52 virtual void saveSettings() = 0;
53
54 virtual Capabilities capabilities() = 0;
55
56 // static functions
57 static TTSBase* getTTS(QObject* parent,QString ttsname);
58 static QStringList getTTSList();
59 static QString getTTSName(QString tts);
60
61 private:
62 //inits the tts List
63 static void initTTSList();
64
65 protected:
66 static QMap<QString,QString> ttsList;
67};
68Q_DECLARE_OPERATORS_FOR_FLAGS(TTSBase::Capabilities)
69
70#endif
diff --git a/utils/rbutilqt/base/ttscarbon.cpp b/utils/rbutilqt/base/ttscarbon.cpp
new file mode 100644
index 0000000000..2d9fa49dbe
--- /dev/null
+++ b/utils/rbutilqt/base/ttscarbon.cpp
@@ -0,0 +1,443 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2010 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include "ttsbase.h"
21#include "ttscarbon.h"
22#include "encttssettings.h"
23#include "rbsettings.h"
24
25#include <CoreFoundation/CoreFoundation.h>
26#include <ApplicationServices/ApplicationServices.h>
27#include <Carbon/Carbon.h>
28#include <unistd.h>
29#include <sys/stat.h>
30#include <inttypes.h>
31#include "Logger.h"
32
33TTSCarbon::TTSCarbon(QObject* parent) : TTSBase(parent)
34{
35}
36
37TTSBase::Capabilities TTSCarbon::capabilities()
38{
39 return TTSBase::CanSpeak;
40}
41
42bool TTSCarbon::configOk()
43{
44 return true;
45}
46
47
48bool TTSCarbon::start(QString *errStr)
49{
50 (void)errStr;
51 VoiceSpec vspec;
52 VoiceSpec* vspecref = NULL;
53 VoiceDescription vdesc;
54 OSErr error;
55 QString selectedVoice
56 = RbSettings::subValue("carbon", RbSettings::TtsVoice).toString();
57 SInt16 numVoices;
58 SInt16 voiceIndex;
59 error = CountVoices(&numVoices);
60 for(voiceIndex = 1; voiceIndex < numVoices; ++voiceIndex) {
61 error = GetIndVoice(voiceIndex, &vspec);
62 error = GetVoiceDescription(&vspec, &vdesc, sizeof(vdesc));
63 // name is pascal string, i.e. the first byte is the length.
64 QString name = QString::fromLocal8Bit((const char*)&vdesc.name[1],
65 vdesc.name[0]);
66 if(name == selectedVoice) {
67 vspecref = &vspec;
68 if(vdesc.script != -1)
69 m_voiceScript = (CFStringBuiltInEncodings)vdesc.script;
70 else
71 m_voiceScript = (CFStringBuiltInEncodings)vdesc.reserved[0];
72 break;
73 }
74 }
75 if(voiceIndex == numVoices) {
76 // voice not found. Add user notification here and proceed with
77 // system default voice.
78 LOG_WARNING() << "Selected voice not found, using system default!";
79 GetVoiceDescription(&vspec, &vdesc, sizeof(vdesc));
80 if(vdesc.script != -1)
81 m_voiceScript = (CFStringBuiltInEncodings)vdesc.script;
82 else
83 m_voiceScript = (CFStringBuiltInEncodings)vdesc.reserved[0];
84 }
85
86 error = NewSpeechChannel(vspecref, &m_channel);
87 //SetSpeechInfo(channel, soSpeechDoneCallBack, speechDone);
88 Fixed rate = (Fixed)(0x10000 * RbSettings::subValue("carbon",
89 RbSettings::TtsSpeed).toInt());
90 if(rate != 0)
91 SetSpeechRate(m_channel, rate);
92
93 Fixed pitch = (Fixed)(0x10000 * RbSettings::subValue("carbon",
94 RbSettings::TtsPitch).toInt());
95 if(pitch != 0)
96 SetSpeechPitch(m_channel, pitch);
97
98 return (error == 0) ? true : false;
99}
100
101
102bool TTSCarbon::stop(void)
103{
104 DisposeSpeechChannel(m_channel);
105 return true;
106}
107
108
109void TTSCarbon::generateSettings(void)
110{
111 QStringList voiceNames;
112 QString systemVoice;
113 SInt16 numVoices;
114 OSErr error;
115 VoiceSpec vspec;
116 VoiceDescription vdesc;
117
118 // get system voice
119 error = GetVoiceDescription(NULL, &vdesc, sizeof(vdesc));
120 systemVoice
121 = QString::fromLocal8Bit((const char*)&vdesc.name[1], vdesc.name[0]);
122 // get list of all voices
123 CountVoices(&numVoices);
124 for(SInt16 i = 1; i < numVoices; ++i) {
125 error = GetIndVoice(i, &vspec);
126 error = GetVoiceDescription(&vspec, &vdesc, sizeof(vdesc));
127 // name is pascal string, i.e. the first byte is the length.
128 QString name
129 = QString::fromLocal8Bit((const char*)&vdesc.name[1], vdesc.name[0]);
130 voiceNames.append(name.trimmed());
131 }
132 // voice
133 EncTtsSetting* setting;
134 QString voice
135 = RbSettings::subValue("carbon", RbSettings::TtsVoice).toString();
136 if(voice.isEmpty())
137 voice = systemVoice;
138 setting = new EncTtsSetting(this, EncTtsSetting::eSTRINGLIST,
139 tr("Voice:"), voice, voiceNames, EncTtsSetting::eNOBTN);
140 insertSetting(ConfigVoice, setting);
141
142 // speed
143 int speed = RbSettings::subValue("carbon", RbSettings::TtsSpeed).toInt();
144 setting = new EncTtsSetting(this, EncTtsSetting::eINT,
145 tr("Speed (words/min):"), speed, 80, 500,
146 EncTtsSetting::eNOBTN);
147 insertSetting(ConfigSpeed, setting);
148
149 // pitch
150 int pitch = RbSettings::subValue("carbon", RbSettings::TtsPitch).toInt();
151 setting = new EncTtsSetting(this, EncTtsSetting::eINT,
152 tr("Pitch (0 for default):"), pitch, 0, 65,
153 EncTtsSetting::eNOBTN);
154 insertSetting(ConfigPitch, setting);
155
156}
157
158
159void TTSCarbon::saveSettings(void)
160{
161 // save settings in user config
162 RbSettings::setSubValue("carbon", RbSettings::TtsVoice,
163 getSetting(ConfigVoice)->current().toString());
164 RbSettings::setSubValue("carbon", RbSettings::TtsSpeed,
165 getSetting(ConfigSpeed)->current().toInt());
166 RbSettings::setSubValue("carbon", RbSettings::TtsPitch,
167 getSetting(ConfigPitch)->current().toInt());
168 RbSettings::sync();
169}
170
171
172/** @brief create wav file from text using the selected TTS voice.
173 */
174TTSStatus TTSCarbon::voice(QString text, QString wavfile, QString* errStr)
175{
176 TTSStatus status = NoError;
177 OSErr error;
178
179 char* tmpfile = NULL;
180 if(!wavfile.isEmpty()) {
181 QString aifffile = wavfile + ".aiff";
182 // FIXME: find out why we need to do this.
183 // Create a local copy of the temporary file filename.
184 // Not doing so causes weird issues (path contains trailing spaces)
185 unsigned int len = aifffile.size() + 1;
186 tmpfile = (char*)malloc(len * sizeof(char));
187 strncpy(tmpfile, aifffile.toLocal8Bit().constData(), len);
188 CFStringRef tmpfileref = CFStringCreateWithCString(kCFAllocatorDefault,
189 tmpfile, kCFStringEncodingUTF8);
190 CFURLRef urlref = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
191 tmpfileref, kCFURLPOSIXPathStyle, false);
192 SetSpeechInfo(m_channel, soOutputToFileWithCFURL, urlref);
193 }
194
195 // speak it.
196 // Convert the string to the encoding requested by the voice. Do this
197 // via CFString, as this allows to directly use the destination encoding
198 // as CFString uses the same values as the voice.
199
200 // allocate enough space to allow storing the string in a 2 byte encoding
201 unsigned int textlen = 2 * text.length() + 1;
202 char* textbuf = (char*)calloc(textlen, sizeof(char));
203 char* utf8data = (char*)text.toUtf8().constData();
204 int utf8bytes = text.toUtf8().size();
205 CFStringRef cfstring = CFStringCreateWithBytes(kCFAllocatorDefault,
206 (UInt8*)utf8data, utf8bytes,
207 kCFStringEncodingUTF8, (Boolean)false);
208 CFIndex usedBuf = 0;
209 CFRange range;
210 range.location = 0; // character in string to start.
211 range.length = text.length(); // number of _characters_ in string
212 // FIXME: check if converting between encodings was lossless.
213 CFStringGetBytes(cfstring, range, m_voiceScript, ' ',
214 false, (UInt8*)textbuf, textlen, &usedBuf);
215
216 error = SpeakText(m_channel, textbuf, (unsigned long)usedBuf);
217 while(SpeechBusy()) {
218 // FIXME: add small delay here to make calls less frequent
219 QCoreApplication::processEvents();
220 }
221 if(error != 0) {
222 *errStr = tr("Could not voice string");
223 status = FatalError;
224 }
225 free(textbuf);
226 CFRelease(cfstring);
227
228 if(!wavfile.isEmpty()) {
229 // convert the temporary aiff file to wav
230 if(status == NoError
231 && convertAiffToWav(tmpfile, wavfile.toLocal8Bit().constData()) != 0) {
232 *errStr = tr("Could not convert intermediate file");
233 status = FatalError;
234 }
235 // remove temporary aiff file
236 unlink(tmpfile);
237 free(tmpfile);
238 }
239
240 return status;
241}
242
243
244unsigned long TTSCarbon::be2u32(unsigned char* buf)
245{
246 return (buf[0]&0xff)<<24 | (buf[1]&0xff)<<16 | (buf[2]&0xff)<<8 | (buf[3]&0xff);
247}
248
249
250unsigned long TTSCarbon::be2u16(unsigned char* buf)
251{
252 return (buf[1]&0xff) | (buf[0]&0xff)<<8;
253}
254
255
256unsigned char* TTSCarbon::u32tobuf(unsigned char* buf, uint32_t val)
257{
258 buf[0] = val & 0xff;
259 buf[1] = (val>> 8) & 0xff;
260 buf[2] = (val>>16) & 0xff;
261 buf[3] = (val>>24) & 0xff;
262 return buf;
263}
264
265
266unsigned char* TTSCarbon::u16tobuf(unsigned char* buf, uint16_t val)
267{
268 buf[0] = val & 0xff;
269 buf[1] = (val>> 8) & 0xff;
270 return buf;
271}
272
273
274/** @brief convert 80 bit extended ("long double") to int.
275 * This is simplified to handle the usual audio sample rates. Everything else
276 * might break. If the value isn't supported it will return 0.
277 * Conversion taken from Rockbox aiff codec.
278 */
279unsigned int TTSCarbon::extended2int(unsigned char* buf)
280{
281 unsigned int result = 0;
282 /* value negative? */
283 if(buf[0] & 0x80)
284 return 0;
285 /* check exponent. Int can handle up to 2^31. */
286 int exponent = buf[0] << 8 | buf[1];
287 if(exponent < 0x4000 || exponent > (0x4000 + 30))
288 return 0;
289 result = ((buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5]) + 1;
290 result >>= (16 + 14 - buf[1]);
291 return result;
292}
293
294
295/** @brief Convert aiff file to wav. Returns 0 on success.
296 */
297int TTSCarbon::convertAiffToWav(const char* aiff, const char* wav)
298{
299 struct commchunk {
300 unsigned long chunksize;
301 unsigned short channels;
302 unsigned long frames;
303 unsigned short size;
304 int rate;
305 };
306
307 struct ssndchunk {
308 unsigned long chunksize;
309 unsigned long offset;
310 unsigned long blocksize;
311 };
312
313 FILE* in;
314 FILE* out;
315 unsigned char obuf[4];
316 unsigned char* buf;
317 /* minimum file size for a valid aiff file is 46 bytes:
318 * - FORM chunk: 12 bytes
319 * - COMM chunk: 18 bytes
320 * - SSND chunk: 16 bytes (with no actual data)
321 */
322 struct stat filestat;
323 stat(aiff, &filestat);
324 if(filestat.st_size < 46)
325 return -1;
326 /* read input file into memory */
327 buf = (unsigned char*)malloc(filestat.st_size * sizeof(unsigned char));
328 if(!buf) /* error out if malloc() failed */
329 return -1;
330 in = fopen(aiff, "rb");
331 if(fread(buf, 1, filestat.st_size, in) < filestat.st_size) {
332 printf("could not read file: not enought bytes read\n");
333 fclose(in);
334 free(buf);
335 return -1;
336 }
337 fclose(in);
338
339 /* check input file format */
340 if(memcmp(buf, "FORM", 4) | memcmp(&buf[8], "AIFF", 4)) {
341 printf("No valid AIFF header found.\n");
342 free(buf);
343 return -1;
344 }
345 /* read COMM chunk */
346 unsigned char* commstart = &buf[12];
347 struct commchunk comm;
348 if(memcmp(commstart, "COMM", 4)) {
349 printf("COMM chunk not at beginning.\n");
350 free(buf);
351 return -1;
352 }
353 comm.chunksize = be2u32(&commstart[4]);
354 comm.channels = be2u16(&commstart[8]);
355 comm.frames = be2u32(&commstart[10]);
356 comm.size = be2u16(&commstart[14]);
357 comm.rate = extended2int(&commstart[16]);
358
359 /* find SSND as next chunk */
360 unsigned char* ssndstart = commstart + 8 + comm.chunksize;
361 while(memcmp(ssndstart, "SSND", 4) && ssndstart < (buf + filestat.st_size)) {
362 printf("Skipping chunk.\n");
363 ssndstart += be2u32(&ssndstart[4]) + 8;
364 }
365 if(ssndstart > (buf + filestat.st_size)) {
366 free(buf);
367 return -1;
368 }
369
370 struct ssndchunk ssnd;
371 ssnd.chunksize = be2u32(&ssndstart[4]);
372 ssnd.offset = be2u32(&ssndstart[8]);
373 ssnd.blocksize = be2u32(&ssndstart[12]);
374
375 /* Calculate the total length of the resulting RIFF chunk.
376 * The length is given by frames * samples * bytes/sample.
377 * We need to add:
378 * - 16 bytes: fmt chunk header
379 * - 8 bytes: data chunk header
380 * - 4 bytes: wave chunk identifier
381 */
382 out = fopen(wav, "wb+");
383
384 /* write the wav header */
385 unsigned short blocksize = comm.channels * (comm.size >> 3);
386 unsigned long rifflen = blocksize * comm.frames + 28;
387 fwrite("RIFF", 1, 4, out);
388 fwrite(u32tobuf(obuf, rifflen), 1, 4, out);
389 fwrite("WAVE", 1, 4, out);
390
391 /* write the fmt chunk and chunk size (always 16) */
392 /* write fmt chunk header:
393 * header, size (always 0x10, format code (always 0x0001)
394 */
395 fwrite("fmt \x10\x00\x00\x00\x01\x00", 1, 10, out);
396 /* number of channels (2 bytes) */
397 fwrite(u16tobuf(obuf, comm.channels), 1, 2, out);
398 /* sampling rate (4 bytes) */
399 fwrite(u32tobuf(obuf, comm.rate), 1, 4, out);
400
401 /* data rate, i.e. bytes/sec */
402 fwrite(u32tobuf(obuf, comm.rate * blocksize), 1, 4, out);
403
404 /* data block size */
405 fwrite(u16tobuf(obuf, blocksize), 1, 2, out);
406
407 /* bits per sample */
408 fwrite(u16tobuf(obuf, comm.size), 1, 2, out);
409
410 /* write the data chunk */
411 /* chunk id */
412 fwrite("data", 1, 4, out);
413 /* chunk size: 4 bytes. */
414 unsigned long cs = blocksize * comm.frames;
415 fwrite(u32tobuf(obuf, cs), 1, 4, out);
416
417 /* write data */
418 unsigned char* data = ssndstart;
419 unsigned long pos = ssnd.chunksize;
420 /* byteswap if samples are 16 bit */
421 if(comm.size == 16) {
422 while(pos) {
423 obuf[1] = *data++ & 0xff;
424 obuf[0] = *data++ & 0xff;
425 fwrite(obuf, 1, 2, out);
426 pos -= 2;
427 }
428 }
429 /* 8 bit samples have need no conversion so we can bulk copy.
430 * Everything that is not 16 bit is considered 8. */
431 else {
432 fwrite(data, 1, pos, out);
433 }
434 /* number of bytes has to be even, even if chunksize is not. */
435 if(cs % 2) {
436 fwrite(obuf, 1, 1, out);
437 }
438
439 fclose(out);
440 free(buf);
441 return 0;
442}
443
diff --git a/utils/rbutilqt/base/ttscarbon.h b/utils/rbutilqt/base/ttscarbon.h
new file mode 100644
index 0000000000..2e9e84aa7d
--- /dev/null
+++ b/utils/rbutilqt/base/ttscarbon.h
@@ -0,0 +1,73 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2010 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef TTSCARBON_H
20#define TTSCARBON_H
21
22#include <QtCore>
23#include "ttsbase.h"
24
25#include <Carbon/Carbon.h>
26#include <inttypes.h>
27
28class TTSCarbon : public TTSBase
29{
30 Q_OBJECT
31 //! Enum to identify the settings
32 enum ConfigValuesCarbon
33 {
34 ConfigVoice,
35 ConfigSpeed,
36 ConfigPitch
37 };
38 public:
39 TTSCarbon(QObject *parent = NULL);
40
41 //! Child class should generate a clip
42 TTSStatus voice(QString text, QString wavfile, QString* errStr);
43 //! Child class should do startup
44 bool start(QString *errStr);
45 //! child class should stop
46 bool stop() ;
47 QString voiceVendor(void) { return QString(); }
48
49 // configuration
50 //! Child class should return true, when configuration is good
51 bool configOk();
52 //! Child class should generate and insertSetting(..) its settings
53 void generateSettings();
54 //! Child class should commit the Settings to permanent storage
55 void saveSettings();
56
57 Capabilities capabilities();
58
59 private:
60 SpeechChannel m_channel;
61 CFStringBuiltInEncodings m_voiceScript;
62
63 unsigned long be2u32(unsigned char* buf);
64 unsigned long be2u16(unsigned char* buf);
65 unsigned char* u32tobuf(unsigned char* buf, uint32_t val);
66 unsigned char* u16tobuf(unsigned char* buf, uint16_t val);
67 unsigned int extended2int(unsigned char* buf);
68 int convertAiffToWav(const char* aiff, const char* wav);
69
70};
71
72#endif // TTSCARBON_H
73
diff --git a/utils/rbutilqt/base/ttsespeak.h b/utils/rbutilqt/base/ttsespeak.h
new file mode 100644
index 0000000000..afe19fbdac
--- /dev/null
+++ b/utils/rbutilqt/base/ttsespeak.h
@@ -0,0 +1,42 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8*
9* Copyright (C) 2012 by Dominik Riebeling
10*
11* This program is free software; you can redistribute it and/or
12* modify it under the terms of the GNU General Public License
13* as published by the Free Software Foundation; either version 2
14* of the License, or (at your option) any later version.
15*
16* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17* KIND, either express or implied.
18*
19****************************************************************************/
20
21#ifndef TTSESPEAK_H
22#define TTSESPEAK_H
23
24#include <QtCore>
25#include "ttsexes.h"
26
27class TTSEspeak : public TTSExes
28{
29 Q_OBJECT
30 public:
31 TTSEspeak(QObject* parent=nullptr) : TTSExes(parent)
32 {
33 m_name = "espeak";
34
35 /* default to espeak */
36 m_TTSTemplate = "\"%exe\" %options -w \"%wavfile\" -- \"%text\"";
37 m_TTSSpeakTemplate = "\"%exe\" %options -- \"%text\"";
38 m_capabilities = TTSBase::CanSpeak;
39 }
40};
41
42#endif
diff --git a/utils/rbutilqt/base/ttsespeakng.h b/utils/rbutilqt/base/ttsespeakng.h
new file mode 100644
index 0000000000..55aba62e7d
--- /dev/null
+++ b/utils/rbutilqt/base/ttsespeakng.h
@@ -0,0 +1,41 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8*
9* Copyright (C) 2020 by Solomon Peachy
10*
11* This program is free software; you can redistribute it and/or
12* modify it under the terms of the GNU General Public License
13* as published by the Free Software Foundation; either version 2
14* of the License, or (at your option) any later version.
15*
16* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17* KIND, either express or implied.
18*
19****************************************************************************/
20
21#ifndef TTSESPEAKNG_H
22#define TTSESPEAKNG_H
23
24#include <QtCore>
25#include "ttsexes.h"
26
27class TTSEspeakNG : public TTSExes
28{
29 Q_OBJECT
30 public:
31 TTSEspeakNG(QObject* parent=nullptr) : TTSExes(parent)
32 {
33 m_name = "espeak-ng";
34
35 m_TTSTemplate = "\"%exe\" %options -w \"%wavfile\" -- \"%text\"";
36 m_TTSSpeakTemplate = "\"%exe\" %options -- \"%text\"";
37 m_capabilities = TTSBase::CanSpeak;
38 }
39};
40
41#endif
diff --git a/utils/rbutilqt/base/ttsexes.cpp b/utils/rbutilqt/base/ttsexes.cpp
new file mode 100644
index 0000000000..446725968f
--- /dev/null
+++ b/utils/rbutilqt/base/ttsexes.cpp
@@ -0,0 +1,127 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8*
9* Copyright (C) 2007 by Dominik Wenger
10*
11* All files in this archive are subject to the GNU General Public License.
12* See the file COPYING in the source tree root for full license agreement.
13*
14* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15* KIND, either express or implied.
16*
17****************************************************************************/
18
19#include <QtCore>
20#include "ttsexes.h"
21#include "utils.h"
22#include "rbsettings.h"
23#include "Logger.h"
24
25TTSExes::TTSExes(QObject* parent) : TTSBase(parent)
26{
27 /* default to espeak */
28 m_name = "espeak";
29 m_capabilities = TTSBase::CanSpeak;
30 m_TTSTemplate = "\"%exe\" %options -w \"%wavfile\" -- \"%text\"";
31 m_TTSSpeakTemplate = "\"%exe\" %options -- \"%text\"";
32}
33
34
35TTSBase::Capabilities TTSExes::capabilities()
36{
37 return m_capabilities;
38}
39
40void TTSExes::generateSettings()
41{
42 loadSettings();
43 insertSetting(eEXEPATH, new EncTtsSetting(this, EncTtsSetting::eSTRING,
44 tr("Path to TTS engine:"), m_TTSexec, EncTtsSetting::eBROWSEBTN));
45 insertSetting(eOPTIONS, new EncTtsSetting(this, EncTtsSetting::eSTRING,
46 tr("TTS engine options:"), m_TTSOpts));
47}
48
49void TTSExes::saveSettings()
50{
51 RbSettings::setSubValue(m_name, RbSettings::TtsPath,
52 getSetting(eEXEPATH)->current().toString());
53 RbSettings::setSubValue(m_name, RbSettings::TtsOptions,
54 getSetting(eOPTIONS)->current().toString());
55 RbSettings::sync();
56}
57
58
59void TTSExes::loadSettings(void)
60{
61 m_TTSexec = RbSettings::subValue(m_name, RbSettings::TtsPath).toString();
62 if(m_TTSexec.isEmpty()) m_TTSexec = Utils::findExecutable(m_name);
63 m_TTSOpts = RbSettings::subValue(m_name, RbSettings::TtsOptions).toString();
64}
65
66
67bool TTSExes::start(QString *errStr)
68{
69 loadSettings();
70
71 QFileInfo tts(m_TTSexec);
72 if(tts.exists())
73 {
74 return true;
75 }
76 else
77 {
78 *errStr = tr("TTS executable not found");
79 return false;
80 }
81}
82
83TTSStatus TTSExes::voice(QString text, QString wavfile, QString *errStr)
84{
85 (void) errStr;
86 QString execstring;
87 if(wavfile.isEmpty() && m_capabilities & TTSBase::CanSpeak) {
88 if(m_TTSSpeakTemplate.isEmpty()) {
89 LOG_ERROR() << "internal error: TTS announces CanSpeak "
90 "but template empty!";
91 return FatalError;
92 }
93 execstring = m_TTSSpeakTemplate;
94 }
95 else if(wavfile.isEmpty()) {
96 LOG_ERROR() << "no output file passed to voice() "
97 "but TTS can't speak directly.";
98 return FatalError;
99 }
100 else {
101 execstring = m_TTSTemplate;
102 }
103
104 execstring.replace("%exe",m_TTSexec);
105 execstring.replace("%options",m_TTSOpts);
106 execstring.replace("%wavfile",wavfile);
107 execstring.replace("%text",text);
108
109 QProcess::execute(execstring);
110
111 if(!wavfile.isEmpty() && !QFileInfo(wavfile).isFile()) {
112 LOG_ERROR() << "output file does not exist:" << wavfile;
113 return FatalError;
114 }
115 return NoError;
116
117}
118
119bool TTSExes::configOk()
120{
121 loadSettings();
122 if (QFileInfo::exists(m_TTSexec))
123 return true;
124 else
125 return false;
126}
127
diff --git a/utils/rbutilqt/base/ttsexes.h b/utils/rbutilqt/base/ttsexes.h
new file mode 100644
index 0000000000..5707c827fe
--- /dev/null
+++ b/utils/rbutilqt/base/ttsexes.h
@@ -0,0 +1,61 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8*
9* Copyright (C) 2009 by Dominik Wenger
10*
11* This program is free software; you can redistribute it and/or
12* modify it under the terms of the GNU General Public License
13* as published by the Free Software Foundation; either version 2
14* of the License, or (at your option) any later version.
15*
16* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17* KIND, either express or implied.
18*
19****************************************************************************/
20
21#ifndef TTSEXES_H
22#define TTSEXES_H
23
24#include <QtCore>
25#include "ttsbase.h"
26
27class TTSExes : public TTSBase
28{
29 enum ESettings
30 {
31 eEXEPATH,
32 eOPTIONS
33 };
34
35 Q_OBJECT
36 public:
37 TTSExes(QObject* parent=nullptr);
38 TTSStatus voice(QString text, QString wavfile, QString *errStr);
39 bool start(QString *errStr);
40 bool stop() {return true;}
41 QString voiceVendor(void) { return QString(); }
42 Capabilities capabilities();
43
44 // for settings
45 void generateSettings();
46 void saveSettings();
47 bool configOk();
48
49 private:
50 void loadSettings(void);
51
52 protected:
53 QString m_TTSTemplate;
54 QString m_TTSSpeakTemplate;
55 QString m_name;
56 QString m_TTSexec;
57 QString m_TTSOpts;
58 TTSBase::Capabilities m_capabilities;
59};
60
61#endif
diff --git a/utils/rbutilqt/base/ttsfestival.cpp b/utils/rbutilqt/base/ttsfestival.cpp
new file mode 100644
index 0000000000..d0ca400909
--- /dev/null
+++ b/utils/rbutilqt/base/ttsfestival.cpp
@@ -0,0 +1,412 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8*
9* Copyright (C) 2007 by Dominik Wenger
10*
11* All files in this archive are subject to the GNU General Public License.
12* See the file COPYING in the source tree root for full license agreement.
13*
14* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15* KIND, either express or implied.
16*
17****************************************************************************/
18
19#include <QtCore>
20#include <QTcpSocket>
21
22#include "ttsfestival.h"
23#include "utils.h"
24#include "rbsettings.h"
25#include "Logger.h"
26
27TTSFestival::~TTSFestival()
28{
29 LOG_INFO() << "Destroying instance";
30 stop();
31}
32
33TTSBase::Capabilities TTSFestival::capabilities()
34{
35 return RunInParallel;
36}
37
38void TTSFestival::generateSettings()
39{
40 // server path
41 QString exepath = RbSettings::subValue("festival-server",
42 RbSettings::TtsPath).toString();
43 if(exepath == "" ) exepath = Utils::findExecutable("festival");
44 insertSetting(eSERVERPATH,new EncTtsSetting(this,
45 EncTtsSetting::eSTRING, "Path to Festival server:",
46 exepath,EncTtsSetting::eBROWSEBTN));
47
48 // client path
49 QString clientpath = RbSettings::subValue("festival-client",
50 RbSettings::TtsPath).toString();
51 if(clientpath == "" ) clientpath = Utils::findExecutable("festival_client");
52 insertSetting(eCLIENTPATH,new EncTtsSetting(this,EncTtsSetting::eSTRING,
53 tr("Path to Festival client:"),
54 clientpath,EncTtsSetting::eBROWSEBTN));
55
56 // voice
57 EncTtsSetting* setting = new EncTtsSetting(this,
58 EncTtsSetting::eSTRINGLIST, tr("Voice:"),
59 RbSettings::subValue("festival", RbSettings::TtsVoice),
60 getVoiceList(), EncTtsSetting::eREFRESHBTN);
61 connect(setting, &EncTtsSetting::refresh,
62 this, &TTSFestival::updateVoiceList);
63 connect(setting, &EncTtsSetting::dataChanged,
64 this, &TTSFestival::clearVoiceDescription);
65 insertSetting(eVOICE,setting);
66
67 //voice description
68 setting = new EncTtsSetting(this,EncTtsSetting::eREADONLYSTRING,
69 tr("Voice description:"),"",EncTtsSetting::eREFRESHBTN);
70 connect(setting, &EncTtsSetting::refresh,
71 this, &TTSFestival::updateVoiceDescription);
72 insertSetting(eVOICEDESC,setting);
73}
74
75void TTSFestival::saveSettings()
76{
77 //save settings in user config
78 RbSettings::setSubValue("festival-server",
79 RbSettings::TtsPath,getSetting(eSERVERPATH)->current().toString());
80 RbSettings::setSubValue("festival-client",
81 RbSettings::TtsPath,getSetting(eCLIENTPATH)->current().toString());
82 RbSettings::setSubValue("festival",
83 RbSettings::TtsVoice,getSetting(eVOICE)->current().toString());
84
85 RbSettings::sync();
86}
87
88void TTSFestival::updateVoiceDescription()
89{
90 // get voice Info with current voice and path
91 currentPath = getSetting(eSERVERPATH)->current().toString();
92 QString info = getVoiceInfo(getSetting(eVOICE)->current().toString());
93 currentPath = "";
94
95 getSetting(eVOICEDESC)->setCurrent(info);
96}
97
98void TTSFestival::clearVoiceDescription()
99{
100 getSetting(eVOICEDESC)->setCurrent("");
101}
102
103void TTSFestival::updateVoiceList()
104{
105 currentPath = getSetting(eSERVERPATH)->current().toString();
106 QStringList voiceList = getVoiceList();
107 currentPath = "";
108
109 getSetting(eVOICE)->setList(voiceList);
110 if(voiceList.size() > 0) getSetting(eVOICE)->setCurrent(voiceList.at(0));
111 else getSetting(eVOICE)->setCurrent("");
112}
113
114void TTSFestival::startServer()
115{
116 if(!configOk())
117 return;
118
119 if(serverProcess.state() != QProcess::Running)
120 {
121 QString path;
122 /* currentPath is set by the GUI - if it's set, it is the currently set
123 path in the configuration GUI; if it's not set, use the saved path */
124 if (currentPath == "")
125 path = RbSettings::subValue("festival-server",RbSettings::TtsPath).toString();
126 else
127 path = currentPath;
128
129 serverProcess.start(QString("%1 --server").arg(path));
130 serverProcess.waitForStarted();
131
132 /* A friendlier version of a spinlock */
133 while (serverProcess.processId() == 0 && serverProcess.state() != QProcess::Running)
134 QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
135
136 if(serverProcess.state() == QProcess::Running)
137 LOG_INFO() << "Server is up and running";
138 else
139 LOG_ERROR() << "Server failed to start, state:"
140 << serverProcess.state();
141 }
142}
143
144bool TTSFestival::ensureServerRunning()
145{
146 if(serverProcess.state() != QProcess::Running)
147 {
148 startServer();
149 }
150 return serverProcess.state() == QProcess::Running;
151}
152
153bool TTSFestival::start(QString* errStr)
154{
155 LOG_INFO() << "Starting server with voice"
156 << RbSettings::subValue("festival", RbSettings::TtsVoice).toString();
157
158 bool running = ensureServerRunning();
159 if (!RbSettings::subValue("festival",RbSettings::TtsVoice).toString().isEmpty())
160 {
161 /* There's no harm in using both methods to set the voice .. */
162 QString voiceSelect = QString("(voice.select '%1)\n")
163 .arg(RbSettings::subValue("festival", RbSettings::TtsVoice).toString());
164 queryServer(voiceSelect, 3000);
165
166 if(prologFile.open())
167 {
168 prologFile.write(voiceSelect.toLatin1());
169 prologFile.close();
170 prologPath = QFileInfo(prologFile).absoluteFilePath();
171 LOG_INFO() << "Prolog created at" << prologPath;
172 }
173
174 }
175
176 if (!running)
177 (*errStr) = "Festival could not be started";
178 return running;
179}
180
181bool TTSFestival::stop()
182{
183 serverProcess.terminate();
184 serverProcess.kill();
185
186 return true;
187}
188
189TTSStatus TTSFestival::voice(QString text, QString wavfile, QString* errStr)
190{
191 LOG_INFO() << "Voicing" << text << "->" << wavfile;
192
193 QString path = RbSettings::subValue("festival-client",
194 RbSettings::TtsPath).toString();
195 QString cmd = QString("%1 --server localhost --otype riff --ttw --withlisp"
196 " --output \"%2\" --prolog \"%3\" - ").arg(path).arg(wavfile).arg(prologPath);
197 LOG_INFO() << "Client cmd:" << cmd;
198
199 QProcess clientProcess;
200 clientProcess.start(cmd);
201 clientProcess.write(QString("%1.\n").arg(text).toLatin1());
202 clientProcess.waitForBytesWritten();
203 clientProcess.closeWriteChannel();
204 clientProcess.waitForReadyRead();
205 QString response = clientProcess.readAll();
206 response = response.trimmed();
207 if(!response.contains("Utterance"))
208 {
209 LOG_WARNING() << "Could not voice string: " << response;
210 *errStr = tr("engine could not voice string");
211 return Warning;
212 /* do not stop the voicing process because of a single string
213 TODO: needs proper settings */
214 }
215 clientProcess.closeReadChannel(QProcess::StandardError);
216 clientProcess.closeReadChannel(QProcess::StandardOutput);
217 clientProcess.terminate();
218 clientProcess.kill();
219
220 return NoError;
221}
222
223bool TTSFestival::configOk()
224{
225 bool ret;
226 if (currentPath == "")
227 {
228 QString serverPath = RbSettings::subValue("festival-server",
229 RbSettings::TtsPath).toString();
230 QString clientPath = RbSettings::subValue("festival-client",
231 RbSettings::TtsPath).toString();
232
233 ret = QFileInfo(serverPath).isExecutable() &&
234 QFileInfo(clientPath).isExecutable();
235 if(RbSettings::subValue("festival",RbSettings::TtsVoice).toString().size() > 0
236 && voices.size() > 0)
237 ret = ret && (voices.indexOf(RbSettings::subValue("festival",
238 RbSettings::TtsVoice).toString()) != -1);
239 }
240 else /* If we're currently configuring the server, we need to know that
241 the entered path is valid */
242 ret = QFileInfo(currentPath).isExecutable();
243
244 return ret;
245}
246
247QStringList TTSFestival::getVoiceList()
248{
249 if(!configOk())
250 return QStringList();
251
252 if(voices.size() > 0)
253 {
254 LOG_INFO() << "Using voice cache";
255 return voices;
256 }
257
258 QString response = queryServer("(voice.list)", 10000);
259
260 // get the 2nd line. It should be (<voice_name>, <voice_name>)
261 response = response.mid(response.indexOf('\n') + 1, -1);
262 response = response.left(response.indexOf('\n')).trimmed();
263
264 voices = response.mid(1, response.size()-2).split(' ');
265
266 voices.sort();
267 if (voices.size() == 1 && voices[0].size() == 0)
268 voices.removeAt(0);
269 if (voices.size() > 0)
270 LOG_INFO() << "Voices:" << voices;
271 else
272 LOG_WARNING() << "No voices. Response was:" << response;
273
274 return voices;
275}
276
277QString TTSFestival::getVoiceInfo(QString voice)
278{
279 if(!configOk())
280 return "";
281
282 if(!getVoiceList().contains(voice))
283 return "";
284
285 if(voiceDescriptions.contains(voice))
286 return voiceDescriptions[voice];
287
288 QString response = queryServer(QString("(voice.description '%1)").arg(voice),
289 10000);
290
291 if (response == "")
292 {
293 voiceDescriptions[voice]=tr("No description available");
294 }
295 else
296 {
297 response = response.remove(QRegExp("(description \"*\")",
298 Qt::CaseInsensitive, QRegExp::Wildcard));
299 LOG_INFO() << "voiceInfo w/o descr:" << response;
300 response = response.remove(')');
301#if QT_VERSION >= 0x050e00
302 QStringList responseLines = response.split('(', Qt::SkipEmptyParts);
303#else
304 QStringList responseLines = response.split('(', QString::SkipEmptyParts);
305#endif
306 responseLines.removeAt(0); // the voice name itself
307
308 QString description;
309 foreach(QString line, responseLines)
310 {
311 line = line.remove('(');
312 line = line.simplified();
313
314 line[0] = line[0].toUpper(); // capitalize the key
315
316 int firstSpace = line.indexOf(' ');
317 if (firstSpace > 0)
318 {
319 // add a colon between the key and the value
320 line = line.insert(firstSpace, ':');
321 // capitalize the value
322 line[firstSpace+2] = line[firstSpace+2].toUpper();
323 }
324
325 description += line + "\n";
326 }
327 voiceDescriptions[voice] = description.trimmed();
328 }
329
330 return voiceDescriptions[voice];
331}
332
333QString TTSFestival::queryServer(QString query, int timeout)
334{
335 if(!configOk())
336 return "";
337
338 // this operation could take some time
339 emit busy();
340
341 LOG_INFO() << "queryServer with" << query;
342
343 if (!ensureServerRunning())
344 {
345 LOG_ERROR() << "queryServer: ensureServerRunning failed";
346 emit busyEnd();
347 return "";
348 }
349
350 QString response;
351
352 QDateTime endTime;
353 if(timeout > 0)
354 endTime = QDateTime::currentDateTime().addMSecs(timeout);
355
356 /* Festival is *extremely* unreliable. Although at this
357 * point we are sure that SIOD is accepting commands,
358 * we might end up with an empty response. Hence, the loop.
359 */
360 while(true)
361 {
362 QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
363 QTcpSocket socket;
364
365 socket.connectToHost("localhost", 1314);
366 socket.waitForConnected();
367
368 if(socket.state() == QAbstractSocket::ConnectedState)
369 {
370 socket.write(QString("%1\n").arg(query).toLatin1());
371 socket.waitForBytesWritten();
372 socket.waitForReadyRead();
373
374 response = socket.readAll().trimmed();
375
376 if (response != "LP" && response != "")
377 break;
378 }
379 socket.abort();
380 socket.disconnectFromHost();
381
382 if(timeout > 0 && QDateTime::currentDateTime() >= endTime)
383 {
384 emit busyEnd();
385 return "";
386 }
387 /* make sure we wait a little as we don't want to flood the server
388 * with requests */
389 QDateTime tmpEndTime = QDateTime::currentDateTime().addMSecs(500);
390 while(QDateTime::currentDateTime() < tmpEndTime)
391 QCoreApplication::processEvents(QEventLoop::AllEvents);
392 }
393 if(response == "nil")
394 {
395 emit busyEnd();
396 return "";
397 }
398
399 QStringList lines = response.split('\n');
400 if(lines.size() > 2)
401 {
402 lines.removeFirst(); /* should be LP */
403 lines.removeLast(); /* should be ft_StUfF_keyOK */
404 }
405 else
406 LOG_ERROR() << "Response too short:" << response;
407
408 emit busyEnd();
409 return lines.join("\n");
410
411}
412
diff --git a/utils/rbutilqt/base/ttsfestival.h b/utils/rbutilqt/base/ttsfestival.h
new file mode 100644
index 0000000000..5f6dc13ab5
--- /dev/null
+++ b/utils/rbutilqt/base/ttsfestival.h
@@ -0,0 +1,72 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8*
9* Copyright (C) 2009 by Dominik Wenger
10*
11* This program is free software; you can redistribute it and/or
12* modify it under the terms of the GNU General Public License
13* as published by the Free Software Foundation; either version 2
14* of the License, or (at your option) any later version.
15*
16* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17* KIND, either express or implied.
18*
19****************************************************************************/
20
21#ifndef TTSFESTIVAL_H
22#define TTSFESTIVAL_H
23
24#include <QTemporaryFile>
25#include "ttsbase.h"
26
27class TTSFestival : public TTSBase
28{
29 enum ESettings
30 {
31 eSERVERPATH,
32 eCLIENTPATH,
33 eVOICE,
34 eVOICEDESC
35 };
36
37 Q_OBJECT
38 public:
39 TTSFestival(QObject* parent=nullptr) : TTSBase(parent) {}
40 ~TTSFestival();
41 bool start(QString *errStr);
42 bool stop();
43 TTSStatus voice(QString text,QString wavfile, QString *errStr);
44 QString voiceVendor(void) { return QString(); }
45 Capabilities capabilities();
46
47 // for settings
48 bool configOk();
49 void generateSettings();
50 void saveSettings();
51
52 private slots:
53 void updateVoiceList();
54 void updateVoiceDescription();
55 void clearVoiceDescription();
56 private:
57 QTemporaryFile prologFile;
58 QString prologPath;
59 QString currentPath;
60 QStringList getVoiceList();
61 QString getVoiceInfo(QString voice);
62
63 inline void startServer();
64 inline bool ensureServerRunning();
65 QString queryServer(QString query, int timeout = -1);
66 QProcess serverProcess;
67 QStringList voices;
68 QMap<QString, QString> voiceDescriptions;
69};
70
71
72#endif
diff --git a/utils/rbutilqt/base/ttsflite.h b/utils/rbutilqt/base/ttsflite.h
new file mode 100644
index 0000000000..717c311a34
--- /dev/null
+++ b/utils/rbutilqt/base/ttsflite.h
@@ -0,0 +1,43 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8*
9* Copyright (C) 2012 by Dominik Riebeling
10*
11* This program is free software; you can redistribute it and/or
12* modify it under the terms of the GNU General Public License
13* as published by the Free Software Foundation; either version 2
14* of the License, or (at your option) any later version.
15*
16* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17* KIND, either express or implied.
18*
19****************************************************************************/
20
21#ifndef TTSFLITE_H
22#define TTSFLITE_H
23
24#include <QtCore>
25#include "ttsexes.h"
26
27class TTSFlite : public TTSExes
28{
29 Q_OBJECT
30 public:
31 TTSFlite(QObject* parent=nullptr) : TTSExes(parent)
32 {
33 m_name = "flite";
34
35 /* default to espeak */
36 m_TTSTemplate = "\"%exe\" %options -o \"%wavfile\" -t \"%text\"";
37 m_TTSSpeakTemplate = "";
38 m_capabilities = TTSBase::None;
39
40 }
41};
42
43#endif
diff --git a/utils/rbutilqt/base/ttsmimic.h b/utils/rbutilqt/base/ttsmimic.h
new file mode 100644
index 0000000000..f4d7a8beac
--- /dev/null
+++ b/utils/rbutilqt/base/ttsmimic.h
@@ -0,0 +1,41 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8*
9* Copyright (C) 2020 by Solomon Peachy
10*
11* This program is free software; you can redistribute it and/or
12* modify it under the terms of the GNU General Public License
13* as published by the Free Software Foundation; either version 2
14* of the License, or (at your option) any later version.
15*
16* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17* KIND, either express or implied.
18*
19****************************************************************************/
20
21#ifndef TTSMIMIC_H
22#define TTSMIMIC_H
23
24#include <QtCore>
25#include "ttsexes.h"
26
27class TTSMimic : public TTSExes
28{
29 Q_OBJECT
30 public:
31 TTSMimic(QObject* parent=nullptr) : TTSExes(parent)
32 {
33 m_name = "mimic";
34
35 m_TTSTemplate = "\"%exe\" %options -o \"%wavfile\" -t \"%text\"";
36 m_TTSSpeakTemplate = "\"%exe\" %options -t \"%text\"";
37 m_capabilities = TTSBase::CanSpeak;
38 }
39};
40
41#endif
diff --git a/utils/rbutilqt/base/ttsmssp.h b/utils/rbutilqt/base/ttsmssp.h
new file mode 100644
index 0000000000..817b9fde58
--- /dev/null
+++ b/utils/rbutilqt/base/ttsmssp.h
@@ -0,0 +1,43 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8*
9* Copyright (C) 2012 by Dominik Riebeling
10*
11* This program is free software; you can redistribute it and/or
12* modify it under the terms of the GNU General Public License
13* as published by the Free Software Foundation; either version 2
14* of the License, or (at your option) any later version.
15*
16* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17* KIND, either express or implied.
18*
19****************************************************************************/
20
21#ifndef TTSMSSP_H
22#define TTSMSSP_H
23
24#include "ttsbase.h"
25#include "ttssapi.h"
26
27class TTSMssp: public TTSSapi
28{
29 Q_OBJECT
30 public:
31 TTSMssp(QObject* parent=nullptr) : TTSSapi(parent)
32 {
33 m_TTSTemplate = "cscript //nologo \"%exe\" "
34 "/language:%lang /voice:\"%voice\" "
35 "/speed:%speed \"%options\" /mssp";
36 m_TTSVoiceTemplate = "cscript //nologo \"%exe\" "
37 "/language:%lang /listvoices /mssp";
38 m_TTSType = "mssp";
39 }
40
41};
42
43#endif
diff --git a/utils/rbutilqt/base/ttssapi.cpp b/utils/rbutilqt/base/ttssapi.cpp
new file mode 100644
index 0000000000..1b326b301e
--- /dev/null
+++ b/utils/rbutilqt/base/ttssapi.cpp
@@ -0,0 +1,274 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8*
9* Copyright (C) 2007 by Dominik Wenger
10*
11* All files in this archive are subject to the GNU General Public License.
12* See the file COPYING in the source tree root for full license agreement.
13*
14* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15* KIND, either express or implied.
16*
17****************************************************************************/
18
19#include "ttssapi.h"
20#include "utils.h"
21#include "rbsettings.h"
22#include "playerbuildinfo.h"
23#include "Logger.h"
24
25TTSSapi::TTSSapi(QObject* parent) : TTSBase(parent)
26{
27 m_TTSTemplate = "cscript //nologo \"%exe\" /language:%lang "
28 "/voice:\"%voice\" /speed:%speed \"%options\"";
29 m_TTSVoiceTemplate = "cscript //nologo \"%exe\" /language:%lang /listvoices";
30 m_TTSType = "sapi";
31 defaultLanguage = "english";
32 m_started = false;
33}
34
35TTSBase::Capabilities TTSSapi::capabilities()
36{
37 return None;
38}
39
40void TTSSapi::generateSettings()
41{
42 // language
43 QMap<QString, QVariant> langmap = PlayerBuildInfo::instance()->value(
44 PlayerBuildInfo::LanguageList).toMap();
45 EncTtsSetting* setting = new EncTtsSetting(this,
46 EncTtsSetting::eSTRINGLIST, tr("Language:"),
47 RbSettings::subValue(m_TTSType, RbSettings::TtsLanguage),
48 langmap.keys());
49 connect(setting, &EncTtsSetting::dataChanged, this, &TTSSapi::updateVoiceList);
50 insertSetting(eLANGUAGE,setting);
51 // voice
52 setting = new EncTtsSetting(this,
53 EncTtsSetting::eSTRINGLIST, tr("Voice:"),
54 RbSettings::subValue(m_TTSType, RbSettings::TtsVoice),
55 getVoiceList(RbSettings::subValue(m_TTSType,
56 RbSettings::TtsLanguage).toString()),
57 EncTtsSetting::eREFRESHBTN);
58 connect(setting, &EncTtsSetting::refresh, this, &TTSSapi::updateVoiceList);
59 insertSetting(eVOICE,setting);
60 //speed
61 int speed = RbSettings::subValue(m_TTSType, RbSettings::TtsSpeed).toInt();
62 if(speed > 10 || speed < -10)
63 speed = 0;
64 insertSetting(eSPEED, new EncTtsSetting(this,
65 EncTtsSetting::eINT, tr("Speed:"), speed, -10, 10));
66 // options
67 insertSetting(eOPTIONS, new EncTtsSetting(this,
68 EncTtsSetting::eSTRING, tr("Options:"),
69 RbSettings::subValue(m_TTSType, RbSettings::TtsOptions)));
70
71}
72
73void TTSSapi::saveSettings()
74{
75 //save settings in user config
76 RbSettings::setSubValue(m_TTSType, RbSettings::TtsLanguage,
77 getSetting(eLANGUAGE)->current().toString());
78 RbSettings::setSubValue(m_TTSType, RbSettings::TtsVoice,
79 getSetting(eVOICE)->current().toString());
80 RbSettings::setSubValue(m_TTSType, RbSettings::TtsSpeed,
81 getSetting(eSPEED)->current().toInt());
82 RbSettings::setSubValue(m_TTSType, RbSettings::TtsOptions,
83 getSetting(eOPTIONS)->current().toString());
84
85 RbSettings::sync();
86}
87
88void TTSSapi::updateVoiceList()
89{
90 LOG_INFO() << "updating voicelist";
91 QStringList voiceList = getVoiceList(getSetting(eLANGUAGE)->current().toString());
92 getSetting(eVOICE)->setList(voiceList);
93 if(voiceList.size() > 0) getSetting(eVOICE)->setCurrent(voiceList.at(0));
94 else getSetting(eVOICE)->setCurrent("");
95}
96
97bool TTSSapi::start(QString *errStr)
98{
99
100 m_TTSOpts = RbSettings::subValue(m_TTSType, RbSettings::TtsOptions).toString();
101 m_TTSLanguage =RbSettings::subValue(m_TTSType, RbSettings::TtsLanguage).toString();
102 m_TTSVoice=RbSettings::subValue(m_TTSType, RbSettings::TtsVoice).toString();
103 m_TTSSpeed=RbSettings::subValue(m_TTSType, RbSettings::TtsSpeed).toString();
104
105 QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
106 QFile::copy(":/builtin/sapi_voice.vbs",QDir::tempPath() + "/sapi_voice.vbs");
107 m_TTSexec = QDir::tempPath() +"/sapi_voice.vbs";
108
109 QFileInfo tts(m_TTSexec);
110 if(!tts.exists())
111 {
112 *errStr = tr("Could not copy the SAPI script");
113 return false;
114 }
115 // create the voice process
116 QString execstring = m_TTSTemplate;
117 execstring.replace("%exe",m_TTSexec);
118 execstring.replace("%options",m_TTSOpts);
119 execstring.replace("%lang",m_TTSLanguage);
120 execstring.replace("%voice",m_TTSVoice);
121 execstring.replace("%speed",m_TTSSpeed);
122
123 LOG_INFO() << "Start:" << execstring;
124 voicescript = new QProcess(nullptr);
125 //connect(voicescript,SIGNAL(readyReadStandardError()),this,SLOT(error()));
126 voicescript->start(execstring);
127 LOG_INFO() << "wait for process";
128 if(!voicescript->waitForStarted())
129 {
130 *errStr = tr("Could not start SAPI process");
131 LOG_ERROR() << "starting process timed out!";
132 return false;
133 }
134
135 if(!voicescript->waitForReadyRead(300))
136 {
137 *errStr = voicescript->readAllStandardError();
138 if(*errStr != "")
139 return false;
140 }
141
142 voicestream = new QTextStream(voicescript);
143#if QT_VERSION < 0x060000
144 voicestream->setCodec("UTF16-LE");
145#else
146 voicestream->setEncoding(QStringConverter::Utf16LE);
147#endif
148
149 m_started = true;
150 return true;
151}
152
153QString TTSSapi::voiceVendor(void)
154{
155 bool keeprunning = m_started;
156 QString vendor;
157 if(!m_started) {
158 QString error;
159 start(&error);
160 }
161 *voicestream << "QUERY\tVENDOR\r\n";
162 voicestream->flush();
163 while((vendor = voicestream->readLine()).isEmpty())
164 QCoreApplication::processEvents();
165
166 LOG_INFO() << "TTS vendor:" << vendor;
167 if(!keeprunning) {
168 stop();
169 }
170 return vendor;
171}
172
173QStringList TTSSapi::getVoiceList(QString language)
174{
175 QStringList result;
176
177 QFile::copy(":/builtin/sapi_voice.vbs",QDir::tempPath() + "/sapi_voice.vbs");
178 m_TTSexec = QDir::tempPath() +"/sapi_voice.vbs";
179
180 QFileInfo tts(m_TTSexec);
181 if(!tts.exists())
182 return result;
183
184 // create the voice process
185 QString execstring = m_TTSVoiceTemplate;
186 execstring.replace("%exe",m_TTSexec);
187 execstring.replace("%lang",language);
188
189 LOG_INFO() << "Start:" << execstring;
190 voicescript = new QProcess(nullptr);
191 voicescript->start(execstring);
192 LOG_INFO() << "wait for process";
193 if(!voicescript->waitForStarted()) {
194 LOG_INFO() << "process startup timed out!";
195 return result;
196 }
197 voicescript->closeWriteChannel();
198 voicescript->waitForReadyRead();
199
200 QString dataRaw = voicescript->readAllStandardError().data();
201 if(dataRaw.startsWith("Error")) {
202 LOG_INFO() << "Error:" << dataRaw;
203 }
204#if QT_VERSION >= 0x050e00
205 result = dataRaw.split(";", Qt::SkipEmptyParts);
206#else
207 result = dataRaw.split(";", QString::SkipEmptyParts);
208#endif
209 if(result.size() > 0)
210 {
211 result.sort();
212 result.removeFirst();
213 for(int i = 0; i< result.size();i++)
214 {
215 result[i] = result.at(i).simplified();
216 }
217 }
218
219 delete voicescript;
220 QFile::setPermissions(QDir::tempPath() +"/sapi_voice.vbs",
221 QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner
222 | QFile::ReadUser | QFile::WriteUser | QFile::ExeUser
223 | QFile::ReadGroup | QFile::WriteGroup | QFile::ExeGroup
224 | QFile::ReadOther | QFile::WriteOther | QFile::ExeOther );
225 QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
226 return result;
227}
228
229
230
231TTSStatus TTSSapi::voice(QString text,QString wavfile, QString *errStr)
232{
233 (void) errStr;
234 QString query = "SPEAK\t"+wavfile+"\t"+text;
235 LOG_INFO() << "voicing" << query;
236 // append newline to query. Done now to keep debug output more readable.
237 query.append("\r\n");
238 *voicestream << query;
239 *voicestream << "SYNC\tbla\r\n";
240 voicestream->flush();
241 // do NOT poll the output with readLine(), this causes sync issues!
242 voicescript->waitForReadyRead();
243
244 if(!QFileInfo(wavfile).isFile()) {
245 LOG_ERROR() << "output file does not exist:" << wavfile;
246 return FatalError;
247 }
248 return NoError;
249}
250
251bool TTSSapi::stop()
252{
253 *voicestream << "QUIT\r\n";
254 voicestream->flush();
255 voicescript->waitForFinished();
256 delete voicestream;
257 delete voicescript;
258 QFile::setPermissions(QDir::tempPath() +"/sapi_voice.vbs",
259 QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner
260 | QFile::ReadUser | QFile::WriteUser | QFile::ExeUser
261 | QFile::ReadGroup | QFile::WriteGroup | QFile::ExeGroup
262 | QFile::ReadOther | QFile::WriteOther | QFile::ExeOther );
263 QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
264 m_started = false;
265 return true;
266}
267
268bool TTSSapi::configOk()
269{
270 if(RbSettings::subValue(m_TTSType, RbSettings::TtsVoice).toString().isEmpty())
271 return false;
272 return true;
273}
274
diff --git a/utils/rbutilqt/base/ttssapi.h b/utils/rbutilqt/base/ttssapi.h
new file mode 100644
index 0000000000..25d7d3dab7
--- /dev/null
+++ b/utils/rbutilqt/base/ttssapi.h
@@ -0,0 +1,77 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8*
9* Copyright (C) 2009 by Dominik Wenger
10*
11* This program is free software; you can redistribute it and/or
12* modify it under the terms of the GNU General Public License
13* as published by the Free Software Foundation; either version 2
14* of the License, or (at your option) any later version.
15*
16* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17* KIND, either express or implied.
18*
19****************************************************************************/
20
21#ifndef TTSSAPI_H
22#define TTSSAPI_H
23
24#include "ttsbase.h"
25
26class TTSSapi : public TTSBase
27{
28 //! Enum to identify the settings
29 enum ESettings
30 {
31 eLANGUAGE,
32 eVOICE,
33 eSPEED,
34 eOPTIONS
35 };
36
37 Q_OBJECT
38 public:
39 TTSSapi(QObject* parent=nullptr);
40
41 TTSStatus voice(QString text,QString wavfile, QString *errStr);
42 bool start(QString *errStr);
43 bool stop();
44 QString voiceVendor(void);
45 Capabilities capabilities();
46
47 // for settings
48 bool configOk();
49 void generateSettings();
50 void saveSettings();
51
52 private slots:
53 void updateVoiceList();
54
55 private:
56 QStringList getVoiceList(QString language);
57
58 QProcess* voicescript;
59 QTextStream* voicestream;
60 QString defaultLanguage;
61
62 QString m_TTSexec;
63 QString m_TTSOpts;
64 QString m_TTSLanguage;
65 QString m_TTSVoice;
66 QString m_TTSSpeed;
67 bool m_started;
68
69 protected:
70 QString m_TTSTemplate;
71 QString m_TTSVoiceTemplate;
72 QString m_TTSType;
73};
74
75
76
77#endif
diff --git a/utils/rbutilqt/base/ttssapi4.h b/utils/rbutilqt/base/ttssapi4.h
new file mode 100644
index 0000000000..d6408eaa2c
--- /dev/null
+++ b/utils/rbutilqt/base/ttssapi4.h
@@ -0,0 +1,43 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8*
9* Copyright (C) 2012 by Dominik Riebeling
10*
11* This program is free software; you can redistribute it and/or
12* modify it under the terms of the GNU General Public License
13* as published by the Free Software Foundation; either version 2
14* of the License, or (at your option) any later version.
15*
16* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17* KIND, either express or implied.
18*
19****************************************************************************/
20
21#ifndef TTSSAPI4_H
22#define TTSSAPI4_H
23
24#include "ttsbase.h"
25#include "ttssapi.h"
26
27class TTSSapi4: public TTSSapi
28{
29 Q_OBJECT
30 public:
31 TTSSapi4(QObject* parent=nullptr) : TTSSapi(parent)
32 {
33 m_TTSTemplate = "cscript //nologo \"%exe\" "
34 "/language:%lang /voice:\"%voice\" "
35 "/speed:%speed \"%options\" /sapi4";
36 m_TTSVoiceTemplate = "cscript //nologo \"%exe\" "
37 "/language:%lang /listvoices /sapi4";
38 m_TTSType = "sapi4";
39 }
40
41};
42
43#endif
diff --git a/utils/rbutilqt/base/ttsswift.h b/utils/rbutilqt/base/ttsswift.h
new file mode 100644
index 0000000000..adbc674d78
--- /dev/null
+++ b/utils/rbutilqt/base/ttsswift.h
@@ -0,0 +1,40 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8*
9* Copyright (C) 2012 by Dominik Riebeling
10*
11* This program is free software; you can redistribute it and/or
12* modify it under the terms of the GNU General Public License
13* as published by the Free Software Foundation; either version 2
14* of the License, or (at your option) any later version.
15*
16* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17* KIND, either express or implied.
18*
19****************************************************************************/
20
21#ifndef TTSSWIFT_H
22#define TTSSWIFT_H
23
24#include <QtCore>
25#include "ttsexes.h"
26
27class TTSSwift : public TTSExes
28{
29 Q_OBJECT
30 public:
31 TTSSwift(QObject* parent=nullptr) : TTSExes(parent)
32 {
33 m_name = "swift";
34 m_TTSTemplate = "\"%exe\" %options -o \"%wavfile\" -- \"%text\"";
35 m_TTSSpeakTemplate = "";
36 m_capabilities = TTSBase::None;
37 }
38};
39
40#endif
diff --git a/utils/rbutilqt/base/uninstall.cpp b/utils/rbutilqt/base/uninstall.cpp
new file mode 100644
index 0000000000..5ab670a031
--- /dev/null
+++ b/utils/rbutilqt/base/uninstall.cpp
@@ -0,0 +1,126 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include "uninstall.h"
21#include "utils.h"
22#include "Logger.h"
23
24Uninstaller::Uninstaller(QObject* parent,QString mountpoint): QObject(parent)
25{
26 m_mountpoint = mountpoint;
27}
28
29void Uninstaller::deleteAll(void)
30{
31 QString rbdir(m_mountpoint + ".rockbox/");
32 emit logItem(tr("Starting Uninstallation"), LOGINFO);
33 emit logProgress(0, 0);
34 Utils::recursiveRmdir(rbdir);
35 emit logProgress(1, 1);
36 emit logItem(tr("Finished Uninstallation"), LOGOK);
37 emit logFinished();
38}
39
40void Uninstaller::uninstall(void)
41{
42 emit logProgress(0, 0);
43 emit logItem(tr("Starting Uninstallation"), LOGINFO);
44
45 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, this);
46
47 for(int i=0; i< uninstallSections.size() ; i++)
48 {
49 emit logItem(tr("Uninstalling %1...").arg(uninstallSections.at(i)), LOGINFO);
50 QCoreApplication::processEvents();
51 // create list of all other install sections
52 QStringList sections = installlog.childGroups();
53 sections.removeAt(sections.indexOf(uninstallSections.at(i)));
54 installlog.beginGroup(uninstallSections.at(i));
55 QStringList toDeleteList = installlog.allKeys();
56 QStringList dirList;
57 installlog.endGroup();
58
59 // iterate over all entries
60 for(int j =0; j < toDeleteList.size(); j++ )
61 {
62 // check if current file is in use by another section
63 bool deleteFile = true;
64 for(int s = 0; s < sections.size(); s++)
65 {
66 installlog.beginGroup(sections.at(s));
67 if(installlog.contains(toDeleteList.at(j)))
68 {
69 deleteFile = false;
70 LOG_INFO() << "file still in use:" << toDeleteList.at(j);
71 }
72 installlog.endGroup();
73 }
74
75 installlog.beginGroup(uninstallSections.at(i));
76 QFileInfo toDelete(m_mountpoint + "/" + toDeleteList.at(j));
77 if(toDelete.isFile()) // if it is a file remove it
78 {
79 if(deleteFile && !QFile::remove(toDelete.filePath()))
80 emit logItem(tr("Could not delete %1")
81 .arg(toDelete.filePath()), LOGWARNING);
82 installlog.remove(toDeleteList.at(j));
83 LOG_INFO() << "deleted:" << toDelete.filePath();
84 }
85 else // if it is a dir, remember it for later deletion
86 {
87 // no need to keep track on folders still in use -- only empty
88 // folders will be rm'ed.
89 dirList << toDeleteList.at(j);
90 }
91 installlog.endGroup();
92 QCoreApplication::processEvents();
93 }
94 // delete the dirs
95 installlog.beginGroup(uninstallSections.at(i));
96 for(int j=0; j < dirList.size(); j++ )
97 {
98 installlog.remove(dirList.at(j));
99 QDir dir(m_mountpoint);
100 dir.rmdir(dirList.at(j)); // rm works only on empty folders
101 }
102
103 installlog.endGroup();
104 //installlog.removeGroup(uninstallSections.at(i))
105 }
106 uninstallSections.clear();
107 installlog.sync();
108 emit logProgress(1, 1);
109 emit logItem(tr("Uninstallation finished"), LOGOK);
110 emit logFinished();
111}
112
113QStringList Uninstaller::getAllSections()
114{
115 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, nullptr);
116 QStringList allSections = installlog.childGroups();
117 allSections.removeAt(allSections.lastIndexOf("Bootloader"));
118 return allSections;
119}
120
121
122bool Uninstaller::uninstallPossible()
123{
124 return QFileInfo::exists(m_mountpoint +"/.rockbox/rbutil.log");
125}
126
diff --git a/utils/rbutilqt/base/uninstall.h b/utils/rbutilqt/base/uninstall.h
new file mode 100644
index 0000000000..d8c9815117
--- /dev/null
+++ b/utils/rbutilqt/base/uninstall.h
@@ -0,0 +1,63 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21
22#ifndef UNINSTALL_H
23#define UNINSTALL_H
24
25#include <QtCore>
26
27#include "progressloggerinterface.h"
28
29
30class Uninstaller : public QObject
31{
32 Q_OBJECT
33public:
34 Uninstaller(QObject* parent,QString mountpoint) ;
35 ~Uninstaller(){}
36
37 void deleteAll(void);
38 void uninstall(void);
39
40 bool uninstallPossible();
41
42 QStringList getAllSections();
43
44 void setSections(QStringList sections) {uninstallSections = sections;}
45
46signals:
47 void logItem(QString, int); //! set logger item
48 void logProgress(int, int); //! set progress bar.
49 void logFinished(void);
50
51private slots:
52
53
54private:
55 QString m_mountpoint;
56
57 QStringList uninstallSections;
58};
59
60
61
62#endif
63
diff --git a/utils/rbutilqt/base/utils.cpp b/utils/rbutilqt/base/utils.cpp
new file mode 100644
index 0000000000..f2d3f04887
--- /dev/null
+++ b/utils/rbutilqt/base/utils.cpp
@@ -0,0 +1,1062 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include "utils.h"
20#include "rockboxinfo.h"
21#include "system.h"
22#include "rbsettings.h"
23#include "playerbuildinfo.h"
24#include "Logger.h"
25
26#if !defined(_UNICODE)
27#define _UNICODE
28#endif
29
30#include <QtCore>
31#include <QDebug>
32#include <cstdlib>
33#include <stdio.h>
34
35#if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
36#include <sys/statvfs.h>
37#endif
38#if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
39#include <stdio.h>
40#endif
41#if defined(Q_OS_LINUX)
42#include <mntent.h>
43#endif
44#if defined(Q_OS_MACX) || defined(Q_OS_OPENBSD)
45#include <sys/param.h>
46#include <sys/ucred.h>
47#include <sys/mount.h>
48#endif
49#if defined(Q_OS_WIN32)
50#include <stdio.h>
51#include <tchar.h>
52#include <windows.h>
53#include <setupapi.h>
54#include <winioctl.h>
55#include <tlhelp32.h>
56#endif
57#if defined(Q_OS_MACX)
58#include <Carbon/Carbon.h>
59#include <CoreFoundation/CoreFoundation.h>
60#include <CoreServices/CoreServices.h>
61#include <IOKit/IOKitLib.h>
62#endif
63
64// recursive function to delete a dir with files
65bool Utils::recursiveRmdir( const QString &dirName )
66{
67 QString dirN = dirName;
68 QDir dir(dirN);
69 // make list of entries in directory
70 QStringList list = dir.entryList(QDir::AllEntries | QDir::NoDotAndDotDot);
71 QFileInfo fileInfo;
72 QString curItem;
73 for(int i = 0; i < list.size(); i++){ // loop through all items of list
74 QString name = list.at(i);
75 curItem = dirN + "/" + name;
76 fileInfo.setFile(curItem);
77 if(fileInfo.isDir()) // is directory
78 recursiveRmdir(curItem); // call recRmdir() recursively for
79 // deleting subdirectory
80 else // is file
81 QFile::remove(curItem); // ok, delete file
82 }
83 dir.cdUp();
84 return dir.rmdir(dirN); // delete empty dir and return if (now empty)
85 // dir-removing was successfull
86}
87
88
89//! @brief resolves the given path, ignoring case.
90//! @param path absolute path to resolve.
91//! @return returns exact casing of path, empty string if path not found.
92QString Utils::resolvePathCase(QString path)
93{
94 int start;
95 QString realpath;
96#if QT_VERSION >= 0x050e00
97 QStringList elems = path.split("/", Qt::SkipEmptyParts);
98#else
99 QStringList elems = path.split("/", QString::SkipEmptyParts);
100#endif
101
102 if(path.isEmpty())
103 return QString();
104#if defined(Q_OS_WIN32)
105 // on windows we must make sure to start with the first entry (i.e. the
106 // drive letter) instead of a single / to make resolving work.
107 start = 1;
108 realpath = elems.at(0) + "/";
109#else
110 start = 0;
111 realpath = "/";
112#endif
113
114 for(int i = start; i < elems.size(); i++) {
115 QStringList direlems
116 = QDir(realpath).entryList(QDir::AllEntries|QDir::Hidden|QDir::System);
117 if(direlems.contains(elems.at(i), Qt::CaseInsensitive)) {
118 // need to filter using QRegExp as QStringList::filter(QString)
119 // matches any substring
120 QString expr = QString("^" + elems.at(i) + "$");
121 QRegExp rx = QRegExp(expr, Qt::CaseInsensitive);
122 QStringList a = direlems.filter(rx);
123
124 if(a.size() != 1)
125 return QString("");
126 if(!realpath.endsWith("/"))
127 realpath += "/";
128 realpath += a.at(0);
129 }
130 else
131 return QString("");
132 }
133 LOG_INFO() << "resolving path" << path << "->" << realpath;
134 return realpath;
135}
136
137
138QString Utils::filesystemType(QString path)
139{
140#if defined(Q_OS_LINUX)
141 FILE *mn = setmntent("/etc/mtab", "r");
142 if(!mn)
143 return QString("");
144
145 struct mntent *ent;
146 while((ent = getmntent(mn))) {
147 if(QString(ent->mnt_dir) == path) {
148 endmntent(mn);
149 LOG_INFO() << "device type is" << ent->mnt_type;
150 return QString(ent->mnt_type);
151 }
152 }
153 endmntent(mn);
154#endif
155
156#if defined(Q_OS_MACX) || defined(Q_OS_OPENBSD)
157 int num;
158 struct statfs *mntinf;
159
160 num = getmntinfo(&mntinf, MNT_WAIT);
161 while(num--) {
162 if(QString(mntinf->f_mntonname) == path) {
163 LOG_INFO() << "device type is" << mntinf->f_fstypename;
164 return QString(mntinf->f_fstypename);
165 }
166 mntinf++;
167 }
168#endif
169
170#if defined(Q_OS_WIN32)
171 wchar_t t[64];
172 memset(t, 0, 32);
173 if(GetVolumeInformationW((LPCWSTR)path.utf16(),
174 NULL, 0, NULL, NULL, NULL, t, 64)) {
175 LOG_INFO() << "device type is" << t;
176 return QString::fromWCharArray(t);
177 }
178#endif
179 return QString("-");
180}
181
182
183QString Utils::filesystemName(QString path)
184{
185 QString name;
186#if defined(Q_OS_WIN32)
187 wchar_t volname[MAX_PATH+1];
188 bool res = GetVolumeInformationW((LPTSTR)path.utf16(), volname, MAX_PATH+1,
189 NULL, NULL, NULL, NULL, 0);
190 if(res) {
191 name = QString::fromWCharArray(volname);
192 }
193#endif
194#if defined(Q_OS_MACX)
195 // BSD label does not include folder.
196 QString bsd = Utils::resolveDevicename(path).remove("/dev/");
197 if(bsd.isEmpty()) {
198 return name;
199 }
200 OSStatus result;
201 ItemCount index = 1;
202
203 do {
204 FSVolumeRefNum volrefnum;
205 HFSUniStr255 volname;
206
207 result = FSGetVolumeInfo(kFSInvalidVolumeRefNum, index, &volrefnum,
208 kFSVolInfoFSInfo, NULL, &volname, NULL);
209
210 if(result == noErr) {
211 GetVolParmsInfoBuffer volparms;
212 /* PBHGetVolParmsSync() is not available for 64bit while
213 FSGetVolumeParms() is available in 10.5+. Thus we need to use
214 PBHGetVolParmsSync() for 10.4, and that also requires 10.4 to
215 always use 32bit.
216 Qt 4 supports 32bit on 10.6 Cocoa only.
217 */
218#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
219 if(FSGetVolumeParms(volrefnum, &volparms, sizeof(volparms)) == noErr)
220#else
221 HParamBlockRec hpb;
222 hpb.ioParam.ioNamePtr = NULL;
223 hpb.ioParam.ioVRefNum = volrefnum;
224 hpb.ioParam.ioBuffer = (Ptr)&volparms;
225 hpb.ioParam.ioReqCount = sizeof(volparms);
226 if(PBHGetVolParmsSync(&hpb) == noErr)
227#endif
228 {
229 if(volparms.vMServerAdr == 0) {
230 if(bsd == (char*)volparms.vMDeviceID) {
231 name = QString::fromUtf16((const ushort*)volname.unicode,
232 (int)volname.length);
233 break;
234 }
235 }
236 }
237 }
238 index++;
239 } while(result == noErr);
240#endif
241
242 LOG_INFO() << "Volume name of" << path << "is" << name;
243 return name;
244}
245
246
247//! @brief figure the free disk space on a filesystem
248//! @param path path on the filesystem to check
249//! @return size in bytes
250qulonglong Utils::filesystemFree(QString path)
251{
252 qulonglong size = filesystemSize(path, FilesystemFree);
253 LOG_INFO() << "free disk space for" << path << size;
254 return size;
255}
256
257
258qulonglong Utils::filesystemTotal(QString path)
259{
260 qulonglong size = filesystemSize(path, FilesystemTotal);
261 LOG_INFO() << "total disk space for" << path << size;
262 return size;
263}
264
265
266qulonglong Utils::filesystemSize(QString path, enum Utils::Size type)
267{
268 qulonglong size = 0;
269#if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
270 // the usage of statfs() is deprecated by the LSB so use statvfs().
271 struct statvfs fs;
272 int ret;
273
274 ret = statvfs(qPrintable(path), &fs);
275
276 if(ret == 0) {
277 if(type == FilesystemFree) {
278 size = (qulonglong)fs.f_frsize * (qulonglong)fs.f_bavail;
279 }
280 if(type == FilesystemTotal) {
281 size = (qulonglong)fs.f_frsize * (qulonglong)fs.f_blocks;
282 }
283 if(type == FilesystemClusterSize) {
284 size = (qulonglong)fs.f_frsize;
285 }
286 }
287#endif
288#if defined(Q_OS_WIN32)
289 BOOL ret;
290 ULARGE_INTEGER freeAvailBytes;
291 ULARGE_INTEGER totalNumberBytes;
292
293 ret = GetDiskFreeSpaceExW((LPCTSTR)path.utf16(), &freeAvailBytes,
294 &totalNumberBytes, NULL);
295 if(ret) {
296 if(type == FilesystemFree) {
297 size = freeAvailBytes.QuadPart;
298 }
299 if(type == FilesystemTotal) {
300 size = totalNumberBytes.QuadPart;
301 }
302 if(type == FilesystemClusterSize) {
303 DWORD sectorsPerCluster;
304 DWORD bytesPerSector;
305 DWORD freeClusters;
306 DWORD totalClusters;
307 ret = GetDiskFreeSpaceW((LPCTSTR)path.utf16(), &sectorsPerCluster,
308 &bytesPerSector, &freeClusters, &totalClusters);
309 if(ret) {
310 size = bytesPerSector * sectorsPerCluster;
311 }
312 }
313 }
314#endif
315 return size;
316}
317
318//! \brief searches for a Executable in the Environement Path
319QString Utils::findExecutable(QString name)
320{
321 //try autodetect tts
322#if defined(Q_OS_LINUX) || defined(Q_OS_MACX) || defined(Q_OS_OPENBSD)
323#if QT_VERSION >= 0x050e00
324 QStringList path = QString(getenv("PATH")).split(":", Qt::SkipEmptyParts);
325#else
326 QStringList path = QString(getenv("PATH")).split(":", QString::SkipEmptyParts);
327#endif
328#elif defined(Q_OS_WIN)
329#if QT_VERSION >= 0x050e00
330 QStringList path = QString(getenv("PATH")).split(";", Qt::SkipEmptyParts);
331#else
332 QStringList path = QString(getenv("PATH")).split(";", QString::SkipEmptyParts);
333#endif
334#endif
335 LOG_INFO() << "system path:" << path;
336 for(int i = 0; i < path.size(); i++)
337 {
338 QString executable = QDir::fromNativeSeparators(path.at(i)) + "/" + name;
339#if defined(Q_OS_WIN)
340 executable += ".exe";
341#if QT_VERSION >= 0x050e00
342 QStringList ex = executable.split("\"", Qt::SkipEmptyParts);
343#else
344 QStringList ex = executable.split("\"", QString::SkipEmptyParts);
345#endif
346 executable = ex.join("");
347#endif
348 if(QFileInfo(executable).isExecutable())
349 {
350 LOG_INFO() << "findExecutable: found" << executable;
351 return QDir::toNativeSeparators(executable);
352 }
353 }
354 LOG_INFO() << "findExecutable: could not find" << name;
355 return "";
356}
357
358
359/** @brief checks different Enviroment things. Ask if user wants to continue.
360 * @param permission if it should check for permission
361 * @return string with error messages if problems occurred, empty strings if none.
362 */
363QString Utils::checkEnvironment(bool permission)
364{
365 LOG_INFO() << "checking environment";
366 QString text = "";
367
368 // check permission
369 if(permission)
370 {
371#if defined(Q_OS_WIN32)
372 if(System::userPermissions() != System::ADMIN)
373 {
374 text += tr("<li>Permissions insufficient for bootloader "
375 "installation.\nAdministrator priviledges are necessary.</li>");
376 }
377#endif
378 }
379
380 // Check TargetId
381 RockboxInfo rbinfo(RbSettings::value(RbSettings::Mountpoint).toString());
382 QString installed = rbinfo.target();
383 if(!installed.isEmpty() && installed !=
384 RbSettings::value(RbSettings::CurrentPlatform).toString().split(".").at(0))
385 {
386 text += tr("<li>Target mismatch detected.<br/>"
387 "Installed target: %1<br/>Selected target: %2.</li>")
388 .arg(PlayerBuildInfo::instance()->value(
389 PlayerBuildInfo::DisplayName, installed).toString(),
390 PlayerBuildInfo::instance()->value(
391 PlayerBuildInfo::DisplayName).toString());
392 }
393
394 if(!text.isEmpty())
395 return tr("Problem detected:") + "<ul>" + text + "</ul>";
396 else
397 return text;
398}
399
400/** @brief Trim version string from filename to version part only.
401 * @param s Version string
402 * @return Version part of string if found, input string on error.
403 */
404QString Utils::trimVersionString(QString s)
405{
406 QRegExp r = QRegExp(".*([\\d\\.]+\\d+[a-z]?).*");
407 if(r.indexIn(s) != -1) {
408 return r.cap(1);
409 }
410 return s;
411}
412
413/** @brief Compare two version strings.
414 * @param s1 first version string
415 * @param s2 second version string
416 * @return 0 if strings identical, 1 if second is newer, -1 if first.
417 */
418int Utils::compareVersionStrings(QString s1, QString s2)
419{
420 LOG_INFO() << "comparing version strings" << s1 << "and" << s2;
421 QString a = s1.trimmed();
422 QString b = s2.trimmed();
423 // if strings are identical return 0.
424 if(a.isEmpty())
425 return 1;
426 if(b.isEmpty())
427 return -1;
428
429 while(!a.isEmpty() || !b.isEmpty()) {
430 // trim all leading non-digits and non-dots (dots are removed afterwards)
431 a.remove(QRegExp("^[^\\d\\.]*"));
432 b.remove(QRegExp("^[^\\d\\.]*"));
433
434 // trim all trailing non-digits for conversion (QString::toInt()
435 // requires this). Copy strings first as replace() changes the string.
436 QString numa = a;
437 QString numb = b;
438 numa.remove(QRegExp("\\D+.*$"));
439 numb.remove(QRegExp("\\D+.*$"));
440
441 // convert to number
442 bool ok1, ok2;
443 unsigned int vala = numa.toUInt(&ok1);
444 unsigned int valb = numb.toUInt(&ok2);
445 // if none of the numbers converted successfully we're at trailing garbage.
446 if(!ok1 && !ok2)
447 break;
448 if(!ok1)
449 return 1;
450 if(!ok2)
451 return -1;
452
453 // if numbers mismatch we have a decision.
454 if(vala != valb)
455 return (vala > valb) ? -1 : 1;
456
457 // trim leading digits.
458 a.remove(QRegExp("^\\d*"));
459 b.remove(QRegExp("^\\d*"));
460
461 // If only one of the following characters is a dot that one is
462 // "greater" then anything else. Make sure it's followed by a number,
463 // Otherwise it might be the end of the string or suffix. Do this
464 // before version addon characters check to avoid stopping too early.
465 bool adot = a.contains(QRegExp("^[a-zA-Z]*\\.[0-9]"));
466 bool bdot = b.contains(QRegExp("^[a-zA-Z]*\\.[0-9]"));
467 if(adot && !bdot)
468 return -1;
469 if(!adot && bdot)
470 return 1;
471 // if number is immediately followed by a character consider it as
472 // version addon (like 1.2.3b). In this case compare characters and end
473 // (version numbers like 1.2b.3 aren't handled).
474 QChar ltra;
475 QChar ltrb;
476 if(a.contains(QRegExp("^[a-zA-Z]")))
477 ltra = a.at(0);
478 if(b.contains(QRegExp("^[a-zA-Z]")))
479 ltrb = b.at(0);
480 if(ltra != ltrb)
481 return (ltra < ltrb) ? 1 : -1;
482
483 // both are identical or no addon characters, ignore.
484 // remove modifiers and following dot.
485 a.remove(QRegExp("^[a-zA-Z]*\\."));
486 b.remove(QRegExp("^[a-zA-Z]*\\."));
487 }
488
489 // no differences found.
490 return 0;
491}
492
493
494/** Resolve mountpoint to devicename / disk number
495 * @param path mountpoint path / drive letter
496 * @return devicename / disk number
497 */
498QString Utils::resolveDevicename(QString path)
499{
500 LOG_INFO() << "resolving device name" << path;
501#if defined(Q_OS_LINUX)
502 FILE *mn = setmntent("/etc/mtab", "r");
503 if(!mn)
504 return QString("");
505
506 struct mntent *ent;
507 while((ent = getmntent(mn))) {
508 // check for valid filesystem type.
509 // Linux can handle hfs (and hfsplus), so consider it a valid file
510 // system. Otherwise resolving the device name would fail, which in
511 // turn would make it impossible to warn about a MacPod.
512 if(QString(ent->mnt_dir) == path
513 && (QString(ent->mnt_type).contains("vfat", Qt::CaseInsensitive)
514 || QString(ent->mnt_type).contains("hfs", Qt::CaseInsensitive))) {
515 endmntent(mn);
516 LOG_INFO() << "device name is" << ent->mnt_fsname;
517 return QString(ent->mnt_fsname);
518 }
519 }
520 endmntent(mn);
521
522#endif
523
524#if defined(Q_OS_MACX) || defined(Q_OS_OPENBSD)
525 int num;
526 struct statfs *mntinf;
527
528 num = getmntinfo(&mntinf, MNT_WAIT);
529 while(num--) {
530 // check for valid filesystem type. OS X can handle hfs (hfs+ is
531 // treated as hfs), BSD should be the same.
532 if(QString(mntinf->f_mntonname) == path
533 && (QString(mntinf->f_fstypename).contains("msdos", Qt::CaseInsensitive)
534 || QString(mntinf->f_fstypename).contains("hfs", Qt::CaseInsensitive))) {
535 LOG_INFO() << "device name is" << mntinf->f_mntfromname;
536 return QString(mntinf->f_mntfromname);
537 }
538 mntinf++;
539 }
540#endif
541
542#if defined(Q_OS_WIN32)
543 DWORD written;
544 HANDLE h;
545 TCHAR uncpath[MAX_PATH];
546 UCHAR buffer[0x400];
547 PVOLUME_DISK_EXTENTS extents = (PVOLUME_DISK_EXTENTS)buffer;
548
549 _stprintf(uncpath, _TEXT("\\\\.\\%c:"), path.toLatin1().at(0));
550 h = CreateFile(uncpath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
551 NULL, OPEN_EXISTING, 0, NULL);
552 if(h == INVALID_HANDLE_VALUE) {
553 //LOG_INFO() << "error getting extents for" << uncpath;
554 return "";
555 }
556 // get the extents
557 if(DeviceIoControl(h, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
558 NULL, 0, extents, sizeof(buffer), &written, NULL)) {
559 if(extents->NumberOfDiskExtents == 1) {
560 CloseHandle(h);
561 LOG_INFO() << "device name is" << extents->Extents[0].DiskNumber;
562 return QString("%1").arg(extents->Extents[0].DiskNumber);
563 }
564 LOG_INFO() << "resolving device name: volume spans multiple disks!";
565 }
566 CloseHandle(h);
567#endif
568 return QString("");
569
570}
571
572
573/** resolve device name to mount point / drive letter
574 * @param device device name / disk number
575 * @return mount point / drive letter
576 */
577QString Utils::resolveMountPoint(QString device)
578{
579 LOG_INFO() << "resolving mountpoint:" << device;
580
581#if defined(Q_OS_LINUX)
582 FILE *mn = setmntent("/etc/mtab", "r");
583 if(!mn)
584 return QString("");
585
586 struct mntent *ent;
587 while((ent = getmntent(mn))) {
588 // Check for valid filesystem. Allow hfs too, as an Ipod might be a
589 // MacPod.
590 if(QString(ent->mnt_fsname) == device) {
591 QString result;
592 if(QString(ent->mnt_type).contains("vfat", Qt::CaseInsensitive)
593 || QString(ent->mnt_type).contains("hfs", Qt::CaseInsensitive)) {
594 LOG_INFO() << "resolved mountpoint is:" << ent->mnt_dir;
595 result = QString(ent->mnt_dir);
596 }
597 else {
598 LOG_INFO() << "mountpoint is wrong filesystem!";
599 }
600 endmntent(mn);
601 return result;
602 }
603 }
604 endmntent(mn);
605
606#endif
607
608#if defined(Q_OS_MACX) || defined(Q_OS_OPENBSD)
609 int num;
610 struct statfs *mntinf;
611
612 num = getmntinfo(&mntinf, MNT_WAIT);
613 while(num--) {
614 // Check for valid filesystem. Allow hfs too, as an Ipod might be a
615 // MacPod.
616 if(QString(mntinf->f_mntfromname) == device) {
617 if(QString(mntinf->f_fstypename).contains("msdos", Qt::CaseInsensitive)
618 || QString(mntinf->f_fstypename).contains("hfs", Qt::CaseInsensitive)) {
619 LOG_INFO() << "resolved mountpoint is:" << mntinf->f_mntonname;
620 return QString(mntinf->f_mntonname);
621 }
622 else {
623 LOG_INFO() << "mountpoint is wrong filesystem!";
624 return QString();
625 }
626 }
627 mntinf++;
628 }
629#endif
630
631#if defined(Q_OS_WIN32)
632 QString result;
633 unsigned int driveno = device.replace(QRegExp("^.*([0-9]+)"), "\\1").toInt();
634
635 int letter;
636 for(letter = 'A'; letter <= 'Z'; letter++) {
637 if(resolveDevicename(QString(letter)).toUInt() == driveno) {
638 result = letter;
639 LOG_INFO() << "resolved mountpoint is:" << result;
640 break;
641 }
642 }
643 if(!result.isEmpty())
644 return result + ":/";
645#endif
646 LOG_INFO() << "resolving mountpoint failed!";
647 return QString("");
648}
649
650
651QStringList Utils::mountpoints(enum MountpointsFilter type)
652{
653 QStringList supported;
654 QStringList tempList;
655#if defined(Q_OS_WIN32)
656 supported << "FAT32" << "FAT16" << "FAT12" << "FAT" << "HFS";
657 QFileInfoList list = QDir::drives();
658 for(int i=0; i<list.size();i++)
659 {
660 wchar_t t[32];
661 memset(t, 0, 32);
662 if(GetVolumeInformationW((LPCWSTR)list.at(i).absolutePath().utf16(),
663 NULL, 0, NULL, NULL, NULL, t, 32) == 0) {
664 // on error empty retrieved type -- don't rely on
665 // GetVolumeInformation not changing it.
666 memset(t, 0, sizeof(t));
667 }
668
669 QString fstype = QString::fromWCharArray(t);
670 if(type == MountpointsAll || supported.contains(fstype)) {
671 tempList << list.at(i).absolutePath();
672 LOG_INFO() << "Added:" << list.at(i).absolutePath()
673 << "type" << fstype;
674 }
675 else {
676 LOG_INFO() << "Ignored:" << list.at(i).absolutePath()
677 << "type" << fstype;
678 }
679 }
680
681#elif defined(Q_OS_MACX) || defined(Q_OS_OPENBSD)
682 supported << "vfat" << "msdos" << "hfs";
683 int num;
684 struct statfs *mntinf;
685
686 num = getmntinfo(&mntinf, MNT_WAIT);
687 while(num--) {
688 if(type == MountpointsAll || supported.contains(mntinf->f_fstypename)) {
689 tempList << QString(mntinf->f_mntonname);
690 LOG_INFO() << "Added:" << mntinf->f_mntonname
691 << "is" << mntinf->f_mntfromname << "type" << mntinf->f_fstypename;
692 }
693 else {
694 LOG_INFO() << "Ignored:" << mntinf->f_mntonname
695 << "is" << mntinf->f_mntfromname << "type" << mntinf->f_fstypename;
696 }
697 mntinf++;
698 }
699#elif defined(Q_OS_LINUX)
700 supported << "vfat" << "msdos" << "hfsplus";
701 FILE *mn = setmntent("/etc/mtab", "r");
702 if(!mn)
703 return QStringList("");
704
705 struct mntent *ent;
706 while((ent = getmntent(mn))) {
707 if(type == MountpointsAll || supported.contains(ent->mnt_type)) {
708 tempList << QString(ent->mnt_dir);
709 LOG_INFO() << "Added:" << ent->mnt_dir
710 << "is" << ent->mnt_fsname << "type" << ent->mnt_type;
711 }
712 else {
713 LOG_INFO() << "Ignored:" << ent->mnt_dir
714 << "is" << ent->mnt_fsname << "type" << ent->mnt_type;
715 }
716 }
717 endmntent(mn);
718
719#else
720#error Unknown Platform
721#endif
722 return tempList;
723}
724
725
726/** Check if a process with a given name is running
727 * @param names list of names to filter on. All processes if empty list.
728 * @return list of processname, process ID pairs.
729 */
730QMap<QString, QList<int> > Utils::findRunningProcess(QStringList names)
731{
732 QMap<QString, QList<int> > processlist;
733 QMap<QString, QList<int> > found;
734#if defined(Q_OS_WIN32)
735 HANDLE hdl;
736 PROCESSENTRY32 entry;
737 bool result;
738
739 hdl = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
740 if(hdl == INVALID_HANDLE_VALUE) {
741 LOG_ERROR() << "CreateToolhelp32Snapshot failed.";
742 return found;
743 }
744 entry.dwSize = sizeof(PROCESSENTRY32);
745 entry.szExeFile[0] = '\0';
746 if(!Process32First(hdl, &entry)) {
747 LOG_ERROR() << "Process32First failed.";
748 return found;
749 }
750
751 do {
752 int pid = entry.th32ProcessID; // FIXME: DWORD vs int!
753 QString name = QString::fromWCharArray(entry.szExeFile);
754 if(processlist.find(name) == processlist.end()) {
755 processlist.insert(name, QList<int>());
756 }
757 processlist[name].append(pid);
758 entry.dwSize = sizeof(PROCESSENTRY32);
759 entry.szExeFile[0] = '\0';
760 result = Process32Next(hdl, &entry);
761 } while(result);
762 CloseHandle(hdl);
763#endif
764#if defined(Q_OS_MACX)
765 ProcessSerialNumber psn = { 0, kNoProcess };
766 OSErr err;
767 do {
768 pid_t pid;
769 err = GetNextProcess(&psn);
770 err = GetProcessPID(&psn, &pid);
771 if(err == noErr) {
772 char buf[32] = {0};
773 ProcessInfoRec info;
774 memset(&info, 0, sizeof(ProcessInfoRec));
775 info.processName = (unsigned char*)buf;
776 info.processInfoLength = sizeof(ProcessInfoRec);
777 err = GetProcessInformation(&psn, &info);
778 if(err == noErr) {
779 // some processes start with nonprintable characters. Skip those.
780 int i;
781 for(i = 0; i < 32; i++) {
782 if(isprint(buf[i])) break;
783 }
784 // avoid adding duplicates.
785 QString name = QString::fromUtf8(&buf[i]);
786 if(processlist.find(name) == processlist.end()) {
787 processlist.insert(name, QList<int>());
788 }
789 processlist[name].append(pid);
790 }
791 }
792 } while(err == noErr);
793#endif
794#if defined(Q_OS_LINUX)
795 // not implemented for Linux!
796#endif
797 // Filter for names (unless empty)
798 if(names.size() > 0) {
799 for(int i = 0; i < names.size(); ++i) {
800 QStringList k(processlist.keys());
801#if defined(Q_OS_WIN32)
802 // the process name might be truncated. Allow the extension to be partial.
803 int index = k.indexOf(QRegExp(names.at(i) + "(\\.(e(x(e?)?)?)?)?",
804 Qt::CaseInsensitive));
805#else
806 int index = k.indexOf(names.at(i));
807#endif
808 if(index != -1) {
809 found.insert(k[index], processlist[k[index]]);
810 }
811 }
812 }
813 else {
814 found = processlist;
815 }
816 LOG_INFO() << "Looking for processes" << names << "found" << found;
817 return found;
818}
819
820
821/** Suspends/resumes processes
822 * @param pidlist a list of PIDs to suspend/resume
823 * @param suspend processes are suspended if true, or resumed when false
824 * @return a list of PIDs successfully suspended/resumed
825 */
826QList<int> Utils::suspendProcess(QList<int> pidlist, bool suspend)
827{
828 QList<int> result;
829#if defined(Q_OS_WIN32)
830 // Enable debug privilege
831 HANDLE hToken = NULL;
832 LUID seDebugValue;
833 TOKEN_PRIVILEGES tNext, tPrev;
834 DWORD sPrev;
835 if(LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &seDebugValue)) {
836 if(OpenProcessToken(GetCurrentProcess(),
837 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
838 memset(&tNext, 0, sizeof(tNext));
839 tNext.PrivilegeCount = 1;
840 tNext.Privileges[0].Luid = seDebugValue;
841 tNext.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
842 if(!AdjustTokenPrivileges(hToken, FALSE, &tNext, sizeof(tNext),
843 &tPrev, &sPrev) || GetLastError() != 0) {
844 CloseHandle(hToken);
845 hToken = NULL;
846 LOG_ERROR() << "AdjustTokenPrivileges(next) error" << GetLastError();
847 }
848 }
849 else {
850 LOG_ERROR() << "OpenProcessToken error" << GetLastError();
851 }
852 }
853 else {
854 LOG_ERROR() << "LookupPrivilegeValue error" << GetLastError();
855 }
856
857 // Suspend/resume threads
858 for(int i = 0; i < pidlist.size(); i++) {
859 HANDLE hdl = INVALID_HANDLE_VALUE;
860 THREADENTRY32 entry;
861 int n_fails = 0;
862
863 hdl = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
864 if(hdl == INVALID_HANDLE_VALUE) {
865 LOG_ERROR() << "CreateToolhelp32Snapshot error" << GetLastError();
866 continue;
867 }
868 entry.dwSize = sizeof(THREADENTRY32);
869 if(!Thread32First(hdl, &entry)) {
870 LOG_ERROR() << "Process32First error" << GetLastError();
871 CloseHandle(hdl);
872 continue;
873 }
874
875 do {
876 if(entry.th32OwnerProcessID != (DWORD)(pidlist[i]))
877 continue;
878 HANDLE thr = OpenThread(THREAD_SUSPEND_RESUME,
879 FALSE, entry.th32ThreadID);
880 if(!thr) {
881 LOG_ERROR() << "OpenThread" << entry.th32ThreadID
882 << "error" << GetLastError();
883 n_fails++;
884 continue;
885 }
886 if(suspend) {
887 // Execution of the specified thread is suspended and
888 // the thread's suspend count is incremented.
889 if(SuspendThread(thr) == (DWORD)(-1)) {
890 LOG_ERROR() << "SuspendThread" << entry.th32ThreadID
891 << "error" << GetLastError();
892 n_fails++;
893 }
894 }
895 else {
896 // Decrements a thread's suspend count. When the
897 // suspend count is decremented to zero, the
898 // execution of the thread is resumed.
899 if(ResumeThread(thr) == (DWORD)(-1)) {
900 LOG_ERROR() << "ResumeThread" << entry.th32ThreadID
901 << "error" << GetLastError();
902 n_fails++;
903 }
904 }
905 CloseHandle(thr);
906 } while(Thread32Next(hdl, &entry));
907 if (!n_fails)
908 result.append(pidlist[i]);
909 CloseHandle(hdl);
910 }
911
912 // Restore previous debug privilege
913 if (hToken) {
914 if(!AdjustTokenPrivileges(hToken, FALSE,
915 &tPrev, sPrev, NULL, NULL) || GetLastError() != 0) {
916 LOG_ERROR() << "AdjustTokenPrivileges(prev) error" << GetLastError();
917 }
918 CloseHandle(hToken);
919 }
920#endif
921#if defined(Q_OS_MACX)
922 int signal = suspend ? SIGSTOP : SIGCONT;
923 for(int i = 0; i < pidlist.size(); i++) {
924 pid_t pid = pidlist[i];
925 if(kill(pid, signal) != 0) {
926 LOG_ERROR() << "kill signal" << signal
927 << "for PID" << pid << "error:" << errno;
928 }
929 else {
930 result.append(pidlist[i]);
931 }
932 }
933#endif
934#if defined(Q_OS_LINUX)
935 // not implemented for Linux!
936#endif
937 LOG_INFO() << (suspend ? "Suspending" : "Resuming")
938 << "PIDs" << pidlist << "result" << result;
939 return result;
940}
941
942
943/** Eject device from PC.
944 * Request the OS to eject the player.
945 * @param device mountpoint of the device
946 * @return true on success, fals otherwise.
947 */
948bool Utils::ejectDevice(QString device)
949{
950#if defined(Q_OS_WIN32)
951 /* See http://support.microsoft.com/kb/165721 on the procedure to eject a
952 * device. */
953 bool success = false;
954 int i;
955 HANDLE hdl;
956 DWORD bytesReturned;
957 TCHAR volume[8];
958
959 /* CreateFile */
960 _stprintf(volume, _TEXT("\\\\.\\%c:"), device.toLatin1().at(0));
961 hdl = CreateFile(volume, GENERIC_READ | GENERIC_WRITE,
962 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
963 OPEN_EXISTING, 0, NULL);
964 if(hdl == INVALID_HANDLE_VALUE)
965 return false;
966
967 /* lock volume to make sure no other application is accessing the volume.
968 * Try up to 10 times. */
969 for(i = 0; i < 10; i++) {
970 if(DeviceIoControl(hdl, FSCTL_LOCK_VOLUME,
971 NULL, 0, NULL, 0, &bytesReturned, NULL))
972 break;
973 /* short break before retry */
974 Sleep(100);
975 }
976 if(i < 10) {
977 /* successfully locked, now dismount */
978 if(DeviceIoControl(hdl, FSCTL_DISMOUNT_VOLUME,
979 NULL, 0, NULL, 0, &bytesReturned, NULL)) {
980 /* make sure media can be removed. */
981 PREVENT_MEDIA_REMOVAL pmr;
982 pmr.PreventMediaRemoval = false;
983 if(DeviceIoControl(hdl, IOCTL_STORAGE_MEDIA_REMOVAL,
984 &pmr, sizeof(PREVENT_MEDIA_REMOVAL),
985 NULL, 0, &bytesReturned, NULL)) {
986 /* eject the media */
987 if(DeviceIoControl(hdl, IOCTL_STORAGE_EJECT_MEDIA,
988 NULL, 0, NULL, 0, &bytesReturned, NULL))
989 success = true;
990 }
991 }
992 }
993 /* close handle */
994 CloseHandle(hdl);
995 return success;
996
997#endif
998#if defined(Q_OS_MACX)
999 // FIXME: FSUnmountVolumeSync is deprecated starting with 10.8.
1000 // Use DADiskUnmount / DiskArbitration framework eventually.
1001 // BSD label does not include folder.
1002 QString bsd = Utils::resolveDevicename(device).remove("/dev/");
1003 OSStatus result;
1004 ItemCount index = 1;
1005 bool found = false;
1006
1007 do {
1008 FSVolumeRefNum volrefnum;
1009
1010 result = FSGetVolumeInfo(kFSInvalidVolumeRefNum, index, &volrefnum,
1011 kFSVolInfoFSInfo, NULL, NULL, NULL);
1012 if(result == noErr) {
1013 GetVolParmsInfoBuffer volparms;
1014 /* See above -- PBHGetVolParmsSync() is not available for 64bit,
1015 * and FSGetVolumeParms() on 10.5+ only. */
1016#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
1017 if(FSGetVolumeParms(volrefnum, &volparms, sizeof(volparms)) == noErr)
1018#else
1019 HParamBlockRec hpb;
1020 hpb.ioParam.ioNamePtr = NULL;
1021 hpb.ioParam.ioVRefNum = volrefnum;
1022 hpb.ioParam.ioBuffer = (Ptr)&volparms;
1023 hpb.ioParam.ioReqCount = sizeof(volparms);
1024 if(PBHGetVolParmsSync(&hpb) == noErr)
1025#endif
1026 {
1027 if(volparms.vMServerAdr == 0) {
1028 if(bsd == (char*)volparms.vMDeviceID) {
1029 pid_t dissenter;
1030 result = FSUnmountVolumeSync(volrefnum, 0, &dissenter);
1031 found = true;
1032 break;
1033 }
1034 }
1035 }
1036 }
1037 index++;
1038 } while(result == noErr);
1039 if(result == noErr && found)
1040 return true;
1041
1042#endif
1043#if defined(Q_OS_LINUX)
1044 (void)device;
1045#endif
1046 return false;
1047}
1048
1049
1050qint64 Utils::recursiveFolderSize(QString path)
1051{
1052 qint64 size = 0;
1053 QList<QFileInfo> items = QDir(path).entryInfoList(QDir::Files | QDir::NoDotAndDotDot);
1054 for (auto item: items) {
1055 size += item.size();
1056 }
1057 QList<QString> folders = QDir(path).entryList(QDir::Dirs | QDir::NoDotAndDotDot);
1058 for (auto folder: folders) {
1059 size += recursiveFolderSize(path + "/" + folder);
1060 }
1061 return size;
1062}
diff --git a/utils/rbutilqt/base/utils.h b/utils/rbutilqt/base/utils.h
new file mode 100644
index 0000000000..7f27c7d321
--- /dev/null
+++ b/utils/rbutilqt/base/utils.h
@@ -0,0 +1,64 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21
22#ifndef UTILS_H
23#define UTILS_H
24
25#include <QtCore/QObject>
26
27#include <QString>
28#include <QUrl>
29
30class Utils : public QObject
31{
32public:
33 enum Size {
34 FilesystemTotal,
35 FilesystemFree,
36 FilesystemClusterSize,
37 };
38 enum MountpointsFilter {
39 MountpointsAll,
40 MountpointsSupported,
41 };
42
43 static bool recursiveRmdir(const QString &dirName);
44 static QString resolvePathCase(QString path);
45 static qulonglong filesystemFree(QString path);
46 static qulonglong filesystemTotal(QString path);
47 static qulonglong filesystemSize(QString path, enum Size type);
48 static QString filesystemType(QString path);
49 static QString findExecutable(QString name);
50 static QString checkEnvironment(bool permission);
51 static int compareVersionStrings(QString s1, QString s2);
52 static QString trimVersionString(QString s);
53 static QString filesystemName(QString path);
54 static QStringList mountpoints(enum MountpointsFilter type = MountpointsAll);
55 static QString resolveDevicename(QString path);
56 static QString resolveMountPoint(QString device);
57 static QMap<QString, QList<int> > findRunningProcess(QStringList names);
58 static QList<int> suspendProcess(QList<int> pidlist, bool suspend);
59 static bool ejectDevice(QString device);
60 static qint64 recursiveFolderSize(QString path);
61};
62
63#endif
64
diff --git a/utils/rbutilqt/base/voicefile.cpp b/utils/rbutilqt/base/voicefile.cpp
new file mode 100644
index 0000000000..eabf7a721a
--- /dev/null
+++ b/utils/rbutilqt/base/voicefile.cpp
@@ -0,0 +1,362 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include "voicefile.h"
21#include "utils.h"
22#include "rockboxinfo.h"
23#include "rbsettings.h"
24#include "playerbuildinfo.h"
25#include "ziputil.h"
26#include "Logger.h"
27
28VoiceFileCreator::VoiceFileCreator(QObject* parent) :QObject(parent)
29{
30 m_wavtrimThreshold=500;
31}
32
33void VoiceFileCreator::abort()
34{
35 m_abort = true;
36 emit aborted();
37}
38
39bool VoiceFileCreator::createVoiceFile()
40{
41 m_talkList.clear();
42 m_abort = false;
43 emit logItem(tr("Starting Voicefile generation"),LOGINFO);
44
45 // test if tempdir exists
46 if(!QDir(QDir::tempPath()+"/rbvoice/").exists())
47 {
48 QDir(QDir::tempPath()).mkdir("rbvoice");
49 }
50 m_path = QDir::tempPath() + "/rbvoice/";
51
52 // read rockbox-info.txt
53 RockboxInfo info(m_mountpoint);
54 if(!info.success())
55 {
56 emit logItem(tr("could not find rockbox-info.txt"),LOGERROR);
57 emit done(true);
58 return false;
59 }
60 QString target = info.target();
61 QString features = info.features();
62 m_targetid = info.targetID().toInt();
63 m_versionstring = info.version();
64 m_voiceformat = info.voicefmt();
65 QString version = m_versionstring.left(m_versionstring.indexOf("-")).remove("r");
66
67 // check if voicefile is present on target
68 QString fn = m_mountpoint + "/.rockbox/langs/voicestrings.zip";
69 LOG_INFO() << "searching for zipped voicestrings at" << fn;
70 if(QFileInfo(fn).isFile()) {
71 // search for binary voice strings file in archive
72 ZipUtil z(this);
73 if(z.open(fn)) {
74 QStringList contents = z.files();
75 int index;
76 for(index = 0; index < contents.size(); ++index) {
77 // strip any path, we don't know the structure in the zip
78 if(QFileInfo(contents.at(index)).baseName() == m_lang) {
79 break;
80 }
81 }
82 if(index < contents.size()) {
83 LOG_INFO() << "extracting strings file from zip";
84 // extract strings
85 QTemporaryFile stringsfile;
86 stringsfile.open();
87 QString sfn = stringsfile.fileName();
88 // ZipUtil::extractArchive() only compares the filename.
89 if(z.extractArchive(sfn, QFileInfo(contents.at(index)).fileName())) {
90 emit logItem(tr("Extracted voice strings from installation"), LOGINFO);
91
92 stringsfile.seek(0);
93 QByteArray data = stringsfile.readAll();
94 const char* buf = data.constData();
95 // check file header
96 // header (4 bytes): cookie = 9a, version = 06, targetid, options
97 // subheader for each user. Only "core" for now.
98 // subheader (6 bytes): count (2bytes), size (2bytes), offset (2bytes)
99 if(buf[0] != (char)0x9a || buf[1] != 0x06 || buf[2] != m_targetid) {
100 emit logItem(tr("Extracted voice strings incompatible"), LOGINFO);
101 }
102 else {
103 QMap<int, QString> voicestrings;
104
105 /* skip header */
106 int idx = 10;
107 do {
108 unsigned int id = ((unsigned char)buf[idx])<<8
109 | ((unsigned char)buf[idx+1]);
110 // need to use strlen here, since QString::size()
111 // returns number of characters, not bytes.
112 int len = strlen(&buf[idx + 2]);
113 voicestrings[id] = QString::fromUtf8(&buf[idx+2]);
114 idx += 2 + len + 1;
115
116 } while(idx < data.size());
117
118 stringsfile.close();
119
120 // create input file suitable for voicefont from strings.
121 QTemporaryFile voicefontlist;
122 voicefontlist.open();
123 m_filename = voicefontlist.fileName();
124 for(int i = 0; i < voicestrings.size(); ++i) {
125 QByteArray qba;
126 qba = QString("id: %1_%2\n")
127 .arg(voicestrings.keys().at(i) < 0x8000 ? "LANG" : "VOICE")
128 .arg(voicestrings.keys().at(i)).toUtf8();
129 voicefontlist.write(qba);
130 qba = QString("voice: \"%1\"\n").arg(
131 voicestrings[voicestrings.keys().at(i)]).toUtf8();
132 voicefontlist.write(qba);
133 }
134 voicefontlist.close();
135
136 // everything successful, now create the actual voice file.
137 create();
138 return true;
139 }
140
141 }
142 }
143 }
144 }
145 emit logItem(tr("Could not retrieve strings from installation, downloading"), LOGINFO);
146 // if either no zip with voice strings is found or something went wrong
147 // retrieving the necessary files we'll end up here, trying to get the
148 // genlang output as previously from the webserver.
149
150 // prepare download url
151 QString genlang = PlayerBuildInfo::instance()->value(
152 PlayerBuildInfo::GenlangUrl).toString();
153 genlang.replace("%LANG%", m_lang);
154 genlang.replace("%TARGET%", target);
155 genlang.replace("%REVISION%", version);
156 genlang.replace("%FEATURES%", features);
157 QUrl genlangUrl(genlang);
158 LOG_INFO() << "downloading" << genlangUrl;
159
160 //download the correct genlang output
161 QTemporaryFile *downloadFile = new QTemporaryFile(this);
162 downloadFile->open();
163 m_filename = downloadFile->fileName();
164 downloadFile->close();
165 // get the real file.
166 getter = new HttpGet(this);
167 getter->setFile(downloadFile);
168
169 connect(getter, &HttpGet::done, this, &VoiceFileCreator::downloadDone);
170 connect(getter, &HttpGet::dataReadProgress, this, &VoiceFileCreator::logProgress);
171 connect(this, &VoiceFileCreator::aborted, getter, &HttpGet::abort);
172 emit logItem(tr("Downloading voice info..."),LOGINFO);
173 getter->getFile(genlangUrl);
174 return true;
175 }
176
177
178void VoiceFileCreator::downloadDone(bool error)
179{
180 LOG_INFO() << "download done, error:" << error;
181
182 // update progress bar
183 emit logProgress(1,1);
184 if(getter->httpResponse() != 200 && !getter->isCached()) {
185 emit logItem(tr("Download error: received HTTP error %1.")
186 .arg(getter->httpResponse()),LOGERROR);
187 emit done(true);
188 return;
189 }
190
191 if(getter->isCached())
192 emit logItem(tr("Cached file used."), LOGINFO);
193 if(error)
194 {
195 emit logItem(tr("Download error: %1").arg(getter->errorString()),LOGERROR);
196 emit done(true);
197 return;
198 }
199 else
200 emit logItem(tr("Download finished."),LOGINFO);
201
202 QCoreApplication::processEvents();
203 create();
204}
205
206
207void VoiceFileCreator::create(void)
208{
209 //open downloaded file
210 QFile genlang(m_filename);
211 if(!genlang.open(QIODevice::ReadOnly))
212 {
213 emit logItem(tr("failed to open downloaded file"),LOGERROR);
214 emit done(true);
215 return;
216 }
217
218 //read in downloaded file
219 emit logItem(tr("Reading strings..."),LOGINFO);
220 QTextStream in(&genlang);
221#if QT_VERSION < 0x060000
222 in.setCodec("UTF-8");
223#else
224 in.setEncoding(QStringConverter::Utf8);
225#endif
226 QString id, voice;
227 bool idfound = false;
228 bool voicefound=false;
229 bool useCorrection = RbSettings::value(RbSettings::UseTtsCorrections).toBool();
230 while (!in.atEnd())
231 {
232 QString line = in.readLine();
233 if(line.contains("id:")) //ID found
234 {
235 id = line.remove("id:").remove('"').trimmed();
236 idfound = true;
237 }
238 else if(line.contains("voice:")) // voice found
239 {
240 voice = line.remove("voice:").remove('"').trimmed();
241 voice = voice.remove("<").remove(">");
242 voicefound=true;
243 }
244
245 if(idfound && voicefound)
246 {
247 TalkGenerator::TalkEntry entry;
248 entry.toSpeak = voice;
249 entry.wavfilename = m_path + "/" + id + ".wav";
250 //voicefont wants them with .mp3 extension
251 entry.talkfilename = m_path + "/" + id + ".mp3";
252 entry.voiced = false;
253 entry.encoded = false;
254 if(id == "VOICE_PAUSE")
255 {
256 QFile::copy(":/builtin/VOICE_PAUSE.wav",m_path + "/VOICE_PAUSE.wav");
257 entry.wavfilename = m_path + "/VOICE_PAUSE.wav";
258 entry.voiced = true;
259 m_talkList.append(entry);
260 }
261 else if(entry.toSpeak.isEmpty()) {
262 LOG_WARNING() << "Empty voice string for ID" << id;
263 }
264 else {
265 m_talkList.append(entry);
266 }
267 idfound=false;
268 voicefound=false;
269 }
270 }
271 genlang.close();
272
273 // check for empty list
274 if(m_talkList.size() == 0)
275 {
276 emit logItem(tr("The downloaded file was empty!"),LOGERROR);
277 emit done(true);
278 return;
279 }
280
281 // generate files
282 {
283 TalkGenerator generator(this);
284 // set language for string correction. If not set no correction will be made.
285 if(useCorrection)
286 generator.setLang(m_lang);
287 connect(&generator, &TalkGenerator::done, this, &VoiceFileCreator::done);
288 connect(&generator, &TalkGenerator::logItem, this, &VoiceFileCreator::logItem);
289 connect(&generator, &TalkGenerator::logProgress, this, &VoiceFileCreator::logProgress);
290 connect(this, &VoiceFileCreator::aborted, &generator, &TalkGenerator::abort);
291
292 if(generator.process(&m_talkList, m_wavtrimThreshold) == TalkGenerator::eERROR)
293 {
294 cleanup();
295 emit logProgress(0,1);
296 emit done(true);
297 return;
298 }
299 }
300
301 //make voicefile
302 emit logItem(tr("Creating voicefiles..."),LOGINFO);
303 FILE* ids2 = fopen(m_filename.toLocal8Bit(), "r");
304 if (ids2 == nullptr)
305 {
306 cleanup();
307 emit logItem(tr("Error opening downloaded file"),LOGERROR);
308 emit done(true);
309 return;
310 }
311
312 FILE* output = fopen(QString(m_mountpoint + "/.rockbox/langs/" + m_lang
313 + ".voice").toLocal8Bit(), "wb");
314 if (output == nullptr)
315 {
316 cleanup();
317 fclose(ids2);
318 emit logItem(tr("Error opening output file"),LOGERROR);
319 emit done(true);
320 return;
321 }
322
323 LOG_INFO() << "Running voicefont, format" << m_voiceformat;
324 voicefont(ids2,m_targetid,m_path.toLocal8Bit().data(), output, m_voiceformat);
325 // ids2 and output are closed by voicefont().
326
327 //cleanup
328 cleanup();
329
330 // Add Voice file to the install log
331 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, nullptr);
332 installlog.beginGroup(QString("Voice (self created, %1)").arg(m_lang));
333 installlog.setValue("/.rockbox/langs/" + m_lang + ".voice", m_versionstring);
334 installlog.endGroup();
335 installlog.sync();
336
337 emit logProgress(1,1);
338 emit logItem(tr("successfully created."),LOGOK);
339
340 emit done(false);
341}
342
343//! \brief Cleans up Files potentially left in the temp dir
344//!
345void VoiceFileCreator::cleanup()
346{
347 emit logItem(tr("Cleaning up..."),LOGINFO);
348
349 for(int i=0; i < m_talkList.size(); i++)
350 {
351 if(QFile::exists(m_talkList[i].wavfilename))
352 QFile::remove(m_talkList[i].wavfilename);
353 if(QFile::exists(m_talkList[i].talkfilename))
354 QFile::remove(m_talkList[i].talkfilename);
355
356 QCoreApplication::processEvents();
357 }
358 emit logItem(tr("Finished"),LOGINFO);
359
360 return;
361}
362
diff --git a/utils/rbutilqt/base/voicefile.h b/utils/rbutilqt/base/voicefile.h
new file mode 100644
index 0000000000..d34535e700
--- /dev/null
+++ b/utils/rbutilqt/base/voicefile.h
@@ -0,0 +1,77 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21
22#ifndef VOICEFILE_H
23#define VOICEFILE_H
24
25#include <QtCore>
26#include "progressloggerinterface.h"
27
28#include "httpget.h"
29#include "voicefont.h"
30#include "talkgenerator.h"
31
32class VoiceFileCreator :public QObject
33{
34 Q_OBJECT
35public:
36 VoiceFileCreator(QObject* parent);
37
38 //start creation
39 bool createVoiceFile();
40
41 void setMountPoint(QString mountpoint) {m_mountpoint =mountpoint; }
42 void setLang(QString name) { m_lang = name; }
43 void setWavtrimThreshold(int th){m_wavtrimThreshold = th;}
44
45public slots:
46 void abort();
47
48signals:
49 void done(bool);
50 void aborted();
51 void logItem(QString, int); //! set logger item
52 void logProgress(int, int); //! set progress bar.
53
54private slots:
55 void downloadDone(bool error);
56
57private:
58
59 void create(void);
60 void cleanup();
61
62 HttpGet *getter;
63 QString m_filename; //the temporary file
64 QString m_mountpoint; //mountpoint of the device
65 QString m_path; //path where the wav and mp3 files are stored to
66 int m_targetid; //the target id
67 QString m_lang; // the language which will be spoken
68 QString m_versionstring; // version string to be used for logging
69 int m_wavtrimThreshold;
70 int m_voiceformat;
71
72 bool m_abort;
73 QList<TalkGenerator::TalkEntry> m_talkList;
74};
75
76#endif
77
diff --git a/utils/rbutilqt/base/zipinstaller.cpp b/utils/rbutilqt/base/zipinstaller.cpp
new file mode 100644
index 0000000000..8de6c53b16
--- /dev/null
+++ b/utils/rbutilqt/base/zipinstaller.cpp
@@ -0,0 +1,204 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include "zipinstaller.h"
21#include "utils.h"
22#include "ziputil.h"
23#include "Logger.h"
24
25ZipInstaller::ZipInstaller(QObject* parent) :
26 QObject(parent),
27 m_unzip(true), m_usecache(false), m_getter(nullptr)
28{
29}
30
31
32void ZipInstaller::install()
33{
34 LOG_INFO() << "initializing installation";
35
36 m_runner = 0;
37 connect(this, &ZipInstaller::cont, this, &ZipInstaller::installContinue);
38 m_url = m_urllist.at(m_runner);
39 m_logsection = m_loglist.at(m_runner);
40 m_logver = m_verlist.at(m_runner);
41 installStart();
42}
43
44
45void ZipInstaller::abort()
46{
47 LOG_INFO() << "Aborted";
48 emit internalAborted();
49}
50
51
52void ZipInstaller::installContinue()
53{
54 LOG_INFO() << "continuing installation";
55
56 m_runner++; // this gets called when a install finished, so increase first.
57 LOG_INFO() << "runner done:" << m_runner << "/" << m_urllist.size();
58 if(m_runner < m_urllist.size()) {
59 emit logItem(tr("done."), LOGOK);
60 m_url = m_urllist.at(m_runner);
61 m_logsection = m_loglist.at(m_runner);
62 if(m_runner < m_verlist.size()) m_logver = m_verlist.at(m_runner);
63 else m_logver = "";
64 installStart();
65 }
66 else {
67 emit logItem(tr("Package installation finished successfully."), LOGOK);
68 emit done(false);
69 return;
70 }
71}
72
73
74void ZipInstaller::installStart()
75{
76 LOG_INFO() << "starting installation";
77
78 emit logItem(tr("Downloading file %1.%2").arg(QFileInfo(m_url).baseName(),
79 QFileInfo(m_url).completeSuffix()),LOGINFO);
80
81 // temporary file needs to be opened to get the filename
82 // make sure to get a fresh one on each run.
83 // making this a parent of the temporary file ensures the file gets deleted
84 // after the class object gets destroyed.
85 m_downloadFile = new QTemporaryFile(this);
86 m_downloadFile->open();
87 m_file = m_downloadFile->fileName();
88 m_downloadFile->close();
89 // get the real file.
90 if(m_getter != nullptr) m_getter->deleteLater();
91 m_getter = new HttpGet(this);
92 if(m_usecache) {
93 m_getter->setCache(true);
94 }
95 m_getter->setFile(m_downloadFile);
96
97 connect(m_getter, &HttpGet::done, this, &ZipInstaller::downloadDone);
98 connect(m_getter, &HttpGet::dataReadProgress, this, &ZipInstaller::logProgress);
99 connect(this, &ZipInstaller::internalAborted, m_getter, &HttpGet::abort);
100
101 m_getter->getFile(QUrl(m_url));
102}
103
104
105void ZipInstaller::downloadDone(bool error)
106{
107 LOG_INFO() << "download done, error:" << error;
108 QStringList zipContents; // needed later
109 // update progress bar
110
111 emit logProgress(1, 1);
112 if(m_getter->httpResponse() != 200 && !m_getter->isCached()) {
113 emit logItem(tr("Download error: received HTTP error %1\n%2")
114 .arg(m_getter->httpResponse()).arg(m_getter->errorString()),
115 LOGERROR);
116 emit done(true);
117 return;
118 }
119 if(m_getter->isCached())
120 emit logItem(tr("Cached file used."), LOGINFO);
121 if(error) {
122 emit logItem(tr("Download error: %1").arg(m_getter->errorString()), LOGERROR);
123 emit done(true);
124 return;
125 }
126 else emit logItem(tr("Download finished."),LOGOK);
127 QCoreApplication::processEvents();
128 if(m_unzip) {
129 // unzip downloaded file
130 LOG_INFO() << "about to unzip" << m_file << "to" << m_mountpoint;
131
132 emit logItem(tr("Extracting file."), LOGINFO);
133 QCoreApplication::processEvents();
134
135 ZipUtil zip(this);
136 connect(&zip, &ZipUtil::logProgress, this, &ZipInstaller::logProgress);
137 connect(&zip, &ZipUtil::logItem, this, &ZipInstaller::logItem);
138 zip.open(m_file, QuaZip::mdUnzip);
139 // check for free space. Make sure after installation will still be
140 // some room for operating (also includes calculation mistakes due to
141 // cluster sizes on the player).
142 if((qint64)Utils::filesystemFree(m_mountpoint)
143 < (zip.totalUncompressedSize(
144 Utils::filesystemSize(m_mountpoint, Utils::FilesystemClusterSize))
145 + 1000000)) {
146 emit logItem(tr("Not enough disk space! Aborting."), LOGERROR);
147 emit logProgress(1, 1);
148 emit done(true);
149 return;
150 }
151 zipContents = zip.files();
152 if(!zip.extractArchive(m_mountpoint)) {
153 emit logItem(tr("Extraction failed!"), LOGERROR);
154 emit logProgress(1, 1);
155 emit done(true);
156 return;
157 }
158 zip.close();
159 }
160 else {
161 if (m_target.isEmpty())
162 m_target = QUrl(m_url).fileName();
163 QString destfile = m_mountpoint + "/" + m_target;
164 // only copy the downloaded file to the output location / name
165 emit logItem(tr("Installing file."), LOGINFO);
166 LOG_INFO() << "saving downloaded file (no extraction) to" << destfile;
167
168 m_downloadFile->open(); // copy fails if file is not opened (filename issue?)
169 // make sure the required path is existing
170 QString path = QFileInfo(destfile).absolutePath();
171 QDir p;
172 p.mkpath(path);
173 // QFile::copy() doesn't overwrite files, so remove old one first
174 // TODO: compare old and new file and fail if those are different.
175 QFile(destfile).remove();
176 if(!m_downloadFile->copy(destfile)) {
177 emit logItem(tr("Installing file failed."), LOGERROR);
178 emit done(true);
179 return;
180 }
181
182 // add file to log
183 zipContents.append(m_target);
184 }
185 if(m_logver.isEmpty()) {
186 // if no version info is set use the timestamp of the server file.
187 m_logver = m_getter->timestamp().toString(Qt::ISODate);
188 }
189
190 emit logItem(tr("Creating installation log"),LOGINFO);
191 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, nullptr);
192
193 installlog.beginGroup(m_logsection);
194 for(int i = 0; i < zipContents.size(); i++)
195 {
196 installlog.setValue(zipContents.at(i), m_logver);
197 }
198 installlog.endGroup();
199 installlog.sync();
200
201 emit cont();
202}
203
204
diff --git a/utils/rbutilqt/base/zipinstaller.h b/utils/rbutilqt/base/zipinstaller.h
new file mode 100644
index 0000000000..59a0f785d9
--- /dev/null
+++ b/utils/rbutilqt/base/zipinstaller.h
@@ -0,0 +1,88 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21
22#ifndef ZIPINSTALLER_H
23#define ZIPINSTALLER_H
24
25#include <QtCore>
26
27#include "progressloggerinterface.h"
28#include "httpget.h"
29#include "Logger.h"
30
31/** Install a file or zip.
32 * Downloads file(s) from a given URL, and installs by either extracting or
33 * copying it to the target path set by setMountpoint().
34 */
35class ZipInstaller : public QObject
36{
37 Q_OBJECT
38public:
39 ZipInstaller(QObject* parent);
40 ~ZipInstaller(){}
41 void install(void);
42 void setMountPoint(QString mountpoint) {m_mountpoint = mountpoint;}
43 void setUrl(QString url){m_urllist = QStringList(url);}
44 void setUrl(QStringList url) { m_urllist = url; }
45 void setLogSection(QString name) {m_loglist = QStringList(name);}
46 void setLogSection(QStringList name) { m_loglist = name; }
47 void setLogVersion(QString v = "")
48 { m_verlist = QStringList(v); LOG_INFO() << m_verlist;}
49 void setLogVersion(QStringList v)
50 { m_verlist = v; LOG_INFO() << m_verlist;}
51 /** Change between copy and unzip mode. */
52 void setUnzip(bool i) { m_unzip = i; }
53 /** Set target filename for copy mode.
54 * If not set the filename part of the download URL is used. */
55 void setTarget(QString t) { m_target = t; }
56 void setCache(bool c) { m_usecache = c; }
57
58public slots:
59 void abort(void);
60
61private slots:
62 void downloadDone(bool);
63 void installStart(void);
64 void installContinue(void);
65
66signals:
67 void done(bool error);
68 void cont();
69 void logItem(QString, int); //! set logger item
70 void logProgress(int, int); //! set progress bar.
71 void internalAborted(void);
72
73private:
74 QString m_url, m_file, m_mountpoint, m_logsection, m_logver;
75 QStringList m_urllist, m_loglist, m_verlist;
76 bool m_unzip;
77 QString m_target;
78 int m_runner;
79 bool m_usecache;
80
81 HttpGet *m_getter;
82 QTemporaryFile *m_downloadFile;
83};
84
85
86
87#endif
88
diff --git a/utils/rbutilqt/base/ziputil.cpp b/utils/rbutilqt/base/ziputil.cpp
new file mode 100644
index 0000000000..45119f7d99
--- /dev/null
+++ b/utils/rbutilqt/base/ziputil.cpp
@@ -0,0 +1,302 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2011 Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include <QDebug>
21#include "ziputil.h"
22#include "progressloggerinterface.h"
23#include "Logger.h"
24
25#include "quazip/quazip.h"
26#include "quazip/quazipfile.h"
27#include "quazip/quazipfileinfo.h"
28
29
30ZipUtil::ZipUtil(QObject* parent) : ArchiveUtil(parent)
31{
32 m_zip = nullptr;
33}
34
35
36ZipUtil::~ZipUtil()
37{
38 if(m_zip) {
39 delete m_zip;
40 }
41}
42
43//! @brief open zip file.
44//! @param zipfile path to zip file
45//! @param mode open mode (see QuaZip::Mode)
46//! @return true on success, false otherwise
47bool ZipUtil::open(QString& zipfile, QuaZip::Mode mode)
48{
49 m_zip = new QuaZip(zipfile);
50 return m_zip->open(mode);
51}
52
53
54//! @brief close zip file.
55//! @return true on success, false otherwise
56bool ZipUtil::close(void)
57{
58 if(!m_zip) {
59 return false;
60 }
61
62 int error = UNZ_OK;
63 if(m_zip->isOpen()) {
64 m_zip->close();
65 error = m_zip->getZipError();
66 }
67 delete m_zip;
68 m_zip = nullptr;
69 return (error == UNZ_OK) ? true : false;
70}
71
72
73//! @brief extract currently opened archive
74//! @brief dest path to extract archive to, can be filename when extracting a
75//! single file.
76//! @brief file file to extract from archive, full archive if empty.
77//! @return true on success, false otherwise
78bool ZipUtil::extractArchive(const QString& dest, QString file)
79{
80 LOG_INFO() << "extractArchive" << dest << file;
81 bool result = true;
82 if(!m_zip) {
83 return false;
84 }
85 QuaZipFile *currentFile = new QuaZipFile(m_zip);
86 int entries = m_zip->getEntriesCount();
87 int current = 0;
88 // construct the filename when extracting a single file from an archive.
89 // if the given destination is a full path use it as output name,
90 // otherwise use it as path to place the file as named in the archive.
91 QString singleoutfile;
92 if(!file.isEmpty() && QFileInfo(dest).isDir()) {
93 singleoutfile = dest + "/" + file;
94 }
95 else if(!file.isEmpty()){
96 singleoutfile = dest;
97 }
98 for(bool more = m_zip->goToFirstFile(); more; more = m_zip->goToNextFile())
99 {
100 ++current;
101 // if the entry is a path ignore it. Path existence is ensured separately.
102 if(m_zip->getCurrentFileName().split("/").last() == "")
103 continue;
104 // some tools set the MS-DOS file attributes. Check those for D flag,
105 // since in some cases a folder entry does not end with a /
106 QuaZipFileInfo fi;
107 currentFile->getFileInfo(&fi);
108 if(fi.externalAttr & 0x10) // FAT entry bit 4 indicating directory
109 continue;
110
111 QString outfilename;
112 if(!singleoutfile.isEmpty()
113 && QFileInfo(m_zip->getCurrentFileName()).fileName() == file) {
114 outfilename = singleoutfile;
115 }
116 else if(singleoutfile.isEmpty()) {
117 outfilename = dest + "/" + m_zip->getCurrentFileName();
118 }
119 if(outfilename.isEmpty())
120 continue;
121 QFile outputFile(outfilename);
122 // make sure the output path exists
123 if(!QDir().mkpath(QFileInfo(outfilename).absolutePath())) {
124 result = false;
125 emit logItem(tr("Creating output path failed"), LOGERROR);
126 LOG_INFO() << "creating output path failed for:"
127 << outfilename;
128 break;
129 }
130 if(!outputFile.open(QFile::WriteOnly)) {
131 result = false;
132 emit logItem(tr("Creating output file failed"), LOGERROR);
133 LOG_INFO() << "creating output file failed:"
134 << outfilename;
135 break;
136 }
137 currentFile->open(QIODevice::ReadOnly);
138 outputFile.write(currentFile->readAll());
139 if(currentFile->getZipError() != UNZ_OK) {
140 result = false;
141 emit logItem(tr("Error during Zip operation"), LOGERROR);
142 LOG_INFO() << "QuaZip error:" << currentFile->getZipError()
143 << "on file" << currentFile->getFileName();
144 break;
145 }
146 currentFile->close();
147 outputFile.close();
148
149 emit logProgress(current, entries);
150 }
151 delete currentFile;
152 emit logProgress(1, 1);
153
154 return result;
155}
156
157
158//! @brief append a folder to current archive
159//! @param source source folder
160//! @param basedir base folder for archive. Will get stripped from zip paths.
161//! @return true on success, false otherwise
162bool ZipUtil::appendDirToArchive(QString& source, QString& basedir)
163{
164 bool result = true;
165 if(!m_zip || !m_zip->isOpen()) {
166 LOG_INFO() << "Zip file not open!";
167 return false;
168 }
169 // get a list of all files and folders. Needed for progress info and avoids
170 // recursive calls.
171 QDirIterator iterator(source, QDirIterator::Subdirectories);
172 QStringList fileList;
173 while(iterator.hasNext()) {
174 iterator.next();
175 // skip folders, we can't add them.
176 if(!QFileInfo(iterator.filePath()).isDir()) {
177 fileList.append(iterator.filePath());
178 }
179 }
180 LOG_INFO() << "Adding" << fileList.size() << "files to archive";
181
182 int max = fileList.size();
183 for(int i = 0; i < max; i++) {
184 QString current = fileList.at(i);
185 if(!appendFileToArchive(current, basedir)) {
186 LOG_ERROR() << "Error appending file" << current
187 << "to archive" << m_zip->getZipName();
188 result = false;
189 break;
190 }
191 emit logProgress(i, max);
192 }
193 return result;
194}
195
196
197//! @brief append a single file to current archive
198//!
199bool ZipUtil::appendFileToArchive(QString& file, QString& basedir)
200{
201 bool result = true;
202 if(!m_zip || !m_zip->isOpen()) {
203 LOG_ERROR() << "Zip file not open!";
204 return false;
205 }
206 // skip folders, we can't add them.
207 QFileInfo fileinfo(file);
208 if(fileinfo.isDir()) {
209 return false;
210 }
211 QString infile = fileinfo.canonicalFilePath();
212 QString newfile = infile;
213 newfile.remove(QDir(basedir).canonicalPath() + "/");
214
215 QuaZipFile fout(m_zip);
216 QFile fin(file);
217
218 if(!fin.open(QFile::ReadOnly)) {
219 LOG_ERROR() << "Could not open file for reading:" << file;
220 return false;
221 }
222 if(!fout.open(QIODevice::WriteOnly, QuaZipNewInfo(newfile, infile))) {
223 fin.close();
224 LOG_ERROR() << "Could not open file for writing:" << newfile;
225 return false;
226 }
227
228 result = (fout.write(fin.readAll()) < 0) ? false : true;
229 fin.close();
230 fout.close();
231 return result;
232}
233
234
235//! @brief calculate total size of extracted files
236qint64 ZipUtil::totalUncompressedSize(unsigned int clustersize)
237{
238 qint64 uncompressed = 0;
239
240 QList<QuaZipFileInfo> items = contentProperties();
241 if(items.size() == 0) {
242 return -1;
243 }
244 int max = items.size();
245 if(clustersize > 0) {
246 for(int i = 0; i < max; ++i) {
247 qint64 item = items.at(i).uncompressedSize;
248 uncompressed += (item + clustersize - (item % clustersize));
249 }
250 }
251 else {
252 for(int i = 0; i < max; ++i) {
253 uncompressed += items.at(i).uncompressedSize;
254 }
255 }
256 if(clustersize > 0) {
257 LOG_INFO() << "calculation rounded to cluster size for each file:"
258 << clustersize;
259 }
260 LOG_INFO() << "size of archive files uncompressed:"
261 << uncompressed;
262 return uncompressed;
263}
264
265
266QStringList ZipUtil::files(void)
267{
268 QList<QuaZipFileInfo> items = contentProperties();
269 QStringList fileList;
270 if(items.size() == 0) {
271 return fileList;
272 }
273 int max = items.size();
274 for(int i = 0; i < max; ++i) {
275 fileList.append(items.at(i).name);
276 }
277 return fileList;
278}
279
280
281QList<QuaZipFileInfo> ZipUtil::contentProperties()
282{
283 QList<QuaZipFileInfo> items;
284 if(!m_zip || !m_zip->isOpen()) {
285 LOG_ERROR() << "Zip file not open!";
286 return items;
287 }
288 QuaZipFileInfo info;
289 QuaZipFile currentFile(m_zip);
290 for(bool more = m_zip->goToFirstFile(); more; more = m_zip->goToNextFile())
291 {
292 currentFile.getFileInfo(&info);
293 if(currentFile.getZipError() != UNZ_OK) {
294 LOG_ERROR() << "QuaZip error:" << currentFile.getZipError()
295 << "on file" << currentFile.getFileName();
296 return QList<QuaZipFileInfo>();
297 }
298 items.append(info);
299 }
300 return items;
301}
302
diff --git a/utils/rbutilqt/base/ziputil.h b/utils/rbutilqt/base/ziputil.h
new file mode 100644
index 0000000000..25c3dce391
--- /dev/null
+++ b/utils/rbutilqt/base/ziputil.h
@@ -0,0 +1,53 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2011 Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef ZIPUTIL_H
20#define ZIPUTIL_H
21
22#include <QtCore>
23#include "archiveutil.h"
24#include "quazip/quazip.h"
25#include "quazip/quazipfile.h"
26#include "quazip/quazipfileinfo.h"
27
28class ZipUtil : public ArchiveUtil
29{
30 Q_OBJECT
31
32 public:
33 ZipUtil(QObject* parent);
34 ~ZipUtil();
35 bool open(QString& zipfile, QuaZip::Mode mode = QuaZip::mdUnzip);
36 virtual bool close(void);
37 virtual bool extractArchive(const QString& dest, QString file = "");
38 bool appendDirToArchive(QString& source, QString& basedir);
39 bool appendFileToArchive(QString& file, QString& basedir);
40 qint64 totalUncompressedSize(unsigned int clustersize = 0);
41 virtual QStringList files(void);
42
43 signals:
44 void logProgress(int, int);
45 void logItem(QString, int);
46
47 private:
48 QList<QuaZipFileInfo> contentProperties();
49 QuaZip* m_zip;
50
51};
52#endif
53
diff --git a/utils/rbutilqt/changelog.txt b/utils/rbutilqt/changelog.txt
new file mode 100644
index 0000000000..992ea19445
--- /dev/null
+++ b/utils/rbutilqt/changelog.txt
@@ -0,0 +1,42 @@
1# Rockbox Utility changelog.
2# This file is parsed by Rockbox Utility. Format:
3# - Lines starting with # are comments and ignored.
4# - A version starts with the string "Version" followed by the number.
5# - After the version individual entries follow. Those start with a *.
6# - After the entries an empty line has to follow.
7# - After that the next version can start.
8
9Version 1.4
10* Rework player detection functionality to provide better results.
11* Limit mountpoints ("Select your device in the filesystem") in configuration dialog to usable ones.
12* Change encoder volume configuration to allow more sensible values.
13* Save proxy password differently in configuration file (better solution for FS#12166).
14* Add support for building Rockbox Utility with Qt5.
15* Add support for extracting Original Firmware files compressed with CAB (G#418).
16* Add support for Creative Zen X-Fi3 (G#419).
17* Add Changelog window.
18* Rework System Trace functionality.
19* Add support for Iriver H300 v1.31K firmware.
20* Add support for Sandisk Sansa Clip Zip v01.01.21 firmware.
21* Fix manual link for Archos Recorder V2.
22
23Version 1.4.1
24* Fix crash on detecting player in MTP mode (FS#12989).
25* Extend hint when uninstallation requires reinstalling the Original Firmware.
26* Improve update check information dialog.
27* Correct USB IDs for Sandisk Sansa c200v2.
28* Add support for iPod Classic 6G bootloader.
29
30Version 1.5.0
31* Add support for xDuoo X3, X3ii, X20.
32* Add support for AGPTek Rocker.
33* Add support for AIGO Eros Q and various clones (AIGO Eros K, AGPTek H3, HIFI Walker H2, Surfans F20)
34* Add support for showing "retired" target status.
35* Update Iriver H100 / H300 series bootloader.
36* Rename Game Files installation to Plugin Data; now installs files for further games (Duke3D, Wolfenstein3D, etc.) as well as other plugins (MIDI patchset)
37* Support installing daily builds.
38* Move Manual / prerendered voice file installation to main dialog.
39* Support installing voice files in other languages than english (available languages depends on build).
40* Improved HiDPI support.
41* Drop support for Qt4, now requires Qt5.
42* Update various external libraries.
diff --git a/utils/rbutilqt/configure.cpp b/utils/rbutilqt/configure.cpp
new file mode 100644
index 0000000000..14080a552c
--- /dev/null
+++ b/utils/rbutilqt/configure.cpp
@@ -0,0 +1,984 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QMessageBox>
20#include <QProgressDialog>
21#include <QFileDialog>
22#include <QUrl>
23#ifdef QT_MULTIMEDIA_LIB
24#include <QSound>
25#endif
26
27#include "version.h"
28#include "configure.h"
29#include "autodetection.h"
30#include "ui_configurefrm.h"
31#include "encoderbase.h"
32#include "ttsbase.h"
33#include "system.h"
34#include "encttscfggui.h"
35#include "rbsettings.h"
36#include "playerbuildinfo.h"
37#include "utils.h"
38#include "comboboxviewdelegate.h"
39#if defined(Q_OS_WIN32)
40#if defined(UNICODE)
41#define _UNICODE
42#endif
43#include <tchar.h>
44#include <windows.h>
45#endif
46#include "rbutilqt.h"
47
48#include "systrace.h"
49#include "Logger.h"
50
51#define DEFAULT_LANG "English (en)"
52#define DEFAULT_LANG_CODE "en"
53
54Config::Config(QWidget *parent,int index) : QDialog(parent)
55{
56 programPath = qApp->applicationDirPath() + "/";
57 ui.setupUi(this);
58 ui.tabConfiguration->setCurrentIndex(index);
59 ui.radioManualProxy->setChecked(true);
60
61 // build language list and sort alphabetically
62 QStringList langs = findLanguageFiles();
63 for(int i = 0; i < langs.size(); ++i)
64 lang.insert(languageName(langs.at(i))
65 + QString(" (%1)").arg(langs.at(i)), langs.at(i));
66 lang.insert(DEFAULT_LANG, DEFAULT_LANG_CODE);
67 QMap<QString, QString>::const_iterator i = lang.constBegin();
68 while (i != lang.constEnd()) {
69 ui.listLanguages->addItem(i.key());
70 i++;
71 }
72
73 ComboBoxViewDelegate *delegate = new ComboBoxViewDelegate(this);
74 ui.mountPoint->setItemDelegate(delegate);
75#if !defined(DBG)
76 ui.mountPoint->setEditable(false);
77#endif
78
79 ui.listLanguages->setSelectionMode(QAbstractItemView::SingleSelection);
80 ui.proxyPass->setEchoMode(QLineEdit::Password);
81 ui.treeDevices->setAlternatingRowColors(true);
82 ui.listLanguages->setAlternatingRowColors(true);
83
84 /* Explicitly set some widgets to have left-to-right layout */
85 ui.treeDevices->setLayoutDirection(Qt::LeftToRight);
86 ui.mountPoint->setLayoutDirection(Qt::LeftToRight);
87 ui.proxyHost->setLayoutDirection(Qt::LeftToRight);
88 ui.proxyPort->setLayoutDirection(Qt::LeftToRight);
89 ui.proxyUser->setLayoutDirection(Qt::LeftToRight);
90 ui.proxyPass->setLayoutDirection(Qt::LeftToRight);
91 ui.listLanguages->setLayoutDirection(Qt::LeftToRight);
92 ui.cachePath->setLayoutDirection(Qt::LeftToRight);
93 ui.comboTts->setLayoutDirection(Qt::LeftToRight);
94
95 this->setModal(true);
96
97 connect(ui.buttonOk, SIGNAL(clicked()), this, SLOT(accept()));
98 connect(ui.buttonCancel, SIGNAL(clicked()), this, SLOT(abort()));
99 connect(ui.radioNoProxy, SIGNAL(toggled(bool)), this, SLOT(setNoProxy(bool)));
100 connect(ui.radioSystemProxy, SIGNAL(toggled(bool)), this, SLOT(setSystemProxy(bool)));
101 connect(ui.refreshMountPoint, SIGNAL(clicked()), this, SLOT(refreshMountpoint()));
102 connect(ui.buttonAutodetect,SIGNAL(clicked()),this,SLOT(autodetect()));
103 connect(ui.buttonCacheBrowse, SIGNAL(clicked()), this, SLOT(browseCache()));
104 connect(ui.buttonCacheClear, SIGNAL(clicked()), this, SLOT(cacheClear()));
105 connect(ui.configTts, SIGNAL(clicked()), this, SLOT(configTts()));
106 connect(ui.configEncoder, SIGNAL(clicked()), this, SLOT(configEnc()));
107 connect(ui.comboTts, SIGNAL(currentIndexChanged(int)), this, SLOT(updateTtsState(int)));
108 connect(ui.treeDevices, SIGNAL(itemSelectionChanged()), this, SLOT(updateEncState()));
109 connect(ui.testTTS,SIGNAL(clicked()),this,SLOT(testTts()));
110 connect(ui.showDisabled, SIGNAL(toggled(bool)), this, SLOT(showDisabled(bool)));
111 connect(ui.mountPoint, SIGNAL(editTextChanged(QString)), this, SLOT(updateMountpoint(QString)));
112 connect(ui.mountPoint, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMountpoint(int)));
113 connect(ui.checkShowProxyPassword, SIGNAL(toggled(bool)), this, SLOT(showProxyPassword(bool)));
114 // delete this dialog after it finished automatically.
115 connect(this, SIGNAL(finished(int)), this, SLOT(deleteLater()));
116
117 setUserSettings();
118 setDevices();
119}
120
121
122void Config::accept()
123{
124 LOG_INFO() << "checking configuration";
125 QString errormsg = tr("The following errors occurred:") + "<ul>";
126 bool error = false;
127
128 // proxy: save entered proxy values, not displayed.
129 if(ui.radioManualProxy->isChecked()) {
130 proxy.setScheme("http");
131 proxy.setUserName(ui.proxyUser->text());
132 proxy.setPassword(ui.proxyPass->text());
133 proxy.setHost(ui.proxyHost->text());
134 proxy.setPort(ui.proxyPort->value());
135 }
136
137 // Encode the password using base64 before storing it to the configuration
138 // file.
139 // There are two reasons for doing this:
140 // - QUrl::toEncoded() has problems with some characters like the colon and
141 // @. Those are not percent encoded, causing the string getting parsed
142 // wrongly when reading it back (see FS#12166).
143 // - The password is cleartext in the configuration file.
144 // While using base64 doesn't provide any real security either it's at
145 // least better than plaintext.
146 // Since this program is open source any fixed mechanism to obfuscate /
147 // encrypt the password isn't much help either since anyone interested in
148 // the password can look at the sources. The best way would be to
149 // eventually use host OS functionality to store the password.
150 QUrl p = proxy;
151 p.setPassword(proxy.password().toUtf8().toBase64());
152 RbSettings::setValue(RbSettings::Proxy, p.toString());
153 LOG_INFO() << "setting proxy to:" << proxy.toString(QUrl::RemovePassword);
154 // proxy type
155 QString proxyType;
156 if(ui.radioNoProxy->isChecked()) proxyType = "none";
157 else if(ui.radioSystemProxy->isChecked()) proxyType = "system";
158 else proxyType = "manual";
159 RbSettings::setValue(RbSettings::ProxyType, proxyType);
160
161 RbSettings::setValue(RbSettings::Language, language);
162
163 // make sure mountpoint is read from dropdown box
164 if(mountpoint.isEmpty()) {
165 updateMountpoint(ui.mountPoint->currentIndex());
166 }
167
168 // mountpoint
169 if(mountpoint.isEmpty()) {
170 errormsg += "<li>" + tr("No mountpoint given") + "</li>";
171 error = true;
172 }
173 else if(!QFileInfo::exists(mountpoint)) {
174 errormsg += "<li>" + tr("Mountpoint does not exist") + "</li>";
175 error = true;
176 }
177 else if(!QFileInfo(mountpoint).isDir()) {
178 errormsg += "<li>" + tr("Mountpoint is not a directory.") + "</li>";
179 error = true;
180 }
181 else if(!QFileInfo(mountpoint).isWritable()) {
182 errormsg += "<li>" + tr("Mountpoint is not writeable") + "</li>";
183 error = true;
184 }
185 else {
186 RbSettings::setValue(RbSettings::Mountpoint,
187 QDir::fromNativeSeparators(mountpoint));
188 }
189
190 // platform
191 QString nplat;
192 if(ui.treeDevices->selectedItems().size() != 0) {
193 nplat = ui.treeDevices->selectedItems().at(0)->data(0, Qt::UserRole).toString();
194 RbSettings::setValue(RbSettings::Platform, nplat);
195 }
196 else {
197 errormsg += "<li>" + tr("No player selected") + "</li>";
198 error = true;
199 }
200
201 // cache settings
202 if(QFileInfo(ui.cachePath->text()).isDir()) {
203 if(!QFileInfo(ui.cachePath->text()).isWritable()) {
204 errormsg += "<li>" + tr("Cache path not writeable. Leave path empty "
205 "to default to systems temporary path.") + "</li>";
206 error = true;
207 }
208 else
209 RbSettings::setValue(RbSettings::CachePath, ui.cachePath->text());
210 }
211 else // default to system temp path
212 RbSettings::setValue(RbSettings::CachePath, QDir::tempPath());
213 RbSettings::setValue(RbSettings::CacheDisabled, ui.cacheDisable->isChecked());
214
215 // tts settings
216 RbSettings::setValue(RbSettings::UseTtsCorrections, ui.ttsCorrections->isChecked());
217 int i = ui.comboTts->currentIndex();
218 RbSettings::setValue(RbSettings::Tts, ui.comboTts->itemData(i).toString());
219
220 RbSettings::setValue(RbSettings::RbutilVersion, PUREVERSION);
221
222 errormsg += "</ul>";
223 errormsg += tr("You need to fix the above errors before you can continue.");
224
225 if(error) {
226 QMessageBox::critical(this, tr("Configuration error"), errormsg);
227 }
228 else {
229 // sync settings
230 RbSettings::sync();
231 this->close();
232 emit settingsUpdated();
233 }
234}
235
236
237void Config::abort()
238{
239 LOG_INFO() << "aborted.";
240 this->close();
241}
242
243
244void Config::setUserSettings()
245{
246 // set proxy
247 proxy.setUrl(RbSettings::value(RbSettings::Proxy).toString(),
248 QUrl::StrictMode);
249 // password is base64 encoded in configuration.
250 QByteArray pw = QByteArray::fromBase64(proxy.password().toUtf8());
251 proxy.setPassword(pw);
252
253 ui.proxyPort->setValue(proxy.port());
254 ui.proxyHost->setText(proxy.host());
255 ui.proxyUser->setText(proxy.userName());
256 ui.proxyPass->setText(proxy.password());
257
258 QString proxyType = RbSettings::value(RbSettings::ProxyType).toString();
259 if(proxyType == "manual") ui.radioManualProxy->setChecked(true);
260 else if(proxyType == "system") ui.radioSystemProxy->setChecked(true);
261 else ui.radioNoProxy->setChecked(true);
262
263 // set language selection
264 QList<QListWidgetItem*> a;
265 QString b;
266 // find key for lang value
267 QMap<QString, QString>::const_iterator i = lang.constBegin();
268 QString l = RbSettings::value(RbSettings::Language).toString();
269 if(l.isEmpty())
270 l = QLocale::system().name();
271 while (i != lang.constEnd()) {
272 if(i.value() == l) {
273 b = i.key();
274 break;
275 }
276 else if(l.startsWith(i.value(), Qt::CaseInsensitive)) {
277 // check if there is a base language (en -> en_US, etc.)
278 b = i.key();
279 break;
280 }
281 i++;
282 }
283 a = ui.listLanguages->findItems(b, Qt::MatchExactly);
284 if(a.size() > 0)
285 ui.listLanguages->setCurrentItem(a.at(0));
286 // don't connect before language list has been set up to prevent
287 // triggering the signal by selecting the saved language.
288 connect(ui.listLanguages, SIGNAL(itemSelectionChanged()), this, SLOT(updateLanguage()));
289
290 // devices tab
291 refreshMountpoint();
292 mountpoint = QDir::toNativeSeparators(RbSettings::value(RbSettings::Mountpoint).toString());
293 setMountpoint(mountpoint);
294
295 // cache tab
296 if(!QFileInfo(RbSettings::value(RbSettings::CachePath).toString()).isDir())
297 RbSettings::setValue(RbSettings::CachePath, QDir::tempPath());
298 ui.cachePath->setText(QDir::toNativeSeparators(RbSettings::value(RbSettings::CachePath).toString()));
299 ui.cacheDisable->setChecked(RbSettings::value(RbSettings::CacheDisabled).toBool());
300 updateCacheInfo(RbSettings::value(RbSettings::CachePath).toString());
301
302 // TTS tab
303 ui.ttsCorrections->setChecked(RbSettings::value(RbSettings::UseTtsCorrections).toBool());
304}
305
306
307void Config::updateCacheInfo(QString path)
308{
309 qint64 sz = Utils::recursiveFolderSize(path + "/rbutil-cache");
310 ui.cacheSize->setText(tr("Current cache size is %L1 kiB.")
311 .arg(sz/1024));
312}
313
314
315void Config::showProxyPassword(bool show)
316{
317 if(show)
318 ui.proxyPass->setEchoMode(QLineEdit::Normal);
319 else
320 ui.proxyPass->setEchoMode(QLineEdit::Password);
321}
322
323
324void Config::showDisabled(bool show)
325{
326 LOG_INFO() << "disabled targets shown:" << show;
327 if(show)
328 QMessageBox::warning(this, tr("Showing disabled targets"),
329 tr("You just enabled showing targets that are marked disabled. "
330 "Disabled targets are not recommended to end users. Please "
331 "use this option only if you know what you are doing."));
332 setDevices();
333
334}
335
336
337void Config::setDevices()
338{
339
340 // setup devices table
341 LOG_INFO() << "setting up devices list";
342
343 QStringList targets;
344 if(ui.showDisabled->isChecked())
345 targets = PlayerBuildInfo::instance()->value(
346 PlayerBuildInfo::TargetNamesAll).toStringList();
347 else
348 targets = PlayerBuildInfo::instance()->value(
349 PlayerBuildInfo::TargetNamesEnabled).toStringList();
350
351 QMultiMap <QString, QString> manuf;
352 for(int it = 0; it < targets.size(); it++)
353 {
354 QString curbrand = PlayerBuildInfo::instance()->value(
355 PlayerBuildInfo::Brand, targets.at(it)).toString();
356 manuf.insert(curbrand, targets.at(it));
357 }
358
359 // set up devices table
360 ui.treeDevices->header()->hide();
361 ui.treeDevices->expandAll();
362 ui.treeDevices->setColumnCount(1);
363 QList<QTreeWidgetItem *> items;
364
365 // get manufacturers
366 QStringList brands = manuf.uniqueKeys();
367 QTreeWidgetItem *w;
368 QTreeWidgetItem *w2;
369 QTreeWidgetItem *w3 = nullptr;
370
371 QString selected = RbSettings::value(RbSettings::Platform).toString();
372 for(int c = 0; c < brands.size(); c++) {
373 w = new QTreeWidgetItem();
374 w->setFlags(Qt::ItemIsEnabled);
375 w->setText(0, brands.at(c));
376 items.append(w);
377 // go through platforms and add all players matching the current brand
378 for(int it = 0; it < targets.size(); it++) {
379 // skip if not current brand
380 if(!manuf.values(brands.at(c)).contains(targets.at(it)))
381 continue;
382 // construct display name
383 QString curname = QString("%1 (%2)").arg(
384 PlayerBuildInfo::instance()->value(PlayerBuildInfo::DisplayName,
385 targets.at(it)).toString(),
386 PlayerBuildInfo::instance()->statusAsString(targets.at(it)));
387 LOG_INFO() << "add supported device:" << brands.at(c) << curname;
388 w2 = new QTreeWidgetItem(w, QStringList(curname));
389 w2->setData(0, Qt::UserRole, targets.at(it));
390
391 if(targets.at(it) == selected) {
392 w2->setSelected(true);
393 w->setExpanded(true);
394 w3 = w2; // save pointer to hilight old selection
395 }
396 items.append(w2);
397 }
398 }
399 // remove any old items in list
400 QTreeWidgetItem* widgetitem;
401 do {
402 widgetitem = ui.treeDevices->takeTopLevelItem(0);
403 delete widgetitem;
404 }
405 while(widgetitem);
406 // add new items
407 ui.treeDevices->insertTopLevelItems(0, items);
408 if(w3 != nullptr) {
409 ui.treeDevices->setCurrentItem(w3); // hilight old selection
410 ui.treeDevices->scrollToItem(w3);
411 }
412
413 // tts / encoder tab
414
415 //encoders
416 updateEncState();
417
418 //tts
419 QStringList ttslist = TTSBase::getTTSList();
420 for(int a = 0; a < ttslist.size(); a++)
421 ui.comboTts->addItem(TTSBase::getTTSName(ttslist.at(a)), ttslist.at(a));
422 //update index of combobox
423 int index = ui.comboTts->findData(RbSettings::value(RbSettings::Tts).toString());
424 if(index < 0) index = 0;
425 ui.comboTts->setCurrentIndex(index);
426 updateTtsState(index);
427
428}
429
430
431void Config::updateTtsState(int index)
432{
433 QString ttsName = ui.comboTts->itemData(index).toString();
434 TTSBase* tts = TTSBase::getTTS(this,ttsName);
435
436 if(!tts)
437 {
438 QMessageBox::critical(this, tr("TTS error"),
439 tr("The selected TTS failed to initialize. You can't use this TTS."));
440 return;
441 }
442
443 if(tts->configOk())
444 {
445 ui.configTTSstatus->setText(tr("Configuration OK"));
446 ui.configTTSstatusimg->setPixmap(QPixmap(QString::fromUtf8(":/icons/go-next.svg")));
447#ifdef QT_MULTIMEDIA_LIB
448 ui.testTTS->setEnabled(true);
449#else
450 ui.testTTS->setEnabled(false);
451#endif
452 }
453 else
454 {
455 ui.configTTSstatus->setText(tr("Configuration INVALID"));
456 ui.configTTSstatusimg->setPixmap(QPixmap(QString::fromUtf8(":/icons/dialog-error.svg")));
457 ui.testTTS->setEnabled(false);
458 }
459
460 delete tts; /* Config objects are never deleted (in fact, they are leaked..), so we can't rely on QObject,
461 since that would delete the TTSBase instance on application exit*/
462}
463
464void Config::updateEncState()
465{
466 if(ui.treeDevices->selectedItems().size() == 0)
467 return;
468
469 QString devname = ui.treeDevices->selectedItems().at(0)->data(0, Qt::UserRole).toString();
470 QString encoder = PlayerBuildInfo::instance()->value(
471 PlayerBuildInfo::Encoder, devname).toString();
472 ui.encoderName->setText(EncoderBase::getEncoderName(
473 PlayerBuildInfo::instance()->value(PlayerBuildInfo::Encoder, devname).toString()));
474
475 EncoderBase* enc = EncoderBase::getEncoder(this,encoder);
476
477 if(enc->configOk())
478 {
479 ui.configEncstatus->setText(tr("Configuration OK"));
480 ui.configEncstatusimg->setPixmap(QPixmap(QString::fromUtf8(":/icons/go-next.svg")));
481 }
482 else
483 {
484 ui.configEncstatus->setText(tr("Configuration INVALID"));
485 ui.configEncstatusimg->setPixmap(QPixmap(QString::fromUtf8(":/icons/dialog-error.svg")));
486 }
487}
488
489
490void Config::setNoProxy(bool checked)
491{
492 ui.proxyPort->setEnabled(!checked);
493 ui.proxyHost->setEnabled(!checked);
494 ui.proxyUser->setEnabled(!checked);
495 ui.proxyPass->setEnabled(!checked);
496 ui.checkShowProxyPassword->setEnabled(!checked);
497 ui.checkShowProxyPassword->setChecked(false);
498 showProxyPassword(false);
499}
500
501
502void Config::setSystemProxy(bool checked)
503{
504 setNoProxy(checked);
505 if(checked) {
506 // save values in input box
507 proxy.setScheme("http");
508 proxy.setUserName(ui.proxyUser->text());
509 proxy.setPassword(ui.proxyPass->text());
510 proxy.setHost(ui.proxyHost->text());
511 proxy.setPort(ui.proxyPort->value());
512 // show system values in input box
513 QUrl envproxy = System::systemProxy();
514 LOG_INFO() << "setting system proxy" << envproxy;
515
516 ui.proxyHost->setText(envproxy.host());
517 ui.proxyPort->setValue(envproxy.port());
518 ui.proxyUser->setText(envproxy.userName());
519 ui.proxyPass->setText(envproxy.password());
520
521 if(envproxy.host().isEmpty() || envproxy.port() == -1) {
522 LOG_WARNING() << "system proxy is invalid.";
523 QMessageBox::warning(this, tr("Proxy Detection"),
524 tr("The System Proxy settings are invalid!\n"
525 "Rockbox Utility can't work with this proxy settings. "
526 "Make sure the system proxy is set correctly. Note that "
527 "\"proxy auto-config (PAC)\" scripts are not supported by "
528 "Rockbox Utility. If your system uses this you need "
529 "to use manual proxy settings."),
530 QMessageBox::Ok ,QMessageBox::Ok);
531 // the current proxy settings are invalid. Check the saved proxy
532 // type again.
533 if(RbSettings::value(RbSettings::ProxyType).toString() == "manual")
534 ui.radioManualProxy->setChecked(true);
535 else
536 ui.radioNoProxy->setChecked(true);
537 }
538
539 }
540 else {
541 ui.proxyHost->setText(proxy.host());
542 ui.proxyPort->setValue(proxy.port());
543 ui.proxyUser->setText(proxy.userName());
544 ui.proxyPass->setText(proxy.password());
545 }
546
547}
548
549
550QStringList Config::findLanguageFiles()
551{
552 QDir dir(programPath);
553 QStringList fileNames;
554 QStringList langs;
555 fileNames = dir.entryList(QStringList("*.qm"), QDir::Files, QDir::Name);
556
557 QDir resDir(":/lang");
558 fileNames += resDir.entryList(QStringList("*.qm"), QDir::Files, QDir::Name);
559
560 QRegExp exp("^rbutil_(.*)\\.qm");
561 for(int i = 0; i < fileNames.size(); i++) {
562 QString a = fileNames.at(i);
563 a.replace(exp, "\\1");
564 langs.append(a);
565 }
566 langs.sort();
567 LOG_INFO() << "available lang files:" << langs;
568
569 return langs;
570}
571
572
573QString Config::languageName(const QString &qmFile)
574{
575 QTranslator translator;
576
577 QString file = "rbutil_" + qmFile;
578 if(!translator.load(file, programPath))
579 translator.load(file, ":/lang");
580
581 return translator.translate("Configure", "English",
582 "This is the localized language name, i.e. your language.");
583}
584
585
586void Config::updateLanguage()
587{
588 LOG_INFO() << "update selected language";
589
590 // remove all old translators
591 for(int i = 0; i < RbUtilQt::translators.size(); ++i) {
592 qApp->removeTranslator(RbUtilQt::translators.at(i));
593 // do not delete old translators, this confuses Qt.
594 }
595 RbUtilQt::translators.clear();
596 QList<QListWidgetItem*> a = ui.listLanguages->selectedItems();
597 if(a.size() > 0)
598 language = lang.value(a.at(0)->text());
599 LOG_INFO() << "new language:" << language;
600
601 QTranslator *translator = new QTranslator(qApp);
602 QTranslator *qttrans = new QTranslator(qApp);
603 QString absolutePath = QCoreApplication::instance()->applicationDirPath();
604
605 if(!translator->load("rbutil_" + language, absolutePath))
606 translator->load("rbutil_" + language, ":/lang");
607 if(!qttrans->load("qt_" + language,
608 QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
609 qttrans->load("qt_" + language, ":/lang");
610
611 qApp->installTranslator(translator);
612 qApp->installTranslator(qttrans);
613 //: This string is used to indicate the writing direction. Translate it
614 //: to "RTL" (without quotes) for RTL languages. Anything else will get
615 //: treated as LTR language.
616 if(QObject::tr("LTR") == "RTL")
617 qApp->setLayoutDirection(Qt::RightToLeft);
618 else
619 qApp->setLayoutDirection(Qt::LeftToRight);
620
621 RbUtilQt::translators.append(translator);
622 RbUtilQt::translators.append(qttrans);
623
624 QLocale::setDefault(QLocale(language));
625
626}
627
628
629void Config::browseCache()
630{
631 QString old = ui.cachePath->text();
632 if(!QFileInfo(old).isDir())
633 old = QDir::tempPath();
634 QString c = QFileDialog::getExistingDirectory(this, tr("Set Cache Path"), old);
635 if(c.isEmpty())
636 c = old;
637 else if(!QFileInfo(c).isDir())
638 c = QDir::tempPath();
639 ui.cachePath->setText(QDir::toNativeSeparators(c));
640 updateCacheInfo(c);
641}
642
643
644void Config::refreshMountpoint()
645{
646 // avoid QComboBox to send signals during rebuild to avoid changing to an
647 // unwanted item.
648 ui.mountPoint->blockSignals(true);
649 ui.mountPoint->clear();
650 QStringList mps = Utils::mountpoints(Utils::MountpointsSupported);
651 for(int i = 0; i < mps.size(); ++i) {
652 // add mountpoint as user data so we can change the displayed string
653 // later (to include volume label or similar)
654 // Skip unwritable mountpoints, they are not useable for us.
655 if(QFileInfo(mps.at(i)).isWritable()) {
656 QString description = tr("%1 (%2 GiB of %3 GiB free)")
657 .arg(Utils::filesystemName(mps.at(i)))
658 .arg((double)Utils::filesystemFree(mps.at(i))/(1<<30), 0, 'f', 2)
659 .arg((double)Utils::filesystemTotal(mps.at(i))/(1<<30), 0, 'f', 2);
660 ui.mountPoint->addItem(QDir::toNativeSeparators(mps.at(i)), description);
661 }
662 else {
663 LOG_WARNING() << "mountpoint not writable, skipping:" << mps.at(i);
664 }
665 }
666 if(!mountpoint.isEmpty()) {
667 setMountpoint(mountpoint);
668 }
669 ui.mountPoint->blockSignals(false);
670}
671
672
673void Config::updateMountpoint(QString m)
674{
675 if(!m.isEmpty()) {
676 mountpoint = QDir::fromNativeSeparators(m);
677 LOG_INFO() << "Mountpoint set to" << mountpoint;
678 }
679}
680
681
682void Config::updateMountpoint(int idx)
683{
684 if(idx == -1) {
685 return;
686 }
687 QString mp = ui.mountPoint->itemText(idx);
688 if(!mp.isEmpty()) {
689 mountpoint = QDir::fromNativeSeparators(mp);
690 LOG_INFO() << "Mountpoint set to" << mountpoint;
691 }
692}
693
694
695void Config::setMountpoint(QString m)
696{
697 if(m.isEmpty()) {
698 return;
699 }
700 int index = ui.mountPoint->findText(QDir::toNativeSeparators(m));
701 if(index != -1) {
702 ui.mountPoint->setCurrentIndex(index);
703 }
704 else {
705 // keep a mountpoint that is not in the list for convenience (to allow
706 // easier development)
707 ui.mountPoint->addItem(QDir::toNativeSeparators(m));
708 ui.mountPoint->setCurrentIndex(ui.mountPoint->findText(m));
709 }
710 LOG_INFO() << "Mountpoint set to" << mountpoint;
711}
712
713
714void Config::autodetect()
715{
716 Autodetection detector(this);
717 // disable tree during detection as "working" feedback.
718 // TODO: replace the tree view with a splash screen during this time.
719 ui.treeDevices->setEnabled(false);
720 this->setCursor(Qt::WaitCursor);
721 QCoreApplication::processEvents();
722
723 detector.detect();
724 QList<struct Autodetection::Detected> detected;
725 detected = detector.detected();
726 this->unsetCursor();
727 if(detected.size() > 1) {
728 // FIXME: handle multiple found players.
729 QString msg;
730 msg = tr("Multiple devices have been detected. Please disconnect "
731 "all players but one and try again.");
732 msg += "<br/>";
733 msg += tr("Detected devices:");
734 msg += "<ul>";
735 for(int i = 0; i < detected.size(); ++i) {
736 QString mp = detected.at(i).mountpoint;
737 if(mp.isEmpty()) {
738 mp = tr("(unknown)");
739 }
740 msg += QString("<li>%1</li>").arg(tr("%1 at %2").arg(
741 PlayerBuildInfo::instance()->value(
742 PlayerBuildInfo::DisplayName,
743 detected.at(i).device).toString(),
744 QDir::toNativeSeparators(mp)));
745 }
746 msg += "</ul>";
747 msg += tr("Note: detecting connected devices might be ambiguous. "
748 "You might have less devices connected than listed. "
749 "In this case it might not be possible to detect your "
750 "player unambiguously.");
751 QMessageBox::information(this, tr("Device Detection"), msg);
752 ui.treeDevices->setEnabled(true);
753 }
754 else if(detected.size() == 0) {
755 QMessageBox::warning(this, tr("Device Detection"),
756 tr("Could not detect a device.\n"
757 "Select your device and Mountpoint manually."),
758 QMessageBox::Ok ,QMessageBox::Ok);
759 ui.treeDevices->setEnabled(true);
760 }
761 else if(detected.at(0).status != Autodetection::PlayerOk
762 && detected.at(0).status != Autodetection::PlayerAmbiguous) {
763 QString msg;
764 switch(detected.at(0).status) {
765 case Autodetection::PlayerIncompatible:
766 msg += tr("Detected an unsupported player:\n%1\n"
767 "Sorry, Rockbox doesn't run on your player.")
768 .arg(PlayerBuildInfo::instance()->value(
769 PlayerBuildInfo::DisplayName,
770 detected.at(0).device).toString());
771 break;
772 case Autodetection::PlayerMtpMode:
773 msg = tr("%1 in MTP mode found!\n"
774 "You need to change your player to MSC mode for installation. ")
775 .arg(PlayerBuildInfo::instance()->value(
776 PlayerBuildInfo::DisplayName,
777 detected.at(0).device).toString());
778 break;
779 case Autodetection::PlayerWrongFilesystem:
780 if(PlayerBuildInfo::instance()->value(
781 PlayerBuildInfo::BootloaderMethod, detected.at(0).device) == "ipod") {
782 msg = tr("%1 \"MacPod\" found!\n"
783 "Rockbox needs a FAT formatted Ipod (so-called \"WinPod\") "
784 "to run. ").arg(PlayerBuildInfo::instance()->value(
785 PlayerBuildInfo::DisplayName,
786 detected.at(0).device).toString());
787 }
788 else {
789 msg = tr("The player contains an incompatible filesystem.\n"
790 "Make sure you selected the correct mountpoint and "
791 "the player is set up to use a filesystem compatible "
792 "with Rockbox.");
793 }
794 break;
795 case Autodetection::PlayerError:
796 default:
797 msg += tr("An unknown error occured during player detection.");
798 break;
799 }
800 QMessageBox::information(this, tr("Device Detection"), msg);
801 ui.treeDevices->setEnabled(true);
802 }
803 else {
804 selectDevice(detected.at(0).device, detected.at(0).mountpoint);
805 }
806
807}
808
809void Config::selectDevice(QString device, QString mountpoint)
810{
811 // collapse all items
812 for(int a = 0; a < ui.treeDevices->topLevelItemCount(); a++)
813 ui.treeDevices->topLevelItem(a)->setExpanded(false);
814 // deselect the selected item(s)
815 for(int a = 0; a < ui.treeDevices->selectedItems().size(); a++)
816 ui.treeDevices->selectedItems().at(a)->setSelected(false);
817
818 // find the new item
819 // enumerate all platform items
820 QList<QTreeWidgetItem*> itmList
821 = ui.treeDevices->findItems("*",Qt::MatchWildcard);
822 for(int i=0; i< itmList.size();i++)
823 {
824 //enumerate device items
825 for(int j=0;j < itmList.at(i)->childCount();j++)
826 {
827 QString data = itmList.at(i)->child(j)->data(0, Qt::UserRole).toString();
828 // unset bold flag
829 QFont f = itmList.at(i)->child(j)->font(0);
830 f.setBold(false);
831 itmList.at(i)->child(j)->setFont(0, f);
832
833 if(device == data) // item found
834 {
835 f.setBold(true);
836 itmList.at(i)->child(j)->setFont(0, f);
837 itmList.at(i)->child(j)->setSelected(true); //select the item
838 itmList.at(i)->setExpanded(true); //expand the platform item
839 //ui.treeDevices->indexOfTopLevelItem(itmList.at(i)->child(j));
840 ui.treeDevices->scrollToItem(itmList.at(i)->child(j));
841 break;
842 }
843 }
844 }
845 this->unsetCursor();
846
847 if(!mountpoint.isEmpty())
848 {
849 setMountpoint(mountpoint);
850 }
851 else
852 {
853 QMessageBox::warning(this, tr("Autodetection"),
854 tr("Could not detect a Mountpoint.\n"
855 "Select your Mountpoint manually."),
856 QMessageBox::Ok, QMessageBox::Ok);
857 }
858 ui.treeDevices->setEnabled(true);
859}
860
861
862void Config::cacheClear()
863{
864 if(QMessageBox::critical(this, tr("Really delete cache?"),
865 tr("Do you really want to delete the cache? "
866 "Make absolutely sure this setting is correct as it will "
867 "remove <b>all</b> files in this folder!"),
868 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
869 return;
870
871 QString cache = ui.cachePath->text() + "/rbutil-cache/";
872 if(!QFileInfo(cache).isDir()) {
873 QMessageBox::critical(this, tr("Path wrong!"),
874 tr("The cache path is invalid. Aborting."), QMessageBox::Ok);
875 return;
876 }
877 QDir dir(cache);
878 dir.removeRecursively();
879 updateCacheInfo(RbSettings::value(RbSettings::CachePath).toString());
880}
881
882
883void Config::configTts()
884{
885 int index = ui.comboTts->currentIndex();
886 TTSBase* tts = TTSBase::getTTS(this,ui.comboTts->itemData(index).toString());
887 EncTtsCfgGui gui(this,tts,TTSBase::getTTSName(ui.comboTts->itemData(index).toString()));
888 gui.exec();
889 updateTtsState(ui.comboTts->currentIndex());
890 delete tts; /* Config objects are never deleted (in fact, they are
891 leaked..), so we can't rely on QObject, since that would
892 delete the TTSBase instance on application exit */
893}
894
895void Config::testTts()
896{
897#ifdef QT_MULTIMEDIA_LIB
898 QString errstr;
899 int index = ui.comboTts->currentIndex();
900 TTSBase* tts;
901 tts = TTSBase::getTTS(this,ui.comboTts->itemData(index).toString());
902 if(!tts)
903 {
904 QMessageBox::critical(this, tr("TTS error"),
905 tr("The selected TTS failed to initialize. You can't use this TTS."));
906 return;
907 }
908 ui.testTTS->setEnabled(false);
909 if(!tts->configOk())
910 {
911 QMessageBox::warning(this,tr("TTS configuration invalid"),
912 tr("TTS configuration invalid. \n Please configure TTS engine."));
913 return;
914 }
915 if(!tts->start(&errstr))
916 {
917 QMessageBox::warning(this,tr("Could not start TTS engine."),
918 tr("Could not start TTS engine.\n") + errstr
919 + tr("\nPlease configure TTS engine."));
920 ui.testTTS->setEnabled(true);
921 return;
922 }
923
924 QString filename;
925 QTemporaryFile file(this);
926 // keep filename empty if the TTS can do speaking for itself.
927 if(!(tts->capabilities() & TTSBase::CanSpeak)) {
928 file.open();
929 filename = file.fileName();
930 file.close();
931 }
932
933 if(tts->voice(tr("Rockbox Utility Voice Test"),filename,&errstr) == FatalError)
934 {
935 tts->stop();
936 QMessageBox::warning(this,tr("Could not voice test string."),
937 tr("Could not voice test string.\n") + errstr
938 + tr("\nPlease configure TTS engine."));
939 ui.testTTS->setEnabled(false);
940 return;
941 }
942 tts->stop();
943 if(!filename.isEmpty()) {
944 QSound::play(filename);
945 }
946 ui.testTTS->setEnabled(true);
947 delete tts; /* Config objects are never deleted (in fact, they are
948 leaked..), so we can't rely on QObject, since that would
949 delete the TTSBase instance on application exit */
950#endif
951}
952
953void Config::configEnc()
954{
955 if(ui.treeDevices->selectedItems().size() == 0)
956 return;
957
958 QString devname = ui.treeDevices->selectedItems().at(0)->data(0, Qt::UserRole).toString();
959 QString encoder = PlayerBuildInfo::instance()->value(
960 PlayerBuildInfo::Encoder, devname).toString();
961 ui.encoderName->setText(
962 EncoderBase::getEncoderName(PlayerBuildInfo::instance()->value(
963 PlayerBuildInfo::Encoder, devname).toString()));
964
965
966 EncoderBase* enc = EncoderBase::getEncoder(this,encoder);
967
968 EncTtsCfgGui gui(this,enc,EncoderBase::getEncoderName(encoder));
969 gui.exec();
970
971 updateEncState();
972}
973
974
975void Config::changeEvent(QEvent *e)
976{
977 if(e->type() == QEvent::LanguageChange) {
978 ui.retranslateUi(this);
979 updateCacheInfo(ui.cachePath->text());
980 } else {
981 QWidget::changeEvent(e);
982 }
983}
984
diff --git a/utils/rbutilqt/configure.h b/utils/rbutilqt/configure.h
new file mode 100644
index 0000000000..5f63e82447
--- /dev/null
+++ b/utils/rbutilqt/configure.h
@@ -0,0 +1,79 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Riebeling
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#ifndef CONFIGURE_H
22#define CONFIGURE_H
23
24#include "ui_configurefrm.h"
25#include <QDialog>
26#include <QWidget>
27#include <QUrl>
28
29class Config : public QDialog
30{
31 Q_OBJECT
32 public:
33 Config(QWidget *parent = nullptr,int index=0);
34
35 signals:
36 void settingsUpdated(void);
37
38 public slots:
39 void accept(void);
40 void abort(void);
41
42 private:
43 void setUserSettings();
44 void setDevices();
45
46 Ui::ConfigForm ui;
47
48 QStringList findLanguageFiles(void);
49 QString languageName(const QString&);
50 QMap<QString, QString> lang;
51 QString language;
52 QString programPath;
53 QUrl proxy;
54 QString mountpoint;
55 void updateCacheInfo(QString);
56 void changeEvent(QEvent *event);
57 void selectDevice(QString device, QString mountpoint);
58
59 private slots:
60 void showProxyPassword(bool show);
61 void setNoProxy(bool);
62 void setSystemProxy(bool);
63 void updateLanguage(void);
64 void refreshMountpoint(void);
65 void browseCache(void);
66 void autodetect(void);
67 void setMountpoint(QString);
68 void updateMountpoint(QString);
69 void updateMountpoint(int);
70 void cacheClear(void);
71 void configTts(void);
72 void configEnc(void);
73 void updateTtsState(int);
74 void updateEncState();
75 void testTts();
76 void showDisabled(bool);
77};
78
79#endif
diff --git a/utils/rbutilqt/configurefrm.ui b/utils/rbutilqt/configurefrm.ui
new file mode 100644
index 0000000000..8a923893b4
--- /dev/null
+++ b/utils/rbutilqt/configurefrm.ui
@@ -0,0 +1,572 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>ConfigForm</class>
4 <widget class="QDialog" name="ConfigForm">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>500</width>
10 <height>465</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Configuration</string>
15 </property>
16 <layout class="QGridLayout" name="gridLayout_2">
17 <item row="0" column="0">
18 <widget class="QLabel" name="labelTitle">
19 <property name="text">
20 <string>Configure Rockbox Utility</string>
21 </property>
22 </widget>
23 </item>
24 <item row="1" column="0" colspan="3">
25 <widget class="QTabWidget" name="tabConfiguration">
26 <property name="currentIndex">
27 <number>0</number>
28 </property>
29 <widget class="QWidget" name="tabDevice">
30 <attribute name="icon">
31 <iconset resource="rbutilqt.qrc">
32 <normaloff>:/icons/multimedia-player.svg</normaloff>:/icons/multimedia-player.svg</iconset>
33 </attribute>
34 <attribute name="title">
35 <string>&amp;Device</string>
36 </attribute>
37 <layout class="QGridLayout" name="gridLayout">
38 <item row="0" column="0" colspan="2">
39 <widget class="QLabel" name="labelMountPoint">
40 <property name="text">
41 <string>Select your device in the &amp;filesystem</string>
42 </property>
43 <property name="buddy">
44 <cstring>mountPoint</cstring>
45 </property>
46 </widget>
47 </item>
48 <item row="1" column="0" colspan="3">
49 <widget class="QComboBox" name="mountPoint">
50 <property name="editable">
51 <bool>true</bool>
52 </property>
53 </widget>
54 </item>
55 <item row="1" column="3">
56 <widget class="QPushButton" name="refreshMountPoint">
57 <property name="text">
58 <string>&amp;Refresh</string>
59 </property>
60 <property name="icon">
61 <iconset resource="rbutilqt.qrc">
62 <normaloff>:/icons/view-refresh.svg</normaloff>:/icons/view-refresh.svg</iconset>
63 </property>
64 <property name="autoDefault">
65 <bool>false</bool>
66 </property>
67 </widget>
68 </item>
69 <item row="2" column="0">
70 <widget class="QLabel" name="labelPlayer">
71 <property name="text">
72 <string>&amp;Select your audio player</string>
73 </property>
74 <property name="buddy">
75 <cstring>treeDevices</cstring>
76 </property>
77 </widget>
78 </item>
79 <item row="2" column="1">
80 <spacer name="horizontalSpacer">
81 <property name="orientation">
82 <enum>Qt::Horizontal</enum>
83 </property>
84 <property name="sizeHint" stdset="0">
85 <size>
86 <width>118</width>
87 <height>20</height>
88 </size>
89 </property>
90 </spacer>
91 </item>
92 <item row="2" column="2" colspan="2">
93 <widget class="QCheckBox" name="showDisabled">
94 <property name="text">
95 <string>Show disabled targets</string>
96 </property>
97 </widget>
98 </item>
99 <item row="3" column="0" colspan="4">
100 <widget class="QTreeWidget" name="treeDevices">
101 <attribute name="headerVisible">
102 <bool>false</bool>
103 </attribute>
104 <column>
105 <property name="text">
106 <string notr="true">1</string>
107 </property>
108 </column>
109 </widget>
110 </item>
111 <item row="4" column="0" colspan="4">
112 <widget class="QPushButton" name="buttonAutodetect">
113 <property name="text">
114 <string>&amp;Autodetect</string>
115 </property>
116 <property name="icon">
117 <iconset resource="rbutilqt.qrc">
118 <normaloff>:/icons/edit-find.svg</normaloff>:/icons/edit-find.svg</iconset>
119 </property>
120 <property name="default">
121 <bool>true</bool>
122 </property>
123 <property name="flat">
124 <bool>false</bool>
125 </property>
126 </widget>
127 </item>
128 </layout>
129 </widget>
130 <widget class="QWidget" name="tabProxy">
131 <attribute name="icon">
132 <iconset resource="rbutilqt.qrc">
133 <normaloff>:/icons/network-idle.svg</normaloff>:/icons/network-idle.svg</iconset>
134 </attribute>
135 <attribute name="title">
136 <string>&amp;Proxy</string>
137 </attribute>
138 <layout class="QGridLayout">
139 <item row="0" column="0">
140 <widget class="QRadioButton" name="radioNoProxy">
141 <property name="text">
142 <string>&amp;No Proxy</string>
143 </property>
144 <property name="checked">
145 <bool>true</bool>
146 </property>
147 </widget>
148 </item>
149 <item row="1" column="0">
150 <widget class="QRadioButton" name="radioSystemProxy">
151 <property name="text">
152 <string>Use S&amp;ystem values</string>
153 </property>
154 </widget>
155 </item>
156 <item row="2" column="0">
157 <widget class="QRadioButton" name="radioManualProxy">
158 <property name="text">
159 <string>&amp;Manual Proxy settings</string>
160 </property>
161 </widget>
162 </item>
163 <item row="3" column="0">
164 <widget class="QGroupBox" name="groupBox">
165 <property name="title">
166 <string>Proxy Values</string>
167 </property>
168 <layout class="QGridLayout">
169 <item row="0" column="0">
170 <widget class="QLabel" name="label">
171 <property name="text">
172 <string>&amp;Host:</string>
173 </property>
174 <property name="buddy">
175 <cstring>proxyHost</cstring>
176 </property>
177 </widget>
178 </item>
179 <item row="1" column="0">
180 <widget class="QLabel" name="label_2">
181 <property name="text">
182 <string>&amp;Port:</string>
183 </property>
184 <property name="buddy">
185 <cstring>proxyPort</cstring>
186 </property>
187 </widget>
188 </item>
189 <item row="3" column="1">
190 <widget class="QLineEdit" name="proxyPass">
191 <property name="echoMode">
192 <enum>QLineEdit::Password</enum>
193 </property>
194 </widget>
195 </item>
196 <item row="2" column="0">
197 <widget class="QLabel" name="label_3">
198 <property name="text">
199 <string>&amp;Username</string>
200 </property>
201 <property name="buddy">
202 <cstring>proxyUser</cstring>
203 </property>
204 </widget>
205 </item>
206 <item row="3" column="0">
207 <widget class="QLabel" name="label_4">
208 <property name="text">
209 <string>Pass&amp;word</string>
210 </property>
211 <property name="buddy">
212 <cstring>proxyPass</cstring>
213 </property>
214 </widget>
215 </item>
216 <item row="3" column="2">
217 <widget class="QCheckBox" name="checkShowProxyPassword">
218 <property name="text">
219 <string>Show</string>
220 </property>
221 </widget>
222 </item>
223 <item row="2" column="1" colspan="2">
224 <widget class="QLineEdit" name="proxyUser"/>
225 </item>
226 <item row="0" column="1" colspan="2">
227 <widget class="QLineEdit" name="proxyHost">
228 <property name="frame">
229 <bool>true</bool>
230 </property>
231 </widget>
232 </item>
233 <item row="1" column="1" colspan="2">
234 <widget class="QSpinBox" name="proxyPort">
235 <property name="buttonSymbols">
236 <enum>QAbstractSpinBox::NoButtons</enum>
237 </property>
238 <property name="maximum">
239 <number>65535</number>
240 </property>
241 </widget>
242 </item>
243 </layout>
244 </widget>
245 </item>
246 <item row="4" column="0">
247 <spacer>
248 <property name="orientation">
249 <enum>Qt::Vertical</enum>
250 </property>
251 <property name="sizeHint" stdset="0">
252 <size>
253 <width>20</width>
254 <height>40</height>
255 </size>
256 </property>
257 </spacer>
258 </item>
259 </layout>
260 </widget>
261 <widget class="QWidget" name="tabLanguage">
262 <attribute name="icon">
263 <iconset resource="rbutilqt.qrc">
264 <normaloff>:/icons/preferences-desktop-locale.svg</normaloff>:/icons/preferences-desktop-locale.svg</iconset>
265 </attribute>
266 <attribute name="title">
267 <string>&amp;Language</string>
268 </attribute>
269 <layout class="QGridLayout">
270 <item row="0" column="0">
271 <widget class="QListWidget" name="listLanguages"/>
272 </item>
273 </layout>
274 </widget>
275 <widget class="QWidget" name="tabCache">
276 <attribute name="icon">
277 <iconset resource="rbutilqt.qrc">
278 <normaloff>:/icons/package-x-generic.svg</normaloff>:/icons/package-x-generic.svg</iconset>
279 </attribute>
280 <attribute name="title">
281 <string>Cac&amp;he</string>
282 </attribute>
283 <attribute name="toolTip">
284 <string>Download cache settings</string>
285 </attribute>
286 <layout class="QGridLayout">
287 <item row="0" column="0" colspan="2">
288 <widget class="QLabel" name="cacheDescription">
289 <property name="text">
290 <string>Rockbox Utility uses a local download cache to save network traffic. You can change the path to the cache and use it as local repository by enabling Offline mode.</string>
291 </property>
292 <property name="wordWrap">
293 <bool>true</bool>
294 </property>
295 </widget>
296 </item>
297 <item row="1" column="0">
298 <widget class="QLabel" name="cacheSize">
299 <property name="text">
300 <string>Current cache size is %1</string>
301 </property>
302 </widget>
303 </item>
304 <item row="2" column="0" colspan="2">
305 <layout class="QHBoxLayout">
306 <item>
307 <widget class="QLabel" name="label_5">
308 <property name="text">
309 <string>P&amp;ath</string>
310 </property>
311 <property name="buddy">
312 <cstring>cachePath</cstring>
313 </property>
314 </widget>
315 </item>
316 <item>
317 <widget class="QLineEdit" name="cachePath">
318 <property name="toolTip">
319 <string>Entering an invalid folder will reset the path to the systems temporary path.</string>
320 </property>
321 </widget>
322 </item>
323 <item>
324 <widget class="QPushButton" name="buttonCacheBrowse">
325 <property name="text">
326 <string>&amp;Browse</string>
327 </property>
328 <property name="icon">
329 <iconset resource="rbutilqt.qrc">
330 <normaloff>:/icons/edit-find.svg</normaloff>:/icons/edit-find.svg</iconset>
331 </property>
332 </widget>
333 </item>
334 </layout>
335 </item>
336 <item row="3" column="0" colspan="2">
337 <layout class="QVBoxLayout">
338 <item>
339 <widget class="QCheckBox" name="cacheDisable">
340 <property name="text">
341 <string>Disable local &amp;download cache</string>
342 </property>
343 </widget>
344 </item>
345 </layout>
346 </item>
347 <item row="4" column="1">
348 <spacer>
349 <property name="orientation">
350 <enum>Qt::Vertical</enum>
351 </property>
352 <property name="sizeHint" stdset="0">
353 <size>
354 <width>20</width>
355 <height>61</height>
356 </size>
357 </property>
358 </spacer>
359 </item>
360 <item row="5" column="0">
361 <spacer>
362 <property name="orientation">
363 <enum>Qt::Horizontal</enum>
364 </property>
365 <property name="sizeHint" stdset="0">
366 <size>
367 <width>40</width>
368 <height>20</height>
369 </size>
370 </property>
371 </spacer>
372 </item>
373 <item row="5" column="1">
374 <widget class="QPushButton" name="buttonCacheClear">
375 <property name="text">
376 <string>Clean cache &amp;now</string>
377 </property>
378 <property name="icon">
379 <iconset resource="rbutilqt.qrc">
380 <normaloff>:/icons/user-trash-full.svg</normaloff>:/icons/user-trash-full.svg</iconset>
381 </property>
382 </widget>
383 </item>
384 </layout>
385 </widget>
386 <widget class="QWidget" name="tabTts">
387 <attribute name="icon">
388 <iconset resource="rbutilqt.qrc">
389 <normaloff>:/icons/audio-input-microphone.svg</normaloff>:/icons/audio-input-microphone.svg</iconset>
390 </attribute>
391 <attribute name="title">
392 <string>&amp;TTS &amp;&amp; Encoder</string>
393 </attribute>
394 <layout class="QVBoxLayout">
395 <item>
396 <widget class="QGroupBox" name="groupBox_2">
397 <property name="title">
398 <string>TTS Engine</string>
399 </property>
400 <layout class="QGridLayout">
401 <item row="0" column="0">
402 <widget class="QLabel" name="labelTts">
403 <property name="text">
404 <string>&amp;Select TTS Engine</string>
405 </property>
406 <property name="buddy">
407 <cstring>comboTts</cstring>
408 </property>
409 </widget>
410 </item>
411 <item row="0" column="1" colspan="2">
412 <widget class="QComboBox" name="comboTts"/>
413 </item>
414 <item row="1" column="0">
415 <widget class="QLabel" name="labelTtsExecutable">
416 <property name="text">
417 <string>Configure TTS Engine</string>
418 </property>
419 </widget>
420 </item>
421 <item row="1" column="1">
422 <widget class="QLabel" name="configTTSstatus">
423 <property name="text">
424 <string>Configuration invalid!</string>
425 </property>
426 </widget>
427 </item>
428 <item row="1" column="2">
429 <widget class="QLabel" name="configTTSstatusimg">
430 <property name="text">
431 <string/>
432 </property>
433 <property name="pixmap">
434 <pixmap resource="rbutilqt.qrc">:/icons/dialog-error.svg</pixmap>
435 </property>
436 </widget>
437 </item>
438 <item row="1" column="3">
439 <widget class="QPushButton" name="configTts">
440 <property name="text">
441 <string>Configure &amp;TTS</string>
442 </property>
443 <property name="icon">
444 <iconset resource="rbutilqt.qrc">
445 <normaloff>:/icons/edit-find.svg</normaloff>:/icons/edit-find.svg</iconset>
446 </property>
447 </widget>
448 </item>
449 <item row="0" column="3">
450 <widget class="QPushButton" name="testTTS">
451 <property name="text">
452 <string>Test TTS</string>
453 </property>
454 <property name="icon">
455 <iconset resource="rbutilqt.qrc">
456 <normaloff>:/icons/audio-volume-high.svg</normaloff>:/icons/audio-volume-high.svg</iconset>
457 </property>
458 </widget>
459 </item>
460 <item row="2" column="0" colspan="3">
461 <widget class="QCheckBox" name="ttsCorrections">
462 <property name="text">
463 <string>&amp;Use string corrections for TTS</string>
464 </property>
465 </widget>
466 </item>
467 </layout>
468 </widget>
469 </item>
470 <item>
471 <widget class="QGroupBox" name="groupBox_3">
472 <property name="title">
473 <string>Encoder Engine</string>
474 </property>
475 <layout class="QGridLayout">
476 <item row="0" column="1">
477 <widget class="QLabel" name="configEncstatus">
478 <property name="text">
479 <string>Configuration invalid!</string>
480 </property>
481 </widget>
482 </item>
483 <item row="0" column="2">
484 <widget class="QLabel" name="configEncstatusimg">
485 <property name="text">
486 <string/>
487 </property>
488 <property name="pixmap">
489 <pixmap resource="rbutilqt.qrc">:/icons/process-stop.svg</pixmap>
490 </property>
491 </widget>
492 </item>
493 <item row="0" column="3">
494 <widget class="QPushButton" name="configEncoder">
495 <property name="text">
496 <string>Configure &amp;Enc</string>
497 </property>
498 <property name="icon">
499 <iconset resource="rbutilqt.qrc">
500 <normaloff>:/icons/edit-find.svg</normaloff>:/icons/edit-find.svg</iconset>
501 </property>
502 </widget>
503 </item>
504 <item row="0" column="0">
505 <widget class="QLabel" name="encoderName">
506 <property name="text">
507 <string>encoder name</string>
508 </property>
509 </widget>
510 </item>
511 </layout>
512 </widget>
513 </item>
514 <item>
515 <spacer>
516 <property name="orientation">
517 <enum>Qt::Vertical</enum>
518 </property>
519 <property name="sizeHint" stdset="0">
520 <size>
521 <width>458</width>
522 <height>131</height>
523 </size>
524 </property>
525 </spacer>
526 </item>
527 </layout>
528 </widget>
529 </widget>
530 </item>
531 <item row="2" column="0">
532 <spacer>
533 <property name="orientation">
534 <enum>Qt::Horizontal</enum>
535 </property>
536 <property name="sizeHint" stdset="0">
537 <size>
538 <width>40</width>
539 <height>20</height>
540 </size>
541 </property>
542 </spacer>
543 </item>
544 <item row="2" column="1">
545 <widget class="QPushButton" name="buttonOk">
546 <property name="text">
547 <string>&amp;Ok</string>
548 </property>
549 <property name="icon">
550 <iconset resource="rbutilqt.qrc">
551 <normaloff>:/icons/go-next.svg</normaloff>:/icons/go-next.svg</iconset>
552 </property>
553 </widget>
554 </item>
555 <item row="2" column="2">
556 <widget class="QPushButton" name="buttonCancel">
557 <property name="text">
558 <string>&amp;Cancel</string>
559 </property>
560 <property name="icon">
561 <iconset resource="rbutilqt.qrc">
562 <normaloff>:/icons/process-stop.svg</normaloff>:/icons/process-stop.svg</iconset>
563 </property>
564 </widget>
565 </item>
566 </layout>
567 </widget>
568 <resources>
569 <include location="rbutilqt.qrc"/>
570 </resources>
571 <connections/>
572</ui>
diff --git a/utils/rbutilqt/createvoicefrm.ui b/utils/rbutilqt/createvoicefrm.ui
new file mode 100644
index 0000000000..936abd7ceb
--- /dev/null
+++ b/utils/rbutilqt/createvoicefrm.ui
@@ -0,0 +1,217 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0" >
3 <class>CreateVoiceFrm</class>
4 <widget class="QDialog" name="CreateVoiceFrm" >
5 <property name="windowModality" >
6 <enum>Qt::WindowModal</enum>
7 </property>
8 <property name="geometry" >
9 <rect>
10 <x>0</x>
11 <y>0</y>
12 <width>588</width>
13 <height>448</height>
14 </rect>
15 </property>
16 <property name="windowTitle" >
17 <string>Create Voice File</string>
18 </property>
19 <layout class="QGridLayout" name="gridLayout" >
20 <item row="0" column="0" rowspan="5" >
21 <widget class="QLabel" name="label" >
22 <property name="text" >
23 <string/>
24 </property>
25 <property name="pixmap" >
26 <pixmap resource="rbutilqt.qrc" >:/icons/wizard.jpg</pixmap>
27 </property>
28 <property name="alignment" >
29 <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
30 </property>
31 </widget>
32 </item>
33 <item row="0" column="1" colspan="3" >
34 <widget class="QLabel" name="label_2" >
35 <property name="sizePolicy" >
36 <sizepolicy hsizetype="Minimum" vsizetype="Minimum" >
37 <horstretch>0</horstretch>
38 <verstretch>0</verstretch>
39 </sizepolicy>
40 </property>
41 <property name="text" >
42 <string>Select the Language you want to generate a voicefile for:</string>
43 </property>
44 </widget>
45 </item>
46 <item row="2" column="1" colspan="3" >
47 <widget class="QGroupBox" name="groupBox_2" >
48 <property name="title" >
49 <string>Generation settings</string>
50 </property>
51 <layout class="QGridLayout" >
52 <item row="0" column="0" >
53 <widget class="QLabel" name="labelTtsProfile" >
54 <property name="text" >
55 <string>TTS:</string>
56 </property>
57 </widget>
58 </item>
59 <item row="0" column="2" >
60 <widget class="QPushButton" name="change" >
61 <property name="sizePolicy" >
62 <sizepolicy hsizetype="Minimum" vsizetype="Minimum" >
63 <horstretch>0</horstretch>
64 <verstretch>0</verstretch>
65 </sizepolicy>
66 </property>
67 <property name="icon">
68 <iconset resource="rbutilqt.qrc">
69 <normaloff>:/icons/preferences-system.svg</normaloff>:/icons/preferences-system.svg</iconset>
70 </property>
71 <property name="text" >
72 <string>Change</string>
73 </property>
74 </widget>
75 </item>
76 <item row="0" column="1" >
77 <spacer name="horizontalSpacer" >
78 <property name="orientation" >
79 <enum>Qt::Horizontal</enum>
80 </property>
81 <property name="sizeHint" stdset="0" >
82 <size>
83 <width>40</width>
84 <height>20</height>
85 </size>
86 </property>
87 </spacer>
88 </item>
89 <item row="1" column="2" >
90 <widget class="QSpinBox" name="wavtrimthreshold" >
91 <property name="accessibleName" >
92 <string>Wavtrim Threshold</string>
93 </property>
94 <property name="maximum" >
95 <number>5000</number>
96 </property>
97 <property name="value" >
98 <number>500</number>
99 </property>
100 </widget>
101 </item>
102 <item row="1" column="0" >
103 <widget class="QLabel" name="label_3" >
104 <property name="text" >
105 <string>Silence threshold</string>
106 </property>
107 </widget>
108 </item>
109 </layout>
110 </widget>
111 </item>
112 <item row="3" column="1" >
113 <spacer>
114 <property name="orientation" >
115 <enum>Qt::Vertical</enum>
116 </property>
117 <property name="sizeHint" stdset="0" >
118 <size>
119 <width>20</width>
120 <height>201</height>
121 </size>
122 </property>
123 </spacer>
124 </item>
125 <item row="4" column="2" >
126 <spacer>
127 <property name="orientation" >
128 <enum>Qt::Horizontal</enum>
129 </property>
130 <property name="sizeHint" stdset="0" >
131 <size>
132 <width>40</width>
133 <height>20</height>
134 </size>
135 </property>
136 </spacer>
137 </item>
138 <item row="4" column="3" >
139 <layout class="QHBoxLayout" >
140 <item>
141 <widget class="QPushButton" name="buttonOk" >
142 <property name="text" >
143 <string>&amp;Install</string>
144 </property>
145 <property name="icon" >
146 <iconset resource="rbutilqt.qrc" >
147 <normaloff>:/icons/go-next.svg</normaloff>:/icons/go-next.svg</iconset>
148 </property>
149 </widget>
150 </item>
151 <item>
152 <widget class="QPushButton" name="buttonCancel" >
153 <property name="text" >
154 <string>&amp;Cancel</string>
155 </property>
156 <property name="icon" >
157 <iconset resource="rbutilqt.qrc" >
158 <normaloff>:/icons/process-stop.svg</normaloff>:/icons/process-stop.svg</iconset>
159 </property>
160 </widget>
161 </item>
162 </layout>
163 </item>
164 <item row="1" column="1" colspan="3" >
165 <widget class="QComboBox" name="comboLanguage" >
166 <property name="accessibleName" >
167 <string>Language</string>
168 </property>
169 </widget>
170 </item>
171 </layout>
172 </widget>
173 <tabstops>
174 <tabstop>buttonOk</tabstop>
175 <tabstop>buttonCancel</tabstop>
176 <tabstop>comboLanguage</tabstop>
177 <tabstop>change</tabstop>
178 <tabstop>wavtrimthreshold</tabstop>
179 </tabstops>
180 <resources>
181 <include location="rbutilqt.qrc"/>
182 </resources>
183 <connections>
184 <connection>
185 <sender>buttonOk</sender>
186 <signal>clicked()</signal>
187 <receiver>CreateVoiceFrm</receiver>
188 <slot>accept()</slot>
189 <hints>
190 <hint type="sourcelabel" >
191 <x>472</x>
192 <y>418</y>
193 </hint>
194 <hint type="destinationlabel" >
195 <x>382</x>
196 <y>328</y>
197 </hint>
198 </hints>
199 </connection>
200 <connection>
201 <sender>buttonCancel</sender>
202 <signal>clicked()</signal>
203 <receiver>CreateVoiceFrm</receiver>
204 <slot>reject()</slot>
205 <hints>
206 <hint type="sourcelabel" >
207 <x>561</x>
208 <y>428</y>
209 </hint>
210 <hint type="destinationlabel" >
211 <x>522</x>
212 <y>332</y>
213 </hint>
214 </hints>
215 </connection>
216 </connections>
217</ui>
diff --git a/utils/rbutilqt/createvoicewindow.cpp b/utils/rbutilqt/createvoicewindow.cpp
new file mode 100644
index 0000000000..158c1201ce
--- /dev/null
+++ b/utils/rbutilqt/createvoicewindow.cpp
@@ -0,0 +1,144 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QMessageBox>
20#include "createvoicewindow.h"
21#include "ui_createvoicefrm.h"
22
23#include "configure.h"
24#include "rbsettings.h"
25#include "playerbuildinfo.h"
26#include "Logger.h"
27
28CreateVoiceWindow::CreateVoiceWindow(QWidget *parent) : QDialog(parent)
29{
30 ui.setupUi(this);
31 voicecreator = new VoiceFileCreator(this);
32 updateSettings();
33 connect(ui.change,SIGNAL(clicked()),this,SLOT(change()));
34}
35
36void CreateVoiceWindow::change()
37{
38 // save window settings
39 saveSettings();
40
41 // call configuration dialog
42 Config *cw = new Config(this,4);
43 connect(cw, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
44 cw->show();
45}
46
47void CreateVoiceWindow::accept()
48{
49 logger = new ProgressLoggerGui(this);
50 connect(logger,SIGNAL(closed()),this,SLOT(close()));
51 logger->show();
52
53 saveSettings();
54
55 //configure voicecreator
56 voicecreator->setMountPoint(RbSettings::value(RbSettings::Mountpoint).toString());
57 voicecreator->setLang(ui.comboLanguage->itemData(ui.comboLanguage->currentIndex()).toString());
58 voicecreator->setWavtrimThreshold(ui.wavtrimthreshold->value());
59
60 //start creating
61 connect(voicecreator, SIGNAL(done(bool)), logger, SLOT(setFinished()));
62 connect(voicecreator, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
63 connect(voicecreator, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
64 connect(logger,SIGNAL(aborted()),voicecreator,SLOT(abort()));
65 voicecreator->createVoiceFile();
66}
67
68
69/** @brief update displayed settings
70 */
71void CreateVoiceWindow::updateSettings(void)
72{
73 // fill in language combobox. Map has QString as value, but is stored as QVariant.
74 QMap<QString, QVariant> langs
75 = PlayerBuildInfo::instance()->value(PlayerBuildInfo::LanguageList).toMap();
76 for(auto it = langs.begin(); it != langs.end(); it++) {
77 ui.comboLanguage->addItem(it.value().toString(), it.key());
78 }
79 // set saved lang
80 int sel = ui.comboLanguage->findData(
81 RbSettings::value(RbSettings::VoiceLanguage).toString());
82 // if no saved language is found try to figure the language from the UI lang
83 if(sel == -1) {
84 // the UI language is stored as ISO 631-1 code. Try to resolve it to the
85 // Rockbox language string.
86 QString uilang = RbSettings::value(RbSettings::Language).toString();
87 // default to english if no language is set.
88 if(uilang.isEmpty()) {
89 // FIXME: we try to set the UI language from the environment, but
90 // don't store it unless changed. Falling back to en is only valid
91 // if the system is actually english.
92 uilang = "en";
93 }
94 QString l = PlayerBuildInfo::instance()->value(
95 PlayerBuildInfo::LanguageInfo, uilang).toStringList().at(0);
96 if(!l.isEmpty()) {
97 sel = ui.comboLanguage->findData(l);
98 }
99 }
100 ui.comboLanguage->setCurrentIndex(sel);
101
102 QString ttsName = RbSettings::value(RbSettings::Tts).toString();
103 TTSBase* tts = TTSBase::getTTS(this,ttsName);
104 if(!tts)
105 {
106 QMessageBox::critical(this, tr("TTS error"),
107 tr("The selected TTS failed to initialize. You can't use this TTS."));
108 return;
109 }
110 if(tts->configOk())
111 ui.labelTtsProfile->setText(tr("Engine: <b>%1</b>")
112 .arg(TTSBase::getTTSName(ttsName)));
113 else
114 ui.labelTtsProfile->setText(tr("Engine: <b>%1</b>")
115 .arg("Invalid TTS configuration!"));
116
117 ui.wavtrimthreshold->setValue(RbSettings::value(RbSettings::WavtrimThreshold).toInt());
118 emit settingsUpdated();
119}
120
121
122/** @brief save options
123 */
124void CreateVoiceWindow::saveSettings(void)
125{
126 // save selected language
127 RbSettings::setValue(RbSettings::VoiceLanguage,
128 ui.comboLanguage->itemData(ui.comboLanguage->currentIndex()).toString());
129 // save wavtrim threshold value
130 RbSettings::setValue(RbSettings::WavtrimThreshold,
131 ui.wavtrimthreshold->value());
132 RbSettings::sync();
133}
134
135void CreateVoiceWindow::changeEvent(QEvent *e)
136{
137 if(e->type() == QEvent::LanguageChange) {
138 ui.retranslateUi(this);
139 updateSettings();
140 } else {
141 QWidget::changeEvent(e);
142 }
143}
144
diff --git a/utils/rbutilqt/createvoicewindow.h b/utils/rbutilqt/createvoicewindow.h
new file mode 100644
index 0000000000..87127267c5
--- /dev/null
+++ b/utils/rbutilqt/createvoicewindow.h
@@ -0,0 +1,56 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#ifndef CREATEVOICEWINDOW_H
22#define CREATEVOICEWINDOW_H
23
24#include <QDialog>
25#include <QUrl>
26
27#include "ui_createvoicefrm.h"
28#include "progressloggergui.h"
29#include "voicefile.h"
30
31
32class CreateVoiceWindow : public QDialog
33{
34 Q_OBJECT
35 public:
36 CreateVoiceWindow(QWidget *parent);
37 void setProxy(QUrl proxy){m_proxy = proxy;}
38
39 public slots:
40 void accept(void);
41 void change(void);
42 void updateSettings(void);
43 void saveSettings(void);
44
45 signals:
46 void settingsUpdated(void);
47
48 private:
49 void changeEvent(QEvent *event);
50 VoiceFileCreator* voicecreator;
51 Ui::CreateVoiceFrm ui;
52 ProgressLoggerGui* logger;
53 QUrl m_proxy;
54};
55
56#endif
diff --git a/utils/rbutilqt/dmgbuild.cfg b/utils/rbutilqt/dmgbuild.cfg
new file mode 100644
index 0000000000..65d7b274a0
--- /dev/null
+++ b/utils/rbutilqt/dmgbuild.cfg
@@ -0,0 +1,9 @@
1# Configuration for creating a dmg with dmgbuild
2# (https://github.com/al45tair/dmgbuild)
3
4import os
5
6files = [ 'RockboxUtility.app' ]
7background = '#c6d6f5'
8icon = os.path.join(defines['basepath'], 'rbutilqt/icons/rbutilqt.icns')
9
diff --git a/utils/rbutilqt/encttscfggui.cpp b/utils/rbutilqt/encttscfggui.cpp
new file mode 100644
index 0000000000..19181c0f8b
--- /dev/null
+++ b/utils/rbutilqt/encttscfggui.cpp
@@ -0,0 +1,384 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 * $Id: encoders.h 17902 2008-06-30 22:09:45Z bluebrother $
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <QSpacerItem>
23#include <QPushButton>
24#include <QHBoxLayout>
25#include <QDoubleSpinBox>
26#include <QSpinBox>
27#include <QLineEdit>
28#include <QFileDialog>
29#include <QComboBox>
30#include <QGroupBox>
31#include <QLabel>
32#include <QCheckBox>
33#include <QProgressDialog>
34#include "encttscfggui.h"
35#include "Logger.h"
36
37EncTtsCfgGui::EncTtsCfgGui(QDialog* parent, EncTtsSettingInterface* iface, QString name)
38 : QDialog(parent)
39{
40 m_settingInterface = iface;
41
42 m_busyCnt=0;
43 // create a busy Dialog
44 m_busyDlg= new QProgressDialog("", "", 0, 0,this);
45 m_busyDlg->setWindowTitle(tr("Waiting for engine..."));
46 m_busyDlg->setModal(true);
47 m_busyDlg->setLabel(nullptr);
48 m_busyDlg->setCancelButton(nullptr);
49 m_busyDlg->hide();
50 connect(iface,SIGNAL(busy()),this,SLOT(showBusy()));
51 connect(iface,SIGNAL(busyEnd()),this,SLOT(hideBusy()));
52
53 //setup the window
54 setWindowTitle(name);
55 setUpWindow();
56}
57
58void EncTtsCfgGui::setUpWindow()
59{
60 m_settingsList = m_settingInterface->getSettings();
61
62 // layout
63 QVBoxLayout *mainLayout = new QVBoxLayout;
64
65 // groupbox
66 QGroupBox *groupBox = new QGroupBox(this);
67 QGridLayout *gridLayout = new QGridLayout(groupBox);
68 // setting widgets
69 for(int i = 0; i < m_settingsList.size(); i++)
70 {
71 QLabel *label = new QLabel(m_settingsList.at(i)->name());
72 gridLayout->addWidget(label, i, 0);
73 QWidget *widget = createWidgets(m_settingsList.at(i));
74 gridLayout->addWidget(widget, i, 1);
75 widget->setLayoutDirection(Qt::LeftToRight);
76 QWidget *btn = createButton(m_settingsList.at(i));
77 if(btn != nullptr)
78 {
79 gridLayout->addWidget(btn, i, 2);
80 }
81 }
82 // add hidden spacers to make the dialog scale properly
83 QSpacerItem* spacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
84 gridLayout->addItem(spacer, m_settingsList.size(), 0);
85 spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
86 gridLayout->addItem(spacer, m_settingsList.size(), 1);
87
88 groupBox->setLayout(gridLayout);
89 mainLayout->addWidget(groupBox);
90
91 // connect browse btn
92 connect(&m_browseBtnMap,SIGNAL(mapped(QObject*)),this,SLOT(browse(QObject*)));
93
94 // ok - cancel buttons
95 QPushButton* okBtn = new QPushButton(tr("Ok"),this);
96 okBtn->setDefault(true);
97 okBtn->setIcon(QIcon(":icons/go-next.svg"));
98 QPushButton* cancelBtn = new QPushButton(tr("Cancel"),this);
99 cancelBtn->setIcon(QIcon(":icons/process-stop.svg"));
100 connect(okBtn,SIGNAL(clicked()),this,SLOT(accept()));
101 connect(cancelBtn,SIGNAL(clicked()),this,SLOT(reject()));
102
103 QHBoxLayout *btnbox = new QHBoxLayout;
104 btnbox->addWidget(okBtn);
105 btnbox->addWidget(cancelBtn);
106 btnbox->insertStretch(0,1);
107
108 mainLayout->addLayout(btnbox);
109
110 this->setLayout(mainLayout);
111}
112
113QWidget* EncTtsCfgGui::createWidgets(EncTtsSetting* setting)
114{
115 // value display
116 QWidget* value = nullptr;
117 switch(setting->type())
118 {
119 case EncTtsSetting::eDOUBLE:
120 {
121 QDoubleSpinBox *spinBox = new QDoubleSpinBox(this);
122 spinBox->setAccessibleName(setting->name());
123 spinBox->setMinimum(setting->min().toDouble());
124 spinBox->setMaximum(setting->max().toDouble());
125 spinBox->setSingleStep(0.01);
126 spinBox->setValue(setting->current().toDouble());
127 connect(spinBox,SIGNAL(valueChanged(double)),this,SLOT(updateSetting()));
128 value = spinBox;
129 break;
130 }
131 case EncTtsSetting::eINT:
132 {
133 QSpinBox *spinBox = new QSpinBox(this);
134 spinBox->setAccessibleName(setting->name());
135 spinBox->setMinimum(setting->min().toInt());
136 spinBox->setMaximum(setting->max().toInt());
137 spinBox->setValue(setting->current().toInt());
138 connect(spinBox,SIGNAL(valueChanged(int)),this,SLOT(updateSetting()));
139 value = spinBox;
140 break;
141 }
142 case EncTtsSetting::eSTRING:
143 {
144 QLineEdit *lineEdit = new QLineEdit(this);
145 lineEdit->setAccessibleName(setting->name());
146 lineEdit->setText(setting->current().toString());
147 connect(lineEdit,SIGNAL(textChanged(QString)),this,SLOT(updateSetting()));
148 value = lineEdit;
149 break;
150 }
151 case EncTtsSetting::eREADONLYSTRING:
152 {
153 value = new QLabel(setting->current().toString(),this);
154 break;
155 }
156 case EncTtsSetting::eSTRINGLIST:
157 {
158 QComboBox *comboBox = new QComboBox(this);
159 comboBox->setAccessibleName(setting->name());
160 comboBox->addItems(setting->list());
161 int index = comboBox->findText(setting->current().toString());
162 comboBox->setCurrentIndex(index);
163 connect(comboBox,SIGNAL(currentIndexChanged(QString)),this,SLOT(updateSetting()));
164 value = comboBox;
165 break;
166 }
167 case EncTtsSetting::eBOOL:
168 {
169 QCheckBox *checkbox = new QCheckBox(this);
170 checkbox->setAccessibleName(setting->name());
171 checkbox->setCheckState(setting->current().toBool() == true ? Qt::Checked : Qt::Unchecked);
172 connect(checkbox,SIGNAL(stateChanged(int)),this,SLOT(updateSetting()));
173 value = checkbox;
174 break;
175 }
176 default:
177 {
178 LOG_WARNING() << "Warning: unknown EncTTsSetting type" << setting->type();
179 break;
180 }
181 }
182
183 // remember widget
184 if(value != nullptr)
185 {
186 m_settingsWidgetsMap.insert(setting,value);
187 connect(setting,SIGNAL(updateGui()),this,SLOT(updateWidget()));
188 }
189
190 return value;
191}
192
193QWidget* EncTtsCfgGui::createButton(EncTtsSetting* setting)
194{
195 if(setting->button() == EncTtsSetting::eBROWSEBTN)
196 {
197 QPushButton* browsebtn = new QPushButton(tr("Browse"),this);
198 browsebtn->setIcon(QIcon(":/icons/system-search.svg"));
199 m_browseBtnMap.setMapping(browsebtn,setting);
200 connect(browsebtn,SIGNAL(clicked()),&m_browseBtnMap,SLOT(map()));
201 return browsebtn;
202 }
203 else if(setting->button() == EncTtsSetting::eREFRESHBTN)
204 {
205 QPushButton* refreshbtn = new QPushButton(tr("Refresh"),this);
206 refreshbtn->setIcon(QIcon(":/icons/view-refresh.svg"));
207 connect(refreshbtn,SIGNAL(clicked()),setting,SIGNAL(refresh()));
208 return refreshbtn;
209 }
210 else
211 return nullptr;
212}
213
214void EncTtsCfgGui::updateSetting()
215{
216 //cast and get the sender widget
217 QWidget* widget = qobject_cast<QWidget*>(QObject::sender());
218 if(widget == nullptr) return;
219 // get the corresponding setting
220 EncTtsSetting* setting = m_settingsWidgetsMap.key(widget);
221
222 // update widget based on setting type
223 switch(setting->type())
224 {
225 case EncTtsSetting::eDOUBLE:
226 {
227 setting->setCurrent(((QDoubleSpinBox*)widget)->value(),false);
228 break;
229 }
230 case EncTtsSetting::eINT:
231 {
232 setting->setCurrent(((QSpinBox*)widget)->value(),false);
233 break;
234 }
235 case EncTtsSetting::eSTRING:
236 {
237 setting->setCurrent(((QLineEdit*)widget)->text(),false);
238 break;
239 }
240 case EncTtsSetting::eREADONLYSTRING:
241 {
242 setting->setCurrent(((QLabel*)widget)->text(),false);
243 break;
244 }
245 case EncTtsSetting::eSTRINGLIST:
246 {
247 setting->setCurrent(((QComboBox*)widget)->currentText(),false);
248 break;
249 }
250 case EncTtsSetting::eBOOL:
251 {
252 setting->setCurrent(((QCheckBox*)widget)->isChecked(),false);
253 break;
254 }
255 default:
256 {
257 LOG_WARNING() << "unknown setting type!";
258 break;
259 }
260 }
261}
262
263void EncTtsCfgGui::updateWidget()
264{
265 // get sender setting
266 EncTtsSetting* setting = qobject_cast<EncTtsSetting*>(QObject::sender());
267 if(setting == nullptr) return;
268 // get corresponding widget
269 QWidget* widget = m_settingsWidgetsMap.value(setting);
270
271 // update Widget based on setting type
272 switch(setting->type())
273 {
274 case EncTtsSetting::eDOUBLE:
275 {
276 QDoubleSpinBox* spinbox = (QDoubleSpinBox*) widget;
277 spinbox->setMinimum(setting->min().toDouble());
278 spinbox->setMaximum(setting->max().toDouble());
279 spinbox->blockSignals(true);
280 spinbox->setValue(setting->current().toDouble());
281 spinbox->blockSignals(false);
282 break;
283 }
284 case EncTtsSetting::eINT:
285 {
286 QSpinBox* spinbox = (QSpinBox*) widget;
287 spinbox->setMinimum(setting->min().toInt());
288 spinbox->setMaximum(setting->max().toInt());
289 spinbox->blockSignals(true);
290 spinbox->setValue(setting->current().toInt());
291 spinbox->blockSignals(false);
292 break;
293 }
294 case EncTtsSetting::eSTRING:
295 {
296 QLineEdit* lineedit = (QLineEdit*) widget;
297
298 lineedit->blockSignals(true);
299 lineedit->setText(setting->current().toString());
300 lineedit->blockSignals(false);
301 break;
302 }
303 case EncTtsSetting::eREADONLYSTRING:
304 {
305 QLabel* label = (QLabel*) widget;
306
307 label->blockSignals(true);
308 label->setText(setting->current().toString());
309 label->blockSignals(false);
310 break;
311 }
312 case EncTtsSetting::eSTRINGLIST:
313 {
314 QComboBox* combobox = (QComboBox*) widget;
315
316 combobox->blockSignals(true);
317 combobox->clear();
318 combobox->addItems(setting->list());
319 int index = combobox->findText(setting->current().toString());
320 combobox->setCurrentIndex(index);
321 combobox->blockSignals(false);
322
323 break;
324 }
325 case EncTtsSetting::eBOOL:
326 {
327 QCheckBox* checkbox = (QCheckBox*) widget;
328
329 checkbox->blockSignals(true);
330 checkbox->setCheckState(setting->current().toBool() == true ? Qt::Checked : Qt::Unchecked);
331 checkbox->blockSignals(false);
332 break;
333 }
334 default:
335 {
336 LOG_WARNING() << "unknown EncTTsSetting";
337 break;
338 }
339 }
340}
341
342void EncTtsCfgGui::showBusy()
343{
344 if(m_busyCnt == 0) m_busyDlg->show();
345
346 m_busyCnt++;
347}
348
349void EncTtsCfgGui::hideBusy()
350{
351 m_busyCnt--;
352
353 if(m_busyCnt == 0) m_busyDlg->hide();
354}
355
356
357void EncTtsCfgGui::accept(void)
358{
359 m_settingInterface->saveSettings();
360 this->done(0);
361}
362
363void EncTtsCfgGui::reject(void)
364{
365 this->done(0);
366}
367
368//! takes a QObject because of QsignalMapper
369void EncTtsCfgGui::browse(QObject* settingObj)
370{
371 // cast top setting
372 EncTtsSetting* setting= qobject_cast<EncTtsSetting*>(settingObj);
373 if(setting == nullptr) return;
374
375 //current path
376 QString curPath = setting->current().toString();
377 // show file dialog
378 QString exe = QFileDialog::getOpenFileName(this, tr("Select executable"), curPath, "*");
379 if(!QFileInfo(exe).isExecutable())
380 return;
381 // set new value, gui will update automatically
382 setting->setCurrent(exe);
383}
384
diff --git a/utils/rbutilqt/encttscfggui.h b/utils/rbutilqt/encttscfggui.h
new file mode 100644
index 0000000000..80af86dabc
--- /dev/null
+++ b/utils/rbutilqt/encttscfggui.h
@@ -0,0 +1,79 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#ifndef ENCTTSCFGGUI_H
22#define ENCTTSCFGGUI_H
23
24#include <QDialog>
25#include <QString>
26#include <QProgressDialog>
27#include "encttssettings.h"
28
29//! \brief Shows and manages a configuration gui for encoders and tts enignes
30//!
31class EncTtsCfgGui: public QDialog
32{
33 Q_OBJECT
34public:
35 //! Creates the UI. give it a endoer or tts engine with already set config. uses show() or exec() to show it.
36 EncTtsCfgGui(QDialog* parent, EncTtsSettingInterface* iface, QString name);
37
38private slots:
39 //! accept current configuration values and close window
40 void accept(void);
41 //! close window and dont save configuration
42 void reject(void);
43 //! updates the corresponding setting from the sending Widget
44 void updateSetting();
45 //! updates corresponding Widget from the sending Setting.
46 void updateWidget();
47 //! shows a busy dialog. counts calls.
48 void showBusy();
49 //! hides the busy dialog, counts calls
50 void hideBusy();
51 //! used via the SignalMapper for all Browse buttons
52 void browse(QObject*);
53
54private:
55 //! creates all dynamic window content
56 void setUpWindow();
57 //! creates the Widgets needed for one setting. returns a Layout with the widgets
58 QWidget* createWidgets(EncTtsSetting* setting);
59 //! creates a button when needed by the setting.
60 QWidget* createButton(EncTtsSetting* setting);
61 //! name of the Encoder or TTS for which this UI is
62 QString m_name;
63 //! the interface pointer to the TTS or encoder
64 EncTtsSettingInterface* m_settingInterface;
65 //! Dialog, shown when enc or tts is busy
66 QProgressDialog* m_busyDlg;
67 //! List of settings from the TTS or Encoder
68 QList<EncTtsSetting*> m_settingsList;
69 //! Maps settings and the correspondig Widget
70 QMap<EncTtsSetting*,QWidget*> m_settingsWidgetsMap;
71 //! Maps all browse buttons to the corresponding Setting
72 QSignalMapper m_browseBtnMap;
73 //! counter how often busyShow() is called,
74 int m_busyCnt;
75};
76
77
78#endif
79
diff --git a/utils/rbutilqt/gui/backupdialog.cpp b/utils/rbutilqt/gui/backupdialog.cpp
new file mode 100644
index 0000000000..f12c47b570
--- /dev/null
+++ b/utils/rbutilqt/gui/backupdialog.cpp
@@ -0,0 +1,152 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2012 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QThread>
20#include <QDialog>
21#include <QMessageBox>
22#include <QFileDialog>
23#include "backupdialog.h"
24#include "ui_backupdialogfrm.h"
25#include "rbsettings.h"
26#include "progressloggergui.h"
27#include "ziputil.h"
28#include "rockboxinfo.h"
29#include "Logger.h"
30
31class BackupSizeThread : public QThread
32{
33 public:
34 void run(void);
35 void setPath(QString p) { m_path = p; }
36 qint64 currentSize(void) { return m_currentSize; }
37
38 private:
39 QString m_path;
40 qint64 m_currentSize;
41};
42
43
44void BackupSizeThread::run(void)
45{
46 LOG_INFO() << "Thread started, calculating" << m_path;
47 m_currentSize = 0;
48
49 QDirIterator it(m_path, QDirIterator::Subdirectories);
50 while(it.hasNext()) {
51 m_currentSize += QFileInfo(it.next()).size();
52 }
53 LOG_INFO() << "Thread done, sum:" << m_currentSize;
54}
55
56
57BackupDialog::BackupDialog(QWidget* parent) : QDialog(parent)
58{
59 ui.setupUi(this);
60
61 m_thread = new BackupSizeThread();
62 connect(m_thread, SIGNAL(finished()), this, SLOT(updateSizeInfo()));
63 connect(m_thread, SIGNAL(terminated()), this, SLOT(updateSizeInfo()));
64
65 connect(ui.buttonCancel, SIGNAL(clicked()), this, SLOT(close()));
66 connect(ui.buttonCancel, SIGNAL(clicked()), m_thread, SLOT(quit()));
67 connect(ui.buttonChange, SIGNAL(clicked()), this, SLOT(changeBackupPath()));
68 connect(ui.buttonBackup, SIGNAL(clicked()), this, SLOT(backup()));
69
70 ui.backupSize->setText(tr("Installation size: calculating ..."));
71 m_mountpoint = RbSettings::value(RbSettings::Mountpoint).toString();
72
73 m_backupName = RbSettings::value(RbSettings::BackupPath).toString();
74 if(m_backupName.isEmpty()) {
75 m_backupName = m_mountpoint;
76 }
77 RockboxInfo info(m_mountpoint);
78 m_backupName += "/.backup/rockbox-backup-" + info.version() + ".zip";
79 ui.backupLocation->setText(QDir::toNativeSeparators(m_backupName));
80
81 m_thread->setPath(m_mountpoint + "/.rockbox");
82 m_thread->start();
83}
84
85
86void BackupDialog::changeBackupPath(void)
87{
88 QString backupString = QFileDialog::getSaveFileName(this,
89 tr("Select Backup Filename"), m_backupName, "*.zip");
90 // only update if a filename was entered, ignore if cancelled
91 if(!backupString.isEmpty()) {
92 m_backupName = backupString;
93 ui.backupLocation->setText(QDir::toNativeSeparators(m_backupName));
94 RbSettings::setValue(RbSettings::BackupPath, QFileInfo(m_backupName).absolutePath());
95 }
96}
97
98
99void BackupDialog::updateSizeInfo(void)
100{
101 double size = m_thread->currentSize() / (1024 * 1024);
102 QString unit = "MiB";
103
104 if(size > 1024) {
105 size /= 1024;
106 unit = "GiB";
107 }
108
109 ui.backupSize->setText(tr("Installation size: %L1 %2").arg(size, 0, 'g', 4).arg(unit));
110}
111
112
113void BackupDialog::backup(void)
114{
115 if(QFileInfo(m_backupName).isFile()) {
116 if(QMessageBox::warning(this, tr("File exists"),
117 tr("The selected backup file already exists. Overwrite?"),
118 QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
119 return;
120 }
121 }
122 m_logger = new ProgressLoggerGui(this);
123 connect(m_logger, SIGNAL(closed()), this, SLOT(close()));
124 m_logger->show();
125 m_logger->addItem(tr("Starting backup ..."),LOGINFO);
126 QCoreApplication::processEvents();
127
128 // create dir, if it doesnt exist
129 QFileInfo backupFile(m_backupName);
130 if(!QDir(backupFile.path()).exists())
131 {
132 QDir a;
133 a.mkpath(backupFile.path());
134 }
135
136 // create backup
137 ZipUtil zip(this);
138 connect(&zip, SIGNAL(logProgress(int, int)), m_logger, SLOT(setProgress(int, int)));
139 connect(&zip, SIGNAL(logItem(QString, int)), m_logger, SLOT(addItem(QString, int)));
140 zip.open(m_backupName, QuaZip::mdCreate);
141
142 QString mp = m_mountpoint + "/.rockbox";
143 if(zip.appendDirToArchive(mp, m_mountpoint)) {
144 m_logger->addItem(tr("Backup successful."), LOGINFO);
145 }
146 else {
147 m_logger->addItem(tr("Backup failed!"), LOGERROR);
148 }
149 zip.close();
150 m_logger->setFinished();
151}
152
diff --git a/utils/rbutilqt/gui/backupdialog.h b/utils/rbutilqt/gui/backupdialog.h
new file mode 100644
index 0000000000..185166134a
--- /dev/null
+++ b/utils/rbutilqt/gui/backupdialog.h
@@ -0,0 +1,48 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2012 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef BACKUPDIALOG_H
20#define BACKUPDIALOG_H
21
22#include <QDialog>
23#include "ui_backupdialogfrm.h"
24#include "progressloggergui.h"
25
26class BackupSizeThread;
27
28class BackupDialog : public QDialog
29{
30 Q_OBJECT
31 public:
32 BackupDialog(QWidget* parent = nullptr);
33
34 private slots:
35 void changeBackupPath(void);
36 void updateSizeInfo(void);
37 void backup(void);
38
39 private:
40 Ui::BackupDialog ui;
41 QString m_backupName;
42 QString m_mountpoint;
43 BackupSizeThread *m_thread;
44 ProgressLoggerGui *m_logger;
45};
46
47#endif
48
diff --git a/utils/rbutilqt/gui/backupdialogfrm.ui b/utils/rbutilqt/gui/backupdialogfrm.ui
new file mode 100644
index 0000000000..f843ad3a65
--- /dev/null
+++ b/utils/rbutilqt/gui/backupdialogfrm.ui
@@ -0,0 +1,145 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>BackupDialog</class>
4 <widget class="QDialog" name="BackupDialog">
5 <property name="windowModality">
6 <enum>Qt::WindowModal</enum>
7 </property>
8 <property name="geometry">
9 <rect>
10 <x>0</x>
11 <y>0</y>
12 <width>554</width>
13 <height>448</height>
14 </rect>
15 </property>
16 <property name="windowTitle">
17 <string>Backup</string>
18 </property>
19 <layout class="QGridLayout" name="gridLayout_2">
20 <item row="0" column="0" rowspan="4">
21 <widget class="QLabel" name="label_4">
22 <property name="text">
23 <string/>
24 </property>
25 <property name="pixmap">
26 <pixmap resource="../rbutilqt.qrc">:/icons/wizard.jpg</pixmap>
27 </property>
28 </widget>
29 </item>
30 <item row="0" column="1" colspan="3">
31 <widget class="QLabel" name="label_2">
32 <property name="text">
33 <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This dialog will create a backup by archiving the contents of the Rockbox installation on the player into a zip file. This will include installed themes and settings stored below the .rockbox folder on the player.&lt;/p&gt;&lt;p&gt;The backup filename will be created based on the installed version. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
34 </property>
35 <property name="wordWrap">
36 <bool>true</bool>
37 </property>
38 </widget>
39 </item>
40 <item row="1" column="1" colspan="3">
41 <widget class="QGroupBox" name="groupBox">
42 <property name="title">
43 <string>Backup</string>
44 </property>
45 <layout class="QGridLayout" name="gridLayout">
46 <item row="0" column="0">
47 <widget class="QLabel" name="backupSize">
48 <property name="text">
49 <string>Size: unknown</string>
50 </property>
51 </widget>
52 </item>
53 <item row="1" column="0">
54 <widget class="QLabel" name="backupLocation">
55 <property name="text">
56 <string>Backup to: unknown</string>
57 </property>
58 </widget>
59 </item>
60 <item row="1" column="1">
61 <spacer name="horizontalSpacer">
62 <property name="orientation">
63 <enum>Qt::Horizontal</enum>
64 </property>
65 <property name="sizeHint" stdset="0">
66 <size>
67 <width>78</width>
68 <height>20</height>
69 </size>
70 </property>
71 </spacer>
72 </item>
73 <item row="1" column="2">
74 <widget class="QPushButton" name="buttonChange">
75 <property name="text">
76 <string>&amp;Change</string>
77 </property>
78 <property name="icon">
79 <iconset resource="../rbutilqt.qrc">
80 <normaloff>:/icons/edit-find.svg</normaloff>:/icons/edit-find.svg</iconset>
81 </property>
82 </widget>
83 </item>
84 </layout>
85 </widget>
86 </item>
87 <item row="2" column="2" colspan="2">
88 <spacer name="verticalSpacer">
89 <property name="orientation">
90 <enum>Qt::Vertical</enum>
91 </property>
92 <property name="sizeHint" stdset="0">
93 <size>
94 <width>20</width>
95 <height>1</height>
96 </size>
97 </property>
98 </spacer>
99 </item>
100 <item row="3" column="1">
101 <spacer name="horizontalSpacer_2">
102 <property name="orientation">
103 <enum>Qt::Horizontal</enum>
104 </property>
105 <property name="sizeHint" stdset="0">
106 <size>
107 <width>143</width>
108 <height>20</height>
109 </size>
110 </property>
111 </spacer>
112 </item>
113 <item row="3" column="2">
114 <widget class="QPushButton" name="buttonBackup">
115 <property name="text">
116 <string>&amp;Backup</string>
117 </property>
118 <property name="icon">
119 <iconset resource="../rbutilqt.qrc">
120 <normaloff>:/icons/go-next.svg</normaloff>:/icons/go-next.svg</iconset>
121 </property>
122 </widget>
123 </item>
124 <item row="3" column="3">
125 <widget class="QPushButton" name="buttonCancel">
126 <property name="text">
127 <string>&amp;Cancel</string>
128 </property>
129 <property name="icon">
130 <iconset resource="../rbutilqt.qrc">
131 <normaloff>:/icons/process-stop.svg</normaloff>:/icons/process-stop.svg</iconset>
132 </property>
133 </widget>
134 </item>
135 </layout>
136 </widget>
137 <tabstops>
138 <tabstop>buttonBackup</tabstop>
139 <tabstop>buttonCancel</tabstop>
140 </tabstops>
141 <resources>
142 <include location="../rbutilqt.qrc"/>
143 </resources>
144 <connections/>
145</ui>
diff --git a/utils/rbutilqt/gui/changelog.cpp b/utils/rbutilqt/gui/changelog.cpp
new file mode 100644
index 0000000000..79d601e412
--- /dev/null
+++ b/utils/rbutilqt/gui/changelog.cpp
@@ -0,0 +1,78 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2013 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include "changelog.h"
20#include "rbsettings.h"
21#include "ui_changelogfrm.h"
22
23Changelog::Changelog(QWidget *parent) : QDialog(parent)
24{
25 ui.setupUi(this);
26 ui.browserChangelog->setOpenExternalLinks(true);
27 // FIXME: support translated changelog file (changelog.de.txt etc)
28 ui.browserChangelog->setHtml(parseChangelogFile(":/docs/changelog.txt"));
29 ui.browserChangelog->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
30 ui.checkBoxShowAlways->setChecked(RbSettings::value(RbSettings::ShowChangelog).toBool());
31 connect(ui.buttonOk, SIGNAL(clicked()), this, SLOT(accept()));
32}
33
34
35void Changelog::accept(void)
36{
37 RbSettings::setValue(RbSettings::ShowChangelog, ui.checkBoxShowAlways->isChecked());
38 this->hide();
39 this->deleteLater();
40}
41
42
43QString Changelog::parseChangelogFile(QString filename)
44{
45 QFile changelog(filename);
46 changelog.open(QIODevice::ReadOnly);
47 QTextStream c(&changelog);
48#if QT_VERSION < 0x060000
49 c.setCodec(QTextCodec::codecForName("UTF-8"));
50#else
51 c.setEncoding(QStringConverter::Utf8);
52#endif
53 QString text;
54 while(!c.atEnd()) {
55 QString line = c.readLine();
56 if(line.startsWith("#"))
57 continue;
58 if(line.startsWith("Version")) {
59 text.append(QString("<h4>Rockbox Utility %1</h4>").arg(line.remove("Version")));
60 line = c.readLine();
61 text.append("<ul>");
62 while(line.startsWith("*")) {
63 QString t = line.remove(QRegExp("^\\*"));
64 t.replace(QRegExp("FS#(\\d+)"),
65 "<a href='http://www.rockbox.org/tracker/task/\\1'>FS#\\1</a>");
66 t.replace(QRegExp("G#(\\d+)"),
67 "<a href='http://gerrit.rockbox.org/r/\\1'>G#\\1</a>");
68 text.append(QString("<li>%1</li>").arg(t));
69 line = c.readLine();
70 if(line.startsWith("#"))
71 line = c.readLine();
72 }
73 text.append("</ul>");
74 }
75 }
76 changelog.close();
77 return text;
78}
diff --git a/utils/rbutilqt/gui/changelog.h b/utils/rbutilqt/gui/changelog.h
new file mode 100644
index 0000000000..aca2a6ed32
--- /dev/null
+++ b/utils/rbutilqt/gui/changelog.h
@@ -0,0 +1,40 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2013 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef CHANGELOG_H
20#define CHANGELOG_H
21
22#include <QDialog>
23#include "ui_changelogfrm.h"
24
25class Changelog : public QDialog
26{
27 Q_OBJECT
28public:
29 Changelog(QWidget *parent = nullptr);
30
31public slots:
32 void accept(void);
33
34private:
35 QString parseChangelogFile(QString filename);
36 Ui::Changelog ui;
37
38};
39
40#endif
diff --git a/utils/rbutilqt/gui/changelogfrm.ui b/utils/rbutilqt/gui/changelogfrm.ui
new file mode 100644
index 0000000000..0a28ee2421
--- /dev/null
+++ b/utils/rbutilqt/gui/changelogfrm.ui
@@ -0,0 +1,60 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>Changelog</class>
4 <widget class="QDialog" name="Changelog">
5 <property name="windowModality">
6 <enum>Qt::WindowModal</enum>
7 </property>
8 <property name="geometry">
9 <rect>
10 <x>0</x>
11 <y>0</y>
12 <width>500</width>
13 <height>400</height>
14 </rect>
15 </property>
16 <property name="windowTitle">
17 <string>Changelog</string>
18 </property>
19 <layout class="QGridLayout" name="gridLayout">
20 <item row="0" column="0" colspan="3">
21 <widget class="QTextBrowser" name="browserChangelog"/>
22 </item>
23 <item row="1" column="1">
24 <spacer name="horizontalSpacer">
25 <property name="orientation">
26 <enum>Qt::Horizontal</enum>
27 </property>
28 <property name="sizeHint" stdset="0">
29 <size>
30 <width>40</width>
31 <height>20</height>
32 </size>
33 </property>
34 </spacer>
35 </item>
36 <item row="1" column="0">
37 <widget class="QCheckBox" name="checkBoxShowAlways">
38 <property name="text">
39 <string>Show on startup</string>
40 </property>
41 </widget>
42 </item>
43 <item row="1" column="2">
44 <widget class="QPushButton" name="buttonOk">
45 <property name="text">
46 <string>&amp;Ok</string>
47 </property>
48 <property name="icon">
49 <iconset resource="../rbutilqt.qrc">
50 <normaloff>:/icons/go-next.svg</normaloff>:/icons/go-next.svg</iconset>
51 </property>
52 </widget>
53 </item>
54 </layout>
55 </widget>
56 <resources>
57 <include location="../rbutilqt.qrc"/>
58 </resources>
59 <connections/>
60</ui>
diff --git a/utils/rbutilqt/gui/comboboxviewdelegate.cpp b/utils/rbutilqt/gui/comboboxviewdelegate.cpp
new file mode 100644
index 0000000000..91489d10c0
--- /dev/null
+++ b/utils/rbutilqt/gui/comboboxviewdelegate.cpp
@@ -0,0 +1,56 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2011 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QStyledItemDelegate>
20#include <QPainter>
21#include <QApplication>
22#include <qdebug.h>
23#include "comboboxviewdelegate.h"
24
25void ComboBoxViewDelegate::paint(QPainter *painter,
26 const QStyleOptionViewItem &option, const QModelIndex &index) const
27{
28 QPen pen;
29 QFont font;
30 pen = painter->pen();
31 font = painter->font();
32
33 painter->save();
34 // paint selection
35 if(option.state & QStyle::State_Selected) {
36 painter->setPen(QPen(Qt::NoPen));
37 painter->setBrush(QApplication::palette().highlight());
38 painter->drawRect(option.rect);
39 painter->restore();
40 painter->save();
41 pen.setColor(QApplication::palette().color(QPalette::HighlightedText));
42 }
43 else {
44 pen.setColor(QApplication::palette().color(QPalette::Text));
45 }
46 // draw data (text)
47 painter->setPen(pen);
48 painter->drawText(option.rect, Qt::AlignLeft, index.data().toString());
49
50 // draw user data right aligned, italic
51 font.setItalic(true);
52 painter->setFont(font);
53 painter->drawText(option.rect, Qt::AlignRight, index.data(Qt::UserRole).toString());
54 painter->restore();
55}
56
diff --git a/utils/rbutilqt/gui/comboboxviewdelegate.h b/utils/rbutilqt/gui/comboboxviewdelegate.h
new file mode 100644
index 0000000000..a0070bb126
--- /dev/null
+++ b/utils/rbutilqt/gui/comboboxviewdelegate.h
@@ -0,0 +1,30 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2011 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QStyledItemDelegate>
20
21class ComboBoxViewDelegate : public QStyledItemDelegate
22{
23 Q_OBJECT
24 public:
25 ComboBoxViewDelegate(QObject* parent = nullptr) : QStyledItemDelegate(parent) { }
26
27 void paint(QPainter *painter, const QStyleOptionViewItem &option,
28 const QModelIndex &index) const;
29};
30
diff --git a/utils/rbutilqt/gui/infowidget.cpp b/utils/rbutilqt/gui/infowidget.cpp
new file mode 100644
index 0000000000..25b0503090
--- /dev/null
+++ b/utils/rbutilqt/gui/infowidget.cpp
@@ -0,0 +1,112 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2012 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QWidget>
20#include <QDebug>
21#include "infowidget.h"
22#include "rbsettings.h"
23#include "Logger.h"
24
25InfoWidget::InfoWidget(QWidget *parent) : QWidget(parent)
26{
27 ui.setupUi(this);
28
29 ui.treeInfo->setAlternatingRowColors(true);
30 ui.treeInfo->setHeaderLabels(QStringList() << tr("File") << tr("Version"));
31 ui.treeInfo->expandAll();
32 ui.treeInfo->setColumnCount(2);
33 ui.treeInfo->setLayoutDirection(Qt::LeftToRight);
34}
35
36
37void InfoWidget::updateInfo(void)
38{
39 LOG_INFO() << "updating server info";
40
41 QString mp = RbSettings::value(RbSettings::Mountpoint).toString();
42 QSettings log(mp + "/.rockbox/rbutil.log", QSettings::IniFormat, this);
43 QStringList groups = log.childGroups();
44 QList<QTreeWidgetItem *> items;
45 QTreeWidgetItem *w, *w2;
46 QString min, max;
47 int olditems = 0;
48
49 // remove old list entries (if any)
50 int l = ui.treeInfo->topLevelItemCount();
51 while(l--) {
52 QTreeWidgetItem *m;
53 m = ui.treeInfo->takeTopLevelItem(l);
54 // delete childs (single level deep, no recursion here)
55 int n = m->childCount();
56 while(n--)
57 delete m->child(n);
58 }
59 // get and populate new items
60 for(int a = 0; a < groups.size(); a++) {
61 log.beginGroup(groups.at(a));
62 QStringList keys = log.allKeys();
63 w = new QTreeWidgetItem;
64 w->setFlags(Qt::ItemIsEnabled);
65 w->setText(0, groups.at(a));
66 items.append(w);
67 // get minimum and maximum version information so we can hilight old files
68 min = max = log.value(keys.at(0)).toString();
69 for(int b = 0; b < keys.size(); b++) {
70 if(log.value(keys.at(b)).toString() > max)
71 max = log.value(keys.at(b)).toString();
72 if(log.value(keys.at(b)).toString() < min)
73 min = log.value(keys.at(b)).toString();
74 }
75
76 for(int b = 0; b < keys.size(); b++) {
77 QString file;
78 file = mp + "/" + keys.at(b);
79 if(QFileInfo(file).isDir())
80 continue;
81 w2 = new QTreeWidgetItem(w, QStringList() << "/"
82 + keys.at(b) << log.value(keys.at(b)).toString());
83 if(log.value(keys.at(b)).toString() != max) {
84 w2->setForeground(0, QBrush(QColor(255, 0, 0)));
85 w2->setForeground(1, QBrush(QColor(255, 0, 0)));
86 olditems++;
87 }
88 items.append(w2);
89 }
90 log.endGroup();
91 if(min != max)
92 w->setData(1, Qt::DisplayRole, QString("%1 / %2").arg(min, max));
93 else
94 w->setData(1, Qt::DisplayRole, max);
95 }
96 ui.treeInfo->insertTopLevelItems(0, items);
97 ui.treeInfo->expandAll();
98 ui.treeInfo->resizeColumnToContents(0);
99 ui.treeInfo->collapseAll();
100}
101
102
103void InfoWidget::changeEvent(QEvent *e)
104{
105 if(e->type() == QEvent::LanguageChange) {
106 ui.retranslateUi(this);
107 ui.treeInfo->setHeaderLabels(QStringList() << tr("File") << tr("Version"));
108 } else {
109 QWidget::changeEvent(e);
110 }
111}
112
diff --git a/utils/rbutilqt/gui/infowidget.h b/utils/rbutilqt/gui/infowidget.h
new file mode 100644
index 0000000000..51eef0a37a
--- /dev/null
+++ b/utils/rbutilqt/gui/infowidget.h
@@ -0,0 +1,41 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2012 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef INFOWIDGET_H
20#define INFOWIDGET_H
21
22#include <QWidget>
23#include "ui_infowidgetfrm.h"
24
25class InfoWidget : public QWidget
26{
27 Q_OBJECT
28 public:
29 InfoWidget(QWidget *parent = nullptr);
30
31 public slots:
32 void updateInfo(void);
33
34 private:
35 void changeEvent(QEvent *e);
36
37 Ui::InfoWidgetFrm ui;
38};
39
40#endif
41
diff --git a/utils/rbutilqt/gui/infowidgetfrm.ui b/utils/rbutilqt/gui/infowidgetfrm.ui
new file mode 100644
index 0000000000..8c7fdb30f7
--- /dev/null
+++ b/utils/rbutilqt/gui/infowidgetfrm.ui
@@ -0,0 +1,43 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>InfoWidgetFrm</class>
4 <widget class="QWidget" name="InfoWidgetFrm">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>400</width>
10 <height>300</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Info</string>
15 </property>
16 <layout class="QGridLayout" name="gridLayout">
17 <item row="0" column="0">
18 <widget class="QLabel" name="labelInfo">
19 <property name="text">
20 <string>Currently installed packages.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; if you manually installed packages this might not be correct!</string>
21 </property>
22 <property name="textFormat">
23 <enum>Qt::RichText</enum>
24 </property>
25 <property name="wordWrap">
26 <bool>true</bool>
27 </property>
28 </widget>
29 </item>
30 <item row="1" column="0">
31 <widget class="QTreeWidget" name="treeInfo">
32 <column>
33 <property name="text">
34 <string>Package</string>
35 </property>
36 </column>
37 </widget>
38 </item>
39 </layout>
40 </widget>
41 <resources/>
42 <connections/>
43</ui>
diff --git a/utils/rbutilqt/gui/selectiveinstallwidget.cpp b/utils/rbutilqt/gui/selectiveinstallwidget.cpp
new file mode 100644
index 0000000000..9bfe7414a3
--- /dev/null
+++ b/utils/rbutilqt/gui/selectiveinstallwidget.cpp
@@ -0,0 +1,691 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2012 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QWidget>
20#include <QMessageBox>
21#include <QFileDialog>
22#include "selectiveinstallwidget.h"
23#include "ui_selectiveinstallwidgetfrm.h"
24#include "playerbuildinfo.h"
25#include "rbsettings.h"
26#include "rockboxinfo.h"
27#include "progressloggergui.h"
28#include "bootloaderinstallbase.h"
29#include "bootloaderinstallhelper.h"
30#include "themesinstallwindow.h"
31#include "utils.h"
32#include "Logger.h"
33
34SelectiveInstallWidget::SelectiveInstallWidget(QWidget* parent) : QWidget(parent)
35{
36 ui.setupUi(this);
37 ui.rockboxCheckbox->setChecked(RbSettings::value(RbSettings::InstallRockbox).toBool());
38 ui.fontsCheckbox->setChecked(RbSettings::value(RbSettings::InstallFonts).toBool());
39 ui.themesCheckbox->setChecked(RbSettings::value(RbSettings::InstallThemes).toBool());
40 ui.pluginDataCheckbox->setChecked(RbSettings::value(RbSettings::InstallPluginData).toBool());
41 ui.voiceCheckbox->setChecked(RbSettings::value(RbSettings::InstallVoice).toBool());
42 ui.manualCheckbox->setChecked(RbSettings::value(RbSettings::InstallManual).toBool());
43
44 ui.manualCombobox->addItem("PDF", "pdf");
45 ui.manualCombobox->addItem("HTML (zip)", "zip");
46 ui.manualCombobox->addItem("HTML", "html");
47
48 // check if Rockbox is installed by looking after rockbox-info.txt.
49 // If installed uncheck bootloader installation.
50 RockboxInfo info(m_mountpoint);
51 ui.bootloaderCheckbox->setChecked(!info.success());
52
53 m_logger = nullptr;
54 m_zipinstaller = nullptr;
55 m_themesinstaller = nullptr;
56
57 connect(ui.installButton, &QAbstractButton::clicked,
58 this, &SelectiveInstallWidget::startInstall);
59 connect(this, &SelectiveInstallWidget::installSkipped,
60 this, &SelectiveInstallWidget::continueInstall);
61 connect(ui.themesCustomize, &QAbstractButton::clicked,
62 this, &SelectiveInstallWidget::customizeThemes);
63 connect(ui.selectedVersion, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
64 this, &SelectiveInstallWidget::selectedVersionChanged);
65 // update version information. This also handles setting the previously
66 // selected build type and bootloader disabling.
67 updateVersion();
68}
69
70
71void SelectiveInstallWidget::selectedVersionChanged(int index)
72{
73 m_buildtype = static_cast<PlayerBuildInfo::BuildType>(ui.selectedVersion->itemData(index).toInt());
74 bool voice = true;
75 switch(m_buildtype) {
76 case PlayerBuildInfo::TypeRelease:
77 ui.selectedDescription->setText(tr("This is the latest stable "
78 "release available."));
79 voice = true;
80 break;
81 case PlayerBuildInfo::TypeDevel:
82 ui.selectedDescription->setText(tr("The development version is "
83 "updated on every code change."));
84 voice = false;
85 break;
86 case PlayerBuildInfo::TypeCandidate:
87 ui.selectedDescription->setText(tr("This will eventually become the "
88 "next Rockbox version. Install it to help testing."));
89 voice = false;
90 break;
91 case PlayerBuildInfo::TypeDaily:
92 ui.selectedDescription->setText(tr("Daily updated development version."));
93 voice = true;
94 break;
95 }
96 ui.voiceCheckbox->setEnabled(voice);
97 ui.voiceCombobox->setEnabled(voice);
98 ui.voiceLabel->setEnabled(voice);
99 ui.voiceCheckbox->setToolTip(voice ? "" : tr("Not available for the selected version"));
100
101 updateVoiceLangs();
102}
103
104
105void SelectiveInstallWidget::updateVersion(void)
106{
107 // get some configuration values globally
108 m_mountpoint = RbSettings::value(RbSettings::Mountpoint).toString();
109 m_target = RbSettings::value(RbSettings::CurrentPlatform).toString();
110 m_blmethod = PlayerBuildInfo::instance()->value(
111 PlayerBuildInfo::BootloaderMethod, m_target).toString();
112
113 if(m_logger != nullptr) {
114 delete m_logger;
115 m_logger = nullptr;
116 }
117
118 // re-populate all version items
119 QMap<PlayerBuildInfo::BuildType, QString> types;
120 types[PlayerBuildInfo::TypeRelease] = tr("Stable Release (Version %1)");
121 if (PlayerBuildInfo::instance()->value(PlayerBuildInfo::BuildStatus).toInt() != STATUS_RETIRED) {
122 types[PlayerBuildInfo::TypeCandidate] = tr("Release Candidate (Revison %1)");
123 types[PlayerBuildInfo::TypeDaily] = tr("Daily Build (%1)");
124 types[PlayerBuildInfo::TypeDevel] = tr("Development Version (Revison %1)");
125 }
126
127 ui.selectedVersion->clear();
128 for(auto i = types.begin(); i != types.end(); i++) {
129 QString version = PlayerBuildInfo::instance()->value(
130 PlayerBuildInfo::BuildVersion, i.key()).toString();
131 if(!version.isEmpty())
132 ui.selectedVersion->addItem(i.value().arg(version), i.key());
133 }
134
135 // select previously selected version
136 int index = ui.selectedVersion->findData(
137 static_cast<PlayerBuildInfo::BuildType>(RbSettings::value(RbSettings::Build).toInt()));
138 if(index < 0) {
139 index = ui.selectedVersion->findData(PlayerBuildInfo::TypeRelease);
140 if(index < 0) {
141 index = ui.selectedVersion->findData(PlayerBuildInfo::TypeDevel);
142 }
143 }
144 ui.selectedVersion->setCurrentIndex(index);
145 // check if Rockbox is installed. If it is untick the bootloader option, as
146 // well as if the selected player doesn't need a bootloader.
147 if(m_blmethod == "none") {
148 ui.bootloaderCheckbox->setEnabled(false);
149 ui.bootloaderCheckbox->setChecked(false);
150 ui.bootloaderLabel->setEnabled(false);
151 ui.bootloaderLabel->setText(tr("The selected player doesn't need a bootloader."));
152 }
153 else {
154 ui.bootloaderCheckbox->setEnabled(true);
155 ui.bootloaderLabel->setEnabled(true);
156 ui.bootloaderLabel->setText(tr("The bootloader is required for starting "
157 "Rockbox. Installation of the bootloader is only necessary "
158 "on first time installation."));
159 // check if Rockbox is installed by looking after rockbox-info.txt.
160 // If installed uncheck bootloader installation.
161 RockboxInfo info(m_mountpoint);
162 ui.bootloaderCheckbox->setChecked(!info.success());
163 }
164
165 updateVoiceLangs();
166}
167
168void SelectiveInstallWidget::updateVoiceLangs()
169{
170 // populate languages for voice file.
171 QVariant current = ui.voiceCombobox->currentData();
172 QMap<QString, QVariant> langs = PlayerBuildInfo::instance()->value(
173 PlayerBuildInfo::LanguageList).toMap();
174 QStringList voicelangs = PlayerBuildInfo::instance()->value(
175 PlayerBuildInfo::BuildVoiceLangs, m_buildtype).toStringList();
176 ui.voiceCombobox->clear();
177 for(auto it = langs.begin(); it != langs.end(); it++) {
178 if(voicelangs.contains(it.key())) {
179 ui.voiceCombobox->addItem(it.value().toString(), it.key());
180 LOG_INFO() << "available voices: adding" << it.key();
181 }
182
183 }
184 // try to select the previously selected one again (if still present)
185 // TODO: Fall back to system language if not found, or english.
186 int sel = ui.voiceCombobox->findData(current);
187 if(sel >= 0)
188 ui.voiceCombobox->setCurrentIndex(sel);
189
190}
191
192
193void SelectiveInstallWidget::saveSettings(void)
194{
195 LOG_INFO() << "saving current settings";
196
197 RbSettings::setValue(RbSettings::InstallRockbox, ui.rockboxCheckbox->isChecked());
198 RbSettings::setValue(RbSettings::InstallFonts, ui.fontsCheckbox->isChecked());
199 RbSettings::setValue(RbSettings::InstallThemes, ui.themesCheckbox->isChecked());
200 RbSettings::setValue(RbSettings::InstallPluginData, ui.pluginDataCheckbox->isChecked());
201 RbSettings::setValue(RbSettings::InstallVoice, ui.voiceCheckbox->isChecked());
202 RbSettings::setValue(RbSettings::InstallManual, ui.manualCheckbox->isChecked());
203 RbSettings::setValue(RbSettings::VoiceLanguage, ui.voiceCombobox->currentData().toString());
204}
205
206
207void SelectiveInstallWidget::startInstall(void)
208{
209 LOG_INFO() << "starting installation";
210 saveSettings();
211
212 m_installStage = 0;
213 if(m_logger != nullptr) delete m_logger;
214 m_logger = new ProgressLoggerGui(this);
215 QString warning = Utils::checkEnvironment(false);
216 if(!warning.isEmpty())
217 {
218 warning += "<br/>" + tr("Continue with installation?");
219 if(QMessageBox::warning(this, tr("Really continue?"), warning,
220 QMessageBox::Ok | QMessageBox::Abort, QMessageBox::Abort)
221 == QMessageBox::Abort)
222 {
223 emit installSkipped(true);
224 return;
225 }
226 }
227
228 m_logger->show();
229 if(!QFileInfo(m_mountpoint).isDir()) {
230 m_logger->addItem(tr("Mountpoint is wrong"), LOGERROR);
231 m_logger->setFinished();
232 return;
233 }
234 // start installation. No errors until now.
235 continueInstall(false);
236
237}
238
239
240void SelectiveInstallWidget::continueInstall(bool error)
241{
242 LOG_INFO() << "continuing install with stage" << m_installStage;
243 if(error) {
244 LOG_ERROR() << "Last part returned error.";
245 m_logger->setFinished();
246 m_installStage = 9;
247 }
248 m_installStage++;
249 switch(m_installStage) {
250 case 0: LOG_ERROR() << "Something wrong!"; break;
251 case 1: installBootloader(); break;
252 case 2: installRockbox(); break;
253 case 3: installFonts(); break;
254 case 4: installThemes(); break;
255 case 5: installPluginData(); break;
256 case 6: installVoicefile(); break;
257 case 7: installManual(); break;
258 case 8: installBootloaderPost(); break;
259 default: break;
260 }
261
262 if(m_installStage > 8) {
263 LOG_INFO() << "All install stages done.";
264 m_logger->setFinished();
265 if(m_blmethod != "none") {
266 // check if Rockbox is installed by looking after rockbox-info.txt.
267 // If installed uncheck bootloader installation.
268 RockboxInfo info(m_mountpoint);
269 ui.bootloaderCheckbox->setChecked(!info.success());
270 }
271 }
272}
273
274
275void SelectiveInstallWidget::installBootloader(void)
276{
277 if(ui.bootloaderCheckbox->isChecked()) {
278 LOG_INFO() << "installing bootloader";
279
280 QString platform = RbSettings::value(RbSettings::Platform).toString();
281 QString backupDestination = "";
282
283 // create installer
284 BootloaderInstallBase *bl =
285 BootloaderInstallHelper::createBootloaderInstaller(this,
286 PlayerBuildInfo::instance()->value(
287 PlayerBuildInfo::BootloaderMethod).toString());
288 if(bl == nullptr) {
289 m_logger->addItem(tr("No install method known."), LOGERROR);
290 m_logger->setFinished();
291 return;
292 }
293
294 // the bootloader install class does NOT use any GUI stuff.
295 // All messages are passed via signals.
296 connect(bl, SIGNAL(done(bool)), m_logger, SLOT(setFinished()));
297 connect(bl, SIGNAL(done(bool)), this, SLOT(continueInstall(bool)));
298 connect(bl, SIGNAL(logItem(QString, int)), m_logger, SLOT(addItem(QString, int)));
299 connect(bl, SIGNAL(logProgress(int, int)), m_logger, SLOT(setProgress(int, int)));
300 // pass Abort button click signal to current installer
301 connect(m_logger, SIGNAL(aborted()), bl, SLOT(progressAborted()));
302
303 // set bootloader filename. Do this now as installed() needs it.
304 QStringList blfile = PlayerBuildInfo::instance()->value(
305 PlayerBuildInfo::BootloaderFile).toStringList();
306 QStringList blfilepath;
307 for(int a = 0; a < blfile.size(); a++) {
308 blfilepath.append(RbSettings::value(RbSettings::Mountpoint).toString()
309 + blfile.at(a));
310 }
311 bl->setBlFile(blfilepath);
312 QUrl url(PlayerBuildInfo::instance()->value(PlayerBuildInfo::BootloaderUrl).toString()
313 + PlayerBuildInfo::instance()->value(PlayerBuildInfo::BootloaderName).toString());
314 bl->setBlUrl(url);
315 bl->setLogfile(RbSettings::value(RbSettings::Mountpoint).toString()
316 + "/.rockbox/rbutil.log");
317
318 if(bl->installed() == BootloaderInstallBase::BootloaderRockbox) {
319 if(QMessageBox::question(this, tr("Bootloader detected"),
320 tr("Bootloader already installed. Do you want to reinstall the bootloader?"),
321 QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
322 // keep m_logger open for auto installs.
323 // don't consider abort as error in auto-mode.
324 m_logger->addItem(tr("Bootloader installation skipped"), LOGINFO);
325 delete bl;
326 emit installSkipped(true);
327 return;
328 }
329 }
330 else if(bl->installed() == BootloaderInstallBase::BootloaderOther
331 && bl->capabilities() & BootloaderInstallBase::Backup)
332 {
333 QString targetFolder = PlayerBuildInfo::instance()->value(
334 PlayerBuildInfo::DisplayName).toString()
335 + " Firmware Backup";
336 // remove invalid character(s)
337 targetFolder.remove(QRegExp("[:/]"));
338 if(QMessageBox::question(this, tr("Create Bootloader backup"),
339 tr("You can create a backup of the original bootloader "
340 "file. Press \"Yes\" to select an output folder on your "
341 "computer to save the file to. The file will get placed "
342 "in a new folder \"%1\" created below the selected folder.\n"
343 "Press \"No\" to skip this step.").arg(targetFolder),
344 QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
345 backupDestination = QFileDialog::getExistingDirectory(this,
346 tr("Browse backup folder"), QDir::homePath());
347 if(!backupDestination.isEmpty())
348 backupDestination += "/" + targetFolder;
349
350 LOG_INFO() << "backing up to" << backupDestination;
351 // backup needs to be done after the m_logger has been set up.
352 }
353 }
354
355 if(bl->capabilities() & BootloaderInstallBase::NeedsOf)
356 {
357 int ret;
358 ret = QMessageBox::information(this, tr("Prerequisites"),
359 bl->ofHint(),QMessageBox::Ok | QMessageBox::Abort);
360 if(ret != QMessageBox::Ok) {
361 // consider aborting an error to close window / abort automatic
362 // installation.
363 m_logger->addItem(tr("Bootloader installation aborted"), LOGINFO);
364 m_logger->setFinished();
365 emit installSkipped(true);
366 return;
367 }
368 // open dialog to browse to of file
369 QString offile;
370 QString filter
371 = PlayerBuildInfo::instance()->value(PlayerBuildInfo::BootloaderFilter).toString();
372 if(!filter.isEmpty()) {
373 filter = tr("Bootloader files (%1)").arg(filter) + ";;";
374 }
375 filter += tr("All files (*)");
376 offile = QFileDialog::getOpenFileName(this,
377 tr("Select firmware file"), QDir::homePath(), filter);
378 if(!QFileInfo(offile).isReadable()) {
379 m_logger->addItem(tr("Error opening firmware file"), LOGERROR);
380 m_logger->setFinished();
381 emit installSkipped(true);
382 return;
383 }
384 if(!bl->setOfFile(offile, blfile)) {
385 m_logger->addItem(tr("Error reading firmware file"), LOGERROR);
386 m_logger->setFinished();
387 emit installSkipped(true);
388 return;
389 }
390 }
391
392 // start install.
393 if(!backupDestination.isEmpty()) {
394 if(!bl->backup(backupDestination)) {
395 if(QMessageBox::warning(this, tr("Backup error"),
396 tr("Could not create backup file. Continue?"),
397 QMessageBox::No | QMessageBox::Yes)
398 == QMessageBox::No) {
399 m_logger->setFinished();
400 return;
401 }
402 }
403 }
404 bl->install();
405
406 }
407 else {
408 LOG_INFO() << "Bootloader install disabled.";
409 emit installSkipped(false);
410 }
411}
412
413void SelectiveInstallWidget::installBootloaderPost()
414{
415 // don't do anything if no bootloader install has been done.
416 if(ui.bootloaderCheckbox->isChecked()) {
417 QString msg = BootloaderInstallHelper::postinstallHints(
418 RbSettings::value(RbSettings::Platform).toString());
419 if(!msg.isEmpty()) {
420 QMessageBox::information(this, tr("Manual steps required"), msg);
421 }
422 }
423 emit installSkipped(false);
424}
425
426
427void SelectiveInstallWidget::installRockbox(void)
428{
429 if(ui.rockboxCheckbox->isChecked()) {
430 LOG_INFO() << "installing Rockbox";
431 QString url;
432
433 RbSettings::setValue(RbSettings::Build, m_buildtype);
434 RbSettings::sync();
435
436 url = PlayerBuildInfo::instance()->value(
437 PlayerBuildInfo::BuildUrl, m_buildtype).toString();
438 //! install build
439 if(m_zipinstaller != nullptr) m_zipinstaller->deleteLater();
440 m_zipinstaller = new ZipInstaller(this);
441 m_zipinstaller->setUrl(url);
442 m_zipinstaller->setLogSection("Rockbox (Base)");
443 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
444 m_zipinstaller->setCache(true);
445 m_zipinstaller->setLogVersion(PlayerBuildInfo::instance()->value(
446 PlayerBuildInfo::BuildVersion, m_buildtype).toString());
447 m_zipinstaller->setMountPoint(m_mountpoint);
448
449 connect(m_zipinstaller, SIGNAL(done(bool)), this, SLOT(continueInstall(bool)));
450
451 connect(m_zipinstaller, SIGNAL(logItem(QString, int)), m_logger, SLOT(addItem(QString, int)));
452 connect(m_zipinstaller, SIGNAL(logProgress(int, int)), m_logger, SLOT(setProgress(int, int)));
453 connect(m_logger, SIGNAL(aborted()), m_zipinstaller, SLOT(abort()));
454 m_zipinstaller->install();
455
456 }
457 else {
458 LOG_INFO() << "Rockbox install disabled.";
459 emit installSkipped(false);
460 }
461}
462
463
464void SelectiveInstallWidget::installFonts(void)
465{
466 if(ui.fontsCheckbox->isChecked()) {
467 LOG_INFO() << "installing Fonts";
468
469 RockboxInfo installInfo(m_mountpoint);
470 QString fontsurl;
471 QString logversion;
472 QString relversion = installInfo.release();
473 if(!relversion.isEmpty()) {
474 // release is empty for non-release versions (i.e. daily / current)
475 logversion = installInfo.release();
476 }
477 fontsurl = PlayerBuildInfo::instance()->value(
478 PlayerBuildInfo::BuildFontUrl, m_buildtype).toString();
479 fontsurl.replace("%RELVERSION%", relversion);
480
481 // create new zip installer
482 if(m_zipinstaller != nullptr) m_zipinstaller->deleteLater();
483 m_zipinstaller = new ZipInstaller(this);
484 m_zipinstaller->setUrl(fontsurl);
485 m_zipinstaller->setLogSection("Fonts");
486 m_zipinstaller->setLogVersion(logversion);
487 m_zipinstaller->setMountPoint(m_mountpoint);
488 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
489 m_zipinstaller->setCache(true);
490
491 connect(m_zipinstaller, SIGNAL(done(bool)), this, SLOT(continueInstall(bool)));
492 connect(m_zipinstaller, SIGNAL(logItem(QString, int)), m_logger, SLOT(addItem(QString, int)));
493 connect(m_zipinstaller, SIGNAL(logProgress(int, int)), m_logger, SLOT(setProgress(int, int)));
494 connect(m_logger, SIGNAL(aborted()), m_zipinstaller, SLOT(abort()));
495 m_zipinstaller->install();
496 }
497 else {
498 LOG_INFO() << "Fonts install disabled.";
499 emit installSkipped(false);
500 }
501}
502
503void SelectiveInstallWidget::installVoicefile(void)
504{
505 if(ui.voiceCheckbox->isChecked() && ui.voiceCheckbox->isEnabled()) {
506 LOG_INFO() << "installing Voice file";
507 QString lang = ui.voiceCombobox->currentData().toString();
508
509 RockboxInfo installInfo(m_mountpoint);
510 QString voiceurl;
511 QString logversion;
512 QString relversion = installInfo.release();
513 if(m_buildtype != PlayerBuildInfo::TypeRelease) {
514 // release is empty for non-release versions (i.e. daily / current)
515 logversion = installInfo.release();
516 }
517 voiceurl = PlayerBuildInfo::instance()->value(
518 PlayerBuildInfo::BuildVoiceUrl, m_buildtype).toString();
519 voiceurl.replace("%LANGUAGE%", lang);
520
521 // create new zip installer
522 if(m_zipinstaller != nullptr) m_zipinstaller->deleteLater();
523 m_zipinstaller = new ZipInstaller(this);
524 m_zipinstaller->setUrl(voiceurl);
525 m_zipinstaller->setLogSection("Prerendered Voice (" + lang + ")");
526 m_zipinstaller->setLogVersion(logversion);
527 m_zipinstaller->setMountPoint(m_mountpoint);
528 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
529 m_zipinstaller->setCache(true);
530
531 connect(m_zipinstaller, SIGNAL(done(bool)), this, SLOT(continueInstall(bool)));
532 connect(m_zipinstaller, SIGNAL(logItem(QString, int)), m_logger, SLOT(addItem(QString, int)));
533 connect(m_zipinstaller, SIGNAL(logProgress(int, int)), m_logger, SLOT(setProgress(int, int)));
534 connect(m_logger, SIGNAL(aborted()), m_zipinstaller, SLOT(abort()));
535 m_zipinstaller->install();
536 }
537 else {
538 LOG_INFO() << "Voice install disabled.";
539 emit installSkipped(false);
540 }
541}
542
543void SelectiveInstallWidget::installManual(void)
544{
545 if(ui.manualCheckbox->isChecked() && ui.manualCheckbox->isEnabled()) {
546 LOG_INFO() << "installing Manual";
547 QString mantype = ui.manualCombobox->currentData().toString();
548
549 RockboxInfo installInfo(m_mountpoint);
550 QString manualurl;
551 QString logversion;
552 QString relversion = installInfo.release();
553 if(m_buildtype != PlayerBuildInfo::TypeRelease) {
554 // release is empty for non-release versions (i.e. daily / current)
555 logversion = installInfo.release();
556 }
557
558 manualurl = PlayerBuildInfo::instance()->value(
559 PlayerBuildInfo::BuildManualUrl, m_buildtype).toString();
560 if(mantype == "pdf")
561 manualurl.replace("%FORMAT%", ".pdf");
562 else
563 manualurl.replace("%FORMAT%", "-html.zip");
564
565 // create new zip installer
566 if(m_zipinstaller != nullptr) m_zipinstaller->deleteLater();
567 m_zipinstaller = new ZipInstaller(this);
568 m_zipinstaller->setUrl(manualurl);
569 m_zipinstaller->setLogSection("Manual (" + mantype + ")");
570 m_zipinstaller->setLogVersion(logversion);
571 m_zipinstaller->setMountPoint(m_mountpoint);
572 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
573 m_zipinstaller->setCache(true);
574 // if type is html extract it.
575 m_zipinstaller->setUnzip(mantype == "html");
576
577 connect(m_zipinstaller, SIGNAL(done(bool)), this, SLOT(continueInstall(bool)));
578 connect(m_zipinstaller, SIGNAL(logItem(QString, int)), m_logger, SLOT(addItem(QString, int)));
579 connect(m_zipinstaller, SIGNAL(logProgress(int, int)), m_logger, SLOT(setProgress(int, int)));
580 connect(m_logger, SIGNAL(aborted()), m_zipinstaller, SLOT(abort()));
581 m_zipinstaller->install();
582 }
583 else {
584 LOG_INFO() << "Manual install disabled.";
585 emit installSkipped(false);
586 }
587}
588
589void SelectiveInstallWidget::customizeThemes(void)
590{
591 if(m_themesinstaller == nullptr)
592 m_themesinstaller = new ThemesInstallWindow(this);
593
594 m_themesinstaller->setSelectOnly(true);
595 m_themesinstaller->show();
596}
597
598
599void SelectiveInstallWidget::installThemes(void)
600{
601 if(ui.themesCheckbox->isChecked()) {
602 LOG_INFO() << "installing themes";
603 if(m_themesinstaller == nullptr)
604 m_themesinstaller = new ThemesInstallWindow(this);
605
606 connect(m_themesinstaller, SIGNAL(done(bool)), this, SLOT(continueInstall(bool)));
607 m_themesinstaller->setLogger(m_logger);
608 m_themesinstaller->setModal(true);
609 m_themesinstaller->install();
610 }
611 else {
612 LOG_INFO() << "Themes install disabled.";
613 emit installSkipped(false);
614 }
615}
616
617static const struct {
618 const char *name; // display name
619 const char *rockfile; // rock file to look for
620 PlayerBuildInfo::BuildInfo zipurl; // download url
621} PluginDataFiles[] = {
622 { "Doom", "games/doom.rock", PlayerBuildInfo::DoomUrl },
623 { "Duke3D", "games/duke3d.rock", PlayerBuildInfo::Duke3DUrl },
624 { "Quake", "games/quake.rock", PlayerBuildInfo::QuakeUrl },
625 { "Puzzles fonts", "games/sgt-blackbox.rock", PlayerBuildInfo::PuzzFontsUrl },
626 { "Wolf3D", "games/wolf3d.rock", PlayerBuildInfo::Wolf3DUrl },
627 { "XWorld", "games/xworld.rock", PlayerBuildInfo::XWorldUrl },
628 { "MIDI Patchset", "viewers/midi.rock", PlayerBuildInfo::MidiPatchsetUrl },
629};
630
631void SelectiveInstallWidget::installPluginData(void)
632{
633 if(ui.pluginDataCheckbox->isChecked()) {
634 // build a list of zip urls that we need, then install
635 QStringList dataUrls;
636 QStringList dataName;
637
638 for(size_t i = 0; i < sizeof(PluginDataFiles) / sizeof(PluginDataFiles[0]); i++)
639 {
640 // check if installed Rockbox has this plugin.
641 if(QFileInfo(m_mountpoint + "/.rockbox/rocks/" + PluginDataFiles[i].rockfile).exists()) {
642 dataName.append(PluginDataFiles[i].name);
643 // game URLs do not depend on the actual build type, but we need
644 // to pass it (simplifies the API, and will allow to make them
645 // type specific later if needed)
646 dataUrls.append(PlayerBuildInfo::instance()->value(
647 PluginDataFiles[i].zipurl, m_buildtype).toString());
648 }
649 }
650
651 if(dataUrls.size() == 0)
652 {
653 m_logger->addItem(
654 tr("Your installation doesn't require any plugin data files, skipping."),
655 LOGINFO);
656 emit installSkipped(false);
657 return;
658 }
659
660 LOG_INFO() << "installing plugin data files";
661
662 // create new zip installer
663 if(m_zipinstaller != nullptr) m_zipinstaller->deleteLater();
664 m_zipinstaller = new ZipInstaller(this);
665
666 m_zipinstaller->setUrl(dataUrls);
667 m_zipinstaller->setLogSection(dataName);
668 m_zipinstaller->setLogVersion();
669 m_zipinstaller->setMountPoint(m_mountpoint);
670 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
671 m_zipinstaller->setCache(true);
672 connect(m_zipinstaller, SIGNAL(done(bool)), this, SLOT(continueInstall(bool)));
673 connect(m_zipinstaller, SIGNAL(logItem(QString, int)), m_logger, SLOT(addItem(QString, int)));
674 connect(m_zipinstaller, SIGNAL(logProgress(int, int)), m_logger, SLOT(setProgress(int, int)));
675 connect(m_logger, SIGNAL(aborted()), m_zipinstaller, SLOT(abort()));
676 m_zipinstaller->install();
677 }
678 else {
679 LOG_INFO() << "Gamefile install disabled.";
680 emit installSkipped(false);
681 }
682}
683
684void SelectiveInstallWidget::changeEvent(QEvent *e)
685{
686 if(e->type() == QEvent::LanguageChange) {
687 ui.retranslateUi(this);
688 } else {
689 QWidget::changeEvent(e);
690 }
691}
diff --git a/utils/rbutilqt/gui/selectiveinstallwidget.h b/utils/rbutilqt/gui/selectiveinstallwidget.h
new file mode 100644
index 0000000000..c961a387e0
--- /dev/null
+++ b/utils/rbutilqt/gui/selectiveinstallwidget.h
@@ -0,0 +1,74 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2012 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef SELECTIVEINSTALLWIDGET_H
20#define SELECTIVEINSTALLWIDGET_H
21
22#include <QWidget>
23#include "ui_selectiveinstallwidgetfrm.h"
24#include "progressloggergui.h"
25#include "zipinstaller.h"
26#include "themesinstallwindow.h"
27#include "playerbuildinfo.h"
28
29class SelectiveInstallWidget : public QWidget
30{
31 Q_OBJECT
32 public:
33 SelectiveInstallWidget(QWidget* parent = nullptr);
34
35 public slots:
36 void updateVersion(void);
37 void saveSettings(void);
38 void startInstall(void);
39
40 private slots:
41 void continueInstall(bool);
42 void customizeThemes(void);
43 void selectedVersionChanged(int);
44 void updateVoiceLangs();
45
46 private:
47 void installBootloader(void);
48 void installRockbox(void);
49 void installFonts(void);
50 void installVoicefile(void);
51 void installManual(void);
52 void installThemes(void);
53 void installPluginData(void);
54 void installBootloaderPost(void);
55
56 signals:
57 void installSkipped(bool);
58
59 private:
60 void changeEvent(QEvent *e);
61
62 Ui::SelectiveInstallWidget ui;
63 QString m_target;
64 QString m_blmethod;
65 QString m_mountpoint;
66 ProgressLoggerGui *m_logger;
67 int m_installStage;
68 ZipInstaller *m_zipinstaller;
69 ThemesInstallWindow *m_themesinstaller;
70 PlayerBuildInfo::BuildType m_buildtype;
71};
72
73#endif
74
diff --git a/utils/rbutilqt/gui/selectiveinstallwidgetfrm.ui b/utils/rbutilqt/gui/selectiveinstallwidgetfrm.ui
new file mode 100644
index 0000000000..f68ff350f3
--- /dev/null
+++ b/utils/rbutilqt/gui/selectiveinstallwidgetfrm.ui
@@ -0,0 +1,316 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>SelectiveInstallWidget</class>
4 <widget class="QWidget" name="SelectiveInstallWidget">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>663</width>
10 <height>440</height>
11 </rect>
12 </property>
13 <property name="sizePolicy">
14 <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
15 <horstretch>0</horstretch>
16 <verstretch>0</verstretch>
17 </sizepolicy>
18 </property>
19 <property name="windowTitle">
20 <string>Selective Installation</string>
21 </property>
22 <layout class="QGridLayout" name="gridLayout_3">
23 <item row="0" column="0">
24 <widget class="QGroupBox" name="versionSelectGroupBox">
25 <property name="title">
26 <string>Rockbox version to install</string>
27 </property>
28 <layout class="QGridLayout" name="gridLayout">
29 <item row="0" column="0">
30 <widget class="QComboBox" name="selectedVersion"/>
31 </item>
32 <item row="0" column="1">
33 <widget class="QLabel" name="selectedDescription">
34 <property name="text">
35 <string>Version information not available yet.</string>
36 </property>
37 <property name="wordWrap">
38 <bool>true</bool>
39 </property>
40 </widget>
41 </item>
42 </layout>
43 </widget>
44 </item>
45 <item row="1" column="0">
46 <widget class="QGroupBox" name="groupBox">
47 <property name="sizePolicy">
48 <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
49 <horstretch>0</horstretch>
50 <verstretch>0</verstretch>
51 </sizepolicy>
52 </property>
53 <property name="title">
54 <string>Rockbox components to install</string>
55 </property>
56 <layout class="QGridLayout" name="gridLayout_2">
57 <item row="0" column="0">
58 <widget class="QCheckBox" name="bootloaderCheckbox">
59 <property name="text">
60 <string>&amp;Bootloader</string>
61 </property>
62 <property name="icon">
63 <iconset resource="../rbutilqt.qrc">
64 <normaloff>:/icons/preferences-system.svg</normaloff>:/icons/preferences-system.svg</iconset>
65 </property>
66 <property name="checked">
67 <bool>true</bool>
68 </property>
69 </widget>
70 </item>
71 <item row="1" column="0">
72 <widget class="QCheckBox" name="rockboxCheckbox">
73 <property name="text">
74 <string>&amp;Rockbox</string>
75 </property>
76 <property name="icon">
77 <iconset resource="../rbutilqt.qrc">
78 <normaloff>:/icons/multimedia-player.svg</normaloff>:/icons/multimedia-player.svg</iconset>
79 </property>
80 <property name="checked">
81 <bool>true</bool>
82 </property>
83 </widget>
84 </item>
85 <item row="3" column="2">
86 <widget class="QLabel" name="themesLabel">
87 <property name="sizePolicy">
88 <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
89 <horstretch>0</horstretch>
90 <verstretch>0</verstretch>
91 </sizepolicy>
92 </property>
93 <property name="text">
94 <string>Themes allow adjusting the user interface of Rockbox. Use &quot;Customize&quot; to select themes.</string>
95 </property>
96 <property name="wordWrap">
97 <bool>true</bool>
98 </property>
99 </widget>
100 </item>
101 <item row="3" column="0">
102 <widget class="QCheckBox" name="themesCheckbox">
103 <property name="text">
104 <string>Themes</string>
105 </property>
106 <property name="icon">
107 <iconset resource="../rbutilqt.qrc">
108 <normaloff>:/icons/preferences-desktop-theme.svg</normaloff>:/icons/preferences-desktop-theme.svg</iconset>
109 </property>
110 </widget>
111 </item>
112 <item row="2" column="0">
113 <widget class="QCheckBox" name="fontsCheckbox">
114 <property name="text">
115 <string>Fonts</string>
116 </property>
117 <property name="icon">
118 <iconset resource="../rbutilqt.qrc">
119 <normaloff>:/icons/preferences-desktop-font.svg</normaloff>:/icons/preferences-desktop-font.svg</iconset>
120 </property>
121 <property name="checked">
122 <bool>true</bool>
123 </property>
124 </widget>
125 </item>
126 <item row="0" column="2">
127 <widget class="QLabel" name="bootloaderLabel">
128 <property name="sizePolicy">
129 <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
130 <horstretch>0</horstretch>
131 <verstretch>0</verstretch>
132 </sizepolicy>
133 </property>
134 <property name="text">
135 <string>The bootloader is required for starting Rockbox. Only necessary for first time install.</string>
136 </property>
137 <property name="wordWrap">
138 <bool>true</bool>
139 </property>
140 </widget>
141 </item>
142 <item row="6" column="2">
143 <widget class="QLabel" name="pluginDataLabe">
144 <property name="sizePolicy">
145 <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
146 <horstretch>0</horstretch>
147 <verstretch>0</verstretch>
148 </sizepolicy>
149 </property>
150 <property name="text">
151 <string>Some plugins require additional data files.</string>
152 </property>
153 <property name="wordWrap">
154 <bool>true</bool>
155 </property>
156 </widget>
157 </item>
158 <item row="3" column="4">
159 <widget class="QPushButton" name="themesCustomize">
160 <property name="text">
161 <string>Customize</string>
162 </property>
163 <property name="icon">
164 <iconset resource="../rbutilqt.qrc">
165 <normaloff>:/icons/preferences-system.svg</normaloff>:/icons/preferences-system.svg</iconset>
166 </property>
167 </widget>
168 </item>
169 <item row="2" column="2">
170 <widget class="QLabel" name="fontsLabel">
171 <property name="sizePolicy">
172 <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
173 <horstretch>0</horstretch>
174 <verstretch>0</verstretch>
175 </sizepolicy>
176 </property>
177 <property name="text">
178 <string>Additional fonts for the User Interface.</string>
179 </property>
180 <property name="wordWrap">
181 <bool>true</bool>
182 </property>
183 </widget>
184 </item>
185 <item row="7" column="2">
186 <widget class="QLabel" name="voiceLabel">
187 <property name="text">
188 <string>Install prerendered voice file.</string>
189 </property>
190 </widget>
191 </item>
192 <item row="6" column="0">
193 <widget class="QCheckBox" name="pluginDataCheckbox">
194 <property name="text">
195 <string>Plugin Data</string>
196 </property>
197 <property name="icon">
198 <iconset resource="../rbutilqt.qrc">
199 <normaloff>:/icons/input-gaming.svg</normaloff>:/icons/input-gaming.svg</iconset>
200 </property>
201 </widget>
202 </item>
203 <item row="1" column="3">
204 <spacer name="horizontalSpacer">
205 <property name="orientation">
206 <enum>Qt::Horizontal</enum>
207 </property>
208 <property name="sizeType">
209 <enum>QSizePolicy::Minimum</enum>
210 </property>
211 <property name="sizeHint" stdset="0">
212 <size>
213 <width>1</width>
214 <height>1</height>
215 </size>
216 </property>
217 </spacer>
218 </item>
219 <item row="8" column="0">
220 <widget class="QCheckBox" name="manualCheckbox">
221 <property name="text">
222 <string>&amp;Manual</string>
223 </property>
224 <property name="icon">
225 <iconset resource="../rbutilqt.qrc">
226 <normaloff>:/icons/edit-find.svg</normaloff>:/icons/edit-find.svg</iconset>
227 </property>
228 </widget>
229 </item>
230 <item row="7" column="0">
231 <widget class="QCheckBox" name="voiceCheckbox">
232 <property name="text">
233 <string>&amp;Voice File</string>
234 </property>
235 <property name="icon">
236 <iconset resource="../rbutilqt.qrc">
237 <normaloff>:/icons/audio-volume-high.svg</normaloff>:/icons/audio-volume-high.svg</iconset>
238 </property>
239 </widget>
240 </item>
241 <item row="7" column="4">
242 <widget class="QComboBox" name="voiceCombobox"/>
243 </item>
244 <item row="1" column="2">
245 <widget class="QLabel" name="rockboxLabel">
246 <property name="sizePolicy">
247 <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
248 <horstretch>0</horstretch>
249 <verstretch>0</verstretch>
250 </sizepolicy>
251 </property>
252 <property name="text">
253 <string>The main Rockbox firmware.</string>
254 </property>
255 <property name="wordWrap">
256 <bool>true</bool>
257 </property>
258 </widget>
259 </item>
260 <item row="8" column="2">
261 <widget class="QLabel" name="manualLabel">
262 <property name="text">
263 <string>Save a copy of the manual on the player.</string>
264 </property>
265 </widget>
266 </item>
267 <item row="8" column="4">
268 <widget class="QComboBox" name="manualCombobox"/>
269 </item>
270 </layout>
271 </widget>
272 </item>
273 <item row="2" column="0">
274 <spacer name="verticalSpacer">
275 <property name="orientation">
276 <enum>Qt::Vertical</enum>
277 </property>
278 <property name="sizeType">
279 <enum>QSizePolicy::Expanding</enum>
280 </property>
281 <property name="sizeHint" stdset="0">
282 <size>
283 <width>20</width>
284 <height>1</height>
285 </size>
286 </property>
287 </spacer>
288 </item>
289 <item row="3" column="0">
290 <widget class="QPushButton" name="installButton">
291 <property name="text">
292 <string>&amp;Install</string>
293 </property>
294 <property name="icon">
295 <iconset resource="../rbutilqt.qrc">
296 <normaloff>:/icons/package-x-generic.svg</normaloff>:/icons/package-x-generic.svg</iconset>
297 </property>
298 </widget>
299 </item>
300 </layout>
301 </widget>
302 <tabstops>
303 <tabstop>selectedVersion</tabstop>
304 <tabstop>bootloaderCheckbox</tabstop>
305 <tabstop>rockboxCheckbox</tabstop>
306 <tabstop>fontsCheckbox</tabstop>
307 <tabstop>themesCheckbox</tabstop>
308 <tabstop>themesCustomize</tabstop>
309 <tabstop>pluginDataCheckbox</tabstop>
310 <tabstop>installButton</tabstop>
311 </tabstops>
312 <resources>
313 <include location="../rbutilqt.qrc"/>
314 </resources>
315 <connections/>
316</ui>
diff --git a/utils/rbutilqt/icons/audio-input-microphone.svg b/utils/rbutilqt/icons/audio-input-microphone.svg
new file mode 100644
index 0000000000..d31409c4e5
--- /dev/null
+++ b/utils/rbutilqt/icons/audio-input-microphone.svg
@@ -0,0 +1,501 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 inkscape:export-ydpi="90.000000"
13 inkscape:export-xdpi="90.000000"
14 inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
15 width="48px"
16 height="48px"
17 id="svg11300"
18 sodipodi:version="0.32"
19 inkscape:version="0.46"
20 sodipodi:docbase="/home/tigert/cvs/freedesktop.org/tango-icon-theme/scalable/devices"
21 sodipodi:docname="audio-input-microphone.svg"
22 inkscape:output_extension="org.inkscape.output.svg.inkscape">
23 <defs
24 id="defs3">
25 <inkscape:perspective
26 sodipodi:type="inkscape:persp3d"
27 inkscape:vp_x="0 : 24 : 1"
28 inkscape:vp_y="0 : 1000 : 0"
29 inkscape:vp_z="48 : 24 : 1"
30 inkscape:persp3d-origin="24 : 16 : 1"
31 id="perspective71" />
32 <linearGradient
33 id="linearGradient2407">
34 <stop
35 style="stop-color:#d5d5d5;stop-opacity:1;"
36 offset="0"
37 id="stop2409" />
38 <stop
39 style="stop-color:#747474;stop-opacity:1;"
40 offset="1"
41 id="stop2411" />
42 </linearGradient>
43 <linearGradient
44 inkscape:collect="always"
45 id="linearGradient2399">
46 <stop
47 style="stop-color:#ffffff;stop-opacity:1;"
48 offset="0"
49 id="stop2401" />
50 <stop
51 style="stop-color:#ffffff;stop-opacity:0;"
52 offset="1"
53 id="stop2403" />
54 </linearGradient>
55 <linearGradient
56 id="linearGradient2371">
57 <stop
58 style="stop-color:#000000;stop-opacity:1;"
59 offset="0"
60 id="stop2373" />
61 <stop
62 style="stop-color:#000000;stop-opacity:0.48453608;"
63 offset="1"
64 id="stop2375" />
65 </linearGradient>
66 <linearGradient
67 inkscape:collect="always"
68 id="linearGradient2355">
69 <stop
70 style="stop-color:#000000;stop-opacity:1;"
71 offset="0"
72 id="stop2357" />
73 <stop
74 style="stop-color:#000000;stop-opacity:0;"
75 offset="1"
76 id="stop2359" />
77 </linearGradient>
78 <linearGradient
79 id="linearGradient2345">
80 <stop
81 style="stop-color:#d5d5d5;stop-opacity:1;"
82 offset="0"
83 id="stop2347" />
84 <stop
85 style="stop-color:#a0a0a0;stop-opacity:1;"
86 offset="1"
87 id="stop2349" />
88 </linearGradient>
89 <linearGradient
90 inkscape:collect="always"
91 id="linearGradient2337">
92 <stop
93 style="stop-color:#ffffff;stop-opacity:1;"
94 offset="0"
95 id="stop2339" />
96 <stop
97 style="stop-color:#ffffff;stop-opacity:0;"
98 offset="1"
99 id="stop2341" />
100 </linearGradient>
101 <linearGradient
102 inkscape:collect="always"
103 id="linearGradient2252">
104 <stop
105 style="stop-color:#c6c6c6;stop-opacity:1;"
106 offset="0"
107 id="stop2254" />
108 <stop
109 style="stop-color:#c6c6c6;stop-opacity:0;"
110 offset="1"
111 id="stop2256" />
112 </linearGradient>
113 <linearGradient
114 inkscape:collect="always"
115 id="linearGradient2242">
116 <stop
117 style="stop-color:#000000;stop-opacity:1;"
118 offset="0"
119 id="stop2244" />
120 <stop
121 style="stop-color:#000000;stop-opacity:0;"
122 offset="1"
123 id="stop2246" />
124 </linearGradient>
125 <linearGradient
126 id="linearGradient2232">
127 <stop
128 style="stop-color:#b0b0b0;stop-opacity:1;"
129 offset="0"
130 id="stop2234" />
131 <stop
132 style="stop-color:#747474;stop-opacity:1;"
133 offset="1"
134 id="stop2236" />
135 </linearGradient>
136 <radialGradient
137 inkscape:collect="always"
138 xlink:href="#linearGradient2232"
139 id="radialGradient2238"
140 cx="15.4375"
141 cy="42.090427"
142 fx="15.4375"
143 fy="42.090427"
144 r="11.1875"
145 gradientTransform="matrix(1.000000,0.000000,0.000000,0.525140,0.000000,22.02165)"
146 gradientUnits="userSpaceOnUse" />
147 <radialGradient
148 inkscape:collect="always"
149 xlink:href="#linearGradient2242"
150 id="radialGradient2248"
151 cx="25.1875"
152 cy="41"
153 fx="25.1875"
154 fy="41"
155 r="16.4375"
156 gradientTransform="matrix(1.000000,0.000000,0.000000,0.425856,-1.940722e-16,23.53992)"
157 gradientUnits="userSpaceOnUse" />
158 <linearGradient
159 inkscape:collect="always"
160 xlink:href="#linearGradient2252"
161 id="linearGradient2258"
162 x1="41.25"
163 y1="36.689548"
164 x2="48.25"
165 y2="35.689548"
166 gradientUnits="userSpaceOnUse" />
167 <radialGradient
168 inkscape:collect="always"
169 xlink:href="#linearGradient2337"
170 id="radialGradient2343"
171 cx="20.275276"
172 cy="5.7119732"
173 fx="20.275276"
174 fy="5.7119732"
175 r="12.494026"
176 gradientTransform="matrix(2.530751,-5.687060e-16,5.159545e-16,2.296006,-31.03641,-6.699856)"
177 gradientUnits="userSpaceOnUse" />
178 <radialGradient
179 inkscape:collect="always"
180 xlink:href="#linearGradient2345"
181 id="radialGradient2351"
182 cx="19.557497"
183 cy="6.644074"
184 fx="19.557497"
185 fy="6.644074"
186 r="10.98921"
187 gradientTransform="matrix(1.491918,-8.445108e-2,-5.874412e-2,3.986724,-9.646804,-20.27595)"
188 gradientUnits="userSpaceOnUse" />
189 <linearGradient
190 inkscape:collect="always"
191 xlink:href="#linearGradient2355"
192 id="linearGradient2361"
193 x1="25.160467"
194 y1="15.803662"
195 x2="33.96875"
196 y2="20.4375"
197 gradientUnits="userSpaceOnUse" />
198 <linearGradient
199 inkscape:collect="always"
200 xlink:href="#linearGradient2355"
201 id="linearGradient2363"
202 x1="25.160467"
203 y1="15.803662"
204 x2="33.96875"
205 y2="20.4375"
206 gradientUnits="userSpaceOnUse" />
207 <linearGradient
208 inkscape:collect="always"
209 xlink:href="#linearGradient2355"
210 id="linearGradient2365"
211 x1="25.160467"
212 y1="15.803662"
213 x2="33.96875"
214 y2="20.4375"
215 gradientUnits="userSpaceOnUse" />
216 <linearGradient
217 inkscape:collect="always"
218 xlink:href="#linearGradient2355"
219 id="linearGradient2367"
220 x1="25.160467"
221 y1="15.803662"
222 x2="33.96875"
223 y2="20.4375"
224 gradientUnits="userSpaceOnUse" />
225 <linearGradient
226 inkscape:collect="always"
227 xlink:href="#linearGradient2355"
228 id="linearGradient2369"
229 x1="25.160467"
230 y1="15.803662"
231 x2="33.96875"
232 y2="20.4375"
233 gradientUnits="userSpaceOnUse" />
234 <linearGradient
235 inkscape:collect="always"
236 xlink:href="#linearGradient2371"
237 id="linearGradient2377"
238 x1="18.328718"
239 y1="15.323075"
240 x2="14.40625"
241 y2="14.046875"
242 gradientUnits="userSpaceOnUse" />
243 <linearGradient
244 inkscape:collect="always"
245 xlink:href="#linearGradient2371"
246 id="linearGradient2379"
247 x1="18.328718"
248 y1="15.323075"
249 x2="14.40625"
250 y2="14.046875"
251 gradientUnits="userSpaceOnUse" />
252 <linearGradient
253 inkscape:collect="always"
254 xlink:href="#linearGradient2371"
255 id="linearGradient2381"
256 x1="18.328718"
257 y1="15.323075"
258 x2="14.40625"
259 y2="14.046875"
260 gradientUnits="userSpaceOnUse" />
261 <linearGradient
262 inkscape:collect="always"
263 xlink:href="#linearGradient2371"
264 id="linearGradient2383"
265 x1="18.328718"
266 y1="15.323075"
267 x2="14.40625"
268 y2="14.046875"
269 gradientUnits="userSpaceOnUse" />
270 <linearGradient
271 inkscape:collect="always"
272 xlink:href="#linearGradient2371"
273 id="linearGradient2385"
274 x1="18.328718"
275 y1="15.323075"
276 x2="14.40625"
277 y2="14.046875"
278 gradientUnits="userSpaceOnUse" />
279 <linearGradient
280 inkscape:collect="always"
281 xlink:href="#linearGradient2399"
282 id="linearGradient2405"
283 x1="16.4375"
284 y1="49.110714"
285 x2="17.402376"
286 y2="43.420425"
287 gradientUnits="userSpaceOnUse" />
288 <radialGradient
289 inkscape:collect="always"
290 xlink:href="#linearGradient2407"
291 id="radialGradient2413"
292 cx="33.499996"
293 cy="20.538168"
294 fx="33.499996"
295 fy="20.538168"
296 r="2.2697367"
297 gradientUnits="userSpaceOnUse"
298 gradientTransform="matrix(0.435326,1.140794e-15,-1.140794e-15,0.435326,18.91658,12.49341)" />
299 </defs>
300 <sodipodi:namedview
301 stroke="#ef2929"
302 fill="#eeeeec"
303 id="base"
304 pagecolor="#ffffff"
305 bordercolor="#666666"
306 borderopacity="0.25490196"
307 inkscape:pageopacity="0.0"
308 inkscape:pageshadow="2"
309 inkscape:zoom="5.6568542"
310 inkscape:cx="38.894521"
311 inkscape:cy="19.55481"
312 inkscape:current-layer="layer1"
313 showgrid="false"
314 inkscape:grid-bbox="true"
315 inkscape:document-units="px"
316 inkscape:showpageshadow="false"
317 inkscape:window-width="807"
318 inkscape:window-height="818"
319 inkscape:window-x="627"
320 inkscape:window-y="30" />
321 <metadata
322 id="metadata4">
323 <rdf:RDF>
324 <cc:Work
325 rdf:about="">
326 <dc:format>image/svg+xml</dc:format>
327 <dc:type
328 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
329 <dc:creator>
330 <cc:Agent>
331 <dc:title>Jakub Steiner</dc:title>
332 </cc:Agent>
333 </dc:creator>
334 <dc:source>http://jimmac.musichall.cz</dc:source>
335 <cc:license
336 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
337 <dc:title>Microphone</dc:title>
338 <dc:subject>
339 <rdf:Bag>
340 <rdf:li>mic</rdf:li>
341 <rdf:li>mike</rdf:li>
342 <rdf:li>microphone</rdf:li>
343 <rdf:li>input</rdf:li>
344 <rdf:li>audio</rdf:li>
345 <rdf:li>record</rdf:li>
346 <rdf:li>voice</rdf:li>
347 </rdf:Bag>
348 </dc:subject>
349 </cc:Work>
350 <cc:License
351 rdf:about="http://creativecommons.org/licenses/publicdomain/">
352 <cc:permits
353 rdf:resource="http://creativecommons.org/ns#Reproduction" />
354 <cc:permits
355 rdf:resource="http://creativecommons.org/ns#Distribution" />
356 <cc:permits
357 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
358 </cc:License>
359 </rdf:RDF>
360 </metadata>
361 <g
362 id="layer1"
363 inkscape:label="Layer 1"
364 inkscape:groupmode="layer">
365 <path
366 sodipodi:type="arc"
367 style="opacity:0.49431818;color:#000000;fill:url(#radialGradient2248);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
368 id="path2240"
369 sodipodi:cx="25.1875"
370 sodipodi:cy="41"
371 sodipodi:rx="16.4375"
372 sodipodi:ry="7"
373 d="M 41.625 41 A 16.4375 7 0 1 1 8.75,41 A 16.4375 7 0 1 1 41.625 41 z"
374 transform="matrix(1.106464,0.000000,0.000000,1.044643,-2.681557,-2.517857)" />
375 <path
376 sodipodi:type="arc"
377 style="opacity:1;color:#000000;fill:url(#radialGradient2238);fill-opacity:1;fill-rule:evenodd;stroke:#424242;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
378 id="path2222"
379 sodipodi:cx="16.4375"
380 sodipodi:cy="46.375"
381 sodipodi:rx="11.1875"
382 sodipodi:ry="5.875"
383 d="M 27.625 46.375 A 11.1875 5.875 0 1 1 5.25,46.375 A 11.1875 5.875 0 1 1 27.625 46.375 z"
384 transform="translate(8.750000,-7.000000)" />
385 <path
386 transform="matrix(2.066667,0.000000,0.000000,1.266667,-43.98333,9.475000)"
387 d="M 35.375 22.125 A 1.875 1.875 0 1 1 31.625,22.125 A 1.875 1.875 0 1 1 35.375 22.125 z"
388 sodipodi:ry="1.875"
389 sodipodi:rx="1.875"
390 sodipodi:cy="22.125"
391 sodipodi:cx="33.5"
392 id="path2260"
393 style="opacity:1;color:#000000;fill:#424242;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
394 sodipodi:type="arc" />
395 <path
396 style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2258);stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
397 d="M 20.25,31.375 C 20.25,31.375 20.985875,34.77724 23.25,34.5 C 29.375,33.75 28.721362,34.010493 33.125,35.375 C 37.5625,36.75 35.21875,38.96875 39.75,39.375 C 44.28125,39.78125 43.875,35.75 47.75,35.5"
398 id="path2250"
399 sodipodi:nodetypes="cszzc" />
400 <rect
401 style="opacity:1;color:#000000;fill:url(#radialGradient2351);fill-opacity:1.0;fill-rule:evenodd;stroke:#7c7c7c;stroke-width:1.00015199;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
402 id="rect1343"
403 width="22.136791"
404 height="30.692028"
405 x="16.028919"
406 y="-4.0142608"
407 rx="6.6936979"
408 ry="6.6936979"
409 transform="matrix(0.970732,0.240164,-0.264014,0.964519,0.000000,0.000000)" />
410 <rect
411 transform="matrix(0.970732,0.240164,-0.264014,0.964519,0.000000,0.000000)"
412 ry="5.4198565"
413 rx="5.4198565"
414 y="-3.006144"
415 x="17.210075"
416 height="28.524395"
417 width="19.862064"
418 id="rect2353"
419 style="opacity:0.30681817;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00015211;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
420 <path
421 style="opacity:0.44318182;color:#000000;fill:url(#radialGradient2343);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1.00015175;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
422 d="M 20.09375,1.96875 C 17.872662,2.3212044 15.943233,4.0082576 15.3125,6.3125 L 10.46875,24.15625 C 13.325696,25.560355 17.10636,24.625 20.6875,24.625 C 21.177508,24.625 21.675568,24.623475 22.15625,24.59375 C 21.221109,24.366187 19.84375,24.03125 19.84375,24.03125 C 19.623887,23.971706 19.422566,23.896056 19.28125,23.78125 C 19.276518,23.777187 19.254589,23.75417 19.25,23.75 C 19.236674,23.737161 19.203065,23.703734 19.1875,23.6875 C 19.181844,23.681964 19.161865,23.661817 19.15625,23.65625 C 19.148027,23.640392 19.131304,23.606164 19.125,23.59375 C 19.115328,23.569412 19.100273,23.521815 19.09375,23.5 C 19.093946,23.496901 19.093689,23.471487 19.09375,23.46875 C 19.087919,23.457968 19.068124,23.417192 19.0625,23.40625 C 19.062571,23.40011 19.062547,23.378998 19.0625,23.375 C 19.06273,23.357135 19.062467,23.324025 19.0625,23.3125 C 19.062394,23.306455 19.062183,23.28488 19.0625,23.28125 C 19.062391,23.278084 19.062511,23.252775 19.0625,23.25 C 19.07062,23.213775 19.087162,23.156517 19.09375,23.125 C 19.099008,23.114735 19.119154,23.073755 19.125,23.0625 C 19.125001,23.059641 19.125263,23.034326 19.125,23.03125 C 19.132615,23.006679 19.147324,22.959774 19.15625,22.9375 C 19.164323,22.921039 19.182401,22.885033 19.1875,22.875 C 19.212265,22.829849 19.250755,22.757324 19.28125,22.71875 C 19.28767,22.712265 19.308241,22.691762 19.3125,22.6875 C 19.323749,22.681989 19.364715,22.66125 19.375,22.65625 C 19.403556,22.639098 19.464338,22.608552 19.5,22.59375 C 19.510877,22.593904 19.551519,22.593435 19.5625,22.59375 C 19.562319,22.592004 19.562446,22.569516 19.5625,22.5625 C 19.569512,22.562442 19.591979,22.562294 19.59375,22.5625 C 19.768583,22.52983 19.990234,22.555664 20.21875,22.59375 L 26.15625,23.96875 C 27.346545,23.677607 28.483477,23.278522 29.5625,22.8125 C 29.410097,22.726366 29.245035,22.671654 29.09375,22.625 C 29.056381,22.61418 29.005859,22.601562 28.96875,22.59375 C 28.96875,22.59375 20.75,20.59375 20.75,20.59375 C 20.530137,20.534206 20.305787,20.458556 20.15625,20.34375 C 20.151246,20.339687 20.129848,20.31667 20.125,20.3125 C 20.12048,20.308108 20.0981,20.285757 20.09375,20.28125 C 20.089575,20.276626 20.066495,20.254744 20.0625,20.25 C 20.057083,20.239373 20.036232,20.198414 20.03125,20.1875 C 20.025548,20.181998 20.005651,20.161786 20,20.15625 C 20.000313,20.153059 19.999908,20.12776 20,20.125 C 19.99427,20.114116 19.974252,20.073532 19.96875,20.0625 C 19.968921,20.059401 19.968692,20.033987 19.96875,20.03125 C 19.968719,20.020468 19.968531,19.979692 19.96875,19.96875 C 19.968021,19.94722 19.967081,19.89805 19.96875,19.875 C 19.968792,19.871465 19.968889,19.847713 19.96875,19.84375 C 19.968042,19.830743 19.967903,19.79231 19.96875,19.78125 C 19.968606,19.777816 19.968772,19.75283 19.96875,19.75 C 19.974494,19.738851 19.99467,19.697882 20,19.6875 C 20.008789,19.659668 20.021637,19.619155 20.03125,19.59375 C 20.036554,19.583113 20.056967,19.541976 20.0625,19.53125 C 20.079623,19.494921 20.106877,19.437683 20.125,19.40625 C 20.13942,19.385289 20.16988,19.33593 20.1875,19.3125 C 20.192078,19.307626 20.214081,19.285911 20.21875,19.28125 C 20.225167,19.274765 20.245742,19.254262 20.25,19.25 C 20.261293,19.244488 20.302246,19.22375 20.3125,19.21875 C 20.328392,19.210493 20.362434,19.19361 20.375,19.1875 C 20.383514,19.183691 20.420935,19.164467 20.4375,19.15625 C 20.440657,19.156494 20.466002,19.156179 20.46875,19.15625 C 20.47303,19.152009 20.493483,19.13144 20.5,19.125 C 20.50278,19.125058 20.527996,19.124835 20.53125,19.125 C 20.538403,19.11798 20.561169,19.095502 20.5625,19.09375 C 20.565755,19.09391 20.59097,19.093692 20.59375,19.09375 C 20.600109,19.093874 20.621997,19.093871 20.625,19.09375 C 20.769148,19.087955 20.947022,19.126587 21.125,19.15625 L 29.4375,21.09375 C 30.056885,21.266602 30.624819,21.702545 31.0625,22.125 C 31.576262,21.851747 32.053779,21.530124 32.53125,21.21875 C 32.385605,21.023752 31.200805,19.519263 30.125,19.1875 C 30.087631,19.17668 30.037109,19.164062 30,19.15625 C 30,19.15625 21.78125,17.15625 21.78125,17.15625 C 21.561387,17.096706 21.337037,17.021056 21.1875,16.90625 C 21.182496,16.902187 21.161098,16.87917 21.15625,16.875 C 21.15173,16.870608 21.12935,16.848257 21.125,16.84375 C 21.120825,16.839126 21.097745,16.817244 21.09375,16.8125 C 21.088333,16.801873 21.067482,16.760914 21.0625,16.75 C 21.056798,16.744498 21.036901,16.724286 21.03125,16.71875 C 21.031563,16.715559 21.031158,16.69026 21.03125,16.6875 C 21.02552,16.676616 21.005502,16.636032 21,16.625 C 21.000171,16.621901 20.999942,16.596487 21,16.59375 C 20.999969,16.582968 20.999781,16.542192 21,16.53125 C 20.999271,16.50972 20.998331,16.46055 21,16.4375 C 21.000042,16.433965 21.000139,16.410213 21,16.40625 C 20.999292,16.393243 20.999153,16.35481 21,16.34375 C 20.999856,16.340316 21.000022,16.31533 21,16.3125 C 21.005744,16.301351 21.02592,16.260382 21.03125,16.25 C 21.040039,16.222168 21.052887,16.181655 21.0625,16.15625 C 21.067804,16.145613 21.088217,16.104476 21.09375,16.09375 C 21.110873,16.057421 21.138127,16.000183 21.15625,15.96875 C 21.17067,15.947789 21.20113,15.89843 21.21875,15.875 C 21.223328,15.870126 21.245331,15.848411 21.25,15.84375 C 21.256417,15.837265 21.276992,15.816763 21.28125,15.8125 C 21.292543,15.806988 21.333496,15.78625 21.34375,15.78125 C 21.359642,15.772993 21.393684,15.75611 21.40625,15.75 C 21.41174,15.744272 21.431987,15.724434 21.4375,15.71875 C 21.448429,15.718922 21.488979,15.718414 21.5,15.71875 C 21.50428,15.714509 21.524733,15.69394 21.53125,15.6875 C 21.53403,15.687558 21.559246,15.687336 21.5625,15.6875 C 21.569653,15.680479 21.592419,15.658003 21.59375,15.65625 C 21.597005,15.65641 21.62222,15.656192 21.625,15.65625 C 21.631359,15.656374 21.653247,15.65637 21.65625,15.65625 C 21.800398,15.650455 21.978272,15.689087 22.15625,15.71875 L 30.46875,17.65625 C 31.8125,18.03125 32.9375,19.65625 32.9375,19.65625 L 32.53125,21.21875 C 32.715417,21.098649 32.91532,21.000499 33.09375,20.875 L 35.6875,11.34375 C 36.528911,8.2698323 34.727126,5.1972501 31.65625,4.4375 L 22.375,2.125 C 21.77522,1.9766113 21.181753,1.9275559 20.59375,1.96875 C 20.590201,1.9689986 20.568585,1.9688282 20.5625,1.96875 C 20.549604,1.9684951 20.512451,1.9693517 20.5,1.96875 C 20.493725,1.9685317 20.475181,1.968773 20.46875,1.96875 C 20.465703,1.968688 20.44411,1.9687787 20.4375,1.96875 C 20.40749,1.9695903 20.34244,1.967511 20.3125,1.96875 C 20.303236,1.9691283 20.266205,1.9689911 20.25,1.96875 C 20.246173,1.9686986 20.222855,1.9685175 20.21875,1.96875 C 20.208132,1.9685699 20.16686,1.9688883 20.15625,1.96875 C 20.145621,1.9685611 20.10437,1.9688977 20.09375,1.96875 z M 15.59375,7.1875 L 20.5,8.15625 C 20.69043,8.2148438 20.89146,8.3014441 21.03125,8.4375 C 21.03578,8.4421471 21.058106,8.4639893 21.0625,8.46875 C 21.066755,8.473626 21.08964,8.495007 21.09375,8.5 C 21.09909,8.5105888 21.120017,8.5516368 21.125,8.5625 C 21.130679,8.5679894 21.150614,8.5882289 21.15625,8.59375 C 21.166339,8.618365 21.179778,8.6651367 21.1875,8.6875 C 21.19627,8.7160534 21.212338,8.7770606 21.21875,8.8125 C 21.218672,8.8186214 21.218698,8.8397544 21.21875,8.84375 C 21.218499,8.8614809 21.218788,8.8944986 21.21875,8.90625 C 21.219104,8.9346107 21.220748,9.0014688 21.21875,9.03125 C 21.218893,9.0346823 21.218733,9.0596721 21.21875,9.0625 C 21.213026,9.0736106 21.192968,9.1141663 21.1875,9.125 C 21.180262,9.1525056 21.164842,9.1934845 21.15625,9.21875 C 21.156534,9.2218273 21.156216,9.2471194 21.15625,9.25 C 21.150586,9.2614818 21.13041,9.3024108 21.125,9.3125 C 21.117875,9.3269531 21.101397,9.3614686 21.09375,9.375 C 21.088157,9.3804857 21.068124,9.4008203 21.0625,9.40625 C 21.057238,9.4173435 21.036629,9.4578747 21.03125,9.46875 C 21.026708,9.4741922 21.004652,9.4947697 21,9.5 C 20.99524,9.5050208 20.973615,9.5264362 20.96875,9.53125 C 20.963783,9.5358592 20.942567,9.5580929 20.9375,9.5625 C 20.926879,9.5678443 20.885828,9.5888438 20.875,9.59375 C 20.869499,9.599424 20.849272,9.6193728 20.84375,9.625 C 20.822682,9.6337196 20.771738,9.6491388 20.75,9.65625 C 20.725775,9.664946 20.681453,9.6814662 20.65625,9.6875 C 20.491012,9.7225536 20.302734,9.7070312 20.125,9.65625 L 15.1875,8.59375 L 15.59375,7.1875 z M 23.40625,8.78125 C 23.409505,8.7814104 23.43472,8.7811922 23.4375,8.78125 C 23.443859,8.7813735 23.465747,8.7813707 23.46875,8.78125 C 23.612898,8.7754546 23.790772,8.8140869 23.96875,8.84375 L 32.28125,10.78125 C 33.625,11.15625 34.5,12.53125 34.5,12.53125 L 34.15625,14.0625 C 34.010605,13.867502 33.013305,12.644263 31.9375,12.3125 C 31.900131,12.30168 31.849609,12.289063 31.8125,12.28125 C 31.8125,12.28125 23.59375,10.28125 23.59375,10.28125 C 23.373887,10.221706 23.149537,10.146056 23,10.03125 C 22.994996,10.027187 22.973598,10.00417 22.96875,10 C 22.96423,9.9956081 22.94185,9.9732567 22.9375,9.96875 C 22.933325,9.964126 22.910245,9.9422438 22.90625,9.9375 C 22.900833,9.9268731 22.879982,9.885914 22.875,9.875 C 22.869298,9.8694981 22.849401,9.8492857 22.84375,9.84375 C 22.844063,9.8405594 22.843658,9.8152595 22.84375,9.8125 C 22.83802,9.8016155 22.818002,9.7610315 22.8125,9.75 C 22.812671,9.7469013 22.812442,9.7214874 22.8125,9.71875 C 22.812469,9.7079678 22.812281,9.6671921 22.8125,9.65625 C 22.811771,9.6347204 22.810831,9.5855497 22.8125,9.5625 C 22.812542,9.5589646 22.812639,9.5352132 22.8125,9.53125 C 22.811792,9.5182428 22.811653,9.4798098 22.8125,9.46875 C 22.812356,9.4653157 22.812522,9.4403304 22.8125,9.4375 C 22.818244,9.4263513 22.83842,9.3853818 22.84375,9.375 C 22.852539,9.347168 22.865387,9.3066552 22.875,9.28125 C 22.880304,9.2706125 22.900717,9.2294764 22.90625,9.21875 C 22.923373,9.1824211 22.950627,9.1251826 22.96875,9.09375 C 22.98317,9.0727891 23.01363,9.0234301 23.03125,9 C 23.035828,8.9951258 23.057831,8.9734113 23.0625,8.96875 C 23.068917,8.9622649 23.089492,8.9417626 23.09375,8.9375 C 23.105043,8.9319882 23.145996,8.9112495 23.15625,8.90625 C 23.172142,8.8979933 23.206184,8.8811106 23.21875,8.875 C 23.22424,8.8692724 23.244487,8.8494344 23.25,8.84375 C 23.260929,8.8439218 23.301479,8.8434137 23.3125,8.84375 C 23.31678,8.8395087 23.337233,8.8189403 23.34375,8.8125 C 23.34653,8.812558 23.371746,8.8123355 23.375,8.8125 C 23.382153,8.8054795 23.404919,8.7830026 23.40625,8.78125 z M 14.6875,10.5625 L 19.59375,11.53125 C 19.78418,11.589844 19.98521,11.676444 20.125,11.8125 C 20.12953,11.817147 20.151856,11.838989 20.15625,11.84375 C 20.160505,11.848626 20.18339,11.870007 20.1875,11.875 C 20.19284,11.885589 20.213767,11.926637 20.21875,11.9375 C 20.224429,11.942989 20.244364,11.963229 20.25,11.96875 C 20.24982,11.970333 20.249942,11.992927 20.25,12 C 20.255657,12.01087 20.275788,12.051496 20.28125,12.0625 C 20.288266,12.085343 20.305742,12.129373 20.3125,12.15625 C 20.312673,12.159712 20.312461,12.183497 20.3125,12.1875 C 20.312071,12.205343 20.312171,12.238477 20.3125,12.25 C 20.312424,12.273503 20.314863,12.318849 20.3125,12.34375 C 20.307243,12.386045 20.293457,12.453613 20.28125,12.5 C 20.281337,12.502663 20.280939,12.528474 20.28125,12.53125 C 20.268545,12.561289 20.232748,12.628396 20.21875,12.65625 C 20.211894,12.671171 20.194889,12.70476 20.1875,12.71875 C 20.182197,12.729764 20.161678,12.770461 20.15625,12.78125 C 20.150671,12.786763 20.130608,12.807042 20.125,12.8125 C 20.089571,12.857753 20.04207,12.905418 20,12.9375 C 19.994489,12.943151 19.974283,12.963147 19.96875,12.96875 C 19.952897,12.976963 19.919231,12.993522 19.90625,13 C 19.897482,13.004048 19.860273,13.023066 19.84375,13.03125 C 19.840605,13.030989 19.815244,13.031326 19.8125,13.03125 C 19.801591,13.036982 19.760968,13.056932 19.75,13.0625 C 19.584762,13.097554 19.396484,13.082031 19.21875,13.03125 L 14.28125,11.96875 L 14.6875,10.5625 z M 22.5,12.21875 C 22.503255,12.21891 22.52847,12.218692 22.53125,12.21875 C 22.537609,12.218874 22.559497,12.218871 22.5625,12.21875 C 22.706648,12.212955 22.884522,12.251587 23.0625,12.28125 L 31.375,14.21875 C 32.71875,14.59375 33.46875,15.875 33.46875,15.875 L 33.15625,17.3125 C 33.010605,17.117502 32.107055,16.081763 31.03125,15.75 C 30.993881,15.73918 30.943359,15.726562 30.90625,15.71875 C 30.90625,15.71875 22.6875,13.71875 22.6875,13.71875 C 22.467637,13.659206 22.243287,13.583556 22.09375,13.46875 C 22.088746,13.464687 22.067348,13.44167 22.0625,13.4375 C 22.05798,13.433108 22.0356,13.410757 22.03125,13.40625 C 22.027075,13.401626 22.003995,13.379744 22,13.375 C 21.994583,13.364373 21.973732,13.323414 21.96875,13.3125 C 21.963048,13.306998 21.943151,13.286786 21.9375,13.28125 C 21.937813,13.278059 21.937408,13.25276 21.9375,13.25 C 21.93177,13.239116 21.911752,13.198531 21.90625,13.1875 C 21.906421,13.184401 21.906192,13.158987 21.90625,13.15625 C 21.906219,13.145468 21.906031,13.104692 21.90625,13.09375 C 21.905521,13.07222 21.904581,13.02305 21.90625,13 C 21.906292,12.996465 21.906389,12.972713 21.90625,12.96875 C 21.905542,12.955743 21.905403,12.91731 21.90625,12.90625 C 21.906106,12.902816 21.906272,12.87783 21.90625,12.875 C 21.911994,12.863851 21.93217,12.822882 21.9375,12.8125 C 21.946289,12.784668 21.959137,12.744155 21.96875,12.71875 C 21.974054,12.708113 21.994467,12.666976 22,12.65625 C 22.017123,12.619921 22.044377,12.562683 22.0625,12.53125 C 22.07692,12.510289 22.10738,12.46093 22.125,12.4375 C 22.129578,12.432626 22.151581,12.410911 22.15625,12.40625 C 22.162667,12.399765 22.183242,12.379263 22.1875,12.375 C 22.198793,12.369488 22.239746,12.34875 22.25,12.34375 C 22.265892,12.335493 22.299934,12.318611 22.3125,12.3125 C 22.321014,12.308691 22.358435,12.289467 22.375,12.28125 C 22.378157,12.281494 22.403502,12.281179 22.40625,12.28125 C 22.41053,12.277009 22.430983,12.25644 22.4375,12.25 C 22.44028,12.250058 22.465496,12.249836 22.46875,12.25 C 22.475903,12.24298 22.498669,12.220503 22.5,12.21875 z M 13.75,13.9375 L 18.65625,14.9375 C 18.795105,14.980224 18.940881,15.047047 19.0625,15.125 C 19.073548,15.130277 19.114073,15.150845 19.125,15.15625 C 19.130531,15.161813 19.150753,15.181903 19.15625,15.1875 C 19.161572,15.192185 19.182327,15.213923 19.1875,15.21875 C 19.200672,15.231805 19.234191,15.265062 19.25,15.28125 C 19.255646,15.286763 19.275644,15.306956 19.28125,15.3125 C 19.28107,15.315942 19.281306,15.340904 19.28125,15.34375 C 19.286785,15.354802 19.306942,15.39585 19.3125,15.40625 C 19.318227,15.411706 19.338071,15.432011 19.34375,15.4375 C 19.354782,15.469447 19.369249,15.527045 19.375,15.5625 C 19.37503,15.573222 19.375203,15.61413 19.375,15.625 C 19.375658,15.648047 19.376586,15.69432 19.375,15.71875 C 19.375084,15.72196 19.375001,15.747197 19.375,15.75 C 19.367191,15.786566 19.350818,15.845106 19.34375,15.875 C 19.34398,15.878131 19.343724,15.903491 19.34375,15.90625 C 19.329563,15.937766 19.295094,16.002488 19.28125,16.03125 C 19.273177,16.047569 19.255262,16.082863 19.25,16.09375 C 19.244615,16.104306 19.2269,16.140139 19.21875,16.15625 C 19.213606,16.167306 19.192664,16.208497 19.1875,16.21875 C 19.162244,16.248235 19.120353,16.289362 19.09375,16.3125 C 19.088228,16.318127 19.068046,16.338172 19.0625,16.34375 C 19.056989,16.349401 19.036783,16.369397 19.03125,16.375 C 19.015397,16.383213 18.981731,16.399772 18.96875,16.40625 C 18.959982,16.410298 18.922773,16.429316 18.90625,16.4375 C 18.903105,16.437239 18.877744,16.437576 18.875,16.4375 C 18.695666,16.490752 18.479492,16.494141 18.28125,16.4375 L 13.34375,15.3125 L 13.75,13.9375 z M 12.875,17.28125 L 17.78125,18.34375 C 18.003418,18.41211 18.236362,18.539845 18.375,18.71875 C 18.380646,18.724263 18.400644,18.744456 18.40625,18.75 C 18.414424,18.76577 18.430828,18.799319 18.4375,18.8125 C 18.447383,18.837267 18.461734,18.883407 18.46875,18.90625 C 18.474518,18.917047 18.494446,18.957811 18.5,18.96875 C 18.499999,18.979491 18.500229,19.020363 18.5,19.03125 C 18.499941,19.037359 18.499936,19.058512 18.5,19.0625 C 18.499931,19.080118 18.500412,19.113018 18.5,19.125 C 18.500071,19.128218 18.500012,19.15344 18.5,19.15625 C 18.500161,19.159315 18.499976,19.184756 18.5,19.1875 C 18.496498,19.199308 18.473579,19.237179 18.46875,19.25 C 18.467422,19.25381 18.469764,19.277879 18.46875,19.28125 C 18.469037,19.284007 18.468696,19.309847 18.46875,19.3125 C 18.460305,19.34459 18.447526,19.40444 18.4375,19.4375 C 18.405986,19.516863 18.356787,19.599683 18.3125,19.65625 C 18.307958,19.661692 18.285902,19.68227 18.28125,19.6875 C 18.27649,19.692521 18.254865,19.713936 18.25,19.71875 C 18.245033,19.723359 18.223817,19.745593 18.21875,19.75 C 18.213228,19.755627 18.193046,19.775672 18.1875,19.78125 C 18.176906,19.786661 18.135789,19.807516 18.125,19.8125 C 18.119509,19.818196 18.099261,19.838099 18.09375,19.84375 C 18.06897,19.853473 18.021425,19.867986 18,19.875 C 17.989091,19.874873 17.948468,19.875291 17.9375,19.875 C 17.772262,19.910054 17.583984,19.894531 17.40625,19.84375 L 12.46875,18.6875 L 12.875,17.28125 z M 11.90625,20.65625 L 16.8125,21.71875 C 17.00293,21.777344 17.20396,21.863944 17.34375,22 C 17.34828,22.004647 17.370606,22.026489 17.375,22.03125 C 17.379255,22.036126 17.40214,22.057507 17.40625,22.0625 C 17.41159,22.073089 17.432517,22.114137 17.4375,22.125 C 17.443179,22.130489 17.463114,22.150729 17.46875,22.15625 C 17.478839,22.180865 17.492278,22.227637 17.5,22.25 C 17.50877,22.278553 17.524838,22.33956 17.53125,22.375 C 17.531771,22.380537 17.531146,22.398259 17.53125,22.40625 C 17.530999,22.423981 17.531288,22.456999 17.53125,22.46875 C 17.531604,22.497111 17.533248,22.563969 17.53125,22.59375 C 17.530255,22.597408 17.532541,22.621075 17.53125,22.625 C 17.526525,22.637499 17.503702,22.676109 17.5,22.6875 C 17.492762,22.715006 17.477342,22.755985 17.46875,22.78125 C 17.460852,22.802717 17.446798,22.850706 17.4375,22.875 C 17.430375,22.889453 17.413897,22.923969 17.40625,22.9375 C 17.400657,22.942986 17.380624,22.96332 17.375,22.96875 C 17.369738,22.979844 17.349129,23.020375 17.34375,23.03125 C 17.339208,23.036692 17.317152,23.05727 17.3125,23.0625 C 17.30774,23.067521 17.286115,23.088936 17.28125,23.09375 C 17.276283,23.098359 17.255067,23.120593 17.25,23.125 C 17.239379,23.130344 17.198328,23.151344 17.1875,23.15625 C 17.181999,23.161924 17.161772,23.181873 17.15625,23.1875 C 17.135182,23.196219 17.084238,23.211639 17.0625,23.21875 C 17.038275,23.227446 16.993953,23.243966 16.96875,23.25 C 16.803512,23.285054 16.615234,23.269531 16.4375,23.21875 L 11.5,22.0625 L 11.90625,20.65625 z "
423 id="rect2302"
424 sodipodi:nodetypes="cccsccsssssssssssssssssssssssscccsccssssssssssssssssssssssssssssssccccsccssssssssssssssssssssssssssssssccccccccssssssssscccsssssssssssssssssssssssssccccssccccsccssssssssssssssssssssssssssscccsssssssssssssssssssssssccccssccccsccssssssssssssssssssssssssssscccssssssssssssssssssssssssscccccssssssssssssssssssssssscccccssssssssssssssssssssssssccc" />
425 <path
426 style="opacity:1;color:#000000;fill:url(#linearGradient2365);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
427 d="M 22.28125,15.84375 L 30.59375,17.78125 C 31.9375,18.15625 33.0625,19.78125 33.0625,19.78125 L 32.65625,21.375 C 32.65625,21.375 31.3125,19.53125 30.125,19.28125 C 30.125,19.28125 21.90625,17.28125 21.90625,17.28125 C 21.421036,17.149843 20.971366,16.960466 21.15625,16.375 C 21.34375,15.78125 21.71875,15.75 22.28125,15.84375 z "
428 id="path2284"
429 sodipodi:nodetypes="cccccczc" />
430 <path
431 style="opacity:1;color:#000000;fill:#747474;fill-opacity:1;fill-rule:evenodd;stroke:#424242;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
432 d="M 31.5,19 L 31.375,34.375 L 31.375,34.40625 L 31.375,34.4375 C 31.462702,35.84074 30.279231,37.074596 29.125,36.84375 L 18.65625,34.6875 C 18.1875,34.5625 16.9375,34.0625 17.34375,32.625 L 15.40625,32.125 C 14.727493,34.561693 16.65625,36.28125 18.09375,36.59375 L 28.75,38.78125 C 31.324613,39.296173 33.497942,36.947282 33.375,34.375 C 33.37399,34.353864 33.376323,34.333663 33.375,34.3125 L 33.5,19 L 31.5,19 z "
433 id="path1345"
434 sodipodi:nodetypes="ccccccccccsccc" />
435 <path
436 sodipodi:nodetypes="cccccczc"
437 id="path2286"
438 d="M 21.25,19.28125 L 29.5625,21.21875 C 30.90625,21.59375 32.03125,23.21875 32.03125,23.21875 L 31.625,24.8125 C 31.625,24.8125 30.28125,22.96875 29.09375,22.71875 C 29.09375,22.71875 20.875,20.71875 20.875,20.71875 C 20.389786,20.587343 19.940116,20.397966 20.125,19.8125 C 20.3125,19.21875 20.6875,19.1875 21.25,19.28125 z "
439 style="opacity:1;color:#000000;fill:url(#linearGradient2367);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
440 <path
441 style="opacity:1;color:#000000;fill:url(#linearGradient2361);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
442 d="M 24.09375,8.9687499 L 32.40625,10.90625 C 33.75,11.28125 34.46875,12.40625 34.46875,12.40625 L 34.0625,14 C 34.0625,14 33.125,12.65625 31.9375,12.40625 C 31.9375,12.40625 23.71875,10.40625 23.71875,10.40625 C 23.233536,10.274843 22.783866,10.085466 22.96875,9.4999999 C 23.15625,8.9062499 23.53125,8.8749999 24.09375,8.9687499 z "
443 id="path2280"
444 sodipodi:nodetypes="cccccczc" />
445 <path
446 sodipodi:nodetypes="cccccczc"
447 id="path2282"
448 d="M 23.1875,12.40625 L 31.5,14.34375 C 32.84375,14.71875 33.5625,15.90625 33.5625,15.90625 L 33.125,17.40625 C 33.125,17.40625 32.21875,16.09375 31.03125,15.84375 C 31.03125,15.84375 22.8125,13.84375 22.8125,13.84375 C 22.327286,13.712343 21.877616,13.522966 22.0625,12.9375 C 22.25,12.34375 22.625,12.3125 23.1875,12.40625 z "
449 style="opacity:1;color:#000000;fill:url(#linearGradient2363);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
450 <path
451 sodipodi:type="arc"
452 style="opacity:1;color:#000000;fill:url(#radialGradient2413);fill-opacity:1.0;fill-rule:evenodd;stroke:#424242;stroke-width:0.78947348;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
453 id="path2220"
454 sodipodi:cx="33.5"
455 sodipodi:cy="22.125"
456 sodipodi:rx="1.875"
457 sodipodi:ry="1.875"
458 d="M 35.375 22.125 A 1.875 1.875 0 1 1 31.625,22.125 A 1.875 1.875 0 1 1 35.375 22.125 z"
459 transform="matrix(1.266667,0.000000,0.000000,1.266667,-10.30833,-8.150000)" />
460 <path
461 style="opacity:1;color:#000000;fill:url(#linearGradient2369);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
462 d="M 20.34375,22.71875 L 28.65625,24.65625 C 30,25.03125 31.125,26.65625 31.125,26.65625 L 30.71875,28.25 C 30.71875,28.25 29.375,26.40625 28.1875,26.15625 C 28.1875,26.15625 19.96875,24.15625 19.96875,24.15625 C 19.483536,24.024843 19.096366,23.835466 19.21875,23.25 C 19.342601,22.657518 19.78125,22.625 20.34375,22.71875 z "
463 id="path2288"
464 sodipodi:nodetypes="cccccczc" />
465 <path
466 style="opacity:1;color:#000000;fill:url(#linearGradient2377);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
467 d="M 16.5625,23.34375 L 11.625,22.1875 L 12.03125,20.78125 L 16.9375,21.84375 C 17.34375,21.96875 17.78125,22.21875 17.625,22.8125 C 17.470582,23.399287 17,23.46875 16.5625,23.34375 z "
468 id="path2292"
469 sodipodi:nodetypes="cccczc" />
470 <path
471 sodipodi:nodetypes="cccczc"
472 id="path2294"
473 d="M 17.53125,19.976562 L 12.59375,18.820312 L 13,17.414062 L 17.90625,18.476562 C 18.3125,18.601562 18.75,18.851562 18.59375,19.445312 C 18.439332,20.0321 17.96875,20.101562 17.53125,19.976562 z "
474 style="opacity:1;color:#000000;fill:url(#linearGradient2379);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
475 <path
476 style="opacity:1;color:#000000;fill:url(#linearGradient2385);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
477 d="M 18.40625,16.546875 L 13.46875,15.453125 L 13.875,14.046875 L 18.78125,15.046875 C 19.1875,15.171875 19.625,15.421875 19.46875,16.015625 C 19.314332,16.602412 18.84375,16.671875 18.40625,16.546875 z "
478 id="path2296"
479 sodipodi:nodetypes="cccczc" />
480 <path
481 sodipodi:nodetypes="cccczc"
482 id="path2298"
483 d="M 19.34375,13.148438 L 14.40625,12.085938 L 14.8125,10.679688 L 19.71875,11.648438 C 20.125,11.773438 20.5625,12.023438 20.40625,12.617188 C 20.251832,13.203974 19.78125,13.273438 19.34375,13.148438 z "
484 style="opacity:1;color:#000000;fill:url(#linearGradient2383);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
485 <path
486 style="opacity:1;color:#000000;fill:url(#linearGradient2381);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
487 d="M 20.25,9.78125 L 15.3125,8.71875 L 15.71875,7.3125 L 20.625,8.28125 C 21.03125,8.40625 21.46875,8.65625 21.3125,9.25 C 21.158082,9.836787 20.6875,9.90625 20.25,9.78125 z "
488 id="path2300"
489 sodipodi:nodetypes="cccczc" />
490 <path
491 transform="matrix(0.916296,0.000000,0.000000,0.807726,10.12589,1.916708)"
492 d="M 27.625 46.375 A 11.1875 5.875 0 1 1 5.25,46.375 A 11.1875 5.875 0 1 1 27.625 46.375 z"
493 sodipodi:ry="5.875"
494 sodipodi:rx="11.1875"
495 sodipodi:cy="46.375"
496 sodipodi:cx="16.4375"
497 id="path2389"
498 style="opacity:0.29545455;color:#000000;fill:none;fill-opacity:1.0;fill-rule:evenodd;stroke:url(#linearGradient2405);stroke-width:1.1623852;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
499 sodipodi:type="arc" />
500 </g>
501</svg>
diff --git a/utils/rbutilqt/icons/audio-volume-high.svg b/utils/rbutilqt/icons/audio-volume-high.svg
new file mode 100644
index 0000000000..0d8e47a50e
--- /dev/null
+++ b/utils/rbutilqt/icons/audio-volume-high.svg
@@ -0,0 +1,645 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="48"
13 height="48"
14 id="svg2566"
15 sodipodi:version="0.32"
16 inkscape:version="0.46"
17 version="1.0"
18 sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/status"
19 sodipodi:docname="audio-volume-high.svg"
20 inkscape:output_extension="org.inkscape.output.svg.inkscape">
21 <defs
22 id="defs2568">
23 <inkscape:perspective
24 sodipodi:type="inkscape:persp3d"
25 inkscape:vp_x="0 : 24 : 1"
26 inkscape:vp_y="0 : 1000 : 0"
27 inkscape:vp_z="48 : 24 : 1"
28 inkscape:persp3d-origin="24 : 16 : 1"
29 id="perspective96" />
30 <linearGradient
31 inkscape:collect="always"
32 id="linearGradient3510">
33 <stop
34 style="stop-color:#ffffff;stop-opacity:1;"
35 offset="0"
36 id="stop3512" />
37 <stop
38 style="stop-color:#ffffff;stop-opacity:0;"
39 offset="1"
40 id="stop3514" />
41 </linearGradient>
42 <linearGradient
43 inkscape:collect="always"
44 id="linearGradient3498">
45 <stop
46 style="stop-color:#3465a4;stop-opacity:1;"
47 offset="0"
48 id="stop3500" />
49 <stop
50 style="stop-color:#3465a4;stop-opacity:0;"
51 offset="1"
52 id="stop3502" />
53 </linearGradient>
54 <linearGradient
55 inkscape:collect="always"
56 id="linearGradient3281">
57 <stop
58 style="stop-color:#ffffff;stop-opacity:1;"
59 offset="0"
60 id="stop3283" />
61 <stop
62 style="stop-color:#ffffff;stop-opacity:0;"
63 offset="1"
64 id="stop3285" />
65 </linearGradient>
66 <linearGradient
67 inkscape:collect="always"
68 id="linearGradient4099">
69 <stop
70 style="stop-color:#6f726f;stop-opacity:1;"
71 offset="0"
72 id="stop4101" />
73 <stop
74 style="stop-color:#6f726f;stop-opacity:0;"
75 offset="1"
76 id="stop4103" />
77 </linearGradient>
78 <linearGradient
79 id="linearGradient4068">
80 <stop
81 style="stop-color:#eaeae9;stop-opacity:1;"
82 offset="0"
83 id="stop4070" />
84 <stop
85 style="stop-color:#a5a7a2;stop-opacity:1;"
86 offset="1"
87 id="stop4072" />
88 </linearGradient>
89 <linearGradient
90 id="linearGradient3670"
91 inkscape:collect="always">
92 <stop
93 id="stop3672"
94 offset="0"
95 style="stop-color:#d3d7cf" />
96 <stop
97 id="stop3674"
98 offset="1"
99 style="stop-color:#555753" />
100 </linearGradient>
101 <radialGradient
102 inkscape:collect="always"
103 xlink:href="#linearGradient3670"
104 id="radialGradient3634"
105 cx="6.8797626"
106 cy="7.1986876"
107 fx="6.8797626"
108 fy="7.1986876"
109 r="9.375"
110 gradientUnits="userSpaceOnUse"
111 gradientTransform="matrix(1.240749,9.690094e-9,-9.043116e-9,1.157631,-1.713645,-1.134736)" />
112 <linearGradient
113 inkscape:collect="always"
114 id="linearGradient3692">
115 <stop
116 style="stop-color:#2e3436;stop-opacity:1;"
117 offset="0"
118 id="stop3694" />
119 <stop
120 style="stop-color:#babdb6"
121 offset="1"
122 id="stop3696" />
123 </linearGradient>
124 <linearGradient
125 inkscape:collect="always"
126 xlink:href="#linearGradient3692"
127 id="linearGradient3698"
128 x1="-0.51990569"
129 y1="-0.51990569"
130 x2="-0.51990569"
131 y2="19.269905"
132 gradientUnits="userSpaceOnUse" />
133 <linearGradient
134 inkscape:collect="always"
135 id="linearGradient3628">
136 <stop
137 style="stop-color:#d3d7cf"
138 offset="0"
139 id="stop3630" />
140 <stop
141 style="stop-color:#555753"
142 offset="1"
143 id="stop3632" />
144 </linearGradient>
145 <radialGradient
146 inkscape:collect="always"
147 xlink:href="#linearGradient3628"
148 id="radialGradient3644"
149 cx="12.704856"
150 cy="13.847466"
151 fx="12.704856"
152 fy="13.847466"
153 r="9.375"
154 gradientUnits="userSpaceOnUse"
155 gradientTransform="matrix(6.370852e-2,-1.424475,1.547293,6.92112e-2,-9.530629,30.98681)" />
156 <linearGradient
157 id="linearGradient3730"
158 inkscape:collect="always">
159 <stop
160 id="stop3732"
161 offset="0"
162 style="stop-color:#eeeeec" />
163 <stop
164 id="stop3734"
165 offset="1"
166 style="stop-color:#888a85" />
167 </linearGradient>
168 <radialGradient
169 inkscape:collect="always"
170 xlink:href="#linearGradient3730"
171 id="radialGradient3728"
172 gradientUnits="userSpaceOnUse"
173 gradientTransform="matrix(-0.310032,2.110862,-2.082775,-0.305867,17.75288,16.41459)"
174 cx="-1.0016617"
175 cy="0.99004257"
176 fx="-1.0016617"
177 fy="0.99004257"
178 r="9.9205227" />
179 <linearGradient
180 id="linearGradient1557"
181 inkscape:collect="always">
182 <stop
183 id="stop1559"
184 offset="0"
185 style="stop-color:#2e3436;stop-opacity:1;" />
186 <stop
187 id="stop1561"
188 offset="1"
189 style="stop-color:#888a85" />
190 </linearGradient>
191 <linearGradient
192 inkscape:collect="always"
193 xlink:href="#linearGradient1557"
194 id="linearGradient1549"
195 x1="17.0625"
196 y1="34.950001"
197 x2="20.3125"
198 y2="5.375"
199 gradientUnits="userSpaceOnUse" />
200 <linearGradient
201 inkscape:collect="always"
202 id="linearGradient3676">
203 <stop
204 style="stop-color:#eeeeec"
205 offset="0"
206 id="stop4022" />
207 <stop
208 style="stop-color:#555753"
209 offset="1"
210 id="stop3680" />
211 </linearGradient>
212 <radialGradient
213 inkscape:collect="always"
214 xlink:href="#linearGradient3676"
215 id="radialGradient3702"
216 gradientUnits="userSpaceOnUse"
217 gradientTransform="matrix(-0.127582,1.416065,-1.630141,-0.146854,17.48751,15.56121)"
218 cx="-1.0016617"
219 cy="0.99004257"
220 fx="-1.0016617"
221 fy="0.99004257"
222 r="9.9205227" />
223 <linearGradient
224 id="linearGradient3788">
225 <stop
226 style="stop-color:#cccdcb;stop-opacity:1;"
227 offset="0"
228 id="stop3790" />
229 <stop
230 style="stop-color:#888a85;stop-opacity:1;"
231 offset="1"
232 id="stop3792" />
233 </linearGradient>
234 <linearGradient
235 id="linearGradient3674">
236 <stop
237 style="stop-color:#ffffff;stop-opacity:0;"
238 offset="0"
239 id="stop3676" />
240 <stop
241 style="stop-color:#ffffff;stop-opacity:1;"
242 offset="1"
243 id="stop3678" />
244 </linearGradient>
245 <linearGradient
246 id="linearGradient3657">
247 <stop
248 style="stop-color:#fafafa;stop-opacity:1;"
249 offset="0"
250 id="stop3659" />
251 <stop
252 style="stop-color:#bfbfbf;stop-opacity:1;"
253 offset="1"
254 id="stop3661" />
255 </linearGradient>
256 <linearGradient
257 inkscape:collect="always"
258 id="linearGradient3609">
259 <stop
260 style="stop-color:#000000;stop-opacity:1;"
261 offset="0"
262 id="stop3611" />
263 <stop
264 style="stop-color:#000000;stop-opacity:0;"
265 offset="1"
266 id="stop3613" />
267 </linearGradient>
268 <linearGradient
269 inkscape:collect="always"
270 xlink:href="#linearGradient4608"
271 id="linearGradient4585"
272 gradientUnits="userSpaceOnUse"
273 gradientTransform="matrix(1.769913,0,0,1.769913,-88.34438,10.67235)"
274 x1="56.302975"
275 y1="4.9369388"
276 x2="56.609135"
277 y2="8.6796741" />
278 <linearGradient
279 inkscape:collect="always"
280 xlink:href="#linearGradient4608"
281 id="linearGradient4641"
282 x1="58.015995"
283 y1="35.01503"
284 x2="57.954308"
285 y2="40.9986"
286 gradientUnits="userSpaceOnUse"
287 spreadMethod="reflect"
288 gradientTransform="matrix(0.997993,0,0,1,-97.71685,-9.352993)" />
289 <linearGradient
290 id="linearGradient4608">
291 <stop
292 style="stop-color:#eeeeec"
293 offset="0"
294 id="stop4610" />
295 <stop
296 style="stop-color:#8a8c87;stop-opacity:1;"
297 offset="1"
298 id="stop4612" />
299 </linearGradient>
300 <radialGradient
301 inkscape:collect="always"
302 xlink:href="#linearGradient3609"
303 id="radialGradient3615"
304 cx="6.4081554"
305 cy="17.403807"
306 fx="6.4081554"
307 fy="17.403807"
308 r="5.524272"
309 gradientTransform="matrix(1,0,0,0.416,2.706926e-15,10.16382)"
310 gradientUnits="userSpaceOnUse" />
311 <linearGradient
312 inkscape:collect="always"
313 xlink:href="#linearGradient3657"
314 id="linearGradient3668"
315 gradientUnits="userSpaceOnUse"
316 x1="10.4375"
317 y1="8.2899637"
318 x2="10.4375"
319 y2="18.984955"
320 gradientTransform="translate(-64.70027,0)" />
321 <radialGradient
322 inkscape:collect="always"
323 xlink:href="#linearGradient3674"
324 id="radialGradient3680"
325 cx="5.0822492"
326 cy="12.516305"
327 fx="5.0822492"
328 fy="12.516305"
329 r="2.9831069"
330 gradientTransform="matrix(1.525791,4.898427e-16,-1.480441e-8,1.768964,-8.162983e-2,6.066255)"
331 gradientUnits="userSpaceOnUse" />
332 <linearGradient
333 inkscape:collect="always"
334 xlink:href="#linearGradient3788"
335 id="linearGradient3794"
336 x1="8.0536165"
337 y1="11.030003"
338 x2="10.4375"
339 y2="11.030003"
340 gradientUnits="userSpaceOnUse"
341 gradientTransform="translate(-64.70027,0)" />
342 <linearGradient
343 inkscape:collect="always"
344 xlink:href="#linearGradient4068"
345 id="linearGradient4095"
346 gradientUnits="userSpaceOnUse"
347 x1="7.5763841"
348 y1="20.301662"
349 x2="7.3215322"
350 y2="27.345011" />
351 <linearGradient
352 inkscape:collect="always"
353 xlink:href="#linearGradient4068"
354 id="linearGradient4097"
355 gradientUnits="userSpaceOnUse"
356 x1="7.5763841"
357 y1="20.301662"
358 x2="7.3215322"
359 y2="27.345011" />
360 <linearGradient
361 inkscape:collect="always"
362 xlink:href="#linearGradient4099"
363 id="linearGradient4105"
364 x1="11.125889"
365 y1="25.559732"
366 x2="9.346509"
367 y2="25.736509"
368 gradientUnits="userSpaceOnUse"
369 gradientTransform="matrix(1.296181,0,0,1.296181,-4.978245,-7.324566)" />
370 <linearGradient
371 inkscape:collect="always"
372 xlink:href="#linearGradient3281"
373 id="linearGradient3287"
374 x1="4.6831215"
375 y1="24.665476"
376 x2="8.3712559"
377 y2="24.317278"
378 gradientUnits="userSpaceOnUse" />
379 <radialGradient
380 inkscape:collect="always"
381 xlink:href="#linearGradient3498"
382 id="radialGradient3504"
383 cx="36.82843"
384 cy="24.427677"
385 fx="36.82843"
386 fy="24.427671"
387 r="1.2404949"
388 gradientTransform="matrix(13.39869,-4.118282e-6,6.831725e-6,22.22678,-456.6246,-518.5208)"
389 gradientUnits="userSpaceOnUse" />
390 <radialGradient
391 inkscape:collect="always"
392 xlink:href="#linearGradient3498"
393 id="radialGradient3506"
394 gradientUnits="userSpaceOnUse"
395 gradientTransform="matrix(21.09444,2.34445e-15,1.470518e-12,22.22672,-740.0468,-518.5196)"
396 cx="36.82843"
397 cy="24.427683"
398 fx="36.82843"
399 fy="24.427683"
400 r="1.2404949" />
401 <radialGradient
402 inkscape:collect="always"
403 xlink:href="#linearGradient3498"
404 id="radialGradient3508"
405 gradientUnits="userSpaceOnUse"
406 gradientTransform="matrix(13.39869,-4.118282e-6,6.831725e-6,22.22678,-456.6246,-518.5208)"
407 cx="36.82843"
408 cy="24.427677"
409 fx="36.82843"
410 fy="24.427671"
411 r="1.2404949" />
412 <linearGradient
413 inkscape:collect="always"
414 xlink:href="#linearGradient3510"
415 id="linearGradient3516"
416 x1="9.485774"
417 y1="22.107626"
418 x2="7.378232"
419 y2="22.637957"
420 gradientUnits="userSpaceOnUse" />
421 </defs>
422 <sodipodi:namedview
423 id="base"
424 pagecolor="#ffffff"
425 bordercolor="#666666"
426 borderopacity="0.13333333"
427 inkscape:pageopacity="0.0"
428 inkscape:pageshadow="2"
429 inkscape:zoom="5.6568542"
430 inkscape:cx="59.859681"
431 inkscape:cy="26.342874"
432 inkscape:current-layer="layer1"
433 showgrid="false"
434 inkscape:grid-bbox="true"
435 inkscape:document-units="px"
436 inkscape:showpageshadow="false"
437 inkscape:window-width="826"
438 inkscape:window-height="688"
439 inkscape:window-x="608"
440 inkscape:window-y="160"
441 stroke="#3465a4"
442 fill="#ef2929" />
443 <metadata
444 id="metadata2571">
445 <rdf:RDF>
446 <cc:Work
447 rdf:about="">
448 <dc:format>image/svg+xml</dc:format>
449 <dc:type
450 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
451 <dc:title>Volume - High</dc:title>
452 <dc:creator>
453 <cc:Agent>
454 <dc:title>Jakub Steiner</dc:title>
455 </cc:Agent>
456 </dc:creator>
457 <dc:contributor>
458 <cc:Agent>
459 <dc:title>Lapo Calamandrei</dc:title>
460 </cc:Agent>
461 </dc:contributor>
462 <cc:license
463 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
464 <dc:publisher>
465 <cc:Agent>
466 <dc:title>http://www.tango-project.org</dc:title>
467 </cc:Agent>
468 </dc:publisher>
469 </cc:Work>
470 <cc:License
471 rdf:about="http://creativecommons.org/licenses/publicdomain/">
472 <cc:permits
473 rdf:resource="http://creativecommons.org/ns#Reproduction" />
474 <cc:permits
475 rdf:resource="http://creativecommons.org/ns#Distribution" />
476 <cc:permits
477 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
478 </cc:License>
479 </rdf:RDF>
480 </metadata>
481 <g
482 id="layer1"
483 inkscape:label="Layer 1"
484 inkscape:groupmode="layer">
485 <path
486 sodipodi:type="arc"
487 style="opacity:0.42857145;color:#000000;fill:url(#radialGradient3615);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
488 id="path3607"
489 sodipodi:cx="6.4081554"
490 sodipodi:cy="17.403807"
491 sodipodi:rx="5.524272"
492 sodipodi:ry="2.2980971"
493 d="M 11.932427 17.403807 A 5.524272 2.2980971 0 1 1 0.88388348,17.403807 A 5.524272 2.2980971 0 1 1 11.932427 17.403807 z"
494 transform="matrix(2.901907,0,0,3.804948,-4.8525,-32.31157)" />
495 <g
496 id="g4090"
497 transform="matrix(1.296182,0,0,1.296182,-4.176277,-7.324567)">
498 <path
499 transform="matrix(1.415965,0,0,1.258558,-2.667614,-6.200669)"
500 d="M 12.374369 24.665476 A 3.6239223 6.3639612 0 1 1 5.126524,24.665476 A 3.6239223 6.3639612 0 1 1 12.374369 24.665476 z"
501 sodipodi:ry="6.3639612"
502 sodipodi:rx="3.6239223"
503 sodipodi:cy="24.665476"
504 sodipodi:cx="8.7504463"
505 id="path4076"
506 style="opacity:1;color:#000000;fill:url(#linearGradient4095);fill-opacity:1;fill-rule:nonzero;stroke:#5d615f;stroke-width:0.57792485;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
507 sodipodi:type="arc" />
508 <path
509 sodipodi:type="arc"
510 style="opacity:1;color:#000000;fill:url(#linearGradient4097);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.86615634;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
511 id="path4060"
512 sodipodi:cx="8.7504463"
513 sodipodi:cy="24.665476"
514 sodipodi:rx="3.6239223"
515 sodipodi:ry="6.3639612"
516 d="M 12.374369 24.665476 A 3.6239223 6.3639612 0 1 1 5.126524,24.665476 A 3.6239223 6.3639612 0 1 1 12.374369 24.665476 z"
517 transform="matrix(1.154526,0,0,1.154526,-0.379902,-3.63468)" />
518 <path
519 transform="matrix(1.081355,0,0,1.081355,1.232653,-1.829889)"
520 d="M 12.374369 24.665476 A 3.6239223 6.3639612 0 1 1 5.126524,24.665476 A 3.6239223 6.3639612 0 1 1 12.374369 24.665476 z"
521 sodipodi:ry="6.3639612"
522 sodipodi:rx="3.6239223"
523 sodipodi:cy="24.665476"
524 sodipodi:cx="8.7504463"
525 id="path4058"
526 style="opacity:1;color:#000000;fill:#93958f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.86615634;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
527 sodipodi:type="arc" />
528 <path
529 sodipodi:type="arc"
530 style="opacity:0.39560439;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3287);stroke-width:0.68416733;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
531 id="path3279"
532 sodipodi:cx="8.7504463"
533 sodipodi:cy="24.665476"
534 sodipodi:rx="3.6239223"
535 sodipodi:ry="6.3639612"
536 d="M 12.374369 24.665476 A 3.6239223 6.3639612 0 1 1 5.126524,24.665476 A 3.6239223 6.3639612 0 1 1 12.374369 24.665476 z"
537 transform="matrix(1.1807,0,0,1.076971,-0.608944,-1.721744)" />
538 </g>
539 <path
540 style="color:#000000;fill:url(#linearGradient4585);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4105);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
541 d="M 9.4806798,18.24261 L 16.570367,12.118401 L 16.341232,37.201244 L 9.1369775,31.676187 C 6.6164956,29.613972 6.1582259,20.41939 9.4806798,18.24261 z "
542 id="path4542"
543 sodipodi:nodetypes="ccccc" />
544 <path
545 style="color:#000000;fill:url(#linearGradient3516);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
546 d="M 7.5383505,21.987453 L 11.593316,18.948432 L 11.341702,22.484506 L 7.3782322,23.145502 L 7.5383505,21.987453 z "
547 id="path4544"
548 sodipodi:nodetypes="ccccc" />
549 <path
550 style="opacity:0.7692308;color:#000000;fill:url(#radialGradient3680);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
551 d="M 8.203516,30.371178 L 12.644321,33.939519 L 12.087496,31.511626 L 7.6110912,29.008887 L 8.203516,30.371178 z "
552 id="path3672"
553 sodipodi:nodetypes="ccccc" />
554 <g
555 style="display:inline"
556 id="g4006"
557 transform="matrix(1.096894,0,0,1.509271,-4.216951,-12.11812)">
558 <path
559 sodipodi:nodetypes="ccsssscscsscscsscscsssssssc"
560 id="path3726"
561 d="M 23.75,14 C 21.81001,14.049168 20.013366,14.683436 18.5,15.6875 C 18.13319,15.264088 17.60375,15 17,15 C 16.9655,15 16.912662,15.000854 16.875,15 C 16.847007,14.9998 16.806453,14.997438 16.78125,15 C 15.773145,15.102481 15,15.965001 15,17 C 15,17.60375 15.264088,18.13319 15.6875,18.5 C 14.639107,20.080181 14,21.962011 14,24 C 14,26.033681 14.611921,27.921829 15.65625,29.5 C 15.243427,29.869532 15,30.401641 15,31 C 15,32.104 15.896,33.000001 17,33 C 17.60375,33 18.13319,32.735911 18.5,32.3125 C 20.080181,33.360893 21.962011,34 24,34 C 26.03799,34 27.919819,33.360893 29.5,32.3125 C 29.86681,32.735912 30.396251,33.000001 31,33 C 32.103999,33 33,32.104001 33,31 C 33,30.39625 32.735912,29.86681 32.3125,29.5 C 33.360893,27.919819 34,26.03799 34,24 C 34,21.962011 33.360893,20.080181 32.3125,18.5 C 32.735912,18.13319 33,17.60375 33,17 C 33,15.896 32.103999,15 31,15 C 30.9655,15 30.912662,15.000854 30.875,15 C 30.847007,14.9998 30.806453,14.997438 30.78125,15 C 30.277198,15.05124 29.819299,15.298435 29.5,15.65625 C 29.493313,15.651825 29.475448,15.660659 29.46875,15.65625 C 27.894622,14.620029 26.025064,14 24,14 C 23.913827,14 23.835651,13.997829 23.75,14 z "
562 style="opacity:1;color:#000000;fill:url(#radialGradient3702);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient1549);stroke-width:1.47668338;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
563 <path
564 sodipodi:nodetypes="ccsssscscsscscsscscsssssssc"
565 id="path3507"
566 d="M 23.75,14 C 21.81001,14.049168 20.013366,14.683436 18.5,15.6875 C 18.13319,15.264088 17.60375,15 17,15 C 16.9655,15 16.912662,15.000854 16.875,15 C 16.847007,14.9998 16.806453,14.997438 16.78125,15 C 15.773145,15.102481 15,15.965001 15,17 C 15,17.60375 15.264088,18.13319 15.6875,18.5 C 14.639107,20.080181 14,21.962011 14,24 C 14,26.033681 14.611921,27.921829 15.65625,29.5 C 15.243427,29.869532 15,30.401641 15,31 C 15,32.104 15.896,33.000001 17,33 C 17.60375,33 18.13319,32.735911 18.5,32.3125 C 20.080181,33.360893 21.962011,34 24,34 C 26.03799,34 27.919819,33.360893 29.5,32.3125 C 29.86681,32.735912 30.396251,33.000001 31,33 C 32.103999,33 33,32.104001 33,31 C 33,30.39625 32.735912,29.86681 32.3125,29.5 C 33.360893,27.919819 34,26.03799 34,24 C 34,21.962011 33.360893,20.080181 32.3125,18.5 C 32.735912,18.13319 33,17.60375 33,17 C 33,15.896 32.103999,15 31,15 C 30.9655,15 30.912662,15.000854 30.875,15 C 30.847007,14.9998 30.806453,14.997438 30.78125,15 C 30.277198,15.05124 29.819299,15.298435 29.5,15.65625 C 29.493313,15.651825 29.475448,15.660659 29.46875,15.65625 C 27.894622,14.620029 26.025064,14 24,14 C 23.913827,14 23.835651,13.997829 23.75,14 z "
567 style="opacity:1;color:#000000;fill:url(#radialGradient3728);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.09104455;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
568 <path
569 transform="matrix(0.846982,0,0,0.911415,16.71027,15.44956)"
570 d="M 18.75 9.375 A 9.375 9.375 0 1 1 0,9.375 A 9.375 9.375 0 1 1 18.75 9.375 z"
571 sodipodi:ry="9.375"
572 sodipodi:rx="9.375"
573 sodipodi:cy="9.375"
574 sodipodi:cx="9.375"
575 id="path3636"
576 style="opacity:1;color:#000000;fill:url(#radialGradient3644);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3698);stroke-width:0.8383193;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
577 sodipodi:type="arc" />
578 <path
579 transform="matrix(0.367272,0,0,0.32,18.56254,21.125)"
580 d="M 18.75 9.375 A 9.375 9.375 0 1 1 0,9.375 A 9.375 9.375 0 1 1 18.75 9.375 z"
581 sodipodi:ry="9.375"
582 sodipodi:rx="9.375"
583 sodipodi:cy="9.375"
584 sodipodi:cx="9.375"
585 id="path3519"
586 style="opacity:1;color:#000000;fill:url(#radialGradient3634);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6.57905483;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
587 sodipodi:type="arc" />
588 <path
589 d="M 17 16.5 A 0.5 0.5 0 1 1 16,16.5 A 0.5 0.5 0 1 1 17 16.5 z"
590 sodipodi:ry="0.5"
591 sodipodi:rx="0.5"
592 sodipodi:cy="16.5"
593 sodipodi:cx="16.5"
594 id="path3718"
595 style="opacity:1;color:#000000;fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
596 sodipodi:type="arc"
597 transform="matrix(1.3125,0,0,1.3125,-4.657679,-5.09375)" />
598 <path
599 transform="translate(15.22159,0.25)"
600 d="M 17 16.5 A 0.5 0.5 0 1 1 16,16.5 A 0.5 0.5 0 1 1 17 16.5 z"
601 sodipodi:ry="0.5"
602 sodipodi:rx="0.5"
603 sodipodi:cy="16.5"
604 sodipodi:cx="16.5"
605 id="path3720"
606 style="opacity:1;color:#000000;fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
607 sodipodi:type="arc" />
608 <path
609 transform="translate(15.22159,14.96875)"
610 d="M 17 16.5 A 0.5 0.5 0 1 1 16,16.5 A 0.5 0.5 0 1 1 17 16.5 z"
611 sodipodi:ry="0.5"
612 sodipodi:rx="0.5"
613 sodipodi:cy="16.5"
614 sodipodi:cx="16.5"
615 id="path3722"
616 style="opacity:1;color:#000000;fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
617 sodipodi:type="arc" />
618 <path
619 transform="matrix(1.375,0,0,1.375,-5.688929,8.8125)"
620 d="M 17 16.5 A 0.5 0.5 0 1 1 16,16.5 A 0.5 0.5 0 1 1 17 16.5 z"
621 sodipodi:ry="0.5"
622 sodipodi:rx="0.5"
623 sodipodi:cy="16.5"
624 sodipodi:cx="16.5"
625 id="path3724"
626 style="opacity:1;color:#000000;fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
627 sodipodi:type="arc" />
628 </g>
629 <path
630 sodipodi:nodetypes="csc"
631 id="path3488"
632 d="M 36.087935,32.865672 C 37.005198,30.700908 37.568925,27.707589 37.568925,24.427683 C 37.568925,21.147777 37.005198,18.154458 36.087935,15.989694"
633 style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient3504);stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
634 <path
635 style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient3508);stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
636 d="M 39.838951,35.702755 C 41.064624,32.810137 41.817892,28.81038 41.817892,24.427678 C 41.817892,20.044976 41.064624,16.045219 39.838951,13.152601"
637 id="path3494"
638 sodipodi:nodetypes="csc" />
639 <path
640 sodipodi:nodetypes="csc"
641 id="path3496"
642 d="M 43.487454,39.708054 C 45.148528,35.787876 46.169383,30.367266 46.169383,24.427674 C 46.169383,18.488083 45.148528,13.067472 43.487454,9.1472948"
643 style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient3506);stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
644 </g>
645</svg>
diff --git a/utils/rbutilqt/icons/dialog-error.svg b/utils/rbutilqt/icons/dialog-error.svg
new file mode 100644
index 0000000000..6dfc2dea82
--- /dev/null
+++ b/utils/rbutilqt/icons/dialog-error.svg
@@ -0,0 +1,330 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="48px"
13 height="48px"
14 id="svg1306"
15 sodipodi:version="0.32"
16 inkscape:version="0.46"
17 sodipodi:docbase="/home/garrett/Source/tango-icon-theme/scalable/status"
18 sodipodi:docname="dialog-error.svg"
19 inkscape:output_extension="org.inkscape.output.svg.inkscape">
20 <defs
21 id="defs1308">
22 <inkscape:perspective
23 sodipodi:type="inkscape:persp3d"
24 inkscape:vp_x="0 : 24 : 1"
25 inkscape:vp_y="0 : 1000 : 0"
26 inkscape:vp_z="48 : 24 : 1"
27 inkscape:persp3d-origin="24 : 16 : 1"
28 id="perspective40" />
29 <linearGradient
30 id="linearGradient3957">
31 <stop
32 style="stop-color:#fffeff;stop-opacity:0.33333334;"
33 offset="0"
34 id="stop3959" />
35 <stop
36 style="stop-color:#fffeff;stop-opacity:0.21568628;"
37 offset="1"
38 id="stop3961" />
39 </linearGradient>
40 <linearGradient
41 id="linearGradient2536">
42 <stop
43 style="stop-color:#a40000;stop-opacity:1;"
44 offset="0"
45 id="stop2538" />
46 <stop
47 style="stop-color:#ff1717;stop-opacity:1;"
48 offset="1"
49 id="stop2540" />
50 </linearGradient>
51 <linearGradient
52 id="linearGradient2479">
53 <stop
54 style="stop-color:#ffe69b;stop-opacity:1;"
55 offset="0"
56 id="stop2481" />
57 <stop
58 style="stop-color:#ffffff;stop-opacity:1;"
59 offset="1"
60 id="stop2483" />
61 </linearGradient>
62 <linearGradient
63 id="linearGradient4126"
64 inkscape:collect="always">
65 <stop
66 id="stop4128"
67 offset="0"
68 style="stop-color:#000000;stop-opacity:1;" />
69 <stop
70 id="stop4130"
71 offset="1"
72 style="stop-color:#000000;stop-opacity:0;" />
73 </linearGradient>
74 <radialGradient
75 inkscape:collect="always"
76 xlink:href="#linearGradient4126"
77 id="radialGradient2169"
78 gradientUnits="userSpaceOnUse"
79 gradientTransform="matrix(1.000000,0.000000,0.000000,0.500000,1.899196e-14,20.00000)"
80 cx="23.857143"
81 cy="40.000000"
82 fx="23.857143"
83 fy="40.000000"
84 r="17.142857" />
85 <linearGradient
86 inkscape:collect="always"
87 xlink:href="#linearGradient2479"
88 id="linearGradient2485"
89 x1="43.93581"
90 y1="53.835983"
91 x2="20.064686"
92 y2="-8.5626707"
93 gradientUnits="userSpaceOnUse" />
94 <linearGradient
95 inkscape:collect="always"
96 xlink:href="#linearGradient2536"
97 id="linearGradient2542"
98 x1="36.917976"
99 y1="66.288063"
100 x2="19.071495"
101 y2="5.5410109"
102 gradientUnits="userSpaceOnUse" />
103 <linearGradient
104 inkscape:collect="always"
105 xlink:href="#linearGradient2536"
106 id="linearGradient3046"
107 gradientUnits="userSpaceOnUse"
108 x1="36.917976"
109 y1="66.288063"
110 x2="19.071495"
111 y2="5.5410109" />
112 <linearGradient
113 inkscape:collect="always"
114 xlink:href="#linearGradient2479"
115 id="linearGradient3048"
116 gradientUnits="userSpaceOnUse"
117 x1="43.93581"
118 y1="53.835983"
119 x2="20.064686"
120 y2="-8.5626707" />
121 <linearGradient
122 inkscape:collect="always"
123 xlink:href="#linearGradient2536"
124 id="linearGradient3064"
125 gradientUnits="userSpaceOnUse"
126 x1="36.917976"
127 y1="66.288063"
128 x2="19.071495"
129 y2="5.5410109" />
130 <linearGradient
131 inkscape:collect="always"
132 xlink:href="#linearGradient2479"
133 id="linearGradient3066"
134 gradientUnits="userSpaceOnUse"
135 x1="43.93581"
136 y1="53.835983"
137 x2="20.064686"
138 y2="-8.5626707" />
139 <linearGradient
140 inkscape:collect="always"
141 xlink:href="#linearGradient3957"
142 id="linearGradient3963"
143 x1="21.993773"
144 y1="33.955299"
145 x2="20.917078"
146 y2="15.814602"
147 gradientUnits="userSpaceOnUse" />
148 <radialGradient
149 inkscape:collect="always"
150 xlink:href="#linearGradient4126"
151 id="radialGradient3976"
152 gradientUnits="userSpaceOnUse"
153 gradientTransform="matrix(1,0,0,0.5,1.893048e-14,20)"
154 cx="23.857143"
155 cy="40.000000"
156 fx="23.857143"
157 fy="40.000000"
158 r="17.142857" />
159 <linearGradient
160 inkscape:collect="always"
161 xlink:href="#linearGradient2536"
162 id="linearGradient3978"
163 gradientUnits="userSpaceOnUse"
164 x1="36.917976"
165 y1="66.288063"
166 x2="19.071495"
167 y2="5.5410109" />
168 <linearGradient
169 inkscape:collect="always"
170 xlink:href="#linearGradient2479"
171 id="linearGradient3980"
172 gradientUnits="userSpaceOnUse"
173 x1="43.93581"
174 y1="53.835983"
175 x2="20.064686"
176 y2="-8.5626707" />
177 <linearGradient
178 inkscape:collect="always"
179 xlink:href="#linearGradient3957"
180 id="linearGradient3982"
181 gradientUnits="userSpaceOnUse"
182 x1="21.993773"
183 y1="33.955299"
184 x2="20.917078"
185 y2="15.814602" />
186 </defs>
187 <sodipodi:namedview
188 id="base"
189 pagecolor="#ffffff"
190 bordercolor="#666666"
191 borderopacity="0.21568627"
192 inkscape:pageopacity="0.0"
193 inkscape:pageshadow="2"
194 inkscape:zoom="1"
195 inkscape:cx="-134.9567"
196 inkscape:cy="20.463852"
197 inkscape:current-layer="layer2"
198 showgrid="true"
199 inkscape:grid-bbox="true"
200 inkscape:document-units="px"
201 inkscape:window-width="925"
202 inkscape:window-height="818"
203 inkscape:window-x="234"
204 inkscape:window-y="30"
205 inkscape:showpageshadow="false"
206 fill="#ef2929">
207 <inkscape:grid
208 id="GridFromPre046Settings"
209 type="xygrid"
210 originx="0px"
211 originy="0px"
212 spacingx="1px"
213 spacingy="1px"
214 color="#0000ff"
215 empcolor="#0000ff"
216 opacity="0.2"
217 empopacity="0.4"
218 empspacing="4" />
219 </sodipodi:namedview>
220 <metadata
221 id="metadata1311">
222 <rdf:RDF>
223 <cc:Work
224 rdf:about="">
225 <dc:format>image/svg+xml</dc:format>
226 <dc:type
227 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
228 <dc:creator>
229 <cc:Agent>
230 <dc:title>Rodney Dawes</dc:title>
231 </cc:Agent>
232 </dc:creator>
233 <dc:contributor>
234 <cc:Agent>
235 <dc:title>Jakub Steiner, Garrett LeSage</dc:title>
236 </cc:Agent>
237 </dc:contributor>
238 <cc:license
239 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
240 <dc:title>Dialog Error</dc:title>
241 </cc:Work>
242 <cc:License
243 rdf:about="http://creativecommons.org/licenses/publicdomain/">
244 <cc:permits
245 rdf:resource="http://creativecommons.org/ns#Reproduction" />
246 <cc:permits
247 rdf:resource="http://creativecommons.org/ns#Distribution" />
248 <cc:permits
249 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
250 </cc:License>
251 </rdf:RDF>
252 </metadata>
253 <g
254 inkscape:groupmode="layer"
255 id="layer2"
256 inkscape:label="Shadow">
257 <path
258 inkscape:r_cy="true"
259 inkscape:r_cx="true"
260 transform="matrix(1.070555,0,0,0.525,-0.892755,22.5)"
261 d="M 41 40 A 17.142857 8.5714283 0 1 1 6.7142868,40 A 17.142857 8.5714283 0 1 1 41 40 z"
262 sodipodi:ry="8.5714283"
263 sodipodi:rx="17.142857"
264 sodipodi:cy="40"
265 sodipodi:cx="23.857143"
266 id="path6548"
267 style="opacity:0.6;color:#000000;fill:url(#radialGradient3976);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
268 sodipodi:type="arc" />
269 </g>
270 <g
271 id="layer1"
272 inkscape:label="Layer 1"
273 inkscape:groupmode="layer">
274 <g
275 id="g4006">
276 <path
277 transform="matrix(0.920488,0,0,0.920488,2.368532,0.97408)"
278 d="M 46.857143 23.928572 A 23.357143 23.357143 0 1 1 0.1428566,23.928572 A 23.357143 23.357143 0 1 1 46.857143 23.928572 z"
279 sodipodi:ry="23.357143"
280 sodipodi:rx="23.357143"
281 sodipodi:cy="23.928572"
282 sodipodi:cx="23.5"
283 id="path1314"
284 style="fill:url(#linearGradient3978);fill-opacity:1;fill-rule:nonzero;stroke:#b20000;stroke-width:1.08638;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
285 sodipodi:type="arc"
286 inkscape:r_cx="true"
287 inkscape:r_cy="true" />
288 <path
289 transform="matrix(0.856093,0,0,0.856093,1.818275,0.197769)"
290 d="M 49.901535 26.635273 A 23.991123 23.991123 0 1 1 1.9192886,26.635273 A 23.991123 23.991123 0 1 1 49.901535 26.635273 z"
291 sodipodi:ry="23.991123"
292 sodipodi:rx="23.991123"
293 sodipodi:cy="26.635273"
294 sodipodi:cx="25.910412"
295 id="path3560"
296 style="opacity:0.34659089;fill:#cc0000;fill-opacity:0;stroke:url(#linearGradient3980);stroke-width:1.16809607;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
297 sodipodi:type="arc"
298 inkscape:r_cx="true"
299 inkscape:r_cy="true" />
300 </g>
301 </g>
302 <g
303 inkscape:groupmode="layer"
304 id="layer3"
305 inkscape:label="Error Box">
306 <rect
307 inkscape:r_cy="true"
308 inkscape:r_cx="true"
309 style="fill:#efefef;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.73876643;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.8627451"
310 id="rect2070"
311 width="27.836435"
312 height="7.1735945"
313 x="10.078821"
314 y="19.164932"
315 transform="matrix(1.005876,0,0,1.115201,-0.138045,-2.372708)" />
316 </g>
317 <g
318 inkscape:groupmode="layer"
319 id="layer4"
320 inkscape:label="Glossy Shine">
321 <path
322 transform="matrix(1.002994,0,0,1.002994,-7.185874e-2,1.968356e-2)"
323 sodipodi:nodetypes="czssc"
324 id="path3955"
325 d="M 43.370686,21.715486 C 43.370686,32.546102 33.016357,15.449178 24.695948,22.101874 C 16.569626,28.599385 4.0989837,34.292422 4.0989837,23.461806 C 4.0989837,12.377753 12.79438,2.0948032 23.625,2.0948032 C 34.455619,2.0948032 43.370686,10.884868 43.370686,21.715486 z "
326 style="fill:url(#linearGradient3982);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
327 inkscape:r_cx="true"
328 inkscape:r_cy="true" />
329 </g>
330</svg>
diff --git a/utils/rbutilqt/icons/dialog-information.svg b/utils/rbutilqt/icons/dialog-information.svg
new file mode 100644
index 0000000000..922b316fac
--- /dev/null
+++ b/utils/rbutilqt/icons/dialog-information.svg
@@ -0,0 +1,1159 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 sodipodi:docname="dialog-information.svg"
13 sodipodi:docbase="/home/garrett/Source/tango-icon-theme/scalable/status"
14 inkscape:version="0.46"
15 sodipodi:version="0.32"
16 id="svg19655"
17 height="48px"
18 width="48px"
19 inkscape:export-filename="/home/jimmac/Desktop/poing.png"
20 inkscape:export-xdpi="392.72742"
21 inkscape:export-ydpi="392.72742"
22 inkscape:output_extension="org.inkscape.output.svg.inkscape">
23 <defs
24 id="defs3">
25 <inkscape:perspective
26 sodipodi:type="inkscape:persp3d"
27 inkscape:vp_x="0 : 24 : 1"
28 inkscape:vp_y="0 : 1000 : 0"
29 inkscape:vp_z="48 : 24 : 1"
30 inkscape:persp3d-origin="24 : 16 : 1"
31 id="perspective155" />
32 <linearGradient
33 inkscape:collect="always"
34 id="linearGradient3300">
35 <stop
36 style="stop-color:#4c4c28;stop-opacity:1;"
37 offset="0"
38 id="stop3302" />
39 <stop
40 style="stop-color:#4c4c28;stop-opacity:0;"
41 offset="1"
42 id="stop3304" />
43 </linearGradient>
44 <linearGradient
45 id="linearGradient3311">
46 <stop
47 id="stop3313"
48 offset="0"
49 style="stop-color:#d6d7a5;stop-opacity:1;" />
50 <stop
51 id="stop3315"
52 offset="1.0000000"
53 style="stop-color:#8e8f6d;stop-opacity:1.0000000;" />
54 </linearGradient>
55 <linearGradient
56 id="linearGradient3265">
57 <stop
58 id="stop3267"
59 offset="0"
60 style="stop-color:#929470;stop-opacity:1;" />
61 <stop
62 style="stop-color:#60614a;stop-opacity:1.0000000;"
63 offset="0.26470590"
64 id="stop3269" />
65 <stop
66 id="stop3271"
67 offset="0.63235295"
68 style="stop-color:#f3f5ba;stop-opacity:1.0000000;" />
69 <stop
70 id="stop3273"
71 offset="1.0000000"
72 style="stop-color:#929470;stop-opacity:1.0000000;" />
73 </linearGradient>
74 <linearGradient
75 id="linearGradient3175"
76 inkscape:collect="always">
77 <stop
78 id="stop3177"
79 offset="0"
80 style="stop-color:#f1f3ff;stop-opacity:1;" />
81 <stop
82 id="stop3179"
83 offset="1"
84 style="stop-color:#f1f3ff;stop-opacity:0;" />
85 </linearGradient>
86 <linearGradient
87 id="linearGradient2399">
88 <stop
89 style="stop-color:#929470;stop-opacity:1;"
90 offset="0"
91 id="stop2401" />
92 <stop
93 id="stop2407"
94 offset="0.26470590"
95 style="stop-color:#fcffc1;stop-opacity:1.0000000;" />
96 <stop
97 style="stop-color:#f3f5ba;stop-opacity:1.0000000;"
98 offset="0.63235295"
99 id="stop2409" />
100 <stop
101 style="stop-color:#929470;stop-opacity:1.0000000;"
102 offset="1.0000000"
103 id="stop2403" />
104 </linearGradient>
105 <linearGradient
106 inkscape:collect="always"
107 id="linearGradient6339">
108 <stop
109 style="stop-color:#ffffff;stop-opacity:1;"
110 offset="0"
111 id="stop6341" />
112 <stop
113 style="stop-color:#ffffff;stop-opacity:0;"
114 offset="1"
115 id="stop6343" />
116 </linearGradient>
117 <linearGradient
118 id="linearGradient20428">
119 <stop
120 id="stop20430"
121 offset="0.0000000"
122 style="stop-color:#a3a3a3;stop-opacity:1.0000000;" />
123 <stop
124 id="stop20432"
125 offset="1"
126 style="stop-color:#b5b5b5;stop-opacity:0;" />
127 </linearGradient>
128 <linearGradient
129 id="linearGradient20393">
130 <stop
131 id="stop20395"
132 offset="0"
133 style="stop-color:#ffffff;stop-opacity:1;" />
134 <stop
135 style="stop-color:#ffffff;stop-opacity:0.44117647;"
136 offset="0.41176471"
137 id="stop2427" />
138 <stop
139 id="stop20397"
140 offset="1.0000000"
141 style="stop-color:#000000;stop-opacity:0.48039216;" />
142 </linearGradient>
143 <linearGradient
144 id="linearGradient20210">
145 <stop
146 id="stop20212"
147 offset="0.0000000"
148 style="stop-color:#000000;stop-opacity:0.51546389;" />
149 <stop
150 style="stop-color:#000000;stop-opacity:0.14432989;"
151 offset="0.55172414"
152 id="stop20218" />
153 <stop
154 id="stop20214"
155 offset="1"
156 style="stop-color:#000000;stop-opacity:0;" />
157 </linearGradient>
158 <radialGradient
159 gradientUnits="userSpaceOnUse"
160 fy="11.4873"
161 fx="17.8335"
162 r="22.7093"
163 cy="11.4873"
164 cx="17.8335"
165 id="aigrd7">
166 <stop
167 id="stop19512"
168 style="stop-color:#ffffff;stop-opacity:0.17525773;"
169 offset="0.0000000" />
170 <stop
171 id="stop19514"
172 style="stop-color:#709ac8;stop-opacity:1.0000000;"
173 offset="0.88200003" />
174 <stop
175 id="stop19516"
176 style="stop-color:#6f96dd;stop-opacity:1.0000000;"
177 offset="1.0000000" />
178 </radialGradient>
179 <linearGradient
180 y2="43.165"
181 x2="26.4785"
182 y1="43.165"
183 x1="23.124"
184 gradientUnits="userSpaceOnUse"
185 id="aigrd1">
186 <stop
187 id="stop19415"
188 style="stop-color:#686868"
189 offset="5.618000e-003" />
190 <stop
191 id="stop19417"
192 style="stop-color:#777777"
193 offset="3.012137e-002" />
194 <stop
195 id="stop19419"
196 style="stop-color:#929292"
197 offset="8.366583e-002" />
198 <stop
199 id="stop19421"
200 style="stop-color:#A7A7A7"
201 offset="0.1422" />
202 <stop
203 id="stop19423"
204 style="stop-color:#B6B6B6"
205 offset="0.2074" />
206 <stop
207 id="stop19425"
208 style="stop-color:#BEBEBE"
209 offset="0.2846" />
210 <stop
211 id="stop19427"
212 style="stop-color:#C1C1C1"
213 offset="0.4045" />
214 <stop
215 id="stop19429"
216 style="stop-color:#BCBCBC"
217 offset="0.4962" />
218 <stop
219 id="stop19431"
220 style="stop-color:#ADADAD"
221 offset="0.6057" />
222 <stop
223 id="stop19433"
224 style="stop-color:#959595"
225 offset="0.7245" />
226 <stop
227 id="stop19435"
228 style="stop-color:#747474"
229 offset="0.8497" />
230 <stop
231 id="stop19437"
232 style="stop-color:#494949"
233 offset="0.9789" />
234 <stop
235 id="stop19439"
236 style="stop-color:#414141"
237 offset="1" />
238 </linearGradient>
239 <linearGradient
240 id="linearGradient19894"
241 gradientUnits="userSpaceOnUse"
242 x1="18.995100"
243 y1="37.226601"
244 x2="30.169901"
245 y2="37.226601">
246 <stop
247 offset="5.618000e-003"
248 style="stop-color:#A3A349"
249 id="stop19896" />
250 <stop
251 offset="2.078677e-002"
252 style="stop-color:#ACAC54"
253 id="stop19898" />
254 <stop
255 offset="6.600059e-002"
256 style="stop-color:#C1C172"
257 id="stop19900" />
258 <stop
259 offset="0.1148"
260 style="stop-color:#D4D68E"
261 id="stop19902" />
262 <stop
263 offset="0.1677"
264 style="stop-color:#E2E4A6"
265 id="stop19904" />
266 <stop
267 offset="0.2265"
268 style="stop-color:#EDF0B8"
269 id="stop19906" />
270 <stop
271 offset="0.2963"
272 style="stop-color:#F3F6C3"
273 id="stop19908" />
274 <stop
275 offset="0.4045"
276 style="stop-color:#F5F8C7"
277 id="stop19910" />
278 <stop
279 offset="0.5239"
280 style="stop-color:#EEF0BE"
281 id="stop19912" />
282 <stop
283 offset="0.6666"
284 style="stop-color:#DBDDA9"
285 id="stop19914" />
286 <stop
287 offset="0.8211"
288 style="stop-color:#BEBD88"
289 id="stop19916" />
290 <stop
291 offset="0.9832"
292 style="stop-color:#989564"
293 id="stop19918" />
294 <stop
295 offset="1"
296 style="stop-color:#949160"
297 id="stop19920" />
298 </linearGradient>
299 <linearGradient
300 gradientTransform="matrix(1.639127,0,0,1.639127,-15.97035,-29.79355)"
301 y2="43.165"
302 x2="26.4785"
303 y1="43.165"
304 x1="23.124"
305 gradientUnits="userSpaceOnUse"
306 id="linearGradient20109"
307 xlink:href="#aigrd1"
308 inkscape:collect="always" />
309 <radialGradient
310 gradientUnits="userSpaceOnUse"
311 r="7.8289826"
312 fy="74.209934"
313 fx="14.772334"
314 cy="74.209934"
315 cx="14.772334"
316 gradientTransform="scale(1.764278,0.566804)"
317 id="radialGradient20216"
318 xlink:href="#linearGradient20210"
319 inkscape:collect="always" />
320 <linearGradient
321 y2="36.726292"
322 x2="32.096882"
323 y1="10.061084"
324 x1="16.998856"
325 gradientTransform="matrix(1.140494,0.000000,0.000000,0.926002,0.272330,-3.247170)"
326 gradientUnits="userSpaceOnUse"
327 id="linearGradient7708"
328 xlink:href="#linearGradient6339"
329 inkscape:collect="always" />
330 <radialGradient
331 r="33.934090"
332 fy="29.869318"
333 fx="68.137589"
334 cy="29.869318"
335 cx="68.137589"
336 gradientTransform="matrix(0.551290,1.265592e-16,-1.355720e-16,0.766034,-10.48701,3.514312)"
337 gradientUnits="userSpaceOnUse"
338 id="radialGradient7720"
339 xlink:href="#aigrd7"
340 inkscape:collect="always" />
341 <linearGradient
342 gradientUnits="userSpaceOnUse"
343 y2="3.8557322"
344 x2="-5.2517161"
345 y1="16.651863"
346 x1="37.940434"
347 gradientTransform="matrix(0.894129,0.000000,0.000000,0.985230,1.515981,2.449800e-2)"
348 id="linearGradient3181"
349 xlink:href="#linearGradient3175"
350 inkscape:collect="always" />
351 <linearGradient
352 inkscape:collect="always"
353 xlink:href="#linearGradient20393"
354 id="linearGradient1700"
355 gradientUnits="userSpaceOnUse"
356 gradientTransform="matrix(-0.6293,0,0,1.589068,50.68808,3.804378)"
357 x1="30.620375"
358 y1="10.313651"
359 x2="32.166080"
360 y2="18.162935" />
361 <linearGradient
362 inkscape:collect="always"
363 xlink:href="#linearGradient20393"
364 id="linearGradient1702"
365 gradientUnits="userSpaceOnUse"
366 gradientTransform="matrix(0.6293,0,0,1.589068,1.411612,3.929378)"
367 x1="30.620375"
368 y1="10.313651"
369 x2="32.166080"
370 y2="18.162935" />
371 <linearGradient
372 inkscape:collect="always"
373 xlink:href="#linearGradient20428"
374 id="linearGradient1704"
375 gradientUnits="userSpaceOnUse"
376 gradientTransform="matrix(1.985083,0,0,0.503757,1.786612,4.554378)"
377 x1="14.637301"
378 y1="31.504122"
379 x2="9.3648205"
380 y2="32.250980" />
381 <linearGradient
382 inkscape:collect="always"
383 xlink:href="#linearGradient19894"
384 id="linearGradient1725"
385 gradientUnits="userSpaceOnUse"
386 gradientTransform="scale(1.026450,0.974232)"
387 x1="-22.874170"
388 y1="38.675991"
389 x2="-4.3908315"
390 y2="38.675991" />
391 <linearGradient
392 inkscape:collect="always"
393 xlink:href="#linearGradient2399"
394 id="linearGradient1727"
395 gradientUnits="userSpaceOnUse"
396 gradientTransform="scale(1.026450,0.974232)"
397 x1="-10.480865"
398 y1="39.033951"
399 x2="-23.851389"
400 y2="39.142845" />
401 <linearGradient
402 inkscape:collect="always"
403 xlink:href="#linearGradient19894"
404 id="linearGradient1729"
405 gradientUnits="userSpaceOnUse"
406 gradientTransform="scale(1.026450,0.974232)"
407 x1="-22.874170"
408 y1="38.675991"
409 x2="-4.3908315"
410 y2="38.675991" />
411 <linearGradient
412 inkscape:collect="always"
413 xlink:href="#linearGradient2399"
414 id="linearGradient1731"
415 gradientUnits="userSpaceOnUse"
416 gradientTransform="scale(1.026450,0.974232)"
417 x1="-10.480865"
418 y1="39.033951"
419 x2="-23.851389"
420 y2="39.142845" />
421 <linearGradient
422 inkscape:collect="always"
423 xlink:href="#linearGradient3311"
424 id="linearGradient2516"
425 gradientUnits="userSpaceOnUse"
426 gradientTransform="matrix(1.603440,0.000000,0.000000,0.549396,0.614167,2.449800e-2)"
427 x1="17.879995"
428 y1="55.362793"
429 x2="11.906206"
430 y2="54.863026" />
431 <linearGradient
432 inkscape:collect="always"
433 xlink:href="#linearGradient3265"
434 id="linearGradient2518"
435 gradientUnits="userSpaceOnUse"
436 gradientTransform="matrix(-0.905728,-4.386156e-2,0.189510,-0.963437,0.614167,2.449800e-2)"
437 x1="-29.007195"
438 y1="-29.799353"
439 x2="-37.641232"
440 y2="-29.598314" />
441 <linearGradient
442 inkscape:collect="always"
443 xlink:href="#linearGradient19894"
444 id="linearGradient2522"
445 gradientUnits="userSpaceOnUse"
446 gradientTransform="matrix(0.618682,-0.132027,6.262726e-2,0.741184,31.12021,8.300410)"
447 x1="-22.874170"
448 y1="38.675991"
449 x2="-4.3908315"
450 y2="38.675991" />
451 <linearGradient
452 inkscape:collect="always"
453 xlink:href="#linearGradient2399"
454 id="linearGradient2524"
455 gradientUnits="userSpaceOnUse"
456 gradientTransform="matrix(0.618682,-0.132027,6.262726e-2,0.741184,31.12021,8.300410)"
457 x1="-10.480865"
458 y1="39.033951"
459 x2="-23.851389"
460 y2="39.142845" />
461 <linearGradient
462 inkscape:collect="always"
463 xlink:href="#linearGradient19894"
464 id="linearGradient2529"
465 gradientUnits="userSpaceOnUse"
466 gradientTransform="matrix(0.566621,2.988977e-2,-0.118557,0.656541,36.18544,20.08311)"
467 x1="-22.874170"
468 y1="38.675991"
469 x2="-4.3908315"
470 y2="38.675991" />
471 <linearGradient
472 inkscape:collect="always"
473 xlink:href="#linearGradient2399"
474 id="linearGradient2531"
475 gradientUnits="userSpaceOnUse"
476 gradientTransform="matrix(0.566621,2.988977e-2,-0.118557,0.656541,36.18544,20.08311)"
477 x1="-10.480865"
478 y1="39.033951"
479 x2="-23.851389"
480 y2="39.142845" />
481 <linearGradient
482 inkscape:collect="always"
483 xlink:href="#linearGradient3300"
484 id="linearGradient3306"
485 gradientTransform="scale(1.002656,0.997352)"
486 x1="24.613028"
487 y1="31.146202"
488 x2="24.613028"
489 y2="26.739624"
490 gradientUnits="userSpaceOnUse" />
491 <linearGradient
492 inkscape:collect="always"
493 xlink:href="#linearGradient3311"
494 id="linearGradient3127"
495 gradientUnits="userSpaceOnUse"
496 gradientTransform="matrix(1.60344,0,0,0.549396,0.614167,2.4498e-2)"
497 x1="17.879995"
498 y1="55.362793"
499 x2="11.906206"
500 y2="54.863026" />
501 <linearGradient
502 inkscape:collect="always"
503 xlink:href="#linearGradient3265"
504 id="linearGradient3129"
505 gradientUnits="userSpaceOnUse"
506 gradientTransform="matrix(-0.905728,-4.386156e-2,0.18951,-0.963437,0.614167,2.4498e-2)"
507 x1="-29.007195"
508 y1="-29.799353"
509 x2="-37.641232"
510 y2="-29.598314" />
511 <radialGradient
512 inkscape:collect="always"
513 xlink:href="#aigrd7"
514 id="radialGradient3131"
515 gradientUnits="userSpaceOnUse"
516 gradientTransform="matrix(0.55129,1.265592e-16,-1.35572e-16,0.766034,-10.48701,3.514312)"
517 cx="68.137589"
518 cy="29.869318"
519 fx="68.137589"
520 fy="29.869318"
521 r="33.934090" />
522 <linearGradient
523 inkscape:collect="always"
524 xlink:href="#linearGradient6339"
525 id="linearGradient3133"
526 gradientUnits="userSpaceOnUse"
527 gradientTransform="matrix(1.140494,0,0,0.926002,0.27233,-3.24717)"
528 x1="16.998856"
529 y1="10.061084"
530 x2="32.096882"
531 y2="36.726292" />
532 <linearGradient
533 inkscape:collect="always"
534 xlink:href="#linearGradient3175"
535 id="linearGradient3135"
536 gradientUnits="userSpaceOnUse"
537 gradientTransform="matrix(0.894129,0,0,0.98523,1.515981,2.4498e-2)"
538 x1="37.940434"
539 y1="16.651863"
540 x2="-5.2517161"
541 y2="3.8557322" />
542 <linearGradient
543 inkscape:collect="always"
544 xlink:href="#linearGradient3311"
545 id="linearGradient3157"
546 gradientUnits="userSpaceOnUse"
547 gradientTransform="matrix(1.60344,0,0,0.549396,0.614167,2.4498e-2)"
548 x1="17.879995"
549 y1="55.362793"
550 x2="11.906206"
551 y2="54.863026" />
552 <linearGradient
553 inkscape:collect="always"
554 xlink:href="#linearGradient3265"
555 id="linearGradient3159"
556 gradientUnits="userSpaceOnUse"
557 gradientTransform="matrix(-0.905728,-4.386156e-2,0.18951,-0.963437,0.614167,2.4498e-2)"
558 x1="-29.007195"
559 y1="-29.799353"
560 x2="-37.641232"
561 y2="-29.598314" />
562 <radialGradient
563 inkscape:collect="always"
564 xlink:href="#aigrd7"
565 id="radialGradient3161"
566 gradientUnits="userSpaceOnUse"
567 gradientTransform="matrix(0.55129,1.265592e-16,-1.35572e-16,0.766034,-10.48701,3.514312)"
568 cx="68.137589"
569 cy="29.869318"
570 fx="68.137589"
571 fy="29.869318"
572 r="33.934090" />
573 <linearGradient
574 inkscape:collect="always"
575 xlink:href="#linearGradient3175"
576 id="linearGradient3163"
577 gradientUnits="userSpaceOnUse"
578 gradientTransform="matrix(0.894129,0,0,0.98523,1.515981,2.4498e-2)"
579 x1="37.940434"
580 y1="16.651863"
581 x2="-5.2517161"
582 y2="3.8557322" />
583 <linearGradient
584 inkscape:collect="always"
585 xlink:href="#linearGradient20393"
586 id="linearGradient3165"
587 gradientUnits="userSpaceOnUse"
588 gradientTransform="matrix(-0.6293,0,0,1.589068,50.68808,3.804378)"
589 x1="30.620375"
590 y1="10.313651"
591 x2="32.166080"
592 y2="18.162935" />
593 <linearGradient
594 inkscape:collect="always"
595 xlink:href="#linearGradient20393"
596 id="linearGradient3167"
597 gradientUnits="userSpaceOnUse"
598 gradientTransform="matrix(0.6293,0,0,1.589068,1.411612,3.929378)"
599 x1="30.620375"
600 y1="10.313651"
601 x2="32.166080"
602 y2="18.162935" />
603 <linearGradient
604 inkscape:collect="always"
605 xlink:href="#linearGradient20428"
606 id="linearGradient3169"
607 gradientUnits="userSpaceOnUse"
608 gradientTransform="matrix(1.985083,0,0,0.503757,1.786612,4.554378)"
609 x1="14.637301"
610 y1="31.504122"
611 x2="9.3648205"
612 y2="32.250980" />
613 <linearGradient
614 inkscape:collect="always"
615 xlink:href="#linearGradient6339"
616 id="linearGradient3171"
617 gradientUnits="userSpaceOnUse"
618 gradientTransform="matrix(1.140494,0,0,0.926002,0.27233,-3.24717)"
619 x1="16.998856"
620 y1="10.061084"
621 x2="32.096882"
622 y2="36.726292" />
623 <linearGradient
624 inkscape:collect="always"
625 xlink:href="#linearGradient3300"
626 id="linearGradient3185"
627 gradientUnits="userSpaceOnUse"
628 gradientTransform="scale(1.002656,0.997352)"
629 x1="24.613028"
630 y1="31.146202"
631 x2="24.613028"
632 y2="26.739624" />
633 <linearGradient
634 inkscape:collect="always"
635 xlink:href="#linearGradient19894"
636 id="linearGradient3187"
637 gradientUnits="userSpaceOnUse"
638 gradientTransform="matrix(0.566621,2.988977e-2,-0.118557,0.656541,36.18544,20.08311)"
639 x1="-22.874170"
640 y1="38.675991"
641 x2="-4.3908315"
642 y2="38.675991" />
643 <linearGradient
644 inkscape:collect="always"
645 xlink:href="#linearGradient2399"
646 id="linearGradient3189"
647 gradientUnits="userSpaceOnUse"
648 gradientTransform="matrix(0.566621,2.988977e-2,-0.118557,0.656541,36.18544,20.08311)"
649 x1="-10.480865"
650 y1="39.033951"
651 x2="-23.851389"
652 y2="39.142845" />
653 <linearGradient
654 inkscape:collect="always"
655 xlink:href="#linearGradient19894"
656 id="linearGradient3191"
657 gradientUnits="userSpaceOnUse"
658 gradientTransform="scale(1.02645,0.974232)"
659 x1="-22.874170"
660 y1="38.675991"
661 x2="-4.3908315"
662 y2="38.675991" />
663 <linearGradient
664 inkscape:collect="always"
665 xlink:href="#linearGradient2399"
666 id="linearGradient3193"
667 gradientUnits="userSpaceOnUse"
668 gradientTransform="scale(1.02645,0.974232)"
669 x1="-10.480865"
670 y1="39.033951"
671 x2="-23.851389"
672 y2="39.142845" />
673 <linearGradient
674 inkscape:collect="always"
675 xlink:href="#linearGradient19894"
676 id="linearGradient3195"
677 gradientUnits="userSpaceOnUse"
678 gradientTransform="scale(1.02645,0.974232)"
679 x1="-22.874170"
680 y1="38.675991"
681 x2="-4.3908315"
682 y2="38.675991" />
683 <linearGradient
684 inkscape:collect="always"
685 xlink:href="#linearGradient2399"
686 id="linearGradient3197"
687 gradientUnits="userSpaceOnUse"
688 gradientTransform="scale(1.02645,0.974232)"
689 x1="-10.480865"
690 y1="39.033951"
691 x2="-23.851389"
692 y2="39.142845" />
693 <linearGradient
694 inkscape:collect="always"
695 xlink:href="#linearGradient19894"
696 id="linearGradient3199"
697 gradientUnits="userSpaceOnUse"
698 gradientTransform="matrix(0.618682,-0.132027,6.262726e-2,0.741184,31.12021,8.30041)"
699 x1="-22.874170"
700 y1="38.675991"
701 x2="-4.3908315"
702 y2="38.675991" />
703 <linearGradient
704 inkscape:collect="always"
705 xlink:href="#linearGradient2399"
706 id="linearGradient3201"
707 gradientUnits="userSpaceOnUse"
708 gradientTransform="matrix(0.618682,-0.132027,6.262726e-2,0.741184,31.12021,8.30041)"
709 x1="-10.480865"
710 y1="39.033951"
711 x2="-23.851389"
712 y2="39.142845" />
713 <linearGradient
714 inkscape:collect="always"
715 xlink:href="#aigrd1"
716 id="linearGradient4100"
717 gradientUnits="userSpaceOnUse"
718 gradientTransform="matrix(1.639127,0,0,1.639127,-15.97035,-29.79355)"
719 x1="23.124"
720 y1="43.165"
721 x2="26.4785"
722 y2="43.165" />
723 <linearGradient
724 inkscape:collect="always"
725 xlink:href="#linearGradient3300"
726 id="linearGradient4102"
727 gradientUnits="userSpaceOnUse"
728 gradientTransform="scale(1.002656,0.997352)"
729 x1="24.613028"
730 y1="31.146202"
731 x2="24.613028"
732 y2="26.739624" />
733 <linearGradient
734 inkscape:collect="always"
735 xlink:href="#linearGradient19894"
736 id="linearGradient4104"
737 gradientUnits="userSpaceOnUse"
738 gradientTransform="matrix(0.566621,2.988977e-2,-0.118557,0.656541,36.18544,20.08311)"
739 x1="-22.874170"
740 y1="38.675991"
741 x2="-4.3908315"
742 y2="38.675991" />
743 <linearGradient
744 inkscape:collect="always"
745 xlink:href="#linearGradient2399"
746 id="linearGradient4106"
747 gradientUnits="userSpaceOnUse"
748 gradientTransform="matrix(0.566621,2.988977e-2,-0.118557,0.656541,36.18544,20.08311)"
749 x1="-10.480865"
750 y1="39.033951"
751 x2="-23.851389"
752 y2="39.142845" />
753 <linearGradient
754 inkscape:collect="always"
755 xlink:href="#linearGradient19894"
756 id="linearGradient4108"
757 gradientUnits="userSpaceOnUse"
758 gradientTransform="scale(1.02645,0.974232)"
759 x1="-22.874170"
760 y1="38.675991"
761 x2="-4.3908315"
762 y2="38.675991" />
763 <linearGradient
764 inkscape:collect="always"
765 xlink:href="#linearGradient2399"
766 id="linearGradient4110"
767 gradientUnits="userSpaceOnUse"
768 gradientTransform="scale(1.02645,0.974232)"
769 x1="-10.480865"
770 y1="39.033951"
771 x2="-23.851389"
772 y2="39.142845" />
773 <linearGradient
774 inkscape:collect="always"
775 xlink:href="#linearGradient19894"
776 id="linearGradient4112"
777 gradientUnits="userSpaceOnUse"
778 gradientTransform="scale(1.02645,0.974232)"
779 x1="-22.874170"
780 y1="38.675991"
781 x2="-4.3908315"
782 y2="38.675991" />
783 <linearGradient
784 inkscape:collect="always"
785 xlink:href="#linearGradient2399"
786 id="linearGradient4114"
787 gradientUnits="userSpaceOnUse"
788 gradientTransform="scale(1.02645,0.974232)"
789 x1="-10.480865"
790 y1="39.033951"
791 x2="-23.851389"
792 y2="39.142845" />
793 <linearGradient
794 inkscape:collect="always"
795 xlink:href="#linearGradient19894"
796 id="linearGradient4116"
797 gradientUnits="userSpaceOnUse"
798 gradientTransform="matrix(0.618682,-0.132027,6.262726e-2,0.741184,31.12021,8.30041)"
799 x1="-22.874170"
800 y1="38.675991"
801 x2="-4.3908315"
802 y2="38.675991" />
803 <linearGradient
804 inkscape:collect="always"
805 xlink:href="#linearGradient2399"
806 id="linearGradient4118"
807 gradientUnits="userSpaceOnUse"
808 gradientTransform="matrix(0.618682,-0.132027,6.262726e-2,0.741184,31.12021,8.30041)"
809 x1="-10.480865"
810 y1="39.033951"
811 x2="-23.851389"
812 y2="39.142845" />
813 <linearGradient
814 inkscape:collect="always"
815 xlink:href="#linearGradient3311"
816 id="linearGradient4120"
817 gradientUnits="userSpaceOnUse"
818 gradientTransform="matrix(1.60344,0,0,0.549396,0.614167,2.4498e-2)"
819 x1="17.879995"
820 y1="55.362793"
821 x2="11.906206"
822 y2="54.863026" />
823 <linearGradient
824 inkscape:collect="always"
825 xlink:href="#linearGradient3265"
826 id="linearGradient4122"
827 gradientUnits="userSpaceOnUse"
828 gradientTransform="matrix(-0.905728,-4.386156e-2,0.18951,-0.963437,0.614167,2.4498e-2)"
829 x1="-29.007195"
830 y1="-29.799353"
831 x2="-37.641232"
832 y2="-29.598314" />
833 <radialGradient
834 inkscape:collect="always"
835 xlink:href="#aigrd7"
836 id="radialGradient4124"
837 gradientUnits="userSpaceOnUse"
838 gradientTransform="matrix(0.55129,1.265592e-16,-1.35572e-16,0.766034,-10.48701,3.514312)"
839 cx="68.137589"
840 cy="29.869318"
841 fx="68.137589"
842 fy="29.869318"
843 r="33.934090" />
844 <linearGradient
845 inkscape:collect="always"
846 xlink:href="#linearGradient3175"
847 id="linearGradient4126"
848 gradientUnits="userSpaceOnUse"
849 gradientTransform="matrix(0.894129,0,0,0.98523,1.515981,2.4498e-2)"
850 x1="37.940434"
851 y1="16.651863"
852 x2="-5.2517161"
853 y2="3.8557322" />
854 <linearGradient
855 inkscape:collect="always"
856 xlink:href="#linearGradient20393"
857 id="linearGradient4128"
858 gradientUnits="userSpaceOnUse"
859 gradientTransform="matrix(-0.6293,0,0,1.589068,50.68808,3.804378)"
860 x1="30.620375"
861 y1="10.313651"
862 x2="32.166080"
863 y2="18.162935" />
864 <linearGradient
865 inkscape:collect="always"
866 xlink:href="#linearGradient20393"
867 id="linearGradient4130"
868 gradientUnits="userSpaceOnUse"
869 gradientTransform="matrix(0.6293,0,0,1.589068,1.411612,3.929378)"
870 x1="30.620375"
871 y1="10.313651"
872 x2="32.166080"
873 y2="18.162935" />
874 <linearGradient
875 inkscape:collect="always"
876 xlink:href="#linearGradient20428"
877 id="linearGradient4132"
878 gradientUnits="userSpaceOnUse"
879 gradientTransform="matrix(1.985083,0,0,0.503757,1.786612,4.554378)"
880 x1="14.637301"
881 y1="31.504122"
882 x2="9.3648205"
883 y2="32.250980" />
884 <linearGradient
885 inkscape:collect="always"
886 xlink:href="#linearGradient6339"
887 id="linearGradient4134"
888 gradientUnits="userSpaceOnUse"
889 gradientTransform="matrix(1.140494,0,0,0.926002,0.27233,-3.24717)"
890 x1="16.998856"
891 y1="10.061084"
892 x2="32.096882"
893 y2="36.726292" />
894 </defs>
895 <sodipodi:namedview
896 inkscape:window-y="30"
897 inkscape:window-x="0"
898 inkscape:window-height="818"
899 inkscape:window-width="1060"
900 inkscape:document-units="px"
901 inkscape:grid-bbox="true"
902 showgrid="true"
903 inkscape:current-layer="layer1"
904 inkscape:cy="19.729332"
905 inkscape:cx="-132.96706"
906 inkscape:zoom="1"
907 inkscape:pageshadow="2"
908 inkscape:pageopacity="0.0"
909 borderopacity="0.55294118"
910 bordercolor="#666666"
911 pagecolor="#ffffff"
912 id="base"
913 inkscape:showpageshadow="false">
914 <inkscape:grid
915 id="GridFromPre046Settings"
916 type="xygrid"
917 originx="0px"
918 originy="0px"
919 spacingx="1px"
920 spacingy="1px"
921 color="#0000ff"
922 empcolor="#0000ff"
923 opacity="0.2"
924 empopacity="0.4"
925 empspacing="4" />
926 </sodipodi:namedview>
927 <metadata
928 id="metadata4">
929 <rdf:RDF>
930 <cc:Work
931 rdf:about="">
932 <dc:format>image/svg+xml</dc:format>
933 <dc:type
934 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
935 <dc:title>Info</dc:title>
936 <dc:creator>
937 <cc:Agent>
938 <dc:title>Jakub Steiner</dc:title>
939 </cc:Agent>
940 </dc:creator>
941 <dc:subject>
942 <rdf:Bag>
943 <rdf:li>dialog</rdf:li>
944 <rdf:li>info</rdf:li>
945 </rdf:Bag>
946 </dc:subject>
947 <dc:source>http://jimmac.musichall.cz</dc:source>
948 <cc:license
949 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
950 <dc:contributor>
951 <cc:Agent>
952 <dc:title>Garrett LeSage</dc:title>
953 </cc:Agent>
954 </dc:contributor>
955 </cc:Work>
956 <cc:License
957 rdf:about="http://creativecommons.org/licenses/publicdomain/">
958 <cc:permits
959 rdf:resource="http://creativecommons.org/ns#Reproduction" />
960 <cc:permits
961 rdf:resource="http://creativecommons.org/ns#Distribution" />
962 <cc:permits
963 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
964 </cc:License>
965 </rdf:RDF>
966 </metadata>
967 <g
968 inkscape:groupmode="layer"
969 inkscape:label="Layer 1"
970 id="layer1">
971 <path
972 transform="matrix(1.197183,0,0,1.098591,-6.201582,-3.209507)"
973 d="M 39.875 42.0625 A 13.8125 4.4375 0 1 1 12.25,42.0625 A 13.8125 4.4375 0 1 1 39.875 42.0625 z"
974 sodipodi:ry="4.4375"
975 sodipodi:rx="13.8125"
976 sodipodi:cy="42.0625"
977 sodipodi:cx="26.0625"
978 id="path20208"
979 style="color:#000000;fill:url(#radialGradient20216);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;opacity:0.8"
980 sodipodi:type="arc"
981 inkscape:r_cx="true"
982 inkscape:r_cy="true" />
983 <g
984 id="g4076"
985 transform="translate(0,1)"
986 inkscape:r_cx="true"
987 inkscape:r_cy="true">
988 <path
989 inkscape:r_cy="true"
990 inkscape:r_cx="true"
991 transform="matrix(1.075823,0,0,0.937493,-2.551335,3.047213)"
992 id="path19509"
993 d="M 21.893504,38.885945 L 21.893504,40.36116 C 21.893504,41.836375 23.204807,43.147679 24.680022,43.147679 C 26.155237,43.147679 27.466539,41.836375 27.466539,40.36116 L 27.466539,38.885945 L 21.893504,38.885945 z "
994 style="fill:url(#linearGradient4100);fill-rule:nonzero;stroke:#565656;stroke-miterlimit:4;stroke-opacity:1" />
995 <g
996 inkscape:r_cy="true"
997 inkscape:r_cx="true"
998 transform="matrix(0.989073,0,0,0.993556,-0.408739,7.920479e-3)"
999 id="g3173">
1000 <path
1001 inkscape:r_cy="true"
1002 inkscape:r_cx="true"
1003 sodipodi:nodetypes="cccccccscccccccs"
1004 id="path3209"
1005 d="M 24.511725,27.668867 C 21.208844,27.660897 17.463275,28.632054 19.492913,30.467931 C 18.98969,30.670934 18.270371,31.124313 18.355167,32.185222 C 18.401983,32.739286 18.989243,33.079394 19.79236,33.32911 C 18.881908,33.967722 18.302581,34.642557 18.355167,35.264921 C 18.401438,35.812525 18.976334,36.187531 19.76303,36.43814 C 18.875519,37.069403 18.303301,37.760121 18.355167,38.373951 C 18.434436,39.312088 20.457743,40.362928 24.838928,40.2419 C 27.993329,40.155914 30.776913,39.590514 30.996599,38.373951 C 31.082862,37.896248 30.691907,37.450531 30.087355,37.05408 C 30.539926,36.597918 30.85698,36.135242 30.820616,35.704878 C 30.774128,35.154694 30.205993,34.781923 29.412754,34.53166 C 30.300265,33.900397 30.872482,33.209679 30.820616,32.595849 C 30.774128,32.045664 30.205993,31.702225 29.412754,31.45196 C 30.310848,30.817288 30.872816,30.133928 30.820616,29.516149 C 30.762593,28.829446 27.61599,27.676358 24.511725,27.668867 z "
1006 style="color:#000000;fill:#aeae57;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4102);stroke-width:2.01752925;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
1007 <path
1008 inkscape:r_cy="true"
1009 inkscape:r_cx="true"
1010 sodipodi:nodetypes="csccc"
1011 id="path3183"
1012 d="M 30.920208,38.329767 C 30.700522,39.546331 27.591422,40.232861 22.615132,39.983673 C 19.463507,39.825856 19.283163,38.944055 19.502848,37.727491 C 19.722534,36.510926 22.458318,35.65848 25.609509,35.824708 C 28.7607,35.990936 31.139893,37.113203 30.920208,38.329767 z "
1013 style="color:#000000;fill:url(#linearGradient4104);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4106);stroke-width:0.08906282;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
1014 <path
1015 inkscape:r_cy="true"
1016 inkscape:r_cx="true"
1017 sodipodi:type="arc"
1018 style="color:#000000;fill:url(#linearGradient4108);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4110);stroke-width:0.13035245;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
1019 id="path1603"
1020 sodipodi:cx="-13.87697"
1021 sodipodi:cy="27.228739"
1022 sodipodi:rx="10.341436"
1023 sodipodi:ry="3.2703688"
1024 d="M -3.5355339 27.228739 A 10.341436 3.2703688 0 1 1 -24.218407,27.228739 A 10.341436 3.2703688 0 1 1 -3.5355339 27.228739 z"
1025 transform="matrix(0.60274,-0.128625,6.428372e-2,0.760788,31.12021,14.49141)" />
1026 <path
1027 inkscape:r_cy="true"
1028 inkscape:r_cx="true"
1029 transform="matrix(0.60274,-0.128625,6.428372e-2,0.760788,31.12021,11.39591)"
1030 d="M -3.5355339 27.228739 A 10.341436 3.2703688 0 1 1 -24.218407,27.228739 A 10.341436 3.2703688 0 1 1 -3.5355339 27.228739 z"
1031 sodipodi:ry="3.2703688"
1032 sodipodi:rx="10.341436"
1033 sodipodi:cy="27.228739"
1034 sodipodi:cx="-13.87697"
1035 id="path2364"
1036 style="color:#000000;fill:url(#linearGradient4112);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4114);stroke-width:0.13035245;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
1037 sodipodi:type="arc" />
1038 <path
1039 inkscape:r_cy="true"
1040 inkscape:r_cx="true"
1041 sodipodi:nodetypes="cccss"
1042 id="path2366"
1043 d="M 30.698087,29.636386 C 30.698087,31.014688 28.157326,32.55444 24.716601,33.288693 C 21.275876,34.022945 18.38922,33.50421 18.273172,32.130802 C 18.157124,30.757395 20.509679,29.155466 23.952388,28.968827 C 27.422379,28.780711 30.698087,28.924901 30.698087,29.636386 z "
1044 style="color:#000000;fill:url(#linearGradient4116);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4118);stroke-width:0.08906286;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
1045 <path
1046 inkscape:r_cy="true"
1047 inkscape:r_cx="true"
1048 transform="matrix(0.335464,0,0,0.335464,11.74678,27.2261)"
1049 d="M 31 22.375 A 3.25 3.25 0 1 1 24.5,22.375 A 3.25 3.25 0 1 1 31 22.375 z"
1050 sodipodi:ry="3.25"
1051 sodipodi:rx="3.25"
1052 sodipodi:cy="22.375"
1053 sodipodi:cx="27.75"
1054 id="path20372"
1055 style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
1056 sodipodi:type="arc" />
1057 <path
1058 inkscape:r_cy="true"
1059 inkscape:r_cx="true"
1060 sodipodi:nodetypes="cscc"
1061 id="path3241"
1062 d="M 19.342183,33.378865 C 22.736592,33.883533 26.320992,33.346192 29.214315,31.470807 C 30.025582,30.944962 30.147604,30.343945 30.520921,29.873844 C 29.09679,31.000705 25.494982,34.035625 19.342183,33.378865 z "
1063 style="fill:#000000;fill-opacity:0.23391807;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
1064 <path
1065 inkscape:r_cy="true"
1066 inkscape:r_cx="true"
1067 sodipodi:type="arc"
1068 style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
1069 id="path2435"
1070 sodipodi:cx="27.75"
1071 sodipodi:cy="22.375"
1072 sodipodi:rx="3.25"
1073 sodipodi:ry="3.25"
1074 d="M 31 22.375 A 3.25 3.25 0 1 1 24.5,22.375 A 3.25 3.25 0 1 1 31 22.375 z"
1075 transform="matrix(0.335464,0,0,0.335464,11.74678,30.23376)" />
1076 <path
1077 inkscape:r_cy="true"
1078 inkscape:r_cx="true"
1079 sodipodi:nodetypes="cscc"
1080 id="path3237"
1081 d="M 19.466621,39.517838 C 22.86103,40.022506 26.44543,39.485165 29.338753,37.60978 C 30.15002,37.083935 30.272043,36.482919 30.645359,36.012817 C 29.221228,37.139678 25.61942,40.174598 19.466621,39.517838 z "
1082 style="fill:#000000;fill-opacity:0.23391807;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
1083 <path
1084 inkscape:r_cy="true"
1085 inkscape:r_cx="true"
1086 style="fill:#000000;fill-opacity:0.23391807;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
1087 d="M 19.487361,36.406872 C 22.88177,36.91154 26.46617,36.374199 29.359492,34.498814 C 30.17076,33.972969 30.292782,33.371953 30.666099,32.901851 C 29.241968,34.028712 25.64016,37.063632 19.487361,36.406872 z "
1088 id="path3239"
1089 sodipodi:nodetypes="cscc" />
1090 </g>
1091 <g
1092 inkscape:r_cy="true"
1093 inkscape:r_cx="true"
1094 transform="translate(-0.988797,0)"
1095 id="g3146">
1096 <g
1097 inkscape:r_cy="true"
1098 inkscape:r_cx="true"
1099 id="g3141">
1100 <path
1101 transform="matrix(0.954439,0,0,0.989869,1.433222,0.639881)"
1102 sodipodi:nodetypes="csscs"
1103 id="path3243"
1104 d="M 18.87103,29.628128 C 18.87103,28.836695 20.445135,27.889988 24.419234,27.942972 C 28.101154,27.992059 30.526608,28.83866 30.526608,30.105404 C 30.526608,31.345281 27.307242,32.174416 23.874677,32.008188 C 20.442113,31.84196 18.87103,30.868005 18.87103,29.628128 z "
1105 style="color:#000000;fill:url(#linearGradient4120);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4122);stroke-width:0.09083303;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
1106 inkscape:r_cx="true"
1107 inkscape:r_cy="true" />
1108 <path
1109 transform="matrix(0.954439,0,0,0.989869,1.433222,0.639881)"
1110 sodipodi:nodetypes="csssssc"
1111 id="path6305"
1112 d="M 24.680021,0.8622936 C 16.858005,0.8622936 10.506261,6.8372628 10.506261,14.195288 C 10.506261,21.737851 16.247826,22.573217 16.247826,25.352995 C 16.247826,28.619061 19.614103,32.322687 25.149309,32.188995 C 31.035159,32.046835 33.464182,28.825655 33.464182,25.352995 C 33.464182,22.384064 38.853781,22.304889 38.853781,14.195288 C 38.853781,6.8372628 32.502038,0.8622936 24.680021,0.8622936 z "
1113 style="color:#000000;fill:url(#radialGradient4124);fill-opacity:1;fill-rule:nonzero;stroke:#616471;stroke-width:1.01595449;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
1114 inkscape:r_cx="true"
1115 inkscape:r_cy="true" />
1116 <path
1117 transform="matrix(0.954439,0,0,0.989869,1.433222,0.639881)"
1118 style="color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4126);stroke-width:0.94685698;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
1119 d="M 24.680021,1.9277146 C 17.389999,1.9277146 11.470252,7.4963123 11.470252,14.353901 C 11.470252,21.383476 16.82132,22.162027 16.82132,24.752746 C 16.82132,27.79668 19.958648,31.248413 25.117392,31.123813 C 30.602931,30.991321 32.866751,27.989222 32.866751,24.752746 C 32.866751,21.98574 37.889791,21.911948 37.889791,14.353901 C 37.889791,7.4963123 31.970044,1.9277146 24.680021,1.9277146 z "
1120 id="path2429"
1121 sodipodi:nodetypes="csssssc"
1122 inkscape:r_cx="true"
1123 inkscape:r_cy="true" />
1124 </g>
1125 <g
1126 id="g1695"
1127 transform="matrix(0.9375,0,0,0.926938,0.569221,0.25176)"
1128 inkscape:r_cx="true"
1129 inkscape:r_cy="true">
1130 <path
1131 style="fill:url(#linearGradient4128);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
1132 d="M 31.947292,19.22274 C 32.260034,19.326988 32.468529,19.63973 32.364281,19.952471 L 28.507134,31.523913 C 28.402887,31.836655 28.090145,32.045149 27.777403,31.940902 C 27.464662,31.836655 27.256168,31.523913 27.360415,31.211172 L 31.217562,19.63973 C 31.321809,19.326988 31.634551,19.118493 31.947292,19.22274 z "
1133 id="path1691"
1134 inkscape:r_cx="true"
1135 inkscape:r_cy="true" />
1136 <path
1137 id="path19612"
1138 d="M 20.152404,19.34774 C 19.839662,19.451988 19.631167,19.76473 19.735415,20.077471 L 23.592562,31.648913 C 23.696809,31.961655 24.009551,32.170149 24.322293,32.065902 C 24.635034,31.961655 24.843528,31.648913 24.739281,31.336172 L 20.882134,19.76473 C 20.777887,19.451988 20.465145,19.243493 20.152404,19.34774 z "
1139 style="fill:url(#linearGradient4130);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
1140 inkscape:r_cx="true"
1141 inkscape:r_cy="true" />
1142 <path
1143 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4132);stroke-width:0.21454535;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
1144 d="M 20.255362,19.273128 C 20.009452,19.315194 19.816806,19.507772 19.774653,19.753667 C 19.732499,19.999562 19.850004,20.245309 20.067862,20.366878 C 20.067862,20.366878 21.910084,21.447747 24.317862,21.991878 C 26.72564,22.536009 29.806763,22.571305 32.130362,20.304378 C 32.305608,20.165345 32.386854,19.938963 32.340007,19.720224 C 32.29316,19.501485 32.126325,19.328233 31.909509,19.273168 C 31.692693,19.218103 31.463406,19.290751 31.317862,19.460628 C 29.367326,21.36359 26.773024,21.36522 24.567862,20.866878 C 22.3627,20.368536 20.661612,19.366878 20.661612,19.366878 C 20.542178,19.287089 20.397682,19.253744 20.255362,19.273128 z "
1145 id="path19614"
1146 inkscape:r_cx="true"
1147 inkscape:r_cy="true" />
1148 </g>
1149 <path
1150 inkscape:r_cy="true"
1151 inkscape:r_cx="true"
1152 style="opacity:0.5977654;color:#000000;fill:url(#linearGradient4134);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.98750001;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
1153 d="M 25.001158,3.5644322 C 18.737608,3.5644322 13.655359,7.5900329 13.655359,12.547843 C 13.655359,14.527956 14.632918,16.261758 16.006008,17.747035 C 17.558672,18.378895 19.249827,18.832941 21.114752,18.832941 C 27.378302,18.832941 32.460549,14.807341 32.460551,9.849528 C 32.460551,7.857476 31.466744,6.1074629 30.07856,4.6174331 C 28.533139,3.9930601 26.854241,3.5644321 25.001158,3.5644322 z "
1154 id="path6334"
1155 transform="matrix(0.954439,0,0,0.989869,1.433222,0.639881)" />
1156 </g>
1157 </g>
1158 </g>
1159</svg>
diff --git a/utils/rbutilqt/icons/dialog-warning.svg b/utils/rbutilqt/icons/dialog-warning.svg
new file mode 100644
index 0000000000..e09eccafd6
--- /dev/null
+++ b/utils/rbutilqt/icons/dialog-warning.svg
@@ -0,0 +1,373 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="48px"
13 height="48px"
14 id="svg1377"
15 sodipodi:version="0.32"
16 inkscape:version="0.46"
17 sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/status"
18 sodipodi:docname="dialog-warning.svg"
19 inkscape:output_extension="org.inkscape.output.svg.inkscape">
20 <defs
21 id="defs1379">
22 <inkscape:perspective
23 sodipodi:type="inkscape:persp3d"
24 inkscape:vp_x="0 : 24 : 1"
25 inkscape:vp_y="0 : 1000 : 0"
26 inkscape:vp_z="48 : 24 : 1"
27 inkscape:persp3d-origin="24 : 16 : 1"
28 id="perspective48" />
29 <radialGradient
30 inkscape:collect="always"
31 xlink:href="#linearGradient5060"
32 id="radialGradient6719"
33 gradientUnits="userSpaceOnUse"
34 gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
35 cx="605.71429"
36 cy="486.64789"
37 fx="605.71429"
38 fy="486.64789"
39 r="117.14286" />
40 <linearGradient
41 inkscape:collect="always"
42 id="linearGradient5060">
43 <stop
44 style="stop-color:black;stop-opacity:1;"
45 offset="0"
46 id="stop5062" />
47 <stop
48 style="stop-color:black;stop-opacity:0;"
49 offset="1"
50 id="stop5064" />
51 </linearGradient>
52 <radialGradient
53 inkscape:collect="always"
54 xlink:href="#linearGradient5060"
55 id="radialGradient6717"
56 gradientUnits="userSpaceOnUse"
57 gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
58 cx="605.71429"
59 cy="486.64789"
60 fx="605.71429"
61 fy="486.64789"
62 r="117.14286" />
63 <linearGradient
64 id="linearGradient5048">
65 <stop
66 style="stop-color:black;stop-opacity:0;"
67 offset="0"
68 id="stop5050" />
69 <stop
70 id="stop5056"
71 offset="0.5"
72 style="stop-color:black;stop-opacity:1;" />
73 <stop
74 style="stop-color:black;stop-opacity:0;"
75 offset="1"
76 id="stop5052" />
77 </linearGradient>
78 <linearGradient
79 inkscape:collect="always"
80 xlink:href="#linearGradient5048"
81 id="linearGradient6715"
82 gradientUnits="userSpaceOnUse"
83 gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
84 x1="302.85715"
85 y1="366.64789"
86 x2="302.85715"
87 y2="609.50507" />
88 <linearGradient
89 y2="56.0523"
90 x2="47.3197"
91 y1="11.1133"
92 x1="4.1914"
93 gradientUnits="userSpaceOnUse"
94 id="aigrd1">
95 <stop
96 id="stop6490"
97 style="stop-color:#D4D4D4"
98 offset="0" />
99 <stop
100 id="stop6492"
101 style="stop-color:#E2E2E2"
102 offset="0.3982" />
103 <stop
104 id="stop6494"
105 style="stop-color:#FFFFFF"
106 offset="1" />
107 </linearGradient>
108 <linearGradient
109 y2="56.0523"
110 x2="47.3197"
111 y1="11.1133"
112 x1="4.1914"
113 gradientUnits="userSpaceOnUse"
114 id="linearGradient7451"
115 xlink:href="#aigrd1"
116 inkscape:collect="always" />
117 <linearGradient
118 id="linearGradient4126"
119 inkscape:collect="always">
120 <stop
121 id="stop4128"
122 offset="0"
123 style="stop-color:#000000;stop-opacity:1;" />
124 <stop
125 id="stop4130"
126 offset="1"
127 style="stop-color:#000000;stop-opacity:0;" />
128 </linearGradient>
129 <radialGradient
130 r="17.142857"
131 fy="40.000000"
132 fx="23.857143"
133 cy="40.000000"
134 cx="23.857143"
135 gradientTransform="matrix(1,0,0,0.5,2.139286e-14,20)"
136 gradientUnits="userSpaceOnUse"
137 id="radialGradient7449"
138 xlink:href="#linearGradient4126"
139 inkscape:collect="always" />
140 <linearGradient
141 inkscape:collect="always"
142 xlink:href="#linearGradient6525"
143 id="linearGradient5250"
144 x1="8.5469341"
145 y1="30.281681"
146 x2="30.85088"
147 y2="48.301884"
148 gradientUnits="userSpaceOnUse"
149 gradientTransform="matrix(0.899009,0,0,0.934235,1.875108,1.193645)" />
150 <linearGradient
151 inkscape:collect="always"
152 xlink:href="#aigrd1"
153 id="linearGradient3922"
154 gradientUnits="userSpaceOnUse"
155 x1="4.1914"
156 y1="11.1133"
157 x2="47.3197"
158 y2="56.0523" />
159 <linearGradient
160 inkscape:collect="always"
161 xlink:href="#linearGradient6525"
162 id="linearGradient3924"
163 gradientUnits="userSpaceOnUse"
164 gradientTransform="matrix(0.899009,0,0,0.934235,1.875108,1.193645)"
165 x1="8.5469341"
166 y1="30.281681"
167 x2="30.85088"
168 y2="48.301884" />
169 <linearGradient
170 inkscape:collect="always"
171 xlink:href="#linearGradient6525"
172 id="linearGradient3933"
173 gradientUnits="userSpaceOnUse"
174 gradientTransform="matrix(0.899009,0,0,0.934235,1.875108,1.193645)"
175 x1="8.5469341"
176 y1="30.281681"
177 x2="30.85088"
178 y2="48.301884" />
179 <linearGradient
180 inkscape:collect="always"
181 xlink:href="#aigrd1"
182 id="linearGradient3935"
183 gradientUnits="userSpaceOnUse"
184 x1="4.1914"
185 y1="11.1133"
186 x2="47.3197"
187 y2="56.0523" />
188 <linearGradient
189 inkscape:collect="always"
190 xlink:href="#aigrd1"
191 id="linearGradient3946"
192 gradientUnits="userSpaceOnUse"
193 x1="4.1914"
194 y1="11.1133"
195 x2="47.3197"
196 y2="56.0523" />
197 <linearGradient
198 inkscape:collect="always"
199 xlink:href="#linearGradient6525"
200 id="linearGradient3948"
201 gradientUnits="userSpaceOnUse"
202 gradientTransform="matrix(0.899009,0,0,0.934235,1.875108,1.193645)"
203 x1="8.5469341"
204 y1="30.281681"
205 x2="30.85088"
206 y2="48.301884" />
207 </defs>
208 <sodipodi:namedview
209 id="base"
210 pagecolor="#ffffff"
211 bordercolor="#666666"
212 borderopacity="1.0"
213 inkscape:pageopacity="0.0"
214 inkscape:pageshadow="2"
215 inkscape:zoom="14.757891"
216 inkscape:cx="13.022822"
217 inkscape:cy="24"
218 inkscape:current-layer="g7435"
219 showgrid="true"
220 inkscape:grid-bbox="true"
221 inkscape:document-units="px"
222 inkscape:window-width="1105"
223 inkscape:window-height="818"
224 inkscape:window-x="0"
225 inkscape:window-y="30">
226 <inkscape:grid
227 id="GridFromPre046Settings"
228 type="xygrid"
229 originx="0px"
230 originy="0px"
231 spacingx="1px"
232 spacingy="1px"
233 color="#0000ff"
234 empcolor="#0000ff"
235 opacity="0.2"
236 empopacity="0.4"
237 empspacing="4" />
238 </sodipodi:namedview>
239 <metadata
240 id="metadata1382">
241 <rdf:RDF>
242 <cc:Work
243 rdf:about="">
244 <dc:format>image/svg+xml</dc:format>
245 <dc:type
246 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
247 <dc:title>Dialog Warning</dc:title>
248 <dc:date>2005-10-14</dc:date>
249 <dc:creator>
250 <cc:Agent>
251 <dc:title>Andreas Nilsson</dc:title>
252 </cc:Agent>
253 </dc:creator>
254 <dc:contributor>
255 <cc:Agent>
256 <dc:title>Jakub Steiner, Garrett LeSage</dc:title>
257 </cc:Agent>
258 </dc:contributor>
259 <dc:subject>
260 <rdf:Bag>
261 <rdf:li>dialog</rdf:li>
262 <rdf:li>warning</rdf:li>
263 </rdf:Bag>
264 </dc:subject>
265 <cc:license
266 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
267 </cc:Work>
268 <cc:License
269 rdf:about="http://creativecommons.org/licenses/publicdomain/">
270 <cc:permits
271 rdf:resource="http://creativecommons.org/ns#Reproduction" />
272 <cc:permits
273 rdf:resource="http://creativecommons.org/ns#Distribution" />
274 <cc:permits
275 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
276 </cc:License>
277 </rdf:RDF>
278 </metadata>
279 <g
280 id="layer1"
281 inkscape:label="Layer 1"
282 inkscape:groupmode="layer">
283 <g
284 transform="matrix(1.566667,0.000000,0.000000,1.566667,-8.925566,-23.94764)"
285 id="g7435">
286 <g
287 style="display:inline"
288 transform="matrix(1.444074e-2,0,0,1.331973e-2,33.38871,40.40337)"
289 id="g6707">
290 <rect
291 style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
292 id="rect6709"
293 width="1339.6335"
294 height="478.35718"
295 x="-1559.2523"
296 y="-150.69685" />
297 <path
298 style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
299 d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
300 id="path6711"
301 sodipodi:nodetypes="cccc" />
302 <path
303 sodipodi:nodetypes="cccc"
304 id="path6713"
305 d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
306 style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
307 </g>
308 <g
309 id="g3937"
310 transform="matrix(1,0,4.537846e-3,1,-0.138907,-1.394718e-15)"
311 inkscape:r_cx="true"
312 inkscape:r_cy="true">
313 <path
314 inkscape:r_cy="true"
315 inkscape:r_cx="true"
316 transform="matrix(1,0,-8.726683e-3,1,0.328074,1.276596)"
317 id="path6485"
318 d="M 33.282781,38.644744 L 22.407791,18.394765 C 22.095292,17.832266 21.532792,17.519767 20.907793,17.519767 C 20.282793,17.519767 19.720294,17.894765 19.407795,18.457265 L 8.7828048,38.707245 C 8.5328048,39.207244 8.5328048,39.894744 8.8453048,40.394743 C 9.1578038,40.894743 9.6578038,41.144742 10.282804,41.144742 L 31.782782,41.144742 C 32.407781,41.144742 32.97028,40.832243 33.220281,40.332243 C 33.53278,39.832243 33.53278,39.207244 33.282781,38.644744 z "
319 style="fill:#cc0000;fill-rule:nonzero;stroke:#9f0000;stroke-width:0.6382978;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
320 <g
321 inkscape:r_cy="true"
322 inkscape:r_cx="true"
323 id="g6487"
324 transform="matrix(0.625,0,-5.534934e-3,0.634254,6.164053,15.76055)"
325 style="fill-rule:nonzero;stroke:#000000;stroke-miterlimit:4">
326 <linearGradient
327 y2="56.052299"
328 x2="47.319698"
329 y1="11.1133"
330 x1="4.1914001"
331 gradientUnits="userSpaceOnUse"
332 id="linearGradient6525">
333 <stop
334 id="stop6529"
335 style="stop-color:#ffffff;stop-opacity:1;"
336 offset="0" />
337 <stop
338 id="stop6531"
339 style="stop-color:#ffffff;stop-opacity:0.34020618;"
340 offset="1" />
341 </linearGradient>
342 <path
343 inkscape:r_cy="true"
344 inkscape:r_cx="true"
345 id="path6496"
346 d="M 9.5,37.6 C 9.2,38.1 9.5,38.5 10,38.5 L 38.2,38.5 C 38.7,38.5 39,38.1 38.7,37.6 L 24.4,11 C 24.1,10.5 23.7,10.5 23.5,11 L 9.5,37.6 z "
347 style="fill:url(#linearGradient3946);stroke:none" />
348 </g>
349 <path
350 inkscape:r_cy="true"
351 inkscape:r_cx="true"
352 transform="matrix(1,0,-8.726683e-3,1,0.318277,1.276596)"
353 sodipodi:nodetypes="ccsccscccc"
354 id="path1325"
355 d="M 32.323106,38.183905 L 22.150271,19.265666 C 21.71698,18.45069 21.561698,18.189213 20.908406,18.189213 C 20.346525,18.189213 20.054127,18.57002 19.651305,19.339291 L 9.7489285,38.242296 C 9.1737649,39.303588 9.1128238,39.580228 9.3937644,40.047345 C 9.6747034,40.514462 10.032797,40.48902 11.356441,40.519491 L 30.974593,40.519491 C 32.206825,40.534726 32.483988,40.440837 32.70874,39.97372 C 32.989681,39.506602 32.867799,39.136 32.323106,38.183905 z "
356 style="opacity:0.5;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3948);stroke-width:0.63829792;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
357 </g>
358 <g
359 style="fill-rule:nonzero;stroke:#000000;stroke-miterlimit:4"
360 transform="matrix(0.555088,0,0,0.555052,7.749711,17.80196)"
361 id="g6498"
362 inkscape:r_cx="true"
363 inkscape:r_cy="true">
364 <path
365 style="stroke:none"
366 d="M 23.9,36.5 C 22.6,36.5 21.6,35.5 21.6,34.2 C 21.6,32.8 22.5,31.9 23.9,31.9 C 25.3,31.9 26.1,32.8 26.2,34.2 C 26.2,35.5 25.3,36.5 23.9,36.5 L 23.9,36.5 z M 22.5,30.6 L 21.9,19.1 L 25.9,19.1 L 25.3,30.6 L 22.4,30.6 L 22.5,30.6 z "
367 id="path6500"
368 inkscape:r_cx="true"
369 inkscape:r_cy="true" />
370 </g>
371 </g>
372 </g>
373</svg>
diff --git a/utils/rbutilqt/icons/document-save.svg b/utils/rbutilqt/icons/document-save.svg
new file mode 100644
index 0000000000..2922c4331a
--- /dev/null
+++ b/utils/rbutilqt/icons/document-save.svg
@@ -0,0 +1,619 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 sodipodi:docname="document-save.svg"
13 sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
14 inkscape:version="0.46"
15 sodipodi:version="0.32"
16 id="svg2913"
17 height="48px"
18 width="48px"
19 inkscape:output_extension="org.inkscape.output.svg.inkscape">
20 <defs
21 id="defs3">
22 <inkscape:perspective
23 sodipodi:type="inkscape:persp3d"
24 inkscape:vp_x="0 : 24 : 1"
25 inkscape:vp_y="0 : 1000 : 0"
26 inkscape:vp_z="48 : 24 : 1"
27 inkscape:persp3d-origin="24 : 16 : 1"
28 id="perspective104" />
29 <radialGradient
30 inkscape:collect="always"
31 xlink:href="#linearGradient5060"
32 id="radialGradient5031"
33 gradientUnits="userSpaceOnUse"
34 gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
35 cx="605.71429"
36 cy="486.64789"
37 fx="605.71429"
38 fy="486.64789"
39 r="117.14286" />
40 <linearGradient
41 inkscape:collect="always"
42 id="linearGradient5060">
43 <stop
44 style="stop-color:black;stop-opacity:1;"
45 offset="0"
46 id="stop5062" />
47 <stop
48 style="stop-color:black;stop-opacity:0;"
49 offset="1"
50 id="stop5064" />
51 </linearGradient>
52 <radialGradient
53 inkscape:collect="always"
54 xlink:href="#linearGradient5060"
55 id="radialGradient5029"
56 gradientUnits="userSpaceOnUse"
57 gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
58 cx="605.71429"
59 cy="486.64789"
60 fx="605.71429"
61 fy="486.64789"
62 r="117.14286" />
63 <linearGradient
64 id="linearGradient5048">
65 <stop
66 style="stop-color:black;stop-opacity:0;"
67 offset="0"
68 id="stop5050" />
69 <stop
70 id="stop5056"
71 offset="0.5"
72 style="stop-color:black;stop-opacity:1;" />
73 <stop
74 style="stop-color:black;stop-opacity:0;"
75 offset="1"
76 id="stop5052" />
77 </linearGradient>
78 <linearGradient
79 inkscape:collect="always"
80 xlink:href="#linearGradient5048"
81 id="linearGradient5027"
82 gradientUnits="userSpaceOnUse"
83 gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
84 x1="302.85715"
85 y1="366.64789"
86 x2="302.85715"
87 y2="609.50507" />
88 <linearGradient
89 inkscape:collect="always"
90 id="linearGradient6925">
91 <stop
92 style="stop-color:#204a87;stop-opacity:1;"
93 offset="0"
94 id="stop6927" />
95 <stop
96 style="stop-color:#204a87;stop-opacity:0;"
97 offset="1"
98 id="stop6929" />
99 </linearGradient>
100 <linearGradient
101 inkscape:collect="always"
102 id="linearGradient6901">
103 <stop
104 style="stop-color:#3465a4;stop-opacity:1;"
105 offset="0"
106 id="stop6903" />
107 <stop
108 style="stop-color:#3465a4;stop-opacity:0;"
109 offset="1"
110 id="stop6905" />
111 </linearGradient>
112 <linearGradient
113 inkscape:collect="always"
114 id="linearGradient4991">
115 <stop
116 style="stop-color:#ffffff;stop-opacity:1;"
117 offset="0"
118 id="stop4993" />
119 <stop
120 style="stop-color:#ffffff;stop-opacity:0;"
121 offset="1"
122 id="stop4995" />
123 </linearGradient>
124 <radialGradient
125 inkscape:collect="always"
126 xlink:href="#linearGradient4991"
127 id="radialGradient4997"
128 cx="23.447077"
129 cy="6.4576745"
130 fx="23.447077"
131 fy="6.4576745"
132 r="19.0625"
133 gradientTransform="matrix(-1.314471,-1.006312e-2,-1.022964e-2,1.336221,46.22108,-4.909887)"
134 gradientUnits="userSpaceOnUse" />
135 <linearGradient
136 id="linearGradient2187"
137 inkscape:collect="always">
138 <stop
139 id="stop2189"
140 offset="0"
141 style="stop-color:#ffffff;stop-opacity:1;" />
142 <stop
143 id="stop2191"
144 offset="1"
145 style="stop-color:#ffffff;stop-opacity:0;" />
146 </linearGradient>
147 <linearGradient
148 inkscape:collect="always"
149 xlink:href="#linearGradient2187"
150 id="linearGradient1764"
151 gradientUnits="userSpaceOnUse"
152 gradientTransform="matrix(0.914114,1.412791e-16,-1.412791e-16,0.914114,-3.868698,-2.706902)"
153 x1="33.059906"
154 y1="27.394117"
155 x2="12.624337"
156 y2="12.583769" />
157 <linearGradient
158 inkscape:collect="always"
159 id="linearGradient8662">
160 <stop
161 style="stop-color:#000000;stop-opacity:1;"
162 offset="0"
163 id="stop8664" />
164 <stop
165 style="stop-color:#000000;stop-opacity:0;"
166 offset="1"
167 id="stop8666" />
168 </linearGradient>
169 <radialGradient
170 inkscape:collect="always"
171 xlink:href="#linearGradient8662"
172 id="radialGradient8668"
173 cx="24.837126"
174 cy="36.421127"
175 fx="24.837126"
176 fy="36.421127"
177 r="15.644737"
178 gradientTransform="matrix(1.000000,-7.816467e-32,-1.132409e-32,0.536723,-5.897962e-14,16.87306)"
179 gradientUnits="userSpaceOnUse" />
180 <linearGradient
181 id="linearGradient2555">
182 <stop
183 id="stop2557"
184 offset="0"
185 style="stop-color:#ffffff;stop-opacity:1;" />
186 <stop
187 style="stop-color:#e6e6e6;stop-opacity:1.0000000;"
188 offset="0.50000000"
189 id="stop2561" />
190 <stop
191 id="stop2563"
192 offset="0.75000000"
193 style="stop-color:#ffffff;stop-opacity:1.0000000;" />
194 <stop
195 style="stop-color:#e1e1e1;stop-opacity:1.0000000;"
196 offset="0.84166664"
197 id="stop2565" />
198 <stop
199 id="stop2559"
200 offset="1.0000000"
201 style="stop-color:#ffffff;stop-opacity:1.0000000;" />
202 </linearGradient>
203 <linearGradient
204 id="linearGradient4274">
205 <stop
206 style="stop-color:#ffffff;stop-opacity:0.25490198;"
207 offset="0.0000000"
208 id="stop4276" />
209 <stop
210 style="stop-color:#ffffff;stop-opacity:1.0000000;"
211 offset="1.0000000"
212 id="stop4278" />
213 </linearGradient>
214 <linearGradient
215 id="linearGradient4264"
216 inkscape:collect="always">
217 <stop
218 id="stop4266"
219 offset="0"
220 style="stop-color:#000000;stop-opacity:1;" />
221 <stop
222 id="stop4268"
223 offset="1"
224 style="stop-color:#000000;stop-opacity:0;" />
225 </linearGradient>
226 <linearGradient
227 id="linearGradient4254"
228 inkscape:collect="always">
229 <stop
230 id="stop4256"
231 offset="0"
232 style="stop-color:#ffffff;stop-opacity:1;" />
233 <stop
234 id="stop4258"
235 offset="1"
236 style="stop-color:#ffffff;stop-opacity:0;" />
237 </linearGradient>
238 <linearGradient
239 id="linearGradient4244">
240 <stop
241 id="stop4246"
242 offset="0.0000000"
243 style="stop-color:#e4e4e4;stop-opacity:1.0000000;" />
244 <stop
245 id="stop4248"
246 offset="1.0000000"
247 style="stop-color:#d3d3d3;stop-opacity:1.0000000;" />
248 </linearGradient>
249 <linearGradient
250 id="linearGradient4236"
251 inkscape:collect="always">
252 <stop
253 id="stop4238"
254 offset="0"
255 style="stop-color:#eeeeee;stop-opacity:1;" />
256 <stop
257 id="stop4240"
258 offset="1"
259 style="stop-color:#eeeeee;stop-opacity:0;" />
260 </linearGradient>
261 <linearGradient
262 id="linearGradient4228">
263 <stop
264 id="stop4230"
265 offset="0.0000000"
266 style="stop-color:#bbbbbb;stop-opacity:1.0000000;" />
267 <stop
268 id="stop4232"
269 offset="1.0000000"
270 style="stop-color:#9f9f9f;stop-opacity:1.0000000;" />
271 </linearGradient>
272 <linearGradient
273 id="linearGradient4184">
274 <stop
275 id="stop4186"
276 offset="0.0000000"
277 style="stop-color:#838383;stop-opacity:1.0000000;" />
278 <stop
279 id="stop4188"
280 offset="1.0000000"
281 style="stop-color:#bbbbbb;stop-opacity:0.0000000;" />
282 </linearGradient>
283 <linearGradient
284 gradientTransform="translate(0.795493,3.799180)"
285 y2="35.281250"
286 x2="24.687500"
287 y1="35.281250"
288 x1="7.0625000"
289 gradientUnits="userSpaceOnUse"
290 id="linearGradient4209"
291 xlink:href="#linearGradient4184"
292 inkscape:collect="always" />
293 <linearGradient
294 gradientUnits="userSpaceOnUse"
295 y2="40.943935"
296 x2="36.183067"
297 y1="28.481176"
298 x1="7.6046205"
299 id="linearGradient4234"
300 xlink:href="#linearGradient4228"
301 inkscape:collect="always"
302 gradientTransform="translate(0.000000,5.125000)" />
303 <linearGradient
304 gradientUnits="userSpaceOnUse"
305 y2="33.758667"
306 x2="12.221823"
307 y1="37.205811"
308 x1="12.277412"
309 id="linearGradient4242"
310 xlink:href="#linearGradient4236"
311 inkscape:collect="always"
312 gradientTransform="translate(0.000000,5.125000)" />
313 <radialGradient
314 gradientUnits="userSpaceOnUse"
315 gradientTransform="matrix(1.286242,0.781698,-0.710782,1.169552,-2.354348,0.248140)"
316 r="20.935817"
317 fy="2.9585190"
318 fx="15.571491"
319 cy="2.9585190"
320 cx="15.571491"
321 id="radialGradient4250"
322 xlink:href="#linearGradient4244"
323 inkscape:collect="always" />
324 <linearGradient
325 gradientUnits="userSpaceOnUse"
326 y2="47.620636"
327 x2="44.096100"
328 y1="4.4331360"
329 x1="12.378357"
330 id="linearGradient4260"
331 xlink:href="#linearGradient4254"
332 inkscape:collect="always"
333 gradientTransform="translate(0.000000,5.125000)" />
334 <radialGradient
335 gradientUnits="userSpaceOnUse"
336 gradientTransform="matrix(1.000000,0.000000,0.000000,0.651032,-2.885063e-16,9.455693)"
337 r="23.555494"
338 fy="27.096155"
339 fx="23.201941"
340 cy="27.096155"
341 cx="23.201941"
342 id="radialGradient4270"
343 xlink:href="#linearGradient4264"
344 inkscape:collect="always" />
345 <linearGradient
346 gradientUnits="userSpaceOnUse"
347 y2="26.357183"
348 x2="23.688078"
349 y1="11.318835"
350 x1="23.688078"
351 id="linearGradient4272"
352 xlink:href="#linearGradient4274"
353 inkscape:collect="always"
354 gradientTransform="translate(0.000000,5.125000)" />
355 <linearGradient
356 inkscape:collect="always"
357 xlink:href="#linearGradient2555"
358 id="linearGradient2553"
359 x1="33.431175"
360 y1="31.964777"
361 x2="21.747974"
362 y2="11.780679"
363 gradientUnits="userSpaceOnUse" />
364 <linearGradient
365 inkscape:collect="always"
366 xlink:href="#linearGradient6901"
367 id="linearGradient6907"
368 x1="14.751649"
369 y1="15.868432"
370 x2="8.8953285"
371 y2="16.743431"
372 gradientUnits="userSpaceOnUse" />
373 <linearGradient
374 inkscape:collect="always"
375 xlink:href="#linearGradient6925"
376 id="linearGradient6931"
377 x1="12.25"
378 y1="18.25"
379 x2="7"
380 y2="21.118431"
381 gradientUnits="userSpaceOnUse" />
382 </defs>
383 <sodipodi:namedview
384 inkscape:window-y="30"
385 inkscape:window-x="0"
386 inkscape:window-height="818"
387 inkscape:window-width="999"
388 inkscape:document-units="px"
389 inkscape:grid-bbox="true"
390 showgrid="false"
391 inkscape:current-layer="layer2"
392 inkscape:cy="11.891468"
393 inkscape:cx="-133.68151"
394 inkscape:zoom="1"
395 inkscape:pageshadow="2"
396 inkscape:pageopacity="0.0"
397 borderopacity="0.22745098"
398 bordercolor="#666666"
399 pagecolor="#ffffff"
400 id="base"
401 inkscape:showpageshadow="false"
402 fill="#3465a4"
403 stroke="#204a87" />
404 <metadata
405 id="metadata4">
406 <rdf:RDF>
407 <cc:Work
408 rdf:about="">
409 <dc:format>image/svg+xml</dc:format>
410 <dc:type
411 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
412 <dc:title>Save</dc:title>
413 <dc:creator>
414 <cc:Agent>
415 <dc:title>Jakub Steiner</dc:title>
416 </cc:Agent>
417 </dc:creator>
418 <dc:subject>
419 <rdf:Bag>
420 <rdf:li>hdd</rdf:li>
421 <rdf:li>hard drive</rdf:li>
422 <rdf:li>save</rdf:li>
423 <rdf:li>io</rdf:li>
424 <rdf:li>store</rdf:li>
425 </rdf:Bag>
426 </dc:subject>
427 <cc:license
428 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
429 <dc:identifier />
430 <dc:source>http://jimmac.musichall.cz</dc:source>
431 </cc:Work>
432 <cc:License
433 rdf:about="http://creativecommons.org/licenses/publicdomain/">
434 <cc:permits
435 rdf:resource="http://creativecommons.org/ns#Reproduction" />
436 <cc:permits
437 rdf:resource="http://creativecommons.org/ns#Distribution" />
438 <cc:permits
439 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
440 </cc:License>
441 </rdf:RDF>
442 </metadata>
443 <g
444 inkscape:label="pix"
445 id="layer2"
446 inkscape:groupmode="layer">
447 <g
448 style="display:inline"
449 id="g5022"
450 transform="matrix(2.411405e-2,0,0,1.929202e-2,45.48953,41.75228)">
451 <rect
452 y="-150.69685"
453 x="-1559.2523"
454 height="478.35718"
455 width="1339.6335"
456 id="rect4173"
457 style="opacity:0.40206185;color:black;fill:url(#linearGradient5027);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
458 <path
459 sodipodi:nodetypes="cccc"
460 id="path5058"
461 d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
462 style="opacity:0.40206185;color:black;fill:url(#radialGradient5029);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
463 <path
464 style="opacity:0.40206185;color:black;fill:url(#radialGradient5031);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
465 d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
466 id="path5018"
467 sodipodi:nodetypes="cccc" />
468 </g>
469 <path
470 sodipodi:nodetypes="cccsccccccccc"
471 id="path4196"
472 d="M 11.28569,13.087628 C 10.66069,13.087628 10.254441,13.377808 10.004442,13.931381 C 10.004441,13.931381 3.5356915,31.034938 3.5356915,31.034938 C 3.5356915,31.034938 3.2856915,31.706497 3.2856915,32.816188 C 3.2856915,32.816188 3.2856915,42.466156 3.2856915,42.466156 C 3.2856915,43.548769 3.943477,44.091158 4.9419415,44.091156 L 43.50444,44.091156 C 44.489293,44.091156 45.09819,43.372976 45.09819,42.247406 L 45.09819,32.597438 C 45.09819,32.597438 45.204153,31.827015 45.00444,31.284938 L 38.28569,14.087631 C 38.101165,13.575725 37.648785,13.099533 37.16069,13.087628 L 11.28569,13.087628 z "
473 style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#535353;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
474 <path
475 sodipodi:nodetypes="ccccccccc"
476 id="path4170"
477 d="M 3.2735915,32.121812 L 4.0381936,31.429597 L 41.647883,31.492097 L 45.11029,31.809395 L 45.11029,42.247927 C 45.11029,43.373496 44.503272,44.091258 43.518419,44.091258 L 4.9354314,44.091258 C 3.9369667,44.091258 3.2735915,43.549207 3.2735915,42.466594 L 3.2735915,32.121812 z "
478 style="fill:url(#linearGradient4234);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.02044296px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
479 <path
480 sodipodi:nodetypes="csccccccs"
481 id="path3093"
482 d="M 3.5490842,31.039404 C 2.8347985,32.50369 3.5484686,33.432261 4.5847985,33.432261 C 4.5847985,33.432261 43.584797,33.432261 43.584797,33.432261 C 44.703844,33.408451 45.430035,32.420356 45.013368,31.289403 L 38.299082,14.078704 C 38.114558,13.566798 37.64432,13.090606 37.156225,13.078701 L 11.299083,13.078701 C 10.674083,13.078701 10.263369,13.382274 10.01337,13.935847 C 10.01337,13.935847 3.5490842,31.039404 3.5490842,31.039404 z "
483 style="fill:url(#radialGradient4250);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
484 <rect
485 y="36.299183"
486 x="7.857996"
487 height="5.5625"
488 width="17.625"
489 id="rect4174"
490 style="opacity:1;color:#000000;fill:url(#linearGradient4209);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.40899992;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
491 <path
492 sodipodi:nodetypes="cscc"
493 id="path4194"
494 d="M 7.8579947,41.86168 C 7.8579947,41.86168 7.8579947,37.850195 7.8579947,37.850195 C 9.6935221,41.029421 16.154485,41.86168 20.795492,41.86168 C 20.795492,41.86168 7.8579947,41.86168 7.8579947,41.86168 z "
495 style="opacity:0.81142853;fill:url(#linearGradient4242);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
496 <path
497 sodipodi:nodetypes="cccccccc"
498 id="path4201"
499 d="M 44.796162,30.753688 C 44.859684,32.003662 44.382159,33.069528 43.474046,33.097438 C 43.474046,33.097438 5.3553296,33.097437 5.3553297,33.097438 C 4.0660978,33.097438 3.4875937,32.772491 3.271279,32.229382 C 3.3630404,33.173714 4.0970964,33.878688 5.3553297,33.878688 C 5.3553296,33.878687 43.474046,33.878688 43.474046,33.878688 C 44.550053,33.845617 45.226851,32.454664 44.82621,30.883897 L 44.796162,30.753688 z "
500 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
501 <path
502 id="path4211"
503 d="M 10.96875,15.28125 C 10.922675,15.481571 10.78125,15.668047 10.78125,15.875 C 10.78125,16.823605 11.37223,17.664474 12.125,18.46875 C 12.365268,18.314675 12.490117,18.114342 12.75,17.96875 C 11.809691,17.152746 11.196604,16.252168 10.96875,15.28125 z M 37.625,15.28125 C 37.396273,16.250866 36.782988,17.153676 35.84375,17.96875 C 36.117894,18.122332 36.247738,18.33699 36.5,18.5 C 37.257262,17.693344 37.8125,16.826956 37.8125,15.875 C 37.8125,15.668047 37.670906,15.481571 37.625,15.28125 z M 39.8125,23.71875 C 39.198709,27.758861 32.513887,30.96875 24.28125,30.96875 C 16.068996,30.968751 9.4211001,27.775964 8.78125,23.75 C 8.7488928,23.947132 8.65625,24.141882 8.65625,24.34375 C 8.6562503,28.661697 15.645354,32.187501 24.28125,32.1875 C 32.917146,32.1875 39.937499,28.661698 39.9375,24.34375 C 39.9375,24.130826 39.848449,23.926394 39.8125,23.71875 z "
504 style="opacity:0.69142857;color:#000000;fill:url(#linearGradient4272);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
505 <path
506 transform="translate(8.838843e-2,5.301780)"
507 d="M 8.5736699 25.593554 A 1.3700194 1.016466 0 1 1 5.833631,25.593554 A 1.3700194 1.016466 0 1 1 8.5736699 25.593554 z"
508 sodipodi:ry="1.016466"
509 sodipodi:rx="1.3700194"
510 sodipodi:cy="25.593554"
511 sodipodi:cx="7.2036505"
512 id="path4224"
513 style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:0.45762706;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
514 sodipodi:type="arc" />
515 <path
516 sodipodi:type="arc"
517 style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:0.45762706;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
518 id="path4226"
519 sodipodi:cx="7.2036505"
520 sodipodi:cy="25.593554"
521 sodipodi:rx="1.3700194"
522 sodipodi:ry="1.016466"
523 d="M 8.5736699 25.593554 A 1.3700194 1.016466 0 1 1 5.833631,25.593554 A 1.3700194 1.016466 0 1 1 8.5736699 25.593554 z"
524 transform="translate(33.96705,5.213390)" />
525 <path
526 style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4260);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
527 d="M 11.642515,13.540723 C 11.040823,13.540723 10.649724,13.820081 10.409049,14.35301 C 10.409048,14.35301 3.9940341,30.943732 3.9940341,30.943732 C 3.9940341,30.943732 3.7533573,31.590247 3.7533573,32.658555 C 3.7533573,32.658555 3.7533573,41.948651 3.7533573,41.948651 C 3.7533573,43.303391 4.1974134,43.57555 5.3478414,43.57555 L 43.034746,43.57555 C 44.357872,43.57555 44.569062,43.259153 44.569062,41.738058 L 44.569062,32.447962 C 44.569062,32.447962 44.671072,31.706271 44.478807,31.184409 L 37.885616,14.378434 C 37.707973,13.885617 37.334964,13.552184 36.865071,13.540723 L 11.642515,13.540723 z "
528 id="path4252"
529 sodipodi:nodetypes="cccsccccccccc" />
530 <path
531 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:0.42372885"
532 d="M 40.5,36.554166 L 40.5,41.575101"
533 id="path4282" />
534 <path
535 id="path4284"
536 d="M 38.5,36.613943 L 38.5,41.634878"
537 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:0.42372885" />
538 <path
539 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:0.42372885"
540 d="M 36.5,36.613943 L 36.5,41.634878"
541 id="path4286" />
542 <path
543 id="path4288"
544 d="M 34.5,36.613943 L 34.5,41.634878"
545 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:0.42372885" />
546 <path
547 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:0.42372885"
548 d="M 32.5,36.613943 L 32.5,41.634878"
549 id="path4290" />
550 <path
551 id="path4292"
552 d="M 30.5,36.613943 L 30.5,41.634878"
553 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:0.42372885" />
554 <path
555 id="path4294"
556 d="M 39.5,36.604065 L 39.5,41.625"
557 style="opacity:0.09714284;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1" />
558 <path
559 style="opacity:0.09714284;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
560 d="M 37.5,36.663842 L 37.5,41.684777"
561 id="path4296" />
562 <path
563 id="path4298"
564 d="M 35.5,36.663842 L 35.5,41.684777"
565 style="opacity:0.09714284;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1" />
566 <path
567 style="opacity:0.09714284;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
568 d="M 33.5,36.663842 L 33.5,41.684777"
569 id="path4300" />
570 <path
571 id="path4302"
572 d="M 31.5,36.663842 L 31.5,41.684777"
573 style="opacity:0.09714284;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1" />
574 <path
575 id="path4572"
576 d="M 7.875,36.3125 L 7.875,41.84375 L 20.4375,41.84375 L 8.21875,41.5 L 7.875,36.3125 z "
577 style="opacity:0.43999999;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
578 <path
579 sodipodi:type="arc"
580 style="opacity:0.20571427;color:#000000;fill:url(#linearGradient2553);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.93365198;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.42372879;visibility:visible;display:inline;overflow:visible"
581 id="path2545"
582 sodipodi:cx="25"
583 sodipodi:cy="19.5625"
584 sodipodi:rx="14.875"
585 sodipodi:ry="6.6875"
586 d="M 39.875 19.5625 A 14.875 6.6875 0 1 1 10.125,19.5625 A 14.875 6.6875 0 1 1 39.875 19.5625 z"
587 transform="matrix(1.037815,0.000000,0.000000,1.060747,-1.632878,3.030370)" />
588 </g>
589 <g
590 inkscape:groupmode="layer"
591 id="layer1"
592 inkscape:label="down">
593 <path
594 transform="matrix(1.130190,1.178179e-16,7.918544e-17,-0.759601,-3.909725,53.66554)"
595 d="M 40.481863 36.421127 A 15.644737 8.3968935 0 1 1 9.1923885,36.421127 A 15.644737 8.3968935 0 1 1 40.481863 36.421127 z"
596 sodipodi:ry="8.3968935"
597 sodipodi:rx="15.644737"
598 sodipodi:cy="36.421127"
599 sodipodi:cx="24.837126"
600 id="path8660"
601 style="opacity:0.14117647;color:#000000;fill:url(#radialGradient8668);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
602 sodipodi:type="arc" />
603 <path
604 style="opacity:1;color:#000000;fill:url(#linearGradient6907);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient6931);stroke-width:0.99999982;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
605 d="M 3.2034501,25.835194 C 2.1729477,-5.3853369 28.741616,-0.4511153 28.582416,15.788689 L 35.89533,15.788689 L 24.517652,28.774671 L 12.585426,15.788689 C 12.585426,15.788689 20.126859,15.788689 20.126859,15.788689 C 20.583921,4.8193225 3.4092324,1.6100346 3.2034501,25.835194 z "
606 id="path1432"
607 sodipodi:nodetypes="ccccccc" />
608 <path
609 sodipodi:nodetypes="ccccccc"
610 id="path2177"
611 d="M 7.6642103,9.1041047 C 12.40638,-0.0400306 28.122336,2.7175443 27.761604,16.579393 L 34.078976,16.579393 C 34.078976,16.579393 24.513151,27.536769 24.513151,27.536769 L 14.41668,16.579393 C 14.41668,16.579393 20.87332,16.579393 20.87332,16.579393 C 21.144975,5.0041615 10.922265,5.5345215 7.6642103,9.1041047 z "
612 style="opacity:0.47159091;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient1764);stroke-width:0.99999934;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible" />
613 <path
614 style="opacity:0.49431817;color:#000000;fill:url(#radialGradient4997);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
615 d="M 34.767155,16.211613 L 32.782979,18.757322 C 27.372947,17.241029 24.896829,21.486664 17.109284,20.489112 L 13.247998,16.080077 L 20.434468,16.162862 C 20.483219,4.3164571 8.3443098,4.998966 5.0292663,13.627829 C 8.8372201,-1.2611216 27.893316,0.8064118 28.28332,16.114112 L 34.767155,16.211613 z "
616 id="path4989"
617 sodipodi:nodetypes="cccccccc" />
618 </g>
619</svg>
diff --git a/utils/rbutilqt/icons/edit-clear.svg b/utils/rbutilqt/icons/edit-clear.svg
new file mode 100644
index 0000000000..b2f20d44e7
--- /dev/null
+++ b/utils/rbutilqt/icons/edit-clear.svg
@@ -0,0 +1,416 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="48px"
13 height="48px"
14 id="svg1306"
15 sodipodi:version="0.32"
16 inkscape:version="0.46"
17 sodipodi:docbase="/home/tigert/cvs/freedesktop.org/tango-icon-theme/scalable/actions"
18 sodipodi:docname="edit-clear.svg"
19 inkscape:export-filename="/home/andreas/projekt/bild/tango/clear2.png"
20 inkscape:export-xdpi="90.000000"
21 inkscape:export-ydpi="90.000000"
22 inkscape:output_extension="org.inkscape.output.svg.inkscape">
23 <defs
24 id="defs1308">
25 <inkscape:perspective
26 sodipodi:type="inkscape:persp3d"
27 inkscape:vp_x="0 : 24 : 1"
28 inkscape:vp_y="0 : 1000 : 0"
29 inkscape:vp_z="48 : 24 : 1"
30 inkscape:persp3d-origin="24 : 16 : 1"
31 id="perspective62" />
32 <linearGradient
33 inkscape:collect="always"
34 id="linearGradient2243">
35 <stop
36 style="stop-color:#ffffff;stop-opacity:1;"
37 offset="0"
38 id="stop2245" />
39 <stop
40 style="stop-color:#ffffff;stop-opacity:0;"
41 offset="1"
42 id="stop2247" />
43 </linearGradient>
44 <linearGradient
45 id="linearGradient9320">
46 <stop
47 id="stop9322"
48 offset="0.0000000"
49 style="stop-color:#fef088;stop-opacity:1.0000000;" />
50 <stop
51 style="stop-color:#fde63a;stop-opacity:1.0000000;"
52 offset="0.50000000"
53 id="stop9324" />
54 <stop
55 id="stop9326"
56 offset="1.0000000"
57 style="stop-color:#dac203;stop-opacity:1.0000000;" />
58 </linearGradient>
59 <linearGradient
60 id="linearGradient8576">
61 <stop
62 style="stop-color:#dac203;stop-opacity:1.0000000;"
63 offset="0.0000000"
64 id="stop8578" />
65 <stop
66 id="stop8584"
67 offset="0.50000000"
68 style="stop-color:#fdec69;stop-opacity:1.0000000;" />
69 <stop
70 style="stop-color:#fdef7e;stop-opacity:1.0000000;"
71 offset="1.0000000"
72 id="stop8580" />
73 </linearGradient>
74 <linearGradient
75 id="linearGradient3558">
76 <stop
77 style="stop-color:#000000;stop-opacity:1;"
78 offset="0"
79 id="stop3560" />
80 <stop
81 style="stop-color:#000000;stop-opacity:0;"
82 offset="1"
83 id="stop3562" />
84 </linearGradient>
85 <radialGradient
86 inkscape:collect="always"
87 xlink:href="#linearGradient3558"
88 id="radialGradient3564"
89 cx="22.571428"
90 cy="30.857143"
91 fx="22.571428"
92 fy="30.857143"
93 r="15.571428"
94 gradientTransform="matrix(1.000000,0.000000,0.000000,0.651376,4.792388e-15,10.75754)"
95 gradientUnits="userSpaceOnUse" />
96 <linearGradient
97 id="linearGradient15303">
98 <stop
99 style="stop-color:#b30000;stop-opacity:1;"
100 offset="0"
101 id="stop15305" />
102 <stop
103 id="stop15311"
104 offset="0.5"
105 style="stop-color:#ff5c5c;stop-opacity:1;" />
106 <stop
107 style="stop-color:#c30000;stop-opacity:1;"
108 offset="1"
109 id="stop15307" />
110 </linearGradient>
111 <linearGradient
112 id="linearGradient11647">
113 <stop
114 style="stop-color:#c17d10;stop-opacity:1;"
115 offset="0"
116 id="stop11649" />
117 <stop
118 style="stop-color:#9b650c;stop-opacity:1.0000000;"
119 offset="1.0000000"
120 id="stop11651" />
121 </linearGradient>
122 <linearGradient
123 inkscape:collect="always"
124 id="linearGradient5739">
125 <stop
126 style="stop-color:#c4a000;stop-opacity:1;"
127 offset="0"
128 id="stop5741" />
129 <stop
130 style="stop-color:#c4a000;stop-opacity:0;"
131 offset="1"
132 id="stop5743" />
133 </linearGradient>
134 <linearGradient
135 inkscape:collect="always"
136 xlink:href="#linearGradient5739"
137 id="linearGradient7988"
138 gradientUnits="userSpaceOnUse"
139 gradientTransform="matrix(0.866026,-0.500000,0.797491,1.381294,-15.69909,-9.225099)"
140 x1="9.1053896"
141 y1="38.828144"
142 x2="10.146956"
143 y2="30.140831" />
144 <linearGradient
145 inkscape:collect="always"
146 xlink:href="#linearGradient5739"
147 id="linearGradient7990"
148 gradientUnits="userSpaceOnUse"
149 gradientTransform="matrix(0.866026,-0.500000,0.797961,1.382110,-15.72934,-9.277499)"
150 x1="19.616243"
151 y1="39.252983"
152 x2="18.485983"
153 y2="29.909071" />
154 <linearGradient
155 inkscape:collect="always"
156 xlink:href="#linearGradient5739"
157 id="linearGradient7992"
158 gradientUnits="userSpaceOnUse"
159 gradientTransform="matrix(0.866026,-0.500000,0.843479,1.460948,-19.74053,-11.13423)"
160 x1="15.096997"
161 y1="36.96777"
162 x2="14.045431"
163 y2="29.000000" />
164 <linearGradient
165 inkscape:collect="always"
166 xlink:href="#linearGradient5739"
167 id="linearGradient7994"
168 gradientUnits="userSpaceOnUse"
169 gradientTransform="matrix(0.866026,-0.500000,0.801305,1.387900,-12.81830,-11.14456)"
170 x1="14.045431"
171 y1="37.575890"
172 x2="14.045431"
173 y2="29.000000" />
174 <linearGradient
175 inkscape:collect="always"
176 xlink:href="#linearGradient5739"
177 id="linearGradient7996"
178 gradientUnits="userSpaceOnUse"
179 gradientTransform="matrix(0.866026,-0.500000,0.861487,1.492140,-17.87951,-13.91085)"
180 x1="16.92873"
181 y1="34.010502"
182 x2="14.045431"
183 y2="29.000000" />
184 <linearGradient
185 inkscape:collect="always"
186 xlink:href="#linearGradient11647"
187 id="linearGradient11653"
188 x1="12.233433"
189 y1="12.363223"
190 x2="16.870909"
191 y2="17.110941"
192 gradientUnits="userSpaceOnUse"
193 gradientTransform="matrix(0.965926,0.262102,-0.258819,0.978177,2.957072,-5.939741)" />
194 <linearGradient
195 inkscape:collect="always"
196 xlink:href="#linearGradient15303"
197 id="linearGradient15309"
198 x1="10.615304"
199 y1="28.122555"
200 x2="2.0069747"
201 y2="27.234833"
202 gradientUnits="userSpaceOnUse"
203 gradientTransform="matrix(1.176700,2.237102e-17,2.319843e-17,1.176702,-0.819769,-5.307055)" />
204 <linearGradient
205 inkscape:collect="always"
206 xlink:href="#linearGradient8576"
207 id="linearGradient8582"
208 x1="11.996646"
209 y1="19.591736"
210 x2="17.774033"
211 y2="16.234594"
212 gradientUnits="userSpaceOnUse"
213 gradientTransform="matrix(1.014891,0.000000,0.000000,1.005920,-0.331699,-0.140188)" />
214 <radialGradient
215 inkscape:collect="always"
216 xlink:href="#linearGradient9320"
217 id="radialGradient9318"
218 cx="20.764477"
219 cy="19.540945"
220 fx="20.764477"
221 fy="19.540945"
222 r="14.799585"
223 gradientTransform="matrix(0.449398,-0.216492,0.564416,1.171617,-1.432288,2.546108)"
224 gradientUnits="userSpaceOnUse" />
225 <linearGradient
226 inkscape:collect="always"
227 xlink:href="#linearGradient2243"
228 id="linearGradient2249"
229 x1="9.5621576"
230 y1="6.952559"
231 x2="14.766725"
232 y2="14.200403"
233 gradientUnits="userSpaceOnUse" />
234 </defs>
235 <sodipodi:namedview
236 id="base"
237 pagecolor="#ffffff"
238 bordercolor="#666666"
239 borderopacity="0.17254902"
240 inkscape:pageopacity="0.0"
241 inkscape:pageshadow="2"
242 inkscape:zoom="4"
243 inkscape:cx="9.561293"
244 inkscape:cy="43.364823"
245 inkscape:current-layer="layer1"
246 showgrid="false"
247 inkscape:grid-bbox="true"
248 inkscape:document-units="px"
249 inkscape:window-width="916"
250 inkscape:window-height="818"
251 inkscape:window-x="518"
252 inkscape:window-y="30"
253 inkscape:showpageshadow="false" />
254 <metadata
255 id="metadata1311">
256 <rdf:RDF>
257 <cc:Work
258 rdf:about="">
259 <dc:format>image/svg+xml</dc:format>
260 <dc:type
261 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
262 <dc:title>Edit Clear</dc:title>
263 <dc:creator>
264 <cc:Agent>
265 <dc:title>Andreas Nilsson</dc:title>
266 </cc:Agent>
267 </dc:creator>
268 <dc:source>http://www.tango-project.org</dc:source>
269 <dc:subject>
270 <rdf:Bag>
271 <rdf:li>clear</rdf:li>
272 <rdf:li>reset</rdf:li>
273 <rdf:li>blank</rdf:li>
274 <rdf:li>edit</rdf:li>
275 </rdf:Bag>
276 </dc:subject>
277 <cc:license
278 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
279 <dc:contributor>
280 <cc:Agent>
281 <dc:title>Jakub Steiner (although minimally ;)</dc:title>
282 </cc:Agent>
283 </dc:contributor>
284 </cc:Work>
285 <cc:License
286 rdf:about="http://creativecommons.org/licenses/publicdomain/">
287 <cc:permits
288 rdf:resource="http://creativecommons.org/ns#Reproduction" />
289 <cc:permits
290 rdf:resource="http://creativecommons.org/ns#Distribution" />
291 <cc:permits
292 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
293 </cc:License>
294 </rdf:RDF>
295 </metadata>
296 <g
297 id="layer1"
298 inkscape:label="Layer 1"
299 inkscape:groupmode="layer">
300 <path
301 sodipodi:type="arc"
302 style="opacity:0.47368421;color:#000000;fill:url(#radialGradient3564);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
303 id="path3556"
304 sodipodi:cx="22.571428"
305 sodipodi:cy="30.857143"
306 sodipodi:rx="15.571428"
307 sodipodi:ry="10.142858"
308 d="M 38.142857 30.857143 A 15.571428 10.142858 0 1 1 7,30.857143 A 15.571428 10.142858 0 1 1 38.142857 30.857143 z"
309 transform="matrix(1.435780,0.000000,0.000000,0.825704,-5.050460,13.43182)" />
310 <path
311 style="fill:url(#linearGradient11653);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#8f5902;stroke-width:1.0063211;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
312 d="M 6.9163118,1.7780186 C 8.6460876,0.8999591 11.042237,1.7815151 11.928102,3.3353385 L 16.098341,12.820053 C 16.984206,14.373873 16.731757,16.189357 15.532312,16.890639 C 14.332867,17.591922 12.654079,16.90558 11.768213,15.351758 L 5.8497502,6.9960305 C 4.9638854,5.4422066 5.2207536,2.6387087 6.9163118,1.7780186 z "
313 id="path7966"
314 sodipodi:nodetypes="cccsccz" />
315 <path
316 style="opacity:0.42307691;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2249);stroke-width:1.00569046;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
317 d="M 7.4462701,2.7359104 C 8.8682231,1.9500906 10.266975,2.5431693 11.141568,4.0752981 L 15.589706,14.162023 L 13.158185,15.581885 L 6.8615741,6.7615491 C 5.9869811,5.2294205 5.9853271,3.5432766 7.4462701,2.7359104 z "
318 id="path14575"
319 sodipodi:nodetypes="cccccz" />
320 <path
321 style="fill:url(#radialGradient9318);fill-opacity:1;fill-rule:evenodd;stroke:#c4a000;stroke-width:1.00000048;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
322 d="M 14.780848,22.793567 C 13.985353,27.080402 15.414814,36.746068 21.040081,42.487564 C 25.386835,42.628855 35.030172,39.069883 41.571176,32.290526 C 32.335,27.773816 26.034647,16.567549 21.135869,19.007852 L 14.780848,22.793567 z "
323 id="path7968"
324 sodipodi:nodetypes="ccccc" />
325 <path
326 style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:url(#linearGradient7988);stroke-width:0.99999988;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
327 d="M 16.338359,24.367274 C 18.687375,30.637545 18.827802,37.155576 23.522142,42.287158"
328 id="path7972"
329 sodipodi:nodetypes="cc" />
330 <path
331 style="opacity:0.46153846;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999976;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
332 d="M 15.91878,23.414124 C 15.006687,23.922228 15.758401,35.934338 21.503034,41.414491 C 28.88902,41.227594 37.02675,35.018304 39.895986,32.576645 C 30.39657,26.592523 24.971183,17.814876 21.415196,20.003061 L 15.91878,23.414124 z "
333 id="path7970"
334 sodipodi:nodetypes="ccccc" />
335 <path
336 style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:url(#linearGradient7990);stroke-width:0.99999970;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
337 d="M 23.848485,22.273332 C 24.714846,21.524332 29.598505,28.360999 38.846986,34.655133"
338 id="path7974"
339 sodipodi:nodetypes="cc" />
340 <path
341 style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:url(#linearGradient7992);stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
342 d="M 18.012893,22.863921 C 21.725203,28.211416 20.975883,35.288176 26.853709,40.945031"
343 id="path7976"
344 sodipodi:nodetypes="cc" />
345 <path
346 style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:url(#linearGradient7994);stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
347 d="M 22.983898,22.775821 C 22.983898,22.775821 31.160628,35.84745 34.165832,37.880382"
348 id="path7978"
349 sodipodi:nodetypes="cc" />
350 <path
351 style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:url(#linearGradient7996);stroke-width:1.0000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
352 d="M 19.300308,22.200695 C 22.747454,25.11751 28.002865,36.363883 30.610322,39.678445"
353 id="path7980"
354 sodipodi:nodetypes="cc" />
355 <path
356 style="fill:url(#linearGradient8582);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#c4a000;stroke-width:1.0103954;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
357 d="M 8.5089452,18.061866 L 19.970616,11.502960 C 20.569266,13.885531 19.628776,14.743545 21.766566,18.650673 L 13.856274,23.177313 C 12.402846,19.699893 10.291388,19.767015 8.5089452,18.061866 z "
358 id="path7982"
359 sodipodi:nodetypes="ccccc" />
360 <path
361 style="opacity:0.24725272;fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
362 d="M 14.043449,21.245689 C 13.229488,19.824472 11.481136,19.009347 10.364130,18.118460 L 19.121552,13.184722 C 19.101959,14.665690 19.688457,16.272928 19.997163,17.703389 L 14.043449,21.245689 z "
363 id="path11655"
364 sodipodi:nodetypes="ccccc" />
365 <rect
366 style="opacity:1;fill:url(#linearGradient15309);fill-opacity:1;fill-rule:evenodd;stroke:#690000;stroke-width:0.99999803;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
367 id="rect7984"
368 width="13.015023"
369 height="3.4598906"
370 x="-1.4127867"
371 y="24.174778"
372 rx="0.99999738"
373 ry="0.99999803"
374 transform="matrix(0.866025,-0.500001,0.500000,0.866026,0.000000,0.000000)" />
375 <path
376 sodipodi:type="arc"
377 style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#8f5902;stroke-width:1.65524161;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
378 id="path10193"
379 sodipodi:cx="-19.319168"
380 sodipodi:cy="4.0836182"
381 sodipodi:rx="2.1465743"
382 sodipodi:ry="2.1465743"
383 d="M -17.172594 4.0836182 A 2.1465743 2.1465743 0 1 1 -21.465742,4.0836182 A 2.1465743 2.1465743 0 1 1 -17.172594 4.0836182 z"
384 transform="matrix(0.583557,0.156364,-0.156364,0.583557,20.45782,5.158782)" />
385 <path
386 style="opacity:0.31730769;fill:#ffffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
387 d="M 27.734834,40.555239 C 27.734834,40.555239 29.241418,40.054591 29.910932,39.613484 C 28.673495,37.66894 26.507591,33.717819 24.507806,30.737564 C 25.701049,37.278302 27.734834,40.555239 27.734834,40.555239 z "
388 id="path3558"
389 sodipodi:nodetypes="cccc" />
390 <path
391 style="opacity:0.31730769;fill:#ffffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
392 d="M 31.141805,39.05827 L 33.167803,37.9731 C 31.223259,36.116945 25.699306,27.857202 25.699306,27.857202 L 31.141805,39.05827 z "
393 id="path3560"
394 sodipodi:nodetypes="cccc" />
395 <path
396 style="opacity:0.31730769;fill:#ffffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
397 d="M 35.658522,36.387809 L 38.094893,34.644057 C 34.912912,33.318232 26.508353,24.763608 26.508353,24.763608 C 28.891288,27.775503 33.275587,33.375914 35.658522,36.387809 z "
398 id="path3562"
399 sodipodi:nodetypes="cccc" />
400 <path
401 style="opacity:0.31730769;fill:#ffffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
402 d="M 39.153689,33.917208 L 40.846002,32.5077 C 37.531439,31.005098 28.350325,22.595683 28.350325,22.595683 C 28.350325,22.595683 34.424912,31.795888 39.153689,33.917208 z "
403 id="path3565"
404 sodipodi:nodetypes="cccc" />
405 <path
406 sodipodi:nodetypes="cccc"
407 id="path2265"
408 d="M 24.376076,41.571705 C 24.376076,41.571705 25.573301,41.292028 26.419592,41.116086 C 24.961184,39.878649 22.618503,36.678829 21.325825,32.505331 C 21.856156,39.399623 24.376076,41.571705 24.376076,41.571705 z "
409 style="opacity:0.31730766;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.25pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
410 <path
411 style="opacity:0.31730766;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.25pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
412 d="M 21.370872,41.969452 C 21.370872,41.969452 22.618892,41.955776 22.618892,41.955776 C 20.320795,39.436707 19.480717,36.590441 18.188038,32.549526 C 18.055457,37.234109 21.370872,41.969452 21.370872,41.969452 z "
413 id="path2267"
414 sodipodi:nodetypes="cccc" />
415 </g>
416</svg>
diff --git a/utils/rbutilqt/icons/edit-find.svg b/utils/rbutilqt/icons/edit-find.svg
new file mode 100644
index 0000000000..a499b486cf
--- /dev/null
+++ b/utils/rbutilqt/icons/edit-find.svg
@@ -0,0 +1,750 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 inkscape:export-ydpi="90.000000"
13 inkscape:export-xdpi="90.000000"
14 inkscape:export-filename="/home/steven/edit-find-48.png"
15 sodipodi:docname="edit-find.svg"
16 sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
17 inkscape:version="0.46"
18 sodipodi:version="0.32"
19 id="svg249"
20 height="48.000000px"
21 width="48.000000px"
22 inkscape:output_extension="org.inkscape.output.svg.inkscape">
23 <defs
24 id="defs3">
25 <inkscape:perspective
26 sodipodi:type="inkscape:persp3d"
27 inkscape:vp_x="0 : 24 : 1"
28 inkscape:vp_y="0 : 1000 : 0"
29 inkscape:vp_z="48 : 24 : 1"
30 inkscape:persp3d-origin="24 : 16 : 1"
31 id="perspective113" />
32 <radialGradient
33 inkscape:collect="always"
34 xlink:href="#linearGradient5060"
35 id="radialGradient5031"
36 gradientUnits="userSpaceOnUse"
37 gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
38 cx="605.71429"
39 cy="486.64789"
40 fx="605.71429"
41 fy="486.64789"
42 r="117.14286" />
43 <linearGradient
44 inkscape:collect="always"
45 id="linearGradient5060">
46 <stop
47 style="stop-color:black;stop-opacity:1;"
48 offset="0"
49 id="stop5062" />
50 <stop
51 style="stop-color:black;stop-opacity:0;"
52 offset="1"
53 id="stop5064" />
54 </linearGradient>
55 <radialGradient
56 inkscape:collect="always"
57 xlink:href="#linearGradient5060"
58 id="radialGradient5029"
59 gradientUnits="userSpaceOnUse"
60 gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
61 cx="605.71429"
62 cy="486.64789"
63 fx="605.71429"
64 fy="486.64789"
65 r="117.14286" />
66 <linearGradient
67 id="linearGradient5048">
68 <stop
69 style="stop-color:black;stop-opacity:0;"
70 offset="0"
71 id="stop5050" />
72 <stop
73 id="stop5056"
74 offset="0.5"
75 style="stop-color:black;stop-opacity:1;" />
76 <stop
77 style="stop-color:black;stop-opacity:0;"
78 offset="1"
79 id="stop5052" />
80 </linearGradient>
81 <linearGradient
82 inkscape:collect="always"
83 xlink:href="#linearGradient5048"
84 id="linearGradient5027"
85 gradientUnits="userSpaceOnUse"
86 gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
87 x1="302.85715"
88 y1="366.64789"
89 x2="302.85715"
90 y2="609.50507" />
91 <linearGradient
92 inkscape:collect="always"
93 id="linearGradient4542">
94 <stop
95 style="stop-color:#000000;stop-opacity:1;"
96 offset="0"
97 id="stop4544" />
98 <stop
99 style="stop-color:#000000;stop-opacity:0;"
100 offset="1"
101 id="stop4546" />
102 </linearGradient>
103 <linearGradient
104 id="linearGradient15662">
105 <stop
106 id="stop15664"
107 offset="0.0000000"
108 style="stop-color:#ffffff;stop-opacity:1.0000000;" />
109 <stop
110 id="stop15666"
111 offset="1.0000000"
112 style="stop-color:#f8f8f8;stop-opacity:1.0000000;" />
113 </linearGradient>
114 <radialGradient
115 id="aigrd3"
116 cx="20.8921"
117 cy="64.5679"
118 r="5.257"
119 fx="20.8921"
120 fy="64.5679"
121 gradientUnits="userSpaceOnUse">
122 <stop
123 offset="0"
124 style="stop-color:#F0F0F0"
125 id="stop15573" />
126 <stop
127 offset="1.0000000"
128 style="stop-color:#9a9a9a;stop-opacity:1.0000000;"
129 id="stop15575" />
130 </radialGradient>
131 <radialGradient
132 id="aigrd2"
133 cx="20.8921"
134 cy="114.5684"
135 r="5.256"
136 fx="20.8921"
137 fy="114.5684"
138 gradientUnits="userSpaceOnUse">
139 <stop
140 offset="0"
141 style="stop-color:#F0F0F0"
142 id="stop15566" />
143 <stop
144 offset="1.0000000"
145 style="stop-color:#9a9a9a;stop-opacity:1.0000000;"
146 id="stop15568" />
147 </radialGradient>
148 <linearGradient
149 id="linearGradient269">
150 <stop
151 id="stop270"
152 offset="0.0000000"
153 style="stop-color:#a3a3a3;stop-opacity:1.0000000;" />
154 <stop
155 id="stop271"
156 offset="1.0000000"
157 style="stop-color:#4c4c4c;stop-opacity:1.0000000;" />
158 </linearGradient>
159 <linearGradient
160 id="linearGradient259">
161 <stop
162 id="stop260"
163 offset="0.0000000"
164 style="stop-color:#fafafa;stop-opacity:1.0000000;" />
165 <stop
166 id="stop261"
167 offset="1.0000000"
168 style="stop-color:#bbbbbb;stop-opacity:1.0000000;" />
169 </linearGradient>
170 <radialGradient
171 inkscape:collect="always"
172 xlink:href="#linearGradient269"
173 id="radialGradient15656"
174 gradientUnits="userSpaceOnUse"
175 gradientTransform="matrix(0.968273,0.000000,0.000000,1.032767,3.353553,0.646447)"
176 cx="8.8244190"
177 cy="3.7561285"
178 fx="8.8244190"
179 fy="3.7561285"
180 r="37.751713" />
181 <radialGradient
182 inkscape:collect="always"
183 xlink:href="#linearGradient259"
184 id="radialGradient15658"
185 gradientUnits="userSpaceOnUse"
186 gradientTransform="scale(0.960493,1.041132)"
187 cx="33.966679"
188 cy="35.736916"
189 fx="33.966679"
190 fy="35.736916"
191 r="86.708450" />
192 <radialGradient
193 inkscape:collect="always"
194 xlink:href="#linearGradient15662"
195 id="radialGradient15668"
196 gradientUnits="userSpaceOnUse"
197 gradientTransform="matrix(0.968273,0.000000,0.000000,1.032767,3.353553,0.646447)"
198 cx="8.1435566"
199 cy="7.2678967"
200 fx="8.1435566"
201 fy="7.2678967"
202 r="38.158695" />
203 <radialGradient
204 r="5.256"
205 fy="114.5684"
206 fx="20.8921"
207 cy="114.5684"
208 cx="20.8921"
209 gradientTransform="matrix(0.229703,0.000000,0.000000,0.229703,4.613529,3.979808)"
210 gradientUnits="userSpaceOnUse"
211 id="radialGradient2283"
212 xlink:href="#aigrd2"
213 inkscape:collect="always" />
214 <radialGradient
215 r="5.257"
216 fy="64.5679"
217 fx="20.8921"
218 cy="64.5679"
219 cx="20.8921"
220 gradientTransform="matrix(0.229703,0.000000,0.000000,0.229703,4.613529,3.979808)"
221 gradientUnits="userSpaceOnUse"
222 id="radialGradient2285"
223 xlink:href="#aigrd3"
224 inkscape:collect="always" />
225 <radialGradient
226 inkscape:collect="always"
227 xlink:href="#linearGradient4542"
228 id="radialGradient4548"
229 cx="24.306795"
230 cy="42.07798"
231 fx="24.306795"
232 fy="42.07798"
233 r="15.821514"
234 gradientTransform="matrix(1.000000,0.000000,0.000000,0.284916,0.000000,30.08928)"
235 gradientUnits="userSpaceOnUse" />
236 <linearGradient
237 id="linearGradient4440">
238 <stop
239 id="stop4442"
240 offset="0"
241 style="stop-color:#7d7d7d;stop-opacity:1;" />
242 <stop
243 style="stop-color:#b1b1b1;stop-opacity:1.0000000;"
244 offset="0.50000000"
245 id="stop4448" />
246 <stop
247 id="stop4444"
248 offset="1.0000000"
249 style="stop-color:#686868;stop-opacity:1.0000000;" />
250 </linearGradient>
251 <linearGradient
252 id="linearGradient4454">
253 <stop
254 id="stop4456"
255 offset="0.0000000"
256 style="stop-color:#729fcf;stop-opacity:0.20784314;" />
257 <stop
258 id="stop4458"
259 offset="1.0000000"
260 style="stop-color:#729fcf;stop-opacity:0.67619050;" />
261 </linearGradient>
262 <linearGradient
263 id="linearGradient4467">
264 <stop
265 id="stop4469"
266 offset="0"
267 style="stop-color:#ffffff;stop-opacity:1;" />
268 <stop
269 id="stop4471"
270 offset="1.0000000"
271 style="stop-color:#ffffff;stop-opacity:0.24761905;" />
272 </linearGradient>
273 <linearGradient
274 id="linearGradient4477"
275 inkscape:collect="always">
276 <stop
277 id="stop4479"
278 offset="0"
279 style="stop-color:#000000;stop-opacity:1;" />
280 <stop
281 id="stop4481"
282 offset="1"
283 style="stop-color:#000000;stop-opacity:0;" />
284 </linearGradient>
285 <linearGradient
286 id="linearGradient2366">
287 <stop
288 style="stop-color:#ffffff;stop-opacity:1;"
289 offset="0"
290 id="stop2368" />
291 <stop
292 id="stop2374"
293 offset="0.50000000"
294 style="stop-color:#ffffff;stop-opacity:0.21904762;" />
295 <stop
296 style="stop-color:#ffffff;stop-opacity:1.0000000;"
297 offset="1.0000000"
298 id="stop2370" />
299 </linearGradient>
300 <linearGradient
301 id="linearGradient2846">
302 <stop
303 style="stop-color:#8a8a8a;stop-opacity:1.0000000;"
304 offset="0.0000000"
305 id="stop2848" />
306 <stop
307 style="stop-color:#484848;stop-opacity:1.0000000;"
308 offset="1.0000000"
309 id="stop2850" />
310 </linearGradient>
311 <radialGradient
312 inkscape:collect="always"
313 xlink:href="#linearGradient4477"
314 id="radialGradient1527"
315 gradientUnits="userSpaceOnUse"
316 gradientTransform="matrix(1.000000,0.000000,0.000000,0.237968,-8.821068e-16,28.93278)"
317 cx="24.130018"
318 cy="37.967922"
319 fx="24.130018"
320 fy="37.967922"
321 r="16.528622" />
322 <linearGradient
323 inkscape:collect="always"
324 xlink:href="#linearGradient2846"
325 id="linearGradient1529"
326 gradientUnits="userSpaceOnUse"
327 x1="27.366341"
328 y1="26.580296"
329 x2="31.335964"
330 y2="30.557772" />
331 <linearGradient
332 inkscape:collect="always"
333 xlink:href="#linearGradient4440"
334 id="linearGradient1531"
335 gradientUnits="userSpaceOnUse"
336 gradientTransform="matrix(1.334593,0.000000,0.000000,1.291292,-6.973842,-7.460658)"
337 x1="30.656250"
338 y1="34.000000"
339 x2="33.218750"
340 y2="31.062500" />
341 <linearGradient
342 inkscape:collect="always"
343 xlink:href="#linearGradient2366"
344 id="linearGradient1533"
345 gradientUnits="userSpaceOnUse"
346 x1="18.292673"
347 y1="13.602121"
348 x2="17.500893"
349 y2="25.743469" />
350 <radialGradient
351 inkscape:collect="always"
352 xlink:href="#linearGradient4454"
353 id="radialGradient1537"
354 gradientUnits="userSpaceOnUse"
355 cx="18.240929"
356 cy="21.817987"
357 fx="18.240929"
358 fy="21.817987"
359 r="8.3085051" />
360 <radialGradient
361 inkscape:collect="always"
362 xlink:href="#linearGradient4467"
363 id="radialGradient1539"
364 gradientUnits="userSpaceOnUse"
365 gradientTransform="matrix(2.592963,-7.746900e-24,-5.714443e-24,2.252104,-25.05975,-18.94100)"
366 cx="15.414371"
367 cy="13.078408"
368 fx="15.414371"
369 fy="13.078408"
370 r="6.6562500" />
371 </defs>
372 <sodipodi:namedview
373 inkscape:window-y="30"
374 inkscape:window-x="418"
375 inkscape:window-height="818"
376 inkscape:window-width="1016"
377 inkscape:document-units="px"
378 inkscape:grid-bbox="true"
379 showgrid="true"
380 inkscape:current-layer="layer6"
381 inkscape:cy="14.980943"
382 inkscape:cx="25.938708"
383 inkscape:zoom="1"
384 inkscape:pageshadow="2"
385 inkscape:pageopacity="0.0"
386 borderopacity="0.25490196"
387 bordercolor="#666666"
388 pagecolor="#ffffff"
389 id="base"
390 inkscape:showpageshadow="false" />
391 <metadata
392 id="metadata4">
393 <rdf:RDF>
394 <cc:Work
395 rdf:about="">
396 <dc:format>image/svg+xml</dc:format>
397 <dc:type
398 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
399 <dc:title>Edit Find</dc:title>
400 <dc:subject>
401 <rdf:Bag>
402 <rdf:li>edit</rdf:li>
403 <rdf:li>find</rdf:li>
404 <rdf:li>locate</rdf:li>
405 <rdf:li>search</rdf:li>
406 </rdf:Bag>
407 </dc:subject>
408 <cc:license
409 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
410 <dc:creator>
411 <cc:Agent>
412 <dc:title>Steven Garrity</dc:title>
413 </cc:Agent>
414 </dc:creator>
415 <dc:source />
416 <dc:contributor>
417 <cc:Agent>
418 <dc:title>Jakub Steiner</dc:title>
419 </cc:Agent>
420 </dc:contributor>
421 </cc:Work>
422 <cc:License
423 rdf:about="http://creativecommons.org/licenses/publicdomain/">
424 <cc:permits
425 rdf:resource="http://creativecommons.org/ns#Reproduction" />
426 <cc:permits
427 rdf:resource="http://creativecommons.org/ns#Distribution" />
428 <cc:permits
429 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
430 </cc:License>
431 </rdf:RDF>
432 </metadata>
433 <g
434 inkscape:groupmode="layer"
435 id="layer6"
436 inkscape:label="Shadow">
437 <g
438 style="display:inline"
439 id="g5022"
440 transform="matrix(2.165152e-2,0,0,1.485743e-2,43.0076,42.68539)">
441 <rect
442 y="-150.69685"
443 x="-1559.2523"
444 height="478.35718"
445 width="1339.6335"
446 id="rect4173"
447 style="opacity:0.40206185;color:black;fill:url(#linearGradient5027);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
448 <path
449 sodipodi:nodetypes="cccc"
450 id="path5058"
451 d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
452 style="opacity:0.40206185;color:black;fill:url(#radialGradient5029);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
453 <path
454 style="opacity:0.40206185;color:black;fill:url(#radialGradient5031);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
455 d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
456 id="path5018"
457 sodipodi:nodetypes="cccc" />
458 </g>
459 </g>
460 <g
461 style="display:inline"
462 inkscape:groupmode="layer"
463 inkscape:label="Base"
464 id="layer1">
465 <rect
466 style="color:#000000;fill:url(#radialGradient15658);fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#radialGradient15656);stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
467 id="rect15391"
468 width="34.875000"
469 height="40.920494"
470 x="6.6035528"
471 y="3.6464462"
472 ry="1.1490486" />
473 <rect
474 style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#radialGradient15668);stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
475 id="rect15660"
476 width="32.775887"
477 height="38.946384"
478 x="7.6660538"
479 y="4.5839462"
480 ry="0.14904857"
481 rx="0.14904857" />
482 <g
483 transform="translate(0.646447,-3.798933e-2)"
484 id="g2270">
485 <g
486 id="g1440"
487 style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:#000000;stroke-miterlimit:4.0000000"
488 transform="matrix(0.229703,0.000000,0.000000,0.229703,4.967081,4.244972)">
489 <radialGradient
490 id="radialGradient1442"
491 cx="20.892099"
492 cy="114.56840"
493 r="5.2560000"
494 fx="20.892099"
495 fy="114.56840"
496 gradientUnits="userSpaceOnUse">
497 <stop
498 offset="0"
499 style="stop-color:#F0F0F0"
500 id="stop1444" />
501 <stop
502 offset="1"
503 style="stop-color:#474747"
504 id="stop1446" />
505 </radialGradient>
506 <path
507 style="stroke:none"
508 d="M 23.428000,113.07000 C 23.428000,115.04300 21.828000,116.64200 19.855000,116.64200 C 17.881000,116.64200 16.282000,115.04200 16.282000,113.07000 C 16.282000,111.09600 17.882000,109.49700 19.855000,109.49700 C 21.828000,109.49700 23.428000,111.09700 23.428000,113.07000 z "
509 id="path1448" />
510 <radialGradient
511 id="radialGradient1450"
512 cx="20.892099"
513 cy="64.567902"
514 r="5.2570000"
515 fx="20.892099"
516 fy="64.567902"
517 gradientUnits="userSpaceOnUse">
518 <stop
519 offset="0"
520 style="stop-color:#F0F0F0"
521 id="stop1452" />
522 <stop
523 offset="1"
524 style="stop-color:#474747"
525 id="stop1454" />
526 </radialGradient>
527 <path
528 style="stroke:none"
529 d="M 23.428000,63.070000 C 23.428000,65.043000 21.828000,66.643000 19.855000,66.643000 C 17.881000,66.643000 16.282000,65.043000 16.282000,63.070000 C 16.282000,61.096000 17.882000,59.497000 19.855000,59.497000 C 21.828000,59.497000 23.428000,61.097000 23.428000,63.070000 z "
530 id="path1456" />
531 </g>
532 <path
533 style="fill:url(#radialGradient2283);fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
534 d="M 9.9950109,29.952326 C 9.9950109,30.405530 9.6274861,30.772825 9.1742821,30.772825 C 8.7208483,30.772825 8.3535532,30.405301 8.3535532,29.952326 C 8.3535532,29.498892 8.7210780,29.131597 9.1742821,29.131597 C 9.6274861,29.131597 9.9950109,29.499122 9.9950109,29.952326 z "
535 id="path15570" />
536 <path
537 style="fill:url(#radialGradient2285);fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
538 d="M 9.9950109,18.467176 C 9.9950109,18.920380 9.6274861,19.287905 9.1742821,19.287905 C 8.7208483,19.287905 8.3535532,18.920380 8.3535532,18.467176 C 8.3535532,18.013742 8.7210780,17.646447 9.1742821,17.646447 C 9.6274861,17.646447 9.9950109,18.013972 9.9950109,18.467176 z "
539 id="path15577" />
540 </g>
541 <path
542 style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.98855311;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:0.017543854"
543 d="M 11.505723,5.4942766 L 11.505723,43.400869"
544 id="path15672"
545 sodipodi:nodetypes="cc" />
546 <path
547 style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:0.20467831"
548 d="M 12.500000,5.0205154 L 12.500000,43.038228"
549 id="path15674"
550 sodipodi:nodetypes="cc" />
551 </g>
552 <g
553 inkscape:groupmode="layer"
554 id="layer5"
555 inkscape:label="Magnifying Glass"
556 style="display:inline">
557 <g
558 transform="matrix(0.909091,0.000000,0.000000,1.000000,2.363628,0.000000)"
559 id="g2253">
560 <rect
561 style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
562 id="rect15686"
563 width="22.000004"
564 height="1.0000000"
565 x="15.000002"
566 y="9.0000000"
567 rx="0.15156493"
568 ry="0.065390877" />
569 <rect
570 style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
571 id="rect15688"
572 width="22.000004"
573 height="1.0000000"
574 x="15.000002"
575 y="11.000000"
576 rx="0.15156493"
577 ry="0.065390877" />
578 <rect
579 style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
580 id="rect15690"
581 width="22.000004"
582 height="1.0000000"
583 x="15.000002"
584 y="13.000000"
585 rx="0.15156493"
586 ry="0.065390877" />
587 <rect
588 style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
589 id="rect15692"
590 width="22.000004"
591 height="1.0000000"
592 x="15.000002"
593 y="15.000000"
594 rx="0.15156493"
595 ry="0.065390877" />
596 <rect
597 style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
598 id="rect15694"
599 width="22.000004"
600 height="1.0000000"
601 x="15.000002"
602 y="17.000000"
603 rx="0.15156493"
604 ry="0.065390877" />
605 <rect
606 style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
607 id="rect15696"
608 width="22.000004"
609 height="1.0000000"
610 x="15.000002"
611 y="19.000000"
612 rx="0.15156493"
613 ry="0.065390877" />
614 <rect
615 style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
616 id="rect15698"
617 width="22.000004"
618 height="1.0000000"
619 x="15.000002"
620 y="21.000000"
621 rx="0.15156493"
622 ry="0.065390877" />
623 <rect
624 style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
625 id="rect15700"
626 width="22.000004"
627 height="1.0000000"
628 x="15.000002"
629 y="23.000000"
630 rx="0.15156493"
631 ry="0.065390877" />
632 <rect
633 style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
634 id="rect15732"
635 width="9.9000053"
636 height="1.0000000"
637 x="14.999992"
638 y="25.000000"
639 rx="0.068204239"
640 ry="0.065390877" />
641 <rect
642 style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
643 id="rect15736"
644 width="22.000004"
645 height="1.0000000"
646 x="14.999992"
647 y="29.000000"
648 rx="0.15156493"
649 ry="0.065390877" />
650 <rect
651 style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
652 id="rect15738"
653 width="22.000004"
654 height="1.0000000"
655 x="14.999992"
656 y="31.000000"
657 rx="0.15156493"
658 ry="0.065390877" />
659 <rect
660 style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
661 id="rect15740"
662 width="22.000004"
663 height="1.0000000"
664 x="14.999992"
665 y="33.000000"
666 rx="0.15156493"
667 ry="0.065390877" />
668 <rect
669 style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
670 id="rect15742"
671 width="22.000004"
672 height="1.0000000"
673 x="14.999992"
674 y="35.000000"
675 rx="0.15156493"
676 ry="0.065390877" />
677 <rect
678 style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
679 id="rect15744"
680 width="15.400014"
681 height="1.0000000"
682 x="14.999992"
683 y="37.000000"
684 rx="0.10609552"
685 ry="0.065390877" />
686 </g>
687 <g
688 id="g1772"
689 transform="matrix(0.665377,0.000000,0.000000,0.665377,15.98645,17.90835)">
690 <path
691 sodipodi:type="arc"
692 style="opacity:0.17112298;color:#000000;fill:url(#radialGradient1527);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
693 id="path4475"
694 sodipodi:cx="24.130018"
695 sodipodi:cy="37.967922"
696 sodipodi:rx="16.528622"
697 sodipodi:ry="3.9332814"
698 d="M 40.658640 37.967922 A 16.528622 3.9332814 0 1 1 7.6013966,37.967922 A 16.528622 3.9332814 0 1 1 40.658640 37.967922 z"
699 transform="matrix(1.446431,0.000000,0.000000,1.519990,-10.97453,-17.75168)" />
700 <path
701 sodipodi:nodetypes="csscccscccscczzzz"
702 id="path2844"
703 d="M 18.627569,3.1435548 C 10.488439,3.1435548 3.8827682,9.7492259 3.8827682,17.888356 C 3.8827682,26.027486 10.488439,32.633158 18.627569,32.633158 C 22.107124,32.633158 25.178570,31.248765 27.701292,29.230511 C 27.495915,30.237392 27.623257,31.265879 28.457436,31.990436 L 39.421520,41.517846 C 40.654936,42.589175 42.508982,42.448806 43.580310,41.215389 C 44.651638,39.981971 44.511269,38.127927 43.277853,37.056599 L 32.313769,27.529188 C 31.642242,26.945909 30.820891,26.773219 30.007531,26.886466 C 31.994231,24.374044 33.372370,21.337663 33.372370,17.888356 C 33.372370,9.7492259 26.766699,3.1435548 18.627569,3.1435548 z M 18.551954,4.3697381 C 26.191413,4.3697381 31.843729,9.1586886 31.843729,17.661513 C 31.843729,26.336626 26.027039,30.953288 18.551954,30.953288 C 11.249005,30.953288 5.2601806,25.475196 5.2601806,17.661513 C 5.2601806,9.6774061 11.084819,4.3697380 18.551954,4.3697381 z "
704 style="opacity:1.0000000;color:#000000;fill:#dcdcdc;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient1529);stroke-width:3.0058157;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
705 <path
706 style="opacity:1.0000000;color:#000000;fill:#dcdcdc;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000004;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
707 d="M 18.602905,3.0803551 C 10.437465,3.0803551 3.8104408,9.7073791 3.8104408,17.872819 C 3.8104408,26.038259 10.437465,32.665283 18.602905,32.665283 C 22.093708,32.665283 25.175082,31.276416 27.705960,29.251638 C 27.499919,30.261774 27.627672,31.293585 28.464547,32.020484 L 39.464073,41.578691 C 40.701476,42.653483 42.561515,42.512661 43.636306,41.275256 C 44.711097,40.037852 44.570274,38.177814 43.332871,37.103023 L 32.333346,27.544815 C 31.659648,26.959651 30.835642,26.786402 30.019653,26.900016 C 32.012775,24.379472 33.395369,21.333276 33.395369,17.872819 C 33.395369,9.7073791 26.768345,3.0803551 18.602905,3.0803551 z M 18.527046,6.2664243 C 24.808154,6.2664245 29.905864,11.364135 29.905864,17.645243 C 29.905864,23.926351 24.808154,29.024061 18.527046,29.024061 C 12.245938,29.024061 7.1482276,23.926351 7.1482276,17.645243 C 7.1482278,11.364135 12.245938,6.2664243 18.527046,6.2664243 z "
708 id="path4430" />
709 <path
710 style="opacity:1.0000000;color:#000000;fill:url(#linearGradient1531);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
711 d="M 39.507004,41.577690 C 39.028332,39.304503 40.904334,36.766268 43.091057,36.789315 C 43.091057,36.789315 32.330690,27.531204 32.330690,27.531204 C 29.385899,27.474498 28.061188,29.803820 28.553876,32.131126 L 39.507004,41.577690 z "
712 id="path4438"
713 sodipodi:nodetypes="ccccc" />
714 <path
715 sodipodi:type="arc"
716 style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient1533);stroke-width:1.2064340;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
717 id="path4450"
718 sodipodi:cx="17.500893"
719 sodipodi:cy="18.920233"
720 sodipodi:rx="11.048544"
721 sodipodi:ry="11.048544"
722 d="M 28.549437 18.920233 A 11.048544 11.048544 0 1 1 6.4523487,18.920233 A 11.048544 11.048544 0 1 1 28.549437 18.920233 z"
723 transform="matrix(1.245743,0.000000,0.000000,1.245743,-3.425346,-6.177033)" />
724 <rect
725 style="opacity:0.43315509;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.5029539;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
726 id="rect4495"
727 width="19.048439"
728 height="4.4404783"
729 x="40.373337"
730 y="0.14086054"
731 rx="3.2112026"
732 ry="2.8373930"
733 transform="matrix(0.752986,0.658037,-0.648902,0.760872,0.000000,0.000000)" />
734 <path
735 sodipodi:type="arc"
736 style="color:#000000;fill:url(#radialGradient1537);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#3063a3;stroke-width:1.0745695;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible"
737 id="path4452"
738 sodipodi:cx="17.589281"
739 sodipodi:cy="18.478292"
740 sodipodi:rx="8.3085051"
741 sodipodi:ry="8.3085051"
742 d="M 25.897786 18.478292 A 8.3085051 8.3085051 0 1 1 9.2807760,18.478292 A 8.3085051 8.3085051 0 1 1 25.897786 18.478292 z"
743 transform="matrix(1.398614,0.000000,0.000000,1.398614,-6.224338,-8.298958)" />
744 <path
745 style="opacity:0.83422458;color:#000000;fill:url(#radialGradient1539);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
746 d="M 18.156915,7.3966938 C 12.949325,7.3966938 8.7323681,11.613651 8.7323681,16.821241 C 8.7323681,18.325216 9.1526753,19.709014 9.7795400,20.971144 C 11.031920,21.432757 12.362297,21.746827 13.774307,21.746827 C 19.945262,21.746827 24.873589,16.885190 25.254413,10.809698 C 23.523449,8.7641668 21.044374,7.3966938 18.156915,7.3966938 z "
747 id="path4462" />
748 </g>
749 </g>
750</svg>
diff --git a/utils/rbutilqt/icons/go-next.svg b/utils/rbutilqt/icons/go-next.svg
new file mode 100644
index 0000000000..41e5990b8f
--- /dev/null
+++ b/utils/rbutilqt/icons/go-next.svg
@@ -0,0 +1,192 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 sodipodi:docname="go-next.svg"
13 sodipodi:docbase="/home/tigert/cvs/freedesktop.org/tango-icon-theme/scalable/actions"
14 inkscape:version="0.46"
15 sodipodi:version="0.32"
16 id="svg11300"
17 height="48"
18 width="48"
19 inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
20 inkscape:export-xdpi="90.000000"
21 inkscape:export-ydpi="90.000000"
22 version="1.0"
23 inkscape:output_extension="org.inkscape.output.svg.inkscape">
24 <defs
25 id="defs3">
26 <inkscape:perspective
27 sodipodi:type="inkscape:persp3d"
28 inkscape:vp_x="0 : 24 : 1"
29 inkscape:vp_y="0 : 1000 : 0"
30 inkscape:vp_z="48 : 24 : 1"
31 inkscape:persp3d-origin="24 : 16 : 1"
32 id="perspective23" />
33 <linearGradient
34 id="linearGradient2591">
35 <stop
36 style="stop-color:#73d216"
37 offset="0"
38 id="stop2593" />
39 <stop
40 style="stop-color:#4e9a06"
41 offset="1.0000000"
42 id="stop2595" />
43 </linearGradient>
44 <linearGradient
45 id="linearGradient8662"
46 inkscape:collect="always">
47 <stop
48 id="stop8664"
49 offset="0"
50 style="stop-color:#000000;stop-opacity:1;" />
51 <stop
52 id="stop8666"
53 offset="1"
54 style="stop-color:#000000;stop-opacity:0;" />
55 </linearGradient>
56 <linearGradient
57 id="linearGradient8650"
58 inkscape:collect="always">
59 <stop
60 id="stop8652"
61 offset="0"
62 style="stop-color:#ffffff;stop-opacity:1;" />
63 <stop
64 id="stop8654"
65 offset="1"
66 style="stop-color:#ffffff;stop-opacity:0;" />
67 </linearGradient>
68 <radialGradient
69 gradientUnits="userSpaceOnUse"
70 gradientTransform="matrix(2.046729,-3.749427e-16,2.853404e-16,1.557610,-19.51799,3.452086)"
71 r="17.171415"
72 fy="2.8969381"
73 fx="19.701141"
74 cy="2.8969381"
75 cx="19.701141"
76 id="radialGradient8656"
77 xlink:href="#linearGradient8650"
78 inkscape:collect="always" />
79 <radialGradient
80 gradientUnits="userSpaceOnUse"
81 gradientTransform="matrix(1.000000,0.000000,0.000000,0.536723,2.511012e-15,16.87306)"
82 r="15.644737"
83 fy="36.421127"
84 fx="24.837126"
85 cy="36.421127"
86 cx="24.837126"
87 id="radialGradient8668"
88 xlink:href="#linearGradient8662"
89 inkscape:collect="always" />
90 <radialGradient
91 inkscape:collect="always"
92 xlink:href="#linearGradient2591"
93 id="radialGradient2597"
94 cx="22.291636"
95 cy="32.797512"
96 fx="22.291636"
97 fy="32.797512"
98 r="16.9562"
99 gradientTransform="matrix(0.843022,1.871885e-16,-2.265228e-16,1.020168,4.499298,1.381992)"
100 gradientUnits="userSpaceOnUse" />
101 </defs>
102 <sodipodi:namedview
103 inkscape:window-y="30"
104 inkscape:window-x="0"
105 inkscape:window-height="818"
106 inkscape:window-width="1280"
107 inkscape:showpageshadow="false"
108 inkscape:document-units="px"
109 inkscape:grid-bbox="true"
110 showgrid="false"
111 inkscape:current-layer="layer1"
112 inkscape:cy="27.398876"
113 inkscape:cx="20.508639"
114 inkscape:zoom="11.313708"
115 inkscape:pageshadow="2"
116 inkscape:pageopacity="0.0"
117 borderopacity="0.25490196"
118 bordercolor="#666666"
119 pagecolor="#ffffff"
120 id="base"
121 fill="#4e9a06"
122 stroke="#4e9a06" />
123 <metadata
124 id="metadata4">
125 <rdf:RDF>
126 <cc:Work
127 rdf:about="">
128 <dc:format>image/svg+xml</dc:format>
129 <dc:type
130 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
131 <dc:creator>
132 <cc:Agent>
133 <dc:title>Jakub Steiner</dc:title>
134 </cc:Agent>
135 </dc:creator>
136 <dc:source>http://jimmac.musichall.cz</dc:source>
137 <cc:license
138 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
139 <dc:title>Go Next</dc:title>
140 <dc:subject>
141 <rdf:Bag>
142 <rdf:li>go</rdf:li>
143 <rdf:li>next</rdf:li>
144 <rdf:li>right</rdf:li>
145 <rdf:li>arrow</rdf:li>
146 <rdf:li>pointer</rdf:li>
147 <rdf:li>&gt;</rdf:li>
148 </rdf:Bag>
149 </dc:subject>
150 </cc:Work>
151 <cc:License
152 rdf:about="http://creativecommons.org/licenses/publicdomain/">
153 <cc:permits
154 rdf:resource="http://creativecommons.org/ns#Reproduction" />
155 <cc:permits
156 rdf:resource="http://creativecommons.org/ns#Distribution" />
157 <cc:permits
158 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
159 </cc:License>
160 </rdf:RDF>
161 </metadata>
162 <g
163 inkscape:groupmode="layer"
164 inkscape:label="Layer 1"
165 id="layer1">
166 <path
167 transform="matrix(1.271186,0.000000,0.000000,1.271186,-8.119376,-15.10179)"
168 d="M 40.481863 36.421127 A 15.644737 8.3968935 0 1 1 9.1923885,36.421127 A 15.644737 8.3968935 0 1 1 40.481863 36.421127 z"
169 sodipodi:ry="8.3968935"
170 sodipodi:rx="15.644737"
171 sodipodi:cy="36.421127"
172 sodipodi:cx="24.837126"
173 id="path8660"
174 style="opacity:0.29946522;color:#000000;fill:url(#radialGradient8668);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
175 sodipodi:type="arc" />
176 <path
177 sodipodi:nodetypes="cccccccc"
178 id="path8643"
179 d="M 8.5541875,15.517348 L 8.5541875,32.511768 L 21.538,32.511768 L 21.538,41.056806 L 41.497835,24.150365 L 21.41919,7.1251168 L 21.41919,15.522652 L 8.5541875,15.517348 z "
180 style="opacity:1;color:#000000;fill:url(#radialGradient2597);fill-opacity:1;fill-rule:evenodd;stroke:#3a7304;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
181 <path
182 sodipodi:nodetypes="cccccc"
183 id="path8645"
184 d="M 21.962385,8.2485033 L 21.962385,16.054978 L 9.1452151,16.054978 L 9.1452151,25.095691 C 26.895215,27.095691 25.778752,17.640403 40.528752,24.140403 L 21.962385,8.2485033 z "
185 style="opacity:0.5080214;color:#000000;fill:url(#radialGradient8656);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
186 <path
187 style="opacity:0.48128339;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000036;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
188 d="M 9.537702,16.561892 L 9.537702,31.546332 L 22.523069,31.546332 L 22.523069,38.941498 L 40.001083,24.145807 L 22.507108,9.3654066 L 22.507108,16.566789 L 9.537702,16.561892 z "
189 id="path8658"
190 sodipodi:nodetypes="cccccccc" />
191 </g>
192</svg>
diff --git a/utils/rbutilqt/icons/input-gaming.svg b/utils/rbutilqt/icons/input-gaming.svg
new file mode 100644
index 0000000000..5909a53eaf
--- /dev/null
+++ b/utils/rbutilqt/icons/input-gaming.svg
@@ -0,0 +1,530 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 sodipodi:docname="input-gaming.svg"
13 sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/devices"
14 inkscape:version="0.46"
15 sodipodi:version="0.32"
16 id="svg2913"
17 height="48px"
18 width="48px"
19 inkscape:output_extension="org.inkscape.output.svg.inkscape">
20 <defs
21 id="defs3">
22 <inkscape:perspective
23 sodipodi:type="inkscape:persp3d"
24 inkscape:vp_x="0 : 24 : 1"
25 inkscape:vp_y="0 : 1000 : 0"
26 inkscape:vp_z="48 : 24 : 1"
27 inkscape:persp3d-origin="24 : 16 : 1"
28 id="perspective79" />
29 <radialGradient
30 inkscape:collect="always"
31 xlink:href="#linearGradient5060"
32 id="radialGradient6719"
33 gradientUnits="userSpaceOnUse"
34 gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
35 cx="605.71429"
36 cy="486.64789"
37 fx="605.71429"
38 fy="486.64789"
39 r="117.14286" />
40 <linearGradient
41 inkscape:collect="always"
42 id="linearGradient5060">
43 <stop
44 style="stop-color:black;stop-opacity:1;"
45 offset="0"
46 id="stop5062" />
47 <stop
48 style="stop-color:black;stop-opacity:0;"
49 offset="1"
50 id="stop5064" />
51 </linearGradient>
52 <radialGradient
53 inkscape:collect="always"
54 xlink:href="#linearGradient5060"
55 id="radialGradient6717"
56 gradientUnits="userSpaceOnUse"
57 gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
58 cx="605.71429"
59 cy="486.64789"
60 fx="605.71429"
61 fy="486.64789"
62 r="117.14286" />
63 <linearGradient
64 id="linearGradient5048">
65 <stop
66 style="stop-color:black;stop-opacity:0;"
67 offset="0"
68 id="stop5050" />
69 <stop
70 id="stop5056"
71 offset="0.5"
72 style="stop-color:black;stop-opacity:1;" />
73 <stop
74 style="stop-color:black;stop-opacity:0;"
75 offset="1"
76 id="stop5052" />
77 </linearGradient>
78 <linearGradient
79 inkscape:collect="always"
80 xlink:href="#linearGradient5048"
81 id="linearGradient6715"
82 gradientUnits="userSpaceOnUse"
83 gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
84 x1="302.85715"
85 y1="366.64789"
86 x2="302.85715"
87 y2="609.50507" />
88 <linearGradient
89 id="linearGradient2510"
90 inkscape:collect="always">
91 <stop
92 id="stop2512"
93 offset="0"
94 style="stop-color:#ffffff;stop-opacity:1;" />
95 <stop
96 id="stop2514"
97 offset="1"
98 style="stop-color:#ffffff;stop-opacity:0;" />
99 </linearGradient>
100 <linearGradient
101 id="linearGradient5411"
102 inkscape:collect="always">
103 <stop
104 id="stop5413"
105 offset="0"
106 style="stop-color:#ffffff;stop-opacity:1;" />
107 <stop
108 id="stop5415"
109 offset="1"
110 style="stop-color:#ffffff;stop-opacity:0;" />
111 </linearGradient>
112 <linearGradient
113 id="linearGradient5069"
114 inkscape:collect="always">
115 <stop
116 id="stop5071"
117 offset="0"
118 style="stop-color:#000000;stop-opacity:1;" />
119 <stop
120 id="stop5073"
121 offset="1"
122 style="stop-color:#000000;stop-opacity:0;" />
123 </linearGradient>
124 <linearGradient
125 id="linearGradient5018">
126 <stop
127 id="stop5020"
128 offset="0"
129 style="stop-color:#aaaaaa;stop-opacity:1;" />
130 <stop
131 id="stop5022"
132 offset="1.0000000"
133 style="stop-color:#cdcdcd;stop-opacity:1.0000000;" />
134 </linearGradient>
135 <linearGradient
136 id="linearGradient4990">
137 <stop
138 id="stop4992"
139 offset="0.0000000"
140 style="stop-color:#ff8a2b;stop-opacity:1.0000000;" />
141 <stop
142 id="stop4994"
143 offset="1.0000000"
144 style="stop-color:#833a00;stop-opacity:1.0000000;" />
145 </linearGradient>
146 <linearGradient
147 id="linearGradient4264"
148 inkscape:collect="always">
149 <stop
150 id="stop4266"
151 offset="0"
152 style="stop-color:#000000;stop-opacity:1;" />
153 <stop
154 id="stop4268"
155 offset="1"
156 style="stop-color:#000000;stop-opacity:0;" />
157 </linearGradient>
158 <linearGradient
159 id="linearGradient4254"
160 inkscape:collect="always">
161 <stop
162 id="stop4256"
163 offset="0"
164 style="stop-color:#ffffff;stop-opacity:1;" />
165 <stop
166 id="stop4258"
167 offset="1"
168 style="stop-color:#ffffff;stop-opacity:0;" />
169 </linearGradient>
170 <linearGradient
171 id="linearGradient4244">
172 <stop
173 id="stop4246"
174 offset="0.0000000"
175 style="stop-color:#e4e4e4;stop-opacity:1.0000000;" />
176 <stop
177 id="stop4248"
178 offset="1.0000000"
179 style="stop-color:#d3d3d3;stop-opacity:1.0000000;" />
180 </linearGradient>
181 <linearGradient
182 id="linearGradient4228">
183 <stop
184 id="stop4230"
185 offset="0.0000000"
186 style="stop-color:#bbbbbb;stop-opacity:1.0000000;" />
187 <stop
188 id="stop4232"
189 offset="1.0000000"
190 style="stop-color:#9f9f9f;stop-opacity:1.0000000;" />
191 </linearGradient>
192 <radialGradient
193 inkscape:collect="always"
194 xlink:href="#linearGradient4264"
195 id="radialGradient1464"
196 gradientUnits="userSpaceOnUse"
197 gradientTransform="matrix(1.000000,0.000000,0.000000,0.651032,-8.174347e-16,9.455693)"
198 cx="23.201941"
199 cy="27.096155"
200 fx="23.201941"
201 fy="27.096155"
202 r="23.555494" />
203 <radialGradient
204 inkscape:collect="always"
205 xlink:href="#linearGradient5069"
206 id="radialGradient1470"
207 gradientUnits="userSpaceOnUse"
208 gradientTransform="matrix(1.000000,0.000000,0.000000,0.624277,0.000000,12.28944)"
209 cx="10.363534"
210 cy="32.708817"
211 fx="10.363534"
212 fy="32.708817"
213 r="3.8227961" />
214 <linearGradient
215 inkscape:collect="always"
216 xlink:href="#linearGradient5411"
217 id="linearGradient1476"
218 gradientUnits="userSpaceOnUse"
219 x1="24.237061"
220 y1="31.712437"
221 x2="24.237061"
222 y2="28.359171" />
223 <linearGradient
224 inkscape:collect="always"
225 xlink:href="#linearGradient4990"
226 id="linearGradient1482"
227 gradientUnits="userSpaceOnUse"
228 x1="23.599133"
229 y1="3.4934268"
230 x2="26.032751"
231 y2="13.095204" />
232 <linearGradient
233 inkscape:collect="always"
234 xlink:href="#linearGradient4990"
235 id="linearGradient1484"
236 gradientUnits="userSpaceOnUse"
237 x1="24.395184"
238 y1="11.509590"
239 x2="17.766058"
240 y2="-6.4607105" />
241 <linearGradient
242 inkscape:collect="always"
243 xlink:href="#linearGradient2510"
244 id="linearGradient1489"
245 gradientUnits="userSpaceOnUse"
246 x1="21.057629"
247 y1="2.4374962"
248 x2="26.286110"
249 y2="29.562496" />
250 <linearGradient
251 inkscape:collect="always"
252 xlink:href="#linearGradient5018"
253 id="linearGradient1496"
254 gradientUnits="userSpaceOnUse"
255 gradientTransform="translate(0.000000,-0.625000)"
256 x1="26.312500"
257 y1="17.500000"
258 x2="23.062500"
259 y2="17.500000" />
260 <linearGradient
261 inkscape:collect="always"
262 xlink:href="#linearGradient5018"
263 id="linearGradient1501"
264 gradientUnits="userSpaceOnUse"
265 gradientTransform="translate(0.000000,-0.625000)"
266 x1="28.468750"
267 y1="28.125000"
268 x2="20.000000"
269 y2="26.375000" />
270 <linearGradient
271 inkscape:collect="always"
272 xlink:href="#linearGradient4254"
273 id="linearGradient1507"
274 gradientUnits="userSpaceOnUse"
275 gradientTransform="translate(0.000000,8.055463)"
276 x1="12.378357"
277 y1="4.4331360"
278 x2="44.096100"
279 y2="47.620636" />
280 <radialGradient
281 inkscape:collect="always"
282 xlink:href="#linearGradient4244"
283 id="radialGradient1512"
284 gradientUnits="userSpaceOnUse"
285 gradientTransform="matrix(1.286242,0.781698,-0.710782,1.169552,-2.354348,3.178602)"
286 cx="15.571491"
287 cy="2.9585190"
288 fx="15.571491"
289 fy="2.9585190"
290 r="20.935817" />
291 <linearGradient
292 inkscape:collect="always"
293 xlink:href="#linearGradient4228"
294 id="linearGradient1516"
295 gradientUnits="userSpaceOnUse"
296 gradientTransform="translate(0.000000,8.055463)"
297 x1="7.6046205"
298 y1="28.481176"
299 x2="36.183067"
300 y2="40.943935" />
301 <radialGradient
302 inkscape:collect="always"
303 xlink:href="#linearGradient4990"
304 id="radialGradient1520"
305 gradientUnits="userSpaceOnUse"
306 gradientTransform="matrix(2.385563,1.107767e-15,-1.107767e-15,2.385563,-30.84370,-6.089588)"
307 cx="22.693991"
308 cy="4.9365706"
309 fx="22.693991"
310 fy="4.9365706"
311 r="6.6291261" />
312 </defs>
313 <sodipodi:namedview
314 inkscape:window-y="80"
315 inkscape:window-x="418"
316 inkscape:window-height="768"
317 inkscape:window-width="1016"
318 inkscape:document-units="px"
319 inkscape:grid-bbox="true"
320 showgrid="false"
321 inkscape:current-layer="layer2"
322 inkscape:cy="6.0880661"
323 inkscape:cx="21.920506"
324 inkscape:zoom="1"
325 inkscape:pageshadow="2"
326 inkscape:pageopacity="0.0"
327 borderopacity="1.0"
328 bordercolor="#666666"
329 pagecolor="#ffffff"
330 id="base"
331 inkscape:showpageshadow="false" />
332 <metadata
333 id="metadata4">
334 <rdf:RDF>
335 <cc:Work
336 rdf:about="">
337 <dc:format>image/svg+xml</dc:format>
338 <dc:type
339 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
340 <dc:title>Input - Gaming</dc:title>
341 <dc:creator>
342 <cc:Agent>
343 <dc:title>Jakub Steiner</dc:title>
344 </cc:Agent>
345 </dc:creator>
346 <dc:subject>
347 <rdf:Bag>
348 <rdf:li>gaming</rdf:li>
349 <rdf:li>controller</rdf:li>
350 <rdf:li>joystick</rdf:li>
351 <rdf:li>game</rdf:li>
352 <rdf:li>gaming</rdf:li>
353 <rdf:li>HID</rdf:li>
354 </rdf:Bag>
355 </dc:subject>
356 <cc:license
357 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
358 <dc:identifier />
359 <dc:source>http://jimmac.musichall.cz</dc:source>
360 </cc:Work>
361 <cc:License
362 rdf:about="http://creativecommons.org/licenses/publicdomain/">
363 <cc:permits
364 rdf:resource="http://creativecommons.org/ns#Reproduction" />
365 <cc:permits
366 rdf:resource="http://creativecommons.org/ns#Distribution" />
367 <cc:permits
368 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
369 </cc:License>
370 </rdf:RDF>
371 </metadata>
372 <g
373 inkscape:label="pix"
374 id="layer2"
375 inkscape:groupmode="layer">
376 <g
377 transform="matrix(2.354239e-2,0,0,2.086758e-2,45.31444,40.2786)"
378 id="g6707">
379 <rect
380 style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
381 id="rect6709"
382 width="1339.6335"
383 height="478.35718"
384 x="-1559.2523"
385 y="-150.69685" />
386 <path
387 style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
388 d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
389 id="path6711"
390 sodipodi:nodetypes="cccc" />
391 <path
392 sodipodi:nodetypes="cccc"
393 id="path6713"
394 d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
395 style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
396 </g>
397 <path
398 sodipodi:nodetypes="cccsccccccccc"
399 id="path4196"
400 d="M 9.2856900,22.018085 C 8.6606900,22.018085 8.2544410,22.308265 8.0044420,22.861838 C 8.0044410,22.861838 3.5356915,33.965402 3.5356915,33.965402 C 3.5356915,33.965402 3.2856915,34.636961 3.2856915,35.746652 C 3.2856915,35.746652 3.2856915,41.396620 3.2856915,41.396620 C 3.2856915,42.479233 3.9434770,43.021622 4.9419415,43.021620 L 43.504440,43.021620 C 44.489293,43.021620 45.098190,42.303440 45.098190,41.177870 L 45.098190,35.527902 C 45.098190,35.527902 45.204153,34.757479 45.004440,34.215402 L 40.285690,23.018089 C 40.101165,22.506182 39.648785,22.029991 39.160690,22.018085 L 9.2856900,22.018085 z "
401 style="fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#535353;stroke-width:2.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000" />
402 <path
403 sodipodi:nodetypes="ccccccccc"
404 id="path4170"
405 d="M 3.2735915,35.052276 L 4.0381936,34.360061 L 41.647883,34.422561 L 45.110290,34.739859 L 45.110290,41.178391 C 45.110290,42.303960 44.503272,43.021722 43.518419,43.021722 L 4.9354314,43.021722 C 3.9369667,43.021722 3.2735915,42.479671 3.2735915,41.397058 L 3.2735915,35.052276 z "
406 style="fill:url(#linearGradient1516);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0204430px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
407 <path
408 id="path5030"
409 d="M 24.562500,19.750000 C 21.937845,19.750000 19.852749,20.801914 19.687500,22.125000 L 19.625000,22.125000 C 19.625000,22.125000 18.343750,27.312500 18.343750,27.312500 C 18.125000,28.406250 20.422495,30.343750 24.562500,30.343750 C 28.733893,30.343750 31.125000,28.375000 30.718750,26.906250 C 30.718750,26.906250 29.531250,22.125000 29.531250,22.125000 L 29.468750,22.125000 C 29.305110,20.801122 27.188264,19.750001 24.562500,19.750000 z "
410 style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#666666;stroke-width:2.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans" />
411 <path
412 sodipodi:nodetypes="csccccccs"
413 id="path3093"
414 d="M 3.5490842,33.969868 C 2.8347985,35.434154 3.5484686,36.362725 4.5847985,36.362725 C 4.5847985,36.362725 43.584797,36.362725 43.584797,36.362725 C 44.703844,36.338915 45.430035,35.350820 45.013368,34.219867 L 40.299082,23.009162 C 40.114558,22.497255 39.644320,22.021063 39.156225,22.009158 L 9.2990830,22.009158 C 8.6740830,22.009158 8.2633690,22.312731 8.0133700,22.866304 C 8.0133700,22.866304 3.5490842,33.969868 3.5490842,33.969868 z "
415 style="fill:url(#radialGradient1512);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
416 <path
417 transform="translate(0.154679,0.287261)"
418 d="M 14.186330 32.708817 A 3.8227961 2.3864853 0 1 1 6.5407379,32.708817 A 3.8227961 2.3864853 0 1 1 14.186330 32.708817 z"
419 sodipodi:ry="2.3864853"
420 sodipodi:rx="3.8227961"
421 sodipodi:cy="32.708817"
422 sodipodi:cx="10.363534"
423 id="path5067"
424 style="opacity:1.0000000;color:#000000;fill:url(#radialGradient1470);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:2.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
425 sodipodi:type="arc" />
426 <path
427 sodipodi:nodetypes="cccccccc"
428 id="path4201"
429 d="M 44.796162,33.684152 C 44.859684,34.934126 44.382159,35.999992 43.474046,36.027902 C 43.474046,36.027902 5.3553296,36.027901 5.3553297,36.027902 C 4.0660978,36.027902 3.4875937,35.702955 3.2712790,35.159846 C 3.3630404,36.104178 4.0970964,36.809152 5.3553297,36.809152 C 5.3553296,36.809151 43.474046,36.809152 43.474046,36.809152 C 44.550053,36.776081 45.226851,35.385128 44.826210,33.814361 L 44.796162,33.684152 z "
430 style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
431 <path
432 style="fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient1507);stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
433 d="M 9.6425150,22.471180 C 9.0408230,22.471180 8.6497240,22.750539 8.4090490,23.283467 C 8.4090480,23.283467 3.9940341,33.874196 3.9940341,33.874196 C 3.9940341,33.874196 3.7533573,34.520711 3.7533573,35.589019 C 3.7533573,35.589019 3.7533573,40.879115 3.7533573,40.879115 C 3.7533573,42.233855 4.1974134,42.506014 5.3478414,42.506014 L 43.034746,42.506014 C 44.357872,42.506014 44.569062,42.189617 44.569062,40.668522 L 44.569062,35.378426 C 44.569062,35.378426 44.671072,34.636735 44.478807,34.114873 L 39.885616,23.308891 C 39.707973,22.816075 39.334964,22.482641 38.865071,22.471180 L 9.6425150,22.471180 z "
434 id="path4252"
435 sodipodi:nodetypes="cccsccccccccc" />
436 <path
437 transform="matrix(1.581301,0.000000,0.000000,1.581301,-14.28370,-16.59070)"
438 d="M 31.819805 28.377787 A 7.2478447 3.7123106 0 1 1 17.324116,28.377787 A 7.2478447 3.7123106 0 1 1 31.819805 28.377787 z"
439 sodipodi:ry="3.7123106"
440 sodipodi:rx="7.2478447"
441 sodipodi:cy="28.377787"
442 sodipodi:cx="24.571960"
443 id="path4341"
444 style="font-family:Bitstream Vera Sans;overflow:visible;display:inline;visibility:visible;stroke-opacity:1.0000000;stroke-dashoffset:0.0000000;stroke-dasharray:none;stroke-miterlimit:4.0000000;marker-end:none;marker-mid:none;marker-start:none;marker:none;stroke-linejoin:miter;stroke-linecap:butt;stroke-width:1.0000000px;stroke:none;fill-rule:evenodd;fill-opacity:0.48022595;fill:#ffffff;color:#000000;opacity:1.0000000"
445 sodipodi:type="arc" />
446 <path
447 sodipodi:type="arc"
448 style="font-family:Bitstream Vera Sans;overflow:visible;display:inline;visibility:visible;stroke-opacity:1.0000000;stroke-dashoffset:0.0000000;stroke-dasharray:none;stroke-miterlimit:4.0000000;marker-end:none;marker-mid:none;marker-start:none;marker:none;stroke-linejoin:miter;stroke-linecap:butt;stroke-width:1.0000000px;stroke:none;fill-rule:evenodd;fill-opacity:1.0000000;fill:#c9c9c9;color:#000000;opacity:1.0000000"
449 id="path4343"
450 sodipodi:cx="24.571960"
451 sodipodi:cy="28.377787"
452 sodipodi:rx="7.2478447"
453 sodipodi:ry="3.7123106"
454 d="M 31.819805 28.377787 A 7.2478447 3.7123106 0 1 1 17.324116,28.377787 A 7.2478447 3.7123106 0 1 1 31.819805 28.377787 z"
455 transform="matrix(0.853659,0.000000,0.000000,0.853659,3.595897,2.933178)" />
456 <path
457 sodipodi:nodetypes="ccccccccccc"
458 id="path4659"
459 d="M 24.562500,1.3437500 C 20.903222,1.3437500 17.937500,4.3094726 17.937500,7.9687500 C 17.937500,10.576309 19.496574,12.761497 21.687500,13.843750 L 21.687500,22.312500 C 21.687500,22.312500 21.687500,22.348136 21.687500,22.375000 C 21.687500,23.188967 22.973326,23.843751 24.562500,23.843750 C 26.151674,23.843750 27.437500,23.188967 27.437500,22.375000 L 27.437500,22.312500 L 27.437500,13.875000 C 29.647942,12.799796 31.187500,10.590605 31.187500,7.9687500 C 31.187500,4.3094724 28.221778,1.3437500 24.562500,1.3437500 z "
460 style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#666666;stroke-width:2.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans" />
461 <path
462 sodipodi:nodetypes="cczccc"
463 id="path5026"
464 d="M 29.531250,22.125000 C 29.531250,22.125000 30.718750,26.906250 30.718750,26.906250 C 31.125000,28.375000 28.733893,30.343750 24.562500,30.343750 C 20.422495,30.343750 18.125000,28.406250 18.343750,27.312500 C 18.343750,27.312500 19.625000,22.125000 19.625000,22.125000 L 29.531250,22.125000 z "
465 style="opacity:1.0000000;color:#000000;fill:url(#linearGradient1501);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans" />
466 <path
467 transform="matrix(0.682927,0.000000,0.000000,0.682927,7.791110,2.903166)"
468 d="M 31.819805 28.377787 A 7.2478447 3.7123106 0 1 1 17.324116,28.377787 A 7.2478447 3.7123106 0 1 1 31.819805 28.377787 z"
469 sodipodi:ry="3.7123106"
470 sodipodi:rx="7.2478447"
471 sodipodi:cy="28.377787"
472 sodipodi:cx="24.571960"
473 id="path4345"
474 style="opacity:1.0000000;color:#000000;fill:#e4e4e4;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
475 sodipodi:type="arc" />
476 <path
477 transform="matrix(0.633635,0.000000,0.000000,0.633635,9.123852,4.176870)"
478 d="M 24.562500,24.656250 C 20.561690,24.656250 17.312500,26.325805 17.312500,28.375000 C 17.312500,30.424195 20.561690,32.093752 24.562500,32.093750 C 28.563310,32.093750 31.812500,30.424195 31.812500,28.375000 C 31.812500,26.325805 28.563310,24.656250 24.562500,24.656250 z "
479 inkscape:href="#path4345"
480 id="path5419"
481 style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient1476);stroke-width:1.0777932px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
482 xlink:href="#path4345"
483 inkscape:original="M 24.5625 24.65625 C 20.56169 24.65625 17.3125 26.325805 17.3125 28.375 C 17.3125 30.424195 20.56169 32.093752 24.5625 32.09375 C 28.56331 32.09375 31.8125 30.424195 31.8125 28.375 C 31.8125 26.325805 28.56331 24.65625 24.5625 24.65625 z "
484 inkscape:radius="0.0000000"
485 sodipodi:type="inkscape:offset" />
486 <path
487 id="path4347"
488 d="M 24.562500,6.2812500 C 22.973326,6.2812500 21.687501,6.9360325 21.687500,7.7500000 C 21.687500,7.7768636 21.747226,7.7859887 21.750000,7.8125000 L 21.687500,7.8125000 L 21.687500,21.687500 L 21.750000,21.687500 C 21.747226,21.714011 21.687500,21.723136 21.687500,21.750000 C 21.687500,22.563967 22.973326,23.218751 24.562500,23.218750 C 26.151674,23.218750 27.437500,22.563967 27.437500,21.750000 C 27.437500,21.723136 27.377774,21.714011 27.375000,21.687500 L 27.437500,21.687500 L 27.437500,7.8125000 L 27.375000,7.8125000 C 27.377774,7.7859887 27.437500,7.7768636 27.437500,7.7500000 C 27.437500,6.9360329 26.151674,6.2812500 24.562500,6.2812500 z "
489 style="opacity:1.0000000;color:#000000;fill:url(#linearGradient1496);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans" />
490 <path
491 transform="matrix(0.967577,0.000000,0.000000,0.967577,0.967730,-0.168660)"
492 d="M 31.024310 8.4020205 A 6.6291261 6.6291261 0 1 1 17.766057,8.4020205 A 6.6291261 6.6291261 0 1 1 31.024310 8.4020205 z"
493 sodipodi:ry="6.6291261"
494 sodipodi:rx="6.6291261"
495 sodipodi:cy="8.4020205"
496 sodipodi:cx="24.395184"
497 id="path4641"
498 style="opacity:1.0000000;color:#000000;fill:url(#radialGradient1520);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0754249;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
499 sodipodi:type="arc" />
500 <g
501 transform="matrix(1.000000,0.000000,0.000000,0.849660,0.810662,5.224199)"
502 id="g5049">
503 <path
504 transform="matrix(0.510331,0.000000,0.000000,0.354752,-2.877670,29.41695)"
505 d="M 31.024310 8.4020205 A 6.6291261 6.6291261 0 1 1 17.766057,8.4020205 A 6.6291261 6.6291261 0 1 1 31.024310 8.4020205 z"
506 sodipodi:ry="6.6291261"
507 sodipodi:rx="6.6291261"
508 sodipodi:cy="8.4020205"
509 sodipodi:cx="24.395184"
510 id="path5039"
511 style="opacity:1.0000000;color:#000000;fill:url(#linearGradient1482);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0754249;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
512 sodipodi:type="arc" />
513 <path
514 sodipodi:type="arc"
515 style="opacity:1.0000000;color:#000000;fill:url(#linearGradient1484);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0754249;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
516 id="path5045"
517 sodipodi:cx="24.395184"
518 sodipodi:cy="8.4020205"
519 sodipodi:rx="6.6291261"
520 sodipodi:ry="6.6291261"
521 d="M 31.024310 8.4020205 A 6.6291261 6.6291261 0 1 1 17.766057,8.4020205 A 6.6291261 6.6291261 0 1 1 31.024310 8.4020205 z"
522 transform="matrix(0.430193,0.000000,0.000000,0.299045,-0.922674,29.60375)" />
523 </g>
524 <path
525 sodipodi:nodetypes="ccccccccccccc"
526 id="path2204"
527 d="M 24.563623,2.0718822 C 21.278747,2.0718822 18.620128,4.7594941 18.620128,8.0443690 C 18.620128,10.357138 20.280154,12.307309 22.208798,13.292040 L 22.208798,20.414005 C 21.341562,20.809402 20.055668,21.457196 20.040768,22.095579 C 20.040768,22.095579 18.794084,27.240824 18.794084,27.240824 C 18.591136,28.255567 20.722671,30.053111 24.563623,30.053111 C 28.433695,30.053111 30.652081,28.226574 30.275176,26.863919 L 29.057485,22.008601 C 29.041525,21.324823 27.831797,20.896706 26.855947,20.500983 L 26.855947,13.292040 C 28.784592,12.307309 30.536109,10.357138 30.536110,8.0443690 C 30.536110,4.7594942 27.848497,2.0718822 24.563623,2.0718822 z "
528 style="opacity:0.52571428;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient1489);stroke-width:0.99999976px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans" />
529 </g>
530</svg>
diff --git a/utils/rbutilqt/icons/media-eject.svg b/utils/rbutilqt/icons/media-eject.svg
new file mode 100644
index 0000000000..d22eae1a4f
--- /dev/null
+++ b/utils/rbutilqt/icons/media-eject.svg
@@ -0,0 +1,450 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="48px"
13 height="48px"
14 id="svg1307"
15 sodipodi:version="0.32"
16 inkscape:version="0.46"
17 sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
18 sodipodi:docname="media-eject.svg"
19 inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions-outlines.png"
20 inkscape:export-xdpi="90"
21 inkscape:export-ydpi="90"
22 inkscape:output_extension="org.inkscape.output.svg.inkscape">
23 <defs
24 id="defs1309">
25 <inkscape:perspective
26 sodipodi:type="inkscape:persp3d"
27 inkscape:vp_x="0 : 24 : 1"
28 inkscape:vp_y="0 : 1000 : 0"
29 inkscape:vp_z="48 : 24 : 1"
30 inkscape:persp3d-origin="24 : 16 : 1"
31 id="perspective68" />
32 <linearGradient
33 id="linearGradient4061">
34 <stop
35 id="stop4063"
36 offset="0"
37 style="stop-color:#474845;stop-opacity:1;" />
38 <stop
39 id="stop4065"
40 offset="1"
41 style="stop-color:#838681;stop-opacity:1" />
42 </linearGradient>
43 <linearGradient
44 id="linearGradient3881">
45 <stop
46 style="stop-color:#474845;stop-opacity:1;"
47 offset="0"
48 id="stop3883" />
49 <stop
50 style="stop-color:#838681;stop-opacity:1"
51 offset="1"
52 id="stop3885" />
53 </linearGradient>
54 <linearGradient
55 id="linearGradient2684">
56 <stop
57 id="stop2686"
58 offset="0"
59 style="stop-color:#ffffff;stop-opacity:1;" />
60 <stop
61 id="stop2688"
62 offset="1"
63 style="stop-color:#000000;stop-opacity:1;" />
64 </linearGradient>
65 <linearGradient
66 id="linearGradient2584">
67 <stop
68 style="stop-color:#000000;stop-opacity:1;"
69 offset="0"
70 id="stop2586" />
71 <stop
72 style="stop-color:#ffffff;stop-opacity:0;"
73 offset="1"
74 id="stop2588" />
75 </linearGradient>
76 <linearGradient
77 id="linearGradient5075">
78 <stop
79 style="stop-color:#adb0a8;stop-opacity:1;"
80 offset="0"
81 id="stop5077" />
82 <stop
83 style="stop-color:#464744;stop-opacity:1"
84 offset="1"
85 id="stop5079" />
86 </linearGradient>
87 <linearGradient
88 id="linearGradient2691"
89 inkscape:collect="always">
90 <stop
91 id="stop2693"
92 offset="0"
93 style="stop-color:#ffffff;stop-opacity:1" />
94 <stop
95 id="stop2695"
96 offset="1"
97 style="stop-color:#d3d7cf" />
98 </linearGradient>
99 <radialGradient
100 inkscape:collect="always"
101 xlink:href="#linearGradient2691"
102 id="radialGradient2820"
103 gradientUnits="userSpaceOnUse"
104 gradientTransform="matrix(7.417671e-4,-0.841008,2.061725,1.819131e-3,-85.84076,115.7349)"
105 cx="107.69903"
106 cy="53.086113"
107 fx="107.69903"
108 fy="53.086113"
109 r="12.551644" />
110 <radialGradient
111 inkscape:collect="always"
112 xlink:href="#linearGradient2691"
113 id="radialGradient3705"
114 gradientUnits="userSpaceOnUse"
115 gradientTransform="matrix(7.541952e-4,-0.786068,2.096269,1.700295e-3,-88.16796,111.9199)"
116 cx="101.15939"
117 cy="53.259945"
118 fx="101.15939"
119 fy="53.259945"
120 r="12.551644" />
121 <linearGradient
122 inkscape:collect="always"
123 xlink:href="#linearGradient2684"
124 id="linearGradient3721"
125 gradientUnits="userSpaceOnUse"
126 gradientTransform="matrix(1.128181,0,0,1.128181,8.232257,-83.36009)"
127 x1="14.628661"
128 y1="107.05981"
129 x2="14.334254"
130 y2="88.591339" />
131 <linearGradient
132 inkscape:collect="always"
133 xlink:href="#linearGradient2684"
134 id="linearGradient3725"
135 gradientUnits="userSpaceOnUse"
136 gradientTransform="matrix(1.128181,0,0,1.128181,8.232257,-83.36009)"
137 x1="14.296268"
138 y1="107.7246"
139 x2="14.888244"
140 y2="90.142509" />
141 <linearGradient
142 inkscape:collect="always"
143 xlink:href="#linearGradient3881"
144 id="linearGradient3887"
145 x1="21.597084"
146 y1="14.977048"
147 x2="21.522573"
148 y2="34.510876"
149 gradientUnits="userSpaceOnUse" />
150 <linearGradient
151 inkscape:collect="always"
152 xlink:href="#linearGradient4061"
153 id="linearGradient3889"
154 x1="21.597084"
155 y1="14.977048"
156 x2="21.522573"
157 y2="34.510876"
158 gradientUnits="userSpaceOnUse" />
159 <linearGradient
160 gradientUnits="userSpaceOnUse"
161 y2="36"
162 x2="23.750401"
163 y1="13.658564"
164 x1="24.476166"
165 id="linearGradient2322"
166 xlink:href="#linearGradient2316"
167 inkscape:collect="always" />
168 <radialGradient
169 r="8.75"
170 fy="147.99352"
171 fx="64.227074"
172 cy="147.99352"
173 cx="64.227074"
174 gradientTransform="matrix(0.222659,-0.996273,2.129992,0.476041,-308.946,20.8517)"
175 gradientUnits="userSpaceOnUse"
176 id="radialGradient1439"
177 xlink:href="#linearGradient2679"
178 inkscape:collect="always" />
179 <radialGradient
180 r="8.75"
181 fy="147.99352"
182 fx="64.227074"
183 cy="147.99352"
184 cx="64.227074"
185 gradientTransform="matrix(0.222659,-0.996273,2.129992,0.476041,-290.946,20.8517)"
186 gradientUnits="userSpaceOnUse"
187 id="radialGradient1436"
188 xlink:href="#linearGradient2679"
189 inkscape:collect="always" />
190 <linearGradient
191 y2="115.13713"
192 x2="49.667324"
193 y1="112.94963"
194 x1="49.430401"
195 gradientTransform="translate(-44.99051,-97.26213)"
196 gradientUnits="userSpaceOnUse"
197 id="linearGradient1426"
198 xlink:href="#linearGradient2584"
199 inkscape:collect="always" />
200 <linearGradient
201 y2="142.18799"
202 x2="54.896976"
203 y1="156"
204 x1="54.988514"
205 gradientTransform="translate(-47.9996,-121)"
206 gradientUnits="userSpaceOnUse"
207 id="linearGradient1401"
208 xlink:href="#linearGradient5075"
209 inkscape:collect="always" />
210 <linearGradient
211 inkscape:collect="always"
212 id="linearGradient2679">
213 <stop
214 style="stop-color:#ffffff;stop-opacity:1"
215 offset="0"
216 id="stop2681" />
217 <stop
218 style="stop-color:#d3d7cf"
219 offset="1"
220 id="stop2683" />
221 </linearGradient>
222 <linearGradient
223 id="linearGradient2316">
224 <stop
225 id="stop2318"
226 offset="0"
227 style="stop-color:#000000;stop-opacity:1;" />
228 <stop
229 id="stop2320"
230 offset="1"
231 style="stop-color:#ffffff;stop-opacity:0.65979379;" />
232 </linearGradient>
233 </defs>
234 <sodipodi:namedview
235 id="base"
236 pagecolor="#ffffff"
237 bordercolor="#969696"
238 borderopacity="0.13333333"
239 inkscape:pageopacity="0"
240 inkscape:pageshadow="2"
241 inkscape:zoom="11.313708"
242 inkscape:cx="21.647252"
243 inkscape:cy="17.061223"
244 inkscape:current-layer="layer1"
245 showgrid="false"
246 inkscape:grid-bbox="true"
247 inkscape:document-units="px"
248 inkscape:grid-points="true"
249 fill="#555753"
250 showguides="false"
251 inkscape:guide-bbox="true"
252 guidetolerance="1px"
253 stroke="#555753"
254 inkscape:window-width="1090"
255 inkscape:window-height="818"
256 inkscape:window-x="344"
257 inkscape:window-y="30"
258 showborder="true"
259 inkscape:showpageshadow="false">
260 <sodipodi:guide
261 orientation="horizontal"
262 position="38.996647"
263 id="guide2194" />
264 <sodipodi:guide
265 orientation="horizontal"
266 position="9.0140845"
267 id="guide2196" />
268 <sodipodi:guide
269 orientation="vertical"
270 position="9.0140845"
271 id="guide2198" />
272 <sodipodi:guide
273 orientation="vertical"
274 position="38.975184"
275 id="guide2200" />
276 <sodipodi:guide
277 orientation="horizontal"
278 position="22.988281"
279 id="guide2202" />
280 <sodipodi:guide
281 orientation="vertical"
282 position="23.908786"
283 id="guide2204" />
284 <sodipodi:guide
285 orientation="vertical"
286 position="157.99417"
287 id="guide4332" />
288 <sodipodi:guide
289 orientation="horizontal"
290 position="-36.062446"
291 id="guide4334" />
292 <sodipodi:guide
293 orientation="horizontal"
294 position="-58.02695"
295 id="guide4336" />
296 <sodipodi:guide
297 orientation="vertical"
298 position="180.00287"
299 id="guide4338" />
300 <sodipodi:guide
301 orientation="vertical"
302 position="107.92217"
303 id="guide4417" />
304 <sodipodi:guide
305 orientation="vertical"
306 position="129.93087"
307 id="guide4419" />
308 <sodipodi:guide
309 orientation="horizontal"
310 position="19.996875"
311 id="guide5106" />
312 <sodipodi:guide
313 orientation="horizontal"
314 position="63.039674"
315 id="guide5119" />
316 <sodipodi:guide
317 orientation="horizontal"
318 position="49.066305"
319 id="guide5121" />
320 <sodipodi:guide
321 orientation="horizontal"
322 position="-86.007168"
323 id="guide5307" />
324 <sodipodi:guide
325 orientation="horizontal"
326 position="-108.09009"
327 id="guide5309" />
328 <sodipodi:guide
329 orientation="horizontal"
330 position="-100.15429"
331 id="guide3111" />
332 <inkscape:grid
333 id="GridFromPre046Settings"
334 type="xygrid"
335 originx="0px"
336 originy="0px"
337 spacingx="0.5px"
338 spacingy="0.5px"
339 color="#0000ff"
340 empcolor="#0000ff"
341 opacity="0.2"
342 empopacity="0.4"
343 empspacing="2" />
344 </sodipodi:namedview>
345 <metadata
346 id="metadata1312">
347 <rdf:RDF>
348 <cc:Work
349 rdf:about="">
350 <dc:format>image/svg+xml</dc:format>
351 <dc:type
352 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
353 <dc:title>Media Playback Start</dc:title>
354 <dc:creator>
355 <cc:Agent>
356 <dc:title>Jakub Steiner</dc:title>
357 </cc:Agent>
358 </dc:creator>
359 <cc:license
360 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
361 <dc:subject>
362 <rdf:Bag>
363 <rdf:li>media</rdf:li>
364 <rdf:li>eject</rdf:li>
365 </rdf:Bag>
366 </dc:subject>
367 <dc:contributor>
368 <cc:Agent>
369 <dc:title />
370 </cc:Agent>
371 </dc:contributor>
372 </cc:Work>
373 <cc:License
374 rdf:about="http://creativecommons.org/licenses/publicdomain/">
375 <cc:permits
376 rdf:resource="http://creativecommons.org/ns#Reproduction" />
377 <cc:permits
378 rdf:resource="http://creativecommons.org/ns#Distribution" />
379 <cc:permits
380 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
381 </cc:License>
382 </rdf:RDF>
383 </metadata>
384 <g
385 inkscape:groupmode="layer"
386 id="layer4"
387 inkscape:label="contorno"
388 style="display:inline" />
389 <g
390 id="layer1"
391 inkscape:label="Layer 1"
392 inkscape:groupmode="layer"
393 style="display:inline">
394 <path
395 sodipodi:nodetypes="cccc"
396 inkscape:r_cy="true"
397 inkscape:r_cx="true"
398 id="path3711"
399 d="M 23.688076,8.7574062 L 10.871765,26.499989 L 36.504387,26.499989 L 23.688076,8.7574062 z "
400 style="opacity:0.15;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3721);stroke-width:3;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
401 <path
402 style="opacity:1;color:#000000;fill:url(#radialGradient2820);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3887);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
403 d="M 23.688076,8.7574062 L 10.871765,26.499989 L 36.504387,26.499989 L 23.688076,8.7574062 z "
404 id="path2818"
405 inkscape:r_cx="true"
406 inkscape:r_cy="true"
407 sodipodi:nodetypes="cccc" />
408 <path
409 sodipodi:nodetypes="cccc"
410 inkscape:r_cy="true"
411 inkscape:r_cx="true"
412 id="path2828"
413 d="M 23.688071,10.492044 L 12.811768,25.591373 L 34.564374,25.502984 L 23.688071,10.492044 z "
414 style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
415 <rect
416 inkscape:r_cy="true"
417 inkscape:r_cx="true"
418 y="30.504408"
419 x="10.614329"
420 height="4.9750595"
421 width="25.882353"
422 id="rect3723"
423 style="opacity:0.15;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3725);stroke-width:3;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
424 <rect
425 style="opacity:1;color:#000000;fill:url(#radialGradient3705);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3889);stroke-width:1.00000024;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
426 id="rect3703"
427 width="25.882353"
428 height="4.9750595"
429 x="10.614329"
430 y="30.504408"
431 inkscape:r_cx="true"
432 inkscape:r_cy="true" />
433 <rect
434 inkscape:r_cy="true"
435 inkscape:r_cx="true"
436 y="31.553034"
437 x="11.616447"
438 height="2.9302683"
439 width="23.87805"
440 id="rect3707"
441 style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999952;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
442 <path
443 style="opacity:0.56111111;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
444 d="M 23.6875,11.3125 L 17.6875,19.625 C 22.683077,19.81186 24.399544,19.457194 29.0625,18.8125 L 23.6875,11.3125 z "
445 id="path3709"
446 inkscape:r_cx="true"
447 inkscape:r_cy="true"
448 sodipodi:nodetypes="cccc" />
449 </g>
450</svg>
diff --git a/utils/rbutilqt/icons/multimedia-player.svg b/utils/rbutilqt/icons/multimedia-player.svg
new file mode 100644
index 0000000000..01bf244efe
--- /dev/null
+++ b/utils/rbutilqt/icons/multimedia-player.svg
@@ -0,0 +1,693 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="48"
13 height="48"
14 id="svg2"
15 sodipodi:version="0.32"
16 inkscape:version="0.46"
17 version="1.0"
18 sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/devices"
19 sodipodi:docname="multimedia-player.svg"
20 inkscape:output_extension="org.inkscape.output.svg.inkscape">
21 <defs
22 id="defs4">
23 <inkscape:perspective
24 sodipodi:type="inkscape:persp3d"
25 inkscape:vp_x="0 : 24 : 1"
26 inkscape:vp_y="0 : 1000 : 0"
27 inkscape:vp_z="48 : 24 : 1"
28 inkscape:persp3d-origin="24 : 16 : 1"
29 id="perspective99" />
30 <radialGradient
31 inkscape:collect="always"
32 xlink:href="#linearGradient5060"
33 id="radialGradient6719"
34 gradientUnits="userSpaceOnUse"
35 gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
36 cx="605.71429"
37 cy="486.64789"
38 fx="605.71429"
39 fy="486.64789"
40 r="117.14286" />
41 <linearGradient
42 inkscape:collect="always"
43 id="linearGradient5060">
44 <stop
45 style="stop-color:black;stop-opacity:1;"
46 offset="0"
47 id="stop5062" />
48 <stop
49 style="stop-color:black;stop-opacity:0;"
50 offset="1"
51 id="stop5064" />
52 </linearGradient>
53 <radialGradient
54 inkscape:collect="always"
55 xlink:href="#linearGradient5060"
56 id="radialGradient6717"
57 gradientUnits="userSpaceOnUse"
58 gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
59 cx="605.71429"
60 cy="486.64789"
61 fx="605.71429"
62 fy="486.64789"
63 r="117.14286" />
64 <linearGradient
65 id="linearGradient5048">
66 <stop
67 style="stop-color:black;stop-opacity:0;"
68 offset="0"
69 id="stop5050" />
70 <stop
71 id="stop5056"
72 offset="0.5"
73 style="stop-color:black;stop-opacity:1;" />
74 <stop
75 style="stop-color:black;stop-opacity:0;"
76 offset="1"
77 id="stop5052" />
78 </linearGradient>
79 <linearGradient
80 inkscape:collect="always"
81 xlink:href="#linearGradient5048"
82 id="linearGradient6715"
83 gradientUnits="userSpaceOnUse"
84 gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
85 x1="302.85715"
86 y1="366.64789"
87 x2="302.85715"
88 y2="609.50507" />
89 <linearGradient
90 inkscape:collect="always"
91 id="linearGradient2413">
92 <stop
93 style="stop-color:#000000;stop-opacity:1;"
94 offset="0"
95 id="stop2415" />
96 <stop
97 style="stop-color:#000000;stop-opacity:0;"
98 offset="1"
99 id="stop2417" />
100 </linearGradient>
101 <linearGradient
102 id="linearGradient2381">
103 <stop
104 style="stop-color:#808080;stop-opacity:1;"
105 offset="0"
106 id="stop2383" />
107 <stop
108 style="stop-color:#c0c0c0;stop-opacity:1;"
109 offset="1"
110 id="stop2385" />
111 </linearGradient>
112 <linearGradient
113 id="linearGradient2373">
114 <stop
115 style="stop-color:#ffffff;stop-opacity:1;"
116 offset="0"
117 id="stop2375" />
118 <stop
119 style="stop-color:#cbcbcb;stop-opacity:1;"
120 offset="1"
121 id="stop2377" />
122 </linearGradient>
123 <linearGradient
124 id="linearGradient2359">
125 <stop
126 id="stop2361"
127 offset="0"
128 style="stop-color:#ffffff;stop-opacity:1;" />
129 <stop
130 style="stop-color:#dddddd;stop-opacity:1;"
131 offset="1"
132 id="stop2365" />
133 </linearGradient>
134 <linearGradient
135 inkscape:collect="always"
136 id="linearGradient9531">
137 <stop
138 style="stop-color:#000000;stop-opacity:1;"
139 offset="0"
140 id="stop9533" />
141 <stop
142 style="stop-color:#000000;stop-opacity:0;"
143 offset="1"
144 id="stop9535" />
145 </linearGradient>
146 <linearGradient
147 id="linearGradient8644">
148 <stop
149 style="stop-color:#d4d4d4;stop-opacity:1;"
150 offset="0"
151 id="stop8646" />
152 <stop
153 style="stop-color:#666666;stop-opacity:1;"
154 offset="1"
155 id="stop8648" />
156 </linearGradient>
157 <linearGradient
158 inkscape:collect="always"
159 id="linearGradient3379">
160 <stop
161 style="stop-color:#ffffff;stop-opacity:1;"
162 offset="0"
163 id="stop3381" />
164 <stop
165 style="stop-color:#ffffff;stop-opacity:0;"
166 offset="1"
167 id="stop3383" />
168 </linearGradient>
169 <linearGradient
170 id="linearGradient2489">
171 <stop
172 style="stop-color:#000000;stop-opacity:1;"
173 offset="0"
174 id="stop2491" />
175 <stop
176 style="stop-color:#ffffff;stop-opacity:1;"
177 offset="1"
178 id="stop2493" />
179 </linearGradient>
180 <linearGradient
181 inkscape:collect="always"
182 id="linearGradient2479">
183 <stop
184 style="stop-color:#ffffff;stop-opacity:1;"
185 offset="0"
186 id="stop2481" />
187 <stop
188 style="stop-color:#ffffff;stop-opacity:0;"
189 offset="1"
190 id="stop2483" />
191 </linearGradient>
192 <linearGradient
193 id="linearGradient2459">
194 <stop
195 style="stop-color:#888a85;stop-opacity:1;"
196 offset="0"
197 id="stop2461" />
198 <stop
199 id="stop2223"
200 offset="0.10810811"
201 style="stop-color:#a9aaa7;stop-opacity:1;" />
202 <stop
203 style="stop-color:#6c6e6a;stop-opacity:1;"
204 offset="0.39737034"
205 id="stop2225" />
206 <stop
207 id="stop2227"
208 offset="0.54395592"
209 style="stop-color:#81837e;stop-opacity:1;" />
210 <stop
211 style="stop-color:#747671;stop-opacity:1;"
212 offset="1"
213 id="stop2463" />
214 </linearGradient>
215 <linearGradient
216 inkscape:collect="always"
217 xlink:href="#linearGradient2459"
218 id="linearGradient2465"
219 x1="25"
220 y1="3.0479441"
221 x2="25"
222 y2="42.952038"
223 gradientUnits="userSpaceOnUse"
224 gradientTransform="translate(-2,0)" />
225 <linearGradient
226 inkscape:collect="always"
227 xlink:href="#linearGradient2479"
228 id="linearGradient2485"
229 x1="16.700136"
230 y1="-2.2827868"
231 x2="38.779945"
232 y2="50.396667"
233 gradientUnits="userSpaceOnUse"
234 gradientTransform="translate(-2,0)" />
235 <linearGradient
236 inkscape:collect="always"
237 xlink:href="#linearGradient2489"
238 id="linearGradient2495"
239 x1="24"
240 y1="6.875185"
241 x2="24"
242 y2="16.24435"
243 gradientUnits="userSpaceOnUse"
244 gradientTransform="matrix(1,0,0,1.062344,-2,-0.49875)" />
245 <radialGradient
246 inkscape:collect="always"
247 xlink:href="#linearGradient3379"
248 id="radialGradient3385"
249 cx="18.873476"
250 cy="5.8855872"
251 fx="18.873476"
252 fy="5.8855872"
253 r="12.5"
254 gradientTransform="matrix(1.629696,8.263413e-18,-3.606261e-16,1.262853,-13.88455,-0.417317)"
255 gradientUnits="userSpaceOnUse" />
256 <linearGradient
257 inkscape:collect="always"
258 xlink:href="#linearGradient2489"
259 id="linearGradient6019"
260 gradientUnits="userSpaceOnUse"
261 gradientTransform="matrix(1,0,0,1.062344,3.625,-3.029752)"
262 x1="29.359375"
263 y1="21.678244"
264 x2="29.359375"
265 y2="27.187134" />
266 <radialGradient
267 inkscape:collect="always"
268 xlink:href="#linearGradient8644"
269 id="radialGradient8650"
270 cx="32.125"
271 cy="22.03125"
272 fx="32.125"
273 fy="22.03125"
274 r="1.21875"
275 gradientUnits="userSpaceOnUse" />
276 <radialGradient
277 inkscape:collect="always"
278 xlink:href="#linearGradient8644"
279 id="radialGradient8654"
280 gradientUnits="userSpaceOnUse"
281 cx="32.125"
282 cy="22.03125"
283 fx="32.125"
284 fy="22.03125"
285 r="1.21875" />
286 <radialGradient
287 inkscape:collect="always"
288 xlink:href="#linearGradient9531"
289 id="radialGradient9537"
290 cx="25.375"
291 cy="41.75"
292 fx="25.375"
293 fy="41.75"
294 r="20.375"
295 gradientTransform="matrix(1,0,0,0.282209,-1.047339e-16,29.96779)"
296 gradientUnits="userSpaceOnUse" />
297 <radialGradient
298 inkscape:collect="always"
299 xlink:href="#linearGradient8644"
300 id="radialGradient9541"
301 gradientUnits="userSpaceOnUse"
302 cx="32.125"
303 cy="22.03125"
304 fx="32.125"
305 fy="22.03125"
306 r="1.21875" />
307 <radialGradient
308 inkscape:collect="always"
309 xlink:href="#linearGradient8644"
310 id="radialGradient9545"
311 gradientUnits="userSpaceOnUse"
312 cx="32.125"
313 cy="22.03125"
314 fx="32.125"
315 fy="22.03125"
316 r="1.21875" />
317 <radialGradient
318 inkscape:collect="always"
319 xlink:href="#linearGradient8644"
320 id="radialGradient9549"
321 gradientUnits="userSpaceOnUse"
322 cx="32.125"
323 cy="22.03125"
324 fx="32.125"
325 fy="22.03125"
326 r="1.21875" />
327 <radialGradient
328 inkscape:collect="always"
329 xlink:href="#linearGradient2359"
330 id="radialGradient2357"
331 cx="32.350128"
332 cy="41.432411"
333 fx="32.350128"
334 fy="41.432411"
335 r="8.2539635"
336 gradientTransform="matrix(1.53543,5.936779e-31,-6.200531e-31,1.255911,-17.32122,-10.99441)"
337 gradientUnits="userSpaceOnUse" />
338 <linearGradient
339 inkscape:collect="always"
340 xlink:href="#linearGradient2373"
341 id="linearGradient2379"
342 x1="20.466257"
343 y1="46.392647"
344 x2="20.495934"
345 y2="49.640648"
346 gradientUnits="userSpaceOnUse" />
347 <linearGradient
348 inkscape:collect="always"
349 xlink:href="#linearGradient2381"
350 id="linearGradient2387"
351 x1="43.462418"
352 y1="30.56131"
353 x2="44.977024"
354 y2="35.43631"
355 gradientUnits="userSpaceOnUse" />
356 <radialGradient
357 inkscape:collect="always"
358 xlink:href="#linearGradient2413"
359 id="radialGradient2419"
360 cx="32.350136"
361 cy="42.961864"
362 fx="32.350136"
363 fy="42.961864"
364 r="7.7781744"
365 gradientTransform="matrix(1,0,0,0.806818,5.966583e-15,8.29945)"
366 gradientUnits="userSpaceOnUse" />
367 </defs>
368 <sodipodi:namedview
369 id="base"
370 pagecolor="#ffffff"
371 bordercolor="#666666"
372 borderopacity="0.41176471"
373 inkscape:pageopacity="0.0"
374 inkscape:pageshadow="2"
375 inkscape:zoom="1"
376 inkscape:cx="21.767189"
377 inkscape:cy="17.084149"
378 inkscape:document-units="px"
379 inkscape:current-layer="layer1"
380 inkscape:showpageshadow="false"
381 inkscape:window-width="872"
382 inkscape:window-height="737"
383 inkscape:window-x="537"
384 inkscape:window-y="111"
385 showgrid="false"
386 fill="#9db029" />
387 <metadata
388 id="metadata7">
389 <rdf:RDF>
390 <cc:Work
391 rdf:about="">
392 <dc:format>image/svg+xml</dc:format>
393 <dc:type
394 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
395 <cc:license
396 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
397 <dc:creator>
398 <cc:Agent>
399 <dc:title>Jakub Steiner</dc:title>
400 </cc:Agent>
401 </dc:creator>
402 <dc:source>http://jimmac.musichall.cz</dc:source>
403 <dc:description>http://www.tango-project.org</dc:description>
404 <dc:title>Multimedia PLayer</dc:title>
405 <dc:subject>
406 <rdf:Bag>
407 <rdf:li>mp3</rdf:li>
408 <rdf:li>player</rdf:li>
409 <rdf:li />
410 </rdf:Bag>
411 </dc:subject>
412 </cc:Work>
413 <cc:License
414 rdf:about="http://creativecommons.org/licenses/publicdomain/">
415 <cc:permits
416 rdf:resource="http://creativecommons.org/ns#Reproduction" />
417 <cc:permits
418 rdf:resource="http://creativecommons.org/ns#Distribution" />
419 <cc:permits
420 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
421 </cc:License>
422 </rdf:RDF>
423 </metadata>
424 <g
425 inkscape:label="Layer 1"
426 inkscape:groupmode="layer"
427 id="layer1">
428 <path
429 sodipodi:type="arc"
430 style="opacity:1;color:#000000;fill:#4c4d4a;fill-opacity:1;fill-rule:evenodd;stroke:#2e3436;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
431 id="path2473"
432 sodipodi:cx="36.592777"
433 sodipodi:cy="13.351768"
434 sodipodi:rx="6.1871843"
435 sodipodi:ry="6.1871843"
436 d="M 42.779962 13.351768 A 6.1871843 6.1871843 0 1 1 30.405593,13.351768 A 6.1871843 6.1871843 0 1 1 42.779962 13.351768 z"
437 transform="translate(9.4407e-2,-3.895187e-2)" />
438 <g
439 transform="matrix(2.243425e-2,0,0,2.086758e-2,42.95382,39.4036)"
440 id="g6707">
441 <rect
442 style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
443 id="rect6709"
444 width="1339.6335"
445 height="478.35718"
446 x="-1559.2523"
447 y="-150.69685" />
448 <path
449 style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
450 d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
451 id="path6711"
452 sodipodi:nodetypes="cccc" />
453 <path
454 sodipodi:nodetypes="cccc"
455 id="path6713"
456 d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
457 style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
458 </g>
459 <path
460 style="opacity:1;color:#000000;fill:url(#linearGradient2465);fill-opacity:1;fill-rule:evenodd;stroke:#2e3436;stroke-width:0.99999982;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
461 d="M 5.375,3.5625 C 4.3091499,3.7244607 3.5,4.6375206 3.5,5.75 L 3.5,40.25 C 3.5,41.477563 4.4911865,42.437501 5.71875,42.4375 L 40.28125,42.4375 C 41.508813,42.4375 42.5,41.477563 42.5,40.25 L 42.5,19.5 C 41.339454,19.426907 40.40625,18.460862 40.40625,17.28125 L 40.40625,9.71875 C 40.40625,8.5391382 41.339452,7.5730933 42.5,7.5 L 42.5,5.75 C 42.5,4.5224367 41.508812,3.5625 40.28125,3.5625 L 5.71875,3.5625 C 5.6036659,3.5625 5.4852604,3.5457454 5.375,3.5625 z "
462 id="rect1580" />
463 <path
464 sodipodi:type="arc"
465 style="opacity:1;color:#000000;fill:url(#radialGradient2419);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.78842843;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
466 id="path2411"
467 sodipodi:cx="32.350136"
468 sodipodi:cy="42.961864"
469 sodipodi:rx="7.7781744"
470 sodipodi:ry="6.2755728"
471 d="M 40.12831 42.961864 A 7.7781744 6.2755728 0 1 1 24.571961,42.961864 A 7.7781744 6.2755728 0 1 1 40.12831 42.961864 z"
472 transform="matrix(1.373227,0,0,1.604378,-17.44787,-31.51651)" />
473 <path
474 transform="matrix(1.173426,0,0,1.370945,-12.04496,-21.31103)"
475 d="M 40.12831 42.961864 A 7.7781744 6.2755728 0 1 1 24.571961,42.961864 A 7.7781744 6.2755728 0 1 1 40.12831 42.961864 z"
476 sodipodi:ry="6.2755728"
477 sodipodi:rx="7.7781744"
478 sodipodi:cy="42.961864"
479 sodipodi:cx="32.350136"
480 id="path2407"
481 style="opacity:1;color:#000000;fill:#b0b0b0;fill-opacity:1;fill-rule:evenodd;stroke:#474747;stroke-width:0.78842843;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
482 sodipodi:type="arc" />
483 <path
484 sodipodi:type="arc"
485 style="opacity:1;color:#000000;fill:url(#radialGradient2357);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.95157808;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
486 id="path2601"
487 sodipodi:cx="32.350136"
488 sodipodi:cy="42.961864"
489 sodipodi:rx="7.7781744"
490 sodipodi:ry="6.2755728"
491 d="M 40.12831 42.961864 A 7.7781744 6.2755728 0 1 1 24.571961,42.961864 A 7.7781744 6.2755728 0 1 1 40.12831 42.961864 z"
492 transform="matrix(1,0,0,1.104361,-6.184621,-8.733106)" />
493 <path
494 id="path2475"
495 d="M 6.2036081,4.4761442 C 5.1878668,4.6304906 4.4167575,5.5006248 4.4167575,6.5608033 L 4.4167575,39.438855 C 4.4167575,40.608706 5.3613453,41.523515 6.5311974,41.523514 L 39.468811,41.523514 C 40.638662,41.523514 41.58325,40.608706 41.58325,39.438855 L 41.58325,20.327288 C 40.477265,20.257631 39.587934,19.160225 39.587934,18.036071 L 39.587934,9.1497273 C 39.587934,8.025573 40.477263,6.9723623 41.58325,6.9027053 L 41.58325,6.0304732 C 41.58325,4.8606213 40.638661,4.4761442 39.468811,4.4761442 L 6.5311974,4.4761442 C 6.4215238,4.4761442 6.3086849,4.4601773 6.2036081,4.4761442 z "
496 style="opacity:0.28140702;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2485);stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
497 sodipodi:nodetypes="cccccccccccccc" />
498 <rect
499 style="opacity:0.28140702;color:#000000;fill:url(#linearGradient2495);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
500 id="rect2487"
501 width="28"
502 height="7"
503 x="8"
504 y="8"
505 rx="1.3319347"
506 ry="1.3319347" />
507 <rect
508 ry="0.62482792"
509 rx="0.62482792"
510 y="9"
511 x="9.5023813"
512 height="5"
513 width="24.995237"
514 id="rect2497"
515 style="opacity:1;color:#000000;fill:#858f4a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible" />
516 <path
517 style="opacity:0.40201003;color:#000000;fill:url(#radialGradient3385);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
518 d="M 10,9 C 9.949065,9.0103701 9.889295,9.0406175 9.84375,9.0625 C 9.808331,9.0816933 9.749586,9.130823 9.71875,9.15625 C 9.70397,9.1696782 9.669678,9.2039696 9.65625,9.21875 C 9.567256,9.3266747 9.5,9.4735572 9.5,9.625 L 9.5,12.21875 C 12.146211,12.602725 15.034555,12.8125 18.0625,12.8125 C 24.51413,12.8125 30.337531,11.855998 34.5,10.3125 L 34.5,9.625 C 34.5,9.4735573 34.432744,9.3266747 34.34375,9.21875 C 34.330322,9.2039696 34.29603,9.1696782 34.28125,9.15625 C 34.250414,9.130823 34.191669,9.0816933 34.15625,9.0625 C 34.074268,9.0231115 33.972356,9 33.875,9 L 10.125,9 C 10.081731,9 10.040748,8.9917039 10,9 z "
519 id="rect2501" />
520 <path
521 transform="scale(1.290708,0.774769)"
522 style="font-size:3.59155464px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#1f1f1f;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Segoe"
523 d="M 5.7944869,27.7462 L 6.6029375,27.7462 C 6.9045705,27.746203 7.1331344,27.811089 7.2886298,27.94086 C 7.4441216,28.070635 7.5218683,28.261202 7.5218704,28.512562 C 7.5218683,28.753404 7.4347686,28.95274 7.2605708,29.11057 C 7.0875385,29.267234 6.8490371,29.345566 6.5450657,29.345565 L 6.2802587,29.345565 L 6.2802587,30.26099 L 5.7944869,30.26099 L 5.7944869,27.7462 M 6.2802587,28.961507 L 6.538051,28.961507 C 6.7028965,28.961508 6.8268237,28.925265 6.909833,28.852778 C 6.9928394,28.780294 7.0343434,28.671565 7.0343449,28.526592 C 7.0343434,28.392144 6.9928394,28.2916 6.909833,28.224957 C 6.8268237,28.15715 6.7028965,28.123246 6.538051,28.123244 L 6.2802587,28.123244 L 6.2802587,28.961507 M 8.9686637,27.711127 C 9.3088776,27.711129 9.5830374,27.826873 9.7911437,28.058357 C 9.9992458,28.288677 10.103298,28.595572 10.1033,28.979044 C 10.103298,29.376547 9.9945693,29.695134 9.7771142,29.934804 C 9.5596549,30.173306 9.2697119,30.292557 8.9072846,30.292557 C 8.5588841,30.292557 8.2771251,30.176813 8.0620066,29.945326 C 7.8480563,29.71384 7.7410814,29.409867 7.7410816,29.033408 C 7.7410814,28.633569 7.8533174,28.313228 8.0777898,28.072387 C 8.3034304,27.831549 8.6003881,27.711129 8.9686637,27.711127 M 8.916053,29.887454 C 9.125325,29.887455 9.2942636,29.810293 9.4228691,29.655968 C 9.551471,29.501644 9.6157729,29.288863 9.6157749,29.017625 C 9.6157729,28.740543 9.5520556,28.522502 9.4246228,28.363499 C 9.2983555,28.203331 9.1288324,28.123246 8.916053,28.123244 C 8.7079475,28.123246 8.5401781,28.203915 8.4127444,28.365253 C 8.285309,28.525425 8.2215917,28.740543 8.2215923,29.01061 C 8.2215917,29.278341 8.285309,29.491706 8.4127444,29.650706 C 8.5413473,29.808539 8.7091167,29.887455 8.916053,29.887454 M 12.781183,30.26099 L 12.274367,30.26099 L 11.074844,28.489764 C 11.044446,28.447678 11.01931,28.396236 10.999436,28.33544 L 10.988913,28.33544 C 11.002942,28.403251 11.009957,28.463461 11.009958,28.51607 L 11.009958,30.26099 L 10.561013,30.26099 L 10.561013,27.7462 L 11.095888,27.7462 L 12.249816,29.466569 C 12.276704,29.508658 12.304178,29.558931 12.332239,29.617386 L 12.342761,29.617386 C 12.331068,29.5601 12.325222,29.491122 12.325224,29.410451 L 12.325224,27.7462 L 12.781183,27.7462 L 12.781183,30.26099 M 15.169707,27.7462 L 14.340212,29.308737 L 14.340212,30.26099 L 13.859701,30.26099 L 13.859701,29.319259 L 13.051251,27.7462 L 13.586126,27.7462 L 13.922834,28.509055 C 14.026885,28.742882 14.084173,28.874993 14.094696,28.905389 C 14.105217,28.935787 14.112816,28.961508 14.117494,28.982551 L 14.121001,28.982551 C 14.13503,28.935787 14.147305,28.901298 14.157829,28.879083 L 14.675167,27.7462 L 15.169707,27.7462"
524 id="text3387" />
525 <path
526 transform="scale(1.290708,0.774769)"
527 style="font-size:3.59155273px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Segoe"
528 d="M 5.7944829,27.518018 L 6.602933,27.518018 C 6.9045659,27.518021 7.1331297,27.582907 7.288625,27.712677 C 7.4441167,27.842452 7.5218635,28.03302 7.5218655,28.28438 C 7.5218635,28.525221 7.4347637,28.724557 7.260566,28.882387 C 7.0875339,29.039051 6.8490326,29.117382 6.5450613,29.117381 L 6.2802545,29.117381 L 6.2802545,30.032806 L 5.7944829,30.032806 L 5.7944829,27.518018 M 6.2802545,28.733324 L 6.5380466,28.733324 C 6.702892,28.733325 6.8268192,28.697082 6.9098284,28.624595 C 6.9928348,28.552111 7.0343387,28.443382 7.0343403,28.298409 C 7.0343387,28.163962 6.9928348,28.063417 6.9098284,27.996775 C 6.8268192,27.928968 6.702892,27.895063 6.5380466,27.895061 L 6.2802545,27.895061 L 6.2802545,28.733324 M 8.968658,27.482944 C 9.3088717,27.482947 9.5830313,27.59869 9.7911376,27.830174 C 9.9992395,28.060494 10.103292,28.367389 10.103294,28.750861 C 10.103292,29.148364 9.994563,29.46695 9.7771081,29.70662 C 9.5596488,29.945122 9.2697061,30.064373 8.9072789,30.064373 C 8.5588786,30.064373 8.2771197,29.948629 8.0620013,29.717143 C 7.8480512,29.485656 7.7410763,29.181684 7.7410765,28.805225 C 7.7410763,28.405386 7.8533122,28.085046 8.0777845,27.844204 C 8.303425,27.603367 8.6003825,27.482947 8.968658,27.482944 M 8.9160473,29.659271 C 9.1253192,29.659271 9.2942577,29.582109 9.4228631,29.427784 C 9.551465,29.27346 9.6157668,29.06068 9.6157688,28.789442 C 9.6157668,28.512361 9.5520495,28.294319 9.4246168,28.135316 C 9.2983496,27.975148 9.1288266,27.895063 8.9160473,27.895061 C 8.7079419,27.895063 8.5401726,27.975733 8.4127389,28.13707 C 8.2853036,28.297242 8.2215863,28.512361 8.2215869,28.782427 C 8.2215863,29.050158 8.2853036,29.263523 8.4127389,29.422523 C 8.5413418,29.580355 8.7091111,29.659271 8.9160473,29.659271 M 12.781175,30.032806 L 12.27436,30.032806 L 11.074837,28.261582 C 11.044439,28.219495 11.019303,28.168054 10.999429,28.107257 L 10.988906,28.107257 C 11.002935,28.175068 11.00995,28.235278 11.009951,28.287887 L 11.009951,30.032806 L 10.561007,30.032806 L 10.561007,27.518018 L 11.095881,27.518018 L 12.249808,29.238386 C 12.276696,29.280475 12.30417,29.330747 12.332231,29.389203 L 12.342753,29.389203 C 12.33106,29.331917 12.325214,29.262938 12.325217,29.182268 L 12.325217,27.518018 L 12.781175,27.518018 L 12.781175,30.032806 M 15.169698,27.518018 L 14.340204,29.080554 L 14.340204,30.032806 L 13.859693,30.032806 L 13.859693,29.091076 L 13.051243,27.518018 L 13.586118,27.518018 L 13.922826,28.280872 C 14.026877,28.514699 14.084164,28.64681 14.094688,28.677206 C 14.105209,28.707604 14.112808,28.733325 14.117486,28.754368 L 14.120993,28.754368 C 14.135021,28.707604 14.147297,28.673115 14.15782,28.6509 L 14.675158,27.518018 L 15.169698,27.518018"
529 id="text4264" />
530 <path
531 style="opacity:0.28140702;color:#000000;fill:url(#linearGradient6019);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
532 d="M 30.03125,20.000248 C 28.64685,20.035361 27.531249,21.169936 27.53125,22.562748 C 27.53125,23.977669 28.678829,25.125247 30.09375,25.125248 C 31.000184,25.125248 31.983569,23.968998 33,23.968998 C 34.018351,23.968998 34.964145,25.125247 35.875,25.125248 C 37.289921,25.125248 38.437502,23.977669 38.4375,22.562748 C 38.4375,21.147827 37.289921,20.000249 35.875,20.000248 C 34.955302,20.000248 34.080743,21.218998 33,21.218998 C 31.856856,21.218998 31.009027,20.000249 30.09375,20.000248 C 30.071642,20.000248 30.053225,19.999691 30.03125,20.000248 z "
533 id="path5141"
534 sodipodi:nodetypes="csszssszsc" />
535 <path
536 sodipodi:type="arc"
537 style="opacity:1;color:#000000;fill:url(#radialGradient8650);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
538 id="path7769"
539 sodipodi:cx="32.125"
540 sodipodi:cy="22.4375"
541 sodipodi:rx="1.21875"
542 sodipodi:ry="1.21875"
543 d="M 33.34375 22.4375 A 1.21875 1.21875 0 1 1 30.90625,22.4375 A 1.21875 1.21875 0 1 1 33.34375 22.4375 z"
544 transform="matrix(1.282051,0,0,1.282051,-11.15465,-6.20352)" />
545 <path
546 transform="matrix(1.282051,0,0,1.282051,-5.15465,-6.20352)"
547 d="M 33.34375 22.4375 A 1.21875 1.21875 0 1 1 30.90625,22.4375 A 1.21875 1.21875 0 1 1 33.34375 22.4375 z"
548 sodipodi:ry="1.21875"
549 sodipodi:rx="1.21875"
550 sodipodi:cy="22.4375"
551 sodipodi:cx="32.125"
552 id="path8652"
553 style="opacity:1;color:#000000;fill:url(#radialGradient8654);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
554 sodipodi:type="arc" />
555 <path
556 sodipodi:type="arc"
557 style="opacity:1;color:#000000;fill:url(#radialGradient9541);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
558 id="path9539"
559 sodipodi:cx="32.125"
560 sodipodi:cy="22.4375"
561 sodipodi:rx="1.21875"
562 sodipodi:ry="1.21875"
563 d="M 33.34375 22.4375 A 1.21875 1.21875 0 1 1 30.90625,22.4375 A 1.21875 1.21875 0 1 1 33.34375 22.4375 z"
564 transform="matrix(0.871794,0,0,0.871794,-18.94388,17.50162)" />
565 <path
566 transform="matrix(0.871794,0,0,0.871794,-15.94388,17.37662)"
567 d="M 33.34375 22.4375 A 1.21875 1.21875 0 1 1 30.90625,22.4375 A 1.21875 1.21875 0 1 1 33.34375 22.4375 z"
568 sodipodi:ry="1.21875"
569 sodipodi:rx="1.21875"
570 sodipodi:cy="22.4375"
571 sodipodi:cx="32.125"
572 id="path9543"
573 style="opacity:1;color:#000000;fill:url(#radialGradient9545);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
574 sodipodi:type="arc" />
575 <path
576 sodipodi:type="arc"
577 style="opacity:1;color:#000000;fill:url(#radialGradient9549);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
578 id="path9547"
579 sodipodi:cx="32.125"
580 sodipodi:cy="22.4375"
581 sodipodi:rx="1.21875"
582 sodipodi:ry="1.21875"
583 d="M 33.34375 22.4375 A 1.21875 1.21875 0 1 1 30.90625,22.4375 A 1.21875 1.21875 0 1 1 33.34375 22.4375 z"
584 transform="matrix(0.871794,0,0,0.871794,-12.94388,17.50162)" />
585 <path
586 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient2387);stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
587 d="M 40.447811,37.298096 C 40.447811,37.298096 46.86789,36.302113 46.458219,33.32062 C 46.060472,30.425901 42.922686,30.845747 42.922686,30.845747"
588 id="path10458"
589 sodipodi:nodetypes="czc" />
590 <rect
591 style="opacity:1;color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:#bebebe;stroke-width:0.99999875;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
592 id="rect9531"
593 width="17.500879"
594 height="4.0658607"
595 x="11.994141"
596 y="45.880501"
597 rx="2.0329304"
598 ry="2.0329304"
599 transform="matrix(0.954928,-0.296837,0.296837,0.954928,0,0)" />
600 <path
601 transform="translate(-4.822191,-1.763958)"
602 d="M 26.870057 40.840546 A 0.61871845 0.61871845 0 1 1 25.632621,40.840546 A 0.61871845 0.61871845 0 1 1 26.870057 40.840546 z"
603 sodipodi:ry="0.61871845"
604 sodipodi:rx="0.61871845"
605 sodipodi:cy="40.840546"
606 sodipodi:cx="26.251339"
607 id="path2367"
608 style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
609 sodipodi:type="arc" />
610 <path
611 sodipodi:type="arc"
612 style="opacity:1;color:#000000;fill:#959595;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
613 id="path9533"
614 sodipodi:cx="26.251339"
615 sodipodi:cy="40.840546"
616 sodipodi:rx="0.61871845"
617 sodipodi:ry="0.61871845"
618 d="M 26.870057 40.840546 A 0.61871845 0.61871845 0 1 1 25.632621,40.840546 A 0.61871845 0.61871845 0 1 1 26.870057 40.840546 z"
619 transform="translate(-4.947191,-1.951458)" />
620 <path
621 transform="translate(-3.540561,-3.929473)"
622 sodipodi:type="arc"
623 style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
624 id="path2369"
625 sodipodi:cx="26.251339"
626 sodipodi:cy="40.840546"
627 sodipodi:rx="0.61871845"
628 sodipodi:ry="0.61871845"
629 d="M 26.870057 40.840546 A 0.61871845 0.61871845 0 1 1 25.632621,40.840546 A 0.61871845 0.61871845 0 1 1 26.870057 40.840546 z" />
630 <path
631 d="M 26.870057 40.840546 A 0.61871845 0.61871845 0 1 1 25.632621,40.840546 A 0.61871845 0.61871845 0 1 1 26.870057 40.840546 z"
632 sodipodi:ry="0.61871845"
633 sodipodi:rx="0.61871845"
634 sodipodi:cy="40.840546"
635 sodipodi:cx="26.251339"
636 id="path10408"
637 style="opacity:1;color:#000000;fill:#959595;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
638 sodipodi:type="arc"
639 transform="translate(-3.665561,-4.116973)" />
640 <path
641 transform="translate(-1.507621,-5.034327)"
642 sodipodi:type="arc"
643 style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
644 id="path2371"
645 sodipodi:cx="26.251339"
646 sodipodi:cy="40.840546"
647 sodipodi:rx="0.61871845"
648 sodipodi:ry="0.61871845"
649 d="M 26.870057 40.840546 A 0.61871845 0.61871845 0 1 1 25.632621,40.840546 A 0.61871845 0.61871845 0 1 1 26.870057 40.840546 z" />
650 <path
651 transform="translate(-1.632621,-5.221827)"
652 sodipodi:type="arc"
653 style="opacity:1;color:#000000;fill:#c4c4c4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
654 id="path10410"
655 sodipodi:cx="26.251339"
656 sodipodi:cy="40.840546"
657 sodipodi:rx="0.61871845"
658 sodipodi:ry="0.61871845"
659 d="M 26.870057 40.840546 A 0.61871845 0.61871845 0 1 1 25.632621,40.840546 A 0.61871845 0.61871845 0 1 1 26.870057 40.840546 z" />
660 <path
661 d="M 26.870057 40.840546 A 0.61871845 0.61871845 0 1 1 25.632621,40.840546 A 0.61871845 0.61871845 0 1 1 26.870057 40.840546 z"
662 sodipodi:ry="0.61871845"
663 sodipodi:rx="0.61871845"
664 sodipodi:cy="40.840546"
665 sodipodi:cx="26.251339"
666 id="path10412"
667 style="opacity:1;color:#000000;fill:#959595;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
668 sodipodi:type="arc"
669 transform="translate(-1.632621,-5.221827)" />
670 <rect
671 transform="matrix(0.954928,-0.296837,0.296837,0.954928,0,0)"
672 ry="1.946794"
673 rx="2.0329304"
674 y="45.880501"
675 x="11.994141"
676 height="3.9619126"
677 width="12.997741"
678 id="rect10456"
679 style="opacity:1;color:#000000;fill:url(#linearGradient2379);fill-opacity:1.0;fill-rule:evenodd;stroke:#bebebe;stroke-width:0.99999875;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible" />
680 <path
681 style="opacity:0.58333333;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
682 d="M 11.5625,10.658537 L 11.5625,12.341463 L 13,11.464939 L 11.5625,10.658537 z "
683 id="path1466" />
684 <path
685 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Alexis;opacity:0.51666667"
686 d="M 14.46875,10.223621 L 14.46875,10.176186 C 14.473268,10.155857 14.484561,10.135528 14.502632,10.115199 C 14.522961,10.094871 14.545549,10.0768 14.570396,10.060987 C 14.595242,10.042918 14.620089,10.028236 14.644936,10.016941 C 14.672042,10.005647 14.694629,10.000001 14.7127,10 L 15.817252,10 L 15.817252,10.711521 C 15.810474,10.729591 15.798051,10.748791 15.779982,10.76912 C 15.76191,10.787191 15.741581,10.805262 15.718994,10.823332 C 15.696405,10.839143 15.672688,10.852696 15.647842,10.86399 C 15.625253,10.875284 15.606053,10.880931 15.590243,10.880931 L 15.583467,10.880931 L 14.46875,10.880931 L 14.46875,10.223621 M 15.549585,10.206679 L 14.871946,10.206679 C 14.838063,10.217974 14.812087,10.232657 14.794017,10.250726 C 14.775946,10.268797 14.762394,10.291386 14.753359,10.31849 L 14.753359,10.677639 L 15.414057,10.677639 C 15.461491,10.666345 15.494244,10.652793 15.512315,10.636981 C 15.530384,10.62117 15.542808,10.595194 15.549585,10.559052 L 15.549585,10.206679 M 15.956962,10 L 15.956962,10.880931 L 16.234795,10.880931 L 16.234795,10.525171 L 16.773518,10.525171 C 16.789328,10.525171 16.802881,10.529688 16.814176,10.538723 C 16.827728,10.547758 16.840151,10.560182 16.851446,10.575993 C 16.862739,10.589546 16.874033,10.604229 16.885328,10.62004 C 16.89888,10.633593 16.911303,10.646016 16.922598,10.65731 C 16.940667,10.682157 16.97342,10.756697 17.020856,10.880931 L 17.356288,10.880931 C 17.356286,10.851567 17.349509,10.818814 17.335959,10.782673 C 17.322404,10.746532 17.304334,10.709262 17.281747,10.670863 C 17.259157,10.632464 17.233182,10.595194 17.203819,10.559052 C 17.176712,10.522912 17.147348,10.490159 17.115726,10.460795 L 17.356288,10.460795 C 17.351768,10.431431 17.341604,10.399808 17.325794,10.365925 C 17.30998,10.329785 17.279487,10.284609 17.234313,10.230397 C 17.211723,10.205551 17.185747,10.179575 17.156384,10.152469 C 17.127019,10.125364 17.093136,10.101647 17.054738,10.081317 C 17.018596,10.058729 16.979067,10.040659 16.936152,10.027105 C 16.895492,10.011295 16.852575,10.00226 16.807399,10 L 15.956962,10 M 16.234795,10.355761 L 16.234795,10.18635 L 16.759965,10.18635 C 16.773517,10.190869 16.78707,10.196516 16.800623,10.203292 C 16.814175,10.210069 16.831116,10.223622 16.851446,10.24395 C 16.871774,10.26428 16.887586,10.284609 16.898881,10.304938 C 16.910174,10.325267 16.918079,10.342208 16.922598,10.355761 L 16.234795,10.355761 M 17.494886,10 L 17.494886,10.880931 L 18.894211,10.880931 C 18.89421,10.851567 18.887433,10.818814 18.873882,10.782673 C 18.860328,10.746532 18.842257,10.709262 18.819671,10.670863 C 18.797081,10.632464 18.771105,10.595194 18.741742,10.559052 C 18.714636,10.522912 18.685271,10.490159 18.653649,10.460795 L 18.894211,10.460795 C 18.889692,10.431431 18.879527,10.400937 18.863717,10.369313 C 18.847904,10.335432 18.81741,10.290256 18.772236,10.233786 C 18.751906,10.20668 18.725929,10.179575 18.694307,10.152469 C 18.664942,10.125364 18.63106,10.101647 18.592662,10.081317 C 18.556519,10.058729 18.51699,10.040659 18.474074,10.027105 C 18.433416,10.011295 18.390498,10.00226 18.345323,10 L 17.494886,10 M 17.776106,10.694581 L 17.776106,10.525171 L 18.311442,10.525171 C 18.336287,10.525171 18.361134,10.542112 18.385981,10.575993 C 18.410827,10.607616 18.430027,10.647145 18.443581,10.694581 L 17.776106,10.694581 M 17.772718,10.355761 L 17.772718,10.18635 L 18.297888,10.18635 C 18.311441,10.190869 18.324993,10.196516 18.338547,10.203292 C 18.352099,10.210069 18.36904,10.223622 18.38937,10.24395 C 18.409698,10.26428 18.425509,10.284609 18.436804,10.304938 C 18.448097,10.325267 18.456003,10.342208 18.460522,10.355761 L 17.772718,10.355761 M 19.04173,10 L 19.04173,10.880931 L 19.326338,10.880931 L 19.326338,10 L 19.04173,10 M 20.558345,10.18635 L 20.558345,10 L 19.47751,10 L 19.47751,10.18635 L 19.870541,10.18635 L 19.870541,10.880931 L 20.165315,10.880931 L 20.165315,10.267667 L 20.165315,10.18635 L 20.558345,10.18635 M 20.699194,10.880931 L 20.699194,10.182963 C 20.708229,10.160375 20.721781,10.137787 20.739852,10.115199 C 20.760181,10.092612 20.782768,10.073412 20.807616,10.057599 C 20.832462,10.03953 20.857309,10.025977 20.882156,10.016941 C 20.907003,10.005647 20.929591,10.000001 20.94992,10 L 22.054472,10 L 22.054472,10.880931 L 21.769864,10.880931 L 21.769864,10.65731 L 20.970249,10.65731 L 20.970249,10.880931 L 20.699194,10.880931 M 21.769864,10.4879 L 21.769864,10.206679 L 21.109166,10.206679 C 21.061729,10.217974 21.028978,10.231527 21.010907,10.247338 C 20.992836,10.263151 20.979284,10.286867 20.970249,10.31849 L 20.970249,10.4879 L 21.769864,10.4879 M 22.178141,10 L 22.466138,10 L 22.466138,10.609875 C 22.484208,10.655052 22.525995,10.683287 22.591501,10.694581 L 23.262364,10.694581 L 23.262364,10.880931 L 22.449197,10.880931 C 22.424349,10.880931 22.396115,10.874155 22.364492,10.860602 C 22.332868,10.844791 22.303504,10.825591 22.276399,10.803003 C 22.249293,10.778156 22.225576,10.75218 22.205247,10.725074 C 22.187176,10.69571 22.178141,10.668604 22.178141,10.643758 L 22.178141,10 M 24.828372,10.355761 L 24.828372,10.525171 L 24.204944,10.525171 L 24.204944,10.355761 L 24.828372,10.355761 M 25.804888,10 L 25.804888,10.880931 L 26.089496,10.880931 L 26.089496,10 L 25.804888,10 M 28.726334,10 L 28.726334,10.697968 C 28.717297,10.720556 28.702615,10.743145 28.682287,10.765733 C 28.664215,10.786061 28.642756,10.805262 28.617911,10.823332 C 28.595322,10.839143 28.570475,10.852696 28.543371,10.86399 C 28.518523,10.875284 28.495935,10.880931 28.475607,10.880931 L 28.011424,10.880931 L 28.011424,10.745403 C 27.95947,10.790579 27.915425,10.824461 27.879284,10.847049 C 27.843143,10.869637 27.809261,10.880931 27.777638,10.880931 L 27.059341,10.880931 L 27.059341,10 L 27.34395,10 L 27.34395,10.674251 L 27.618393,10.674251 C 27.665828,10.662957 27.69858,10.649404 27.716652,10.633593 C 27.734721,10.617781 27.748273,10.594064 27.757309,10.562441 L 27.757309,10 L 28.028365,10 L 28.028365,10.674251 L 28.316362,10.674251 C 28.363795,10.662957 28.396548,10.649404 28.41462,10.633593 C 28.432689,10.617781 28.446241,10.594064 28.455278,10.562441 L 28.455278,10 L 28.726334,10 M 28.87147,10 L 28.87147,10.880931 L 29.156079,10.880931 L 29.156079,10 L 28.87147,10 M 29.307251,10.687803 L 29.307251,10.880931 L 30.489731,10.880931 C 30.523611,10.880931 30.555235,10.873026 30.5846,10.857213 C 30.613963,10.839143 30.638811,10.817685 30.659141,10.792838 C 30.681728,10.765733 30.698669,10.736368 30.709964,10.704745 C 30.723515,10.673122 30.730292,10.641499 30.730293,10.609875 C 30.730292,10.589546 30.725774,10.5647 30.71674,10.535335 C 30.707704,10.505971 30.69528,10.477736 30.67947,10.45063 C 30.665916,10.423525 30.647846,10.400937 30.625259,10.382866 C 30.602669,10.364797 30.578952,10.355761 30.554107,10.355761 L 29.710446,10.355761 C 29.70141,10.339949 29.696893,10.328655 29.696893,10.321879 C 29.696893,10.312844 29.698022,10.304939 29.700282,10.298161 C 29.704798,10.291386 29.710446,10.28235 29.717223,10.271056 C 29.730775,10.252986 29.746586,10.234916 29.764657,10.216844 C 29.784986,10.196516 29.79515,10.186351 29.795151,10.18635 L 30.62187,10.18635 L 30.62187,10 L 29.795151,10 C 29.722868,10.000001 29.657364,10.014683 29.598636,10.044047 C 29.542165,10.073412 29.492471,10.112941 29.449555,10.162634 C 29.408897,10.210069 29.377273,10.265409 29.354685,10.328655 C 29.332097,10.391902 29.320803,10.457406 29.320803,10.525171 L 30.323709,10.525171 C 30.328226,10.525171 30.335002,10.536464 30.344039,10.559052 C 30.353072,10.579382 30.35759,10.596322 30.357592,10.609875 C 30.35759,10.62117 30.353072,10.636981 30.344039,10.65731 C 30.335002,10.677639 30.325967,10.687804 30.316933,10.687803 L 29.307251,10.687803 M 30.863703,10 L 30.863703,10.880931 L 31.148312,10.880931 L 31.148312,10.528558 L 31.934373,10.528558 L 31.934373,10.880931 L 32.218982,10.880931 L 32.218982,10 L 31.927597,10 L 31.927597,10.355761 L 31.1517,10.355761 L 31.1517,10 L 30.863703,10 M 33.184141,10 L 33.184141,10.880931 L 33.46875,10.880931 L 33.46875,10 L 33.184141,10"
687 id="text2341" />
688 <path
689 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Segoe;opacity:0.47666667"
690 d="M 15.540446,13 L 15,13 L 15,12 L 15.140167,12 L 15.140167,12.873082 L 15.540446,12.873082 L 15.540446,13 M 15.685495,12 L 15.960949,12 C 16.072525,12.000001 16.157834,12.025803 16.216877,12.077405 C 16.276383,12.129011 16.306136,12.201767 16.306137,12.295676 C 16.306136,12.388192 16.273129,12.465133 16.207113,12.526499 C 16.141562,12.587866 16.050907,12.61855 15.935147,12.618549 L 15.822176,12.618549 L 15.822176,13 L 15.685495,13 L 15.685495,12 M 15.822176,12.49721 L 15.936542,12.49721 C 16.01232,12.497211 16.070665,12.480474 16.111577,12.447002 C 16.152952,12.413064 16.17364,12.364714 16.173641,12.301953 C 16.17364,12.242446 16.154114,12.19642 16.115063,12.163877 C 16.076476,12.130869 16.020688,12.114366 15.947699,12.114365 L 15.822176,12.114365 L 15.822176,12.49721"
691 id="text2346" />
692 </g>
693</svg>
diff --git a/utils/rbutilqt/icons/network-idle.svg b/utils/rbutilqt/icons/network-idle.svg
new file mode 100644
index 0000000000..8201ad256a
--- /dev/null
+++ b/utils/rbutilqt/icons/network-idle.svg
@@ -0,0 +1,1370 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="48.000000px"
13 height="48.000000px"
14 id="svg2327"
15 sodipodi:version="0.32"
16 inkscape:version="0.46"
17 sodipodi:docbase="/home/dobey/network-status icons/scalable/status"
18 sodipodi:docname="network-idle.svg"
19 inkscape:output_extension="org.inkscape.output.svg.inkscape">
20 <defs
21 id="defs3">
22 <inkscape:perspective
23 sodipodi:type="inkscape:persp3d"
24 inkscape:vp_x="0 : 24 : 1"
25 inkscape:vp_y="0 : 1000 : 0"
26 inkscape:vp_z="48 : 24 : 1"
27 inkscape:persp3d-origin="24 : 16 : 1"
28 id="perspective185" />
29 <linearGradient
30 id="linearGradient2985"
31 inkscape:collect="always">
32 <stop
33 id="stop2987"
34 offset="0"
35 style="stop-color:#d8dfd6;stop-opacity:1;" />
36 <stop
37 id="stop2989"
38 offset="1"
39 style="stop-color:#d8dfd6;stop-opacity:0;" />
40 </linearGradient>
41 <linearGradient
42 id="linearGradient2752">
43 <stop
44 id="stop2754"
45 offset="0"
46 style="stop-color:#9d9d9d;stop-opacity:1;" />
47 <stop
48 id="stop2756"
49 offset="1.0000000"
50 style="stop-color:#b9b9b9;stop-opacity:1.0000000;" />
51 </linearGradient>
52 <linearGradient
53 id="linearGradient2711">
54 <stop
55 id="stop2713"
56 offset="0.0000000"
57 style="stop-color:#909090;stop-opacity:1.0000000;" />
58 <stop
59 id="stop2715"
60 offset="1.0000000"
61 style="stop-color:#bebebe;stop-opacity:0.0000000;" />
62 </linearGradient>
63 <linearGradient
64 id="linearGradient2701">
65 <stop
66 id="stop2703"
67 offset="0.0000000"
68 style="stop-color:#585956;stop-opacity:1.0000000;" />
69 <stop
70 id="stop2705"
71 offset="1.0000000"
72 style="stop-color:#bbbeb8;stop-opacity:1.0000000;" />
73 </linearGradient>
74 <linearGradient
75 id="linearGradient2691">
76 <stop
77 id="stop2693"
78 offset="0.0000000"
79 style="stop-color:#868686;stop-opacity:1.0000000;" />
80 <stop
81 id="stop2695"
82 offset="1.0000000"
83 style="stop-color:#e9e9e9;stop-opacity:1.0000000;" />
84 </linearGradient>
85 <linearGradient
86 id="linearGradient2683"
87 inkscape:collect="always">
88 <stop
89 id="stop2685"
90 offset="0"
91 style="stop-color:#000000;stop-opacity:1;" />
92 <stop
93 id="stop2687"
94 offset="1"
95 style="stop-color:#000000;stop-opacity:0;" />
96 </linearGradient>
97 <linearGradient
98 id="linearGradient2675">
99 <stop
100 id="stop2677"
101 offset="0.0000000"
102 style="stop-color:#5b5b97;stop-opacity:1.0000000;" />
103 <stop
104 id="stop2679"
105 offset="1.0000000"
106 style="stop-color:#1b1b43;stop-opacity:1.0000000;" />
107 </linearGradient>
108 <linearGradient
109 id="linearGradient2667">
110 <stop
111 id="stop2669"
112 offset="0.0000000"
113 style="stop-color:#ffffff;stop-opacity:1.0000000;" />
114 <stop
115 id="stop2671"
116 offset="1.0000000"
117 style="stop-color:#fcfcff;stop-opacity:0.0000000;" />
118 </linearGradient>
119 <linearGradient
120 id="linearGradient2635"
121 inkscape:collect="always">
122 <stop
123 id="stop2637"
124 offset="0"
125 style="stop-color:#f9fff5;stop-opacity:1;" />
126 <stop
127 id="stop2639"
128 offset="1"
129 style="stop-color:#f9fff5;stop-opacity:0;" />
130 </linearGradient>
131 <linearGradient
132 id="linearGradient2623">
133 <stop
134 id="stop2625"
135 offset="0.0000000"
136 style="stop-color:#dfdfde;stop-opacity:1.0000000;" />
137 <stop
138 id="stop2627"
139 offset="1.0000000"
140 style="stop-color:#9d9f9a;stop-opacity:1.0000000;" />
141 </linearGradient>
142 <linearGradient
143 inkscape:collect="always"
144 id="linearGradient2454">
145 <stop
146 style="stop-color:#000000;stop-opacity:1;"
147 offset="0"
148 id="stop2456" />
149 <stop
150 style="stop-color:#000000;stop-opacity:0;"
151 offset="1"
152 id="stop2458" />
153 </linearGradient>
154 <linearGradient
155 inkscape:collect="always"
156 id="linearGradient2415">
157 <stop
158 style="stop-color:#ffffff;stop-opacity:1;"
159 offset="0"
160 id="stop2417" />
161 <stop
162 style="stop-color:#ffffff;stop-opacity:0;"
163 offset="1"
164 id="stop2419" />
165 </linearGradient>
166 <linearGradient
167 id="linearGradient2379">
168 <stop
169 style="stop-color:#1a4876;stop-opacity:1.0000000;"
170 offset="0.0000000"
171 id="stop2381" />
172 <stop
173 style="stop-color:#3f54a3;stop-opacity:0.0000000;"
174 offset="1.0000000"
175 id="stop2383" />
176 </linearGradient>
177 <linearGradient
178 inkscape:collect="always"
179 id="linearGradient2328">
180 <stop
181 style="stop-color:#ffffff;stop-opacity:1;"
182 offset="0"
183 id="stop2330" />
184 <stop
185 style="stop-color:#ffffff;stop-opacity:0;"
186 offset="1"
187 id="stop2332" />
188 </linearGradient>
189 <linearGradient
190 inkscape:collect="always"
191 id="linearGradient2307">
192 <stop
193 style="stop-color:#5a7aa4;stop-opacity:1;"
194 offset="0"
195 id="stop2309" />
196 <stop
197 style="stop-color:#5a7aa4;stop-opacity:0;"
198 offset="1"
199 id="stop2311" />
200 </linearGradient>
201 <linearGradient
202 id="linearGradient2253">
203 <stop
204 style="stop-color:#8f8f8f;stop-opacity:1.0000000;"
205 offset="0.0000000"
206 id="stop2255" />
207 <stop
208 style="stop-color:#494949;stop-opacity:1.0000000;"
209 offset="1.0000000"
210 id="stop2257" />
211 </linearGradient>
212 <linearGradient
213 id="linearGradient2245">
214 <stop
215 style="stop-color:#dde1d9;stop-opacity:1.0000000;"
216 offset="0.0000000"
217 id="stop2247" />
218 <stop
219 style="stop-color:#cacdc6;stop-opacity:1.0000000;"
220 offset="1.0000000"
221 id="stop2249" />
222 </linearGradient>
223 <linearGradient
224 inkscape:collect="always"
225 xlink:href="#linearGradient2245"
226 id="linearGradient2251"
227 gradientTransform="matrix(1.129863,0.000000,0.000000,0.885063,-1.625000,-1.304372)"
228 x1="8.6116238"
229 y1="7.2293582"
230 x2="34.784473"
231 y2="33.339787"
232 gradientUnits="userSpaceOnUse" />
233 <linearGradient
234 inkscape:collect="always"
235 xlink:href="#linearGradient2307"
236 id="linearGradient2313"
237 gradientTransform="matrix(1.208393,0.000000,0.000000,0.984410,-0.789284,-0.503380)"
238 x1="16.851954"
239 y1="9.3235140"
240 x2="24.418941"
241 y2="53.734985"
242 gradientUnits="userSpaceOnUse" />
243 <linearGradient
244 inkscape:collect="always"
245 xlink:href="#linearGradient2328"
246 id="linearGradient2334"
247 gradientTransform="matrix(1.289166,0.000000,0.000000,0.922731,-0.789284,-0.503380)"
248 x1="16.119127"
249 y1="10.842293"
250 x2="27.289009"
251 y2="39.031910"
252 gradientUnits="userSpaceOnUse" />
253 <linearGradient
254 inkscape:collect="always"
255 xlink:href="#linearGradient2415"
256 id="linearGradient2421"
257 gradientTransform="matrix(1.108069,0.000000,0.000000,0.902471,1.000000,1.000000)"
258 x1="17.698339"
259 y1="13.004725"
260 x2="34.974548"
261 y2="55.200756"
262 gradientUnits="userSpaceOnUse" />
263 <linearGradient
264 inkscape:collect="always"
265 xlink:href="#linearGradient2379"
266 id="linearGradient2445"
267 gradientUnits="userSpaceOnUse"
268 gradientTransform="matrix(1.027870,0.000000,0.000000,0.822296,1.523986,1.001198)"
269 x1="21.356108"
270 y1="30.078255"
271 x2="19.994572"
272 y2="-1.3221773" />
273 <radialGradient
274 inkscape:collect="always"
275 xlink:href="#linearGradient2454"
276 id="radialGradient2460"
277 gradientTransform="scale(1.925808,0.519262)"
278 cx="12.575710"
279 cy="67.501709"
280 fx="12.575710"
281 fy="67.501709"
282 r="8.7662794"
283 gradientUnits="userSpaceOnUse" />
284 <radialGradient
285 inkscape:collect="always"
286 xlink:href="#linearGradient2454"
287 id="radialGradient2464"
288 gradientUnits="userSpaceOnUse"
289 gradientTransform="scale(1.925808,0.519262)"
290 cx="12.575710"
291 cy="67.501709"
292 fx="12.575710"
293 fy="67.501709"
294 r="8.7662794" />
295 <linearGradient
296 y2="92.570930"
297 x2="10.728384"
298 y1="84.029198"
299 x1="10.728384"
300 gradientTransform="scale(1.983556,0.504145)"
301 gradientUnits="userSpaceOnUse"
302 id="linearGradient2653"
303 xlink:href="#linearGradient2623"
304 inkscape:collect="always" />
305 <linearGradient
306 y2="74.098007"
307 x2="8.6485014"
308 y1="101.28460"
309 x1="13.628710"
310 gradientTransform="scale(2.143634,0.466498)"
311 gradientUnits="userSpaceOnUse"
312 id="linearGradient2655"
313 xlink:href="#linearGradient2635"
314 inkscape:collect="always" />
315 <radialGradient
316 r="8.7662794"
317 fy="67.501709"
318 fx="12.575710"
319 cy="67.501709"
320 cx="12.575710"
321 gradientTransform="scale(1.925808,0.519262)"
322 gradientUnits="userSpaceOnUse"
323 id="radialGradient2659"
324 xlink:href="#linearGradient2454"
325 inkscape:collect="always" />
326 <linearGradient
327 gradientUnits="userSpaceOnUse"
328 y2="26.729263"
329 x2="17.199417"
330 y1="1.6537577"
331 x1="11.492236"
332 gradientTransform="matrix(1.238977,0.000000,0.000000,0.895955,0.590553,-1.331524)"
333 id="linearGradient2673"
334 xlink:href="#linearGradient2667"
335 inkscape:collect="always" />
336 <linearGradient
337 gradientUnits="userSpaceOnUse"
338 y2="8.8666229"
339 x2="16.315819"
340 y1="32.622238"
341 x1="19.150396"
342 gradientTransform="matrix(1.174139,0.000000,0.000000,0.945431,0.721825,-1.331524)"
343 id="linearGradient2681"
344 xlink:href="#linearGradient2675"
345 inkscape:collect="always" />
346 <linearGradient
347 gradientUnits="userSpaceOnUse"
348 y2="162.45061"
349 x2="3.7069974"
350 y1="171.29134"
351 x1="3.7069976"
352 gradientTransform="matrix(5.705159,0.000000,0.000000,0.175280,1.000000,-0.679373)"
353 id="linearGradient2689"
354 xlink:href="#linearGradient2683"
355 inkscape:collect="always" />
356 <linearGradient
357 gradientUnits="userSpaceOnUse"
358 y2="64.892525"
359 x2="12.127711"
360 y1="53.535141"
361 x1="12.206709"
362 gradientTransform="scale(1.816345,0.550556)"
363 id="linearGradient2707"
364 xlink:href="#linearGradient2701"
365 inkscape:collect="always" />
366 <linearGradient
367 gradientUnits="userSpaceOnUse"
368 y2="3.8451097"
369 x2="35.520542"
370 y1="3.9384086"
371 x1="34.300991"
372 id="linearGradient2717"
373 xlink:href="#linearGradient2711"
374 inkscape:collect="always" />
375 <linearGradient
376 y2="3.8451097"
377 x2="35.520542"
378 y1="3.9384086"
379 x1="34.300991"
380 gradientUnits="userSpaceOnUse"
381 id="linearGradient2721"
382 xlink:href="#linearGradient2711"
383 inkscape:collect="always" />
384 <linearGradient
385 y2="3.8451097"
386 x2="35.520542"
387 y1="3.9384086"
388 x1="34.300991"
389 gradientUnits="userSpaceOnUse"
390 id="linearGradient2725"
391 xlink:href="#linearGradient2711"
392 inkscape:collect="always" />
393 <linearGradient
394 y2="3.8451097"
395 x2="35.520542"
396 y1="3.9384086"
397 x1="34.300991"
398 gradientUnits="userSpaceOnUse"
399 id="linearGradient2729"
400 xlink:href="#linearGradient2711"
401 inkscape:collect="always" />
402 <linearGradient
403 y2="3.8451097"
404 x2="35.520542"
405 y1="3.9384086"
406 x1="34.300991"
407 gradientUnits="userSpaceOnUse"
408 id="linearGradient2733"
409 xlink:href="#linearGradient2711"
410 inkscape:collect="always" />
411 <linearGradient
412 y2="74.098007"
413 x2="8.6485014"
414 y1="101.28460"
415 x1="13.628710"
416 gradientTransform="matrix(2.143634,0.000000,0.000000,0.466498,1.000000,-0.508826)"
417 gradientUnits="userSpaceOnUse"
418 id="linearGradient2741"
419 xlink:href="#linearGradient2635"
420 inkscape:collect="always" />
421 <linearGradient
422 gradientUnits="userSpaceOnUse"
423 y2="100.20015"
424 x2="8.1134233"
425 y1="88.509071"
426 x1="8.1134243"
427 gradientTransform="scale(2.309851,0.432928)"
428 id="linearGradient2758"
429 xlink:href="#linearGradient2752"
430 inkscape:collect="always" />
431 <linearGradient
432 gradientUnits="userSpaceOnUse"
433 y2="31.246054"
434 x2="32.536823"
435 y1="5.3817744"
436 x1="10.390738"
437 gradientTransform="scale(1.104397,0.905471)"
438 id="linearGradient2979"
439 xlink:href="#linearGradient2253"
440 inkscape:collect="always" />
441 <linearGradient
442 y2="52.536461"
443 x2="18.176752"
444 y1="48.643234"
445 x1="18.316999"
446 gradientTransform="scale(1.129863,0.885063)"
447 gradientUnits="userSpaceOnUse"
448 id="linearGradient2981"
449 xlink:href="#linearGradient2245"
450 inkscape:collect="always" />
451 <linearGradient
452 gradientUnits="userSpaceOnUse"
453 y2="44.878883"
454 x2="-23.885700"
455 y1="49.953003"
456 x1="-23.885700"
457 gradientTransform="scale(1.492875,0.669848)"
458 id="linearGradient2991"
459 xlink:href="#linearGradient2985"
460 inkscape:collect="always" />
461 <linearGradient
462 y2="100.20015"
463 x2="8.1134233"
464 y1="88.509071"
465 x1="8.1134243"
466 gradientTransform="scale(2.309851,0.432928)"
467 gradientUnits="userSpaceOnUse"
468 id="linearGradient1409"
469 xlink:href="#linearGradient2752"
470 inkscape:collect="always" />
471 <linearGradient
472 y2="100.20015"
473 x2="8.1134233"
474 y1="88.509071"
475 x1="8.1134243"
476 gradientTransform="scale(2.309851,0.432928)"
477 gradientUnits="userSpaceOnUse"
478 id="linearGradient1411"
479 xlink:href="#linearGradient2752"
480 inkscape:collect="always" />
481 <linearGradient
482 y2="31.246054"
483 x2="32.536823"
484 y1="5.3817744"
485 x1="10.390738"
486 gradientTransform="scale(1.104397,0.905471)"
487 gradientUnits="userSpaceOnUse"
488 id="linearGradient1413"
489 xlink:href="#linearGradient2253"
490 inkscape:collect="always" />
491 <radialGradient
492 inkscape:collect="always"
493 xlink:href="#linearGradient2454"
494 id="radialGradient2816"
495 gradientUnits="userSpaceOnUse"
496 gradientTransform="scale(1.925808,0.519262)"
497 cx="12.575710"
498 cy="67.501709"
499 fx="12.575710"
500 fy="67.501709"
501 r="8.7662794" />
502 <linearGradient
503 inkscape:collect="always"
504 xlink:href="#linearGradient2985"
505 id="linearGradient2818"
506 gradientUnits="userSpaceOnUse"
507 gradientTransform="scale(1.492875,0.669848)"
508 x1="-23.885700"
509 y1="49.953003"
510 x2="-23.885700"
511 y2="44.878883" />
512 <radialGradient
513 inkscape:collect="always"
514 xlink:href="#linearGradient2454"
515 id="radialGradient2820"
516 gradientUnits="userSpaceOnUse"
517 gradientTransform="scale(1.925808,0.519262)"
518 cx="12.575710"
519 cy="67.501709"
520 fx="12.575710"
521 fy="67.501709"
522 r="8.7662794" />
523 <linearGradient
524 inkscape:collect="always"
525 xlink:href="#linearGradient2701"
526 id="linearGradient2822"
527 gradientUnits="userSpaceOnUse"
528 gradientTransform="scale(1.816345,0.550556)"
529 x1="12.206709"
530 y1="53.535141"
531 x2="12.127711"
532 y2="64.892525" />
533 <linearGradient
534 inkscape:collect="always"
535 xlink:href="#linearGradient2245"
536 id="linearGradient2824"
537 gradientUnits="userSpaceOnUse"
538 gradientTransform="matrix(1.129863,0.000000,0.000000,0.885063,-1.625000,-1.304372)"
539 x1="8.6116238"
540 y1="7.2293582"
541 x2="34.784473"
542 y2="33.339787" />
543 <linearGradient
544 inkscape:collect="always"
545 xlink:href="#linearGradient2253"
546 id="linearGradient2826"
547 gradientUnits="userSpaceOnUse"
548 gradientTransform="scale(1.104397,0.905471)"
549 x1="10.390738"
550 y1="5.3817744"
551 x2="32.536823"
552 y2="31.246054" />
553 <linearGradient
554 inkscape:collect="always"
555 xlink:href="#linearGradient2675"
556 id="linearGradient2828"
557 gradientUnits="userSpaceOnUse"
558 gradientTransform="matrix(1.174139,0.000000,0.000000,0.945431,0.721825,-1.331524)"
559 x1="19.150396"
560 y1="32.622238"
561 x2="16.315819"
562 y2="8.8666229" />
563 <linearGradient
564 inkscape:collect="always"
565 xlink:href="#linearGradient2683"
566 id="linearGradient2830"
567 gradientUnits="userSpaceOnUse"
568 gradientTransform="matrix(5.705159,0.000000,0.000000,0.175280,1.000000,-0.679373)"
569 x1="3.7069976"
570 y1="171.29134"
571 x2="3.7069974"
572 y2="162.45061" />
573 <linearGradient
574 inkscape:collect="always"
575 xlink:href="#linearGradient2415"
576 id="linearGradient2832"
577 gradientUnits="userSpaceOnUse"
578 gradientTransform="matrix(1.108069,0.000000,0.000000,0.902471,1.000000,1.000000)"
579 x1="17.698339"
580 y1="13.004725"
581 x2="34.974548"
582 y2="55.200756" />
583 <linearGradient
584 inkscape:collect="always"
585 xlink:href="#linearGradient2667"
586 id="linearGradient2834"
587 gradientUnits="userSpaceOnUse"
588 gradientTransform="matrix(1.238977,0.000000,0.000000,0.895955,0.590553,-1.331524)"
589 x1="11.492236"
590 y1="1.6537577"
591 x2="17.199417"
592 y2="26.729263" />
593 <radialGradient
594 inkscape:collect="always"
595 xlink:href="#linearGradient2454"
596 id="radialGradient2836"
597 gradientUnits="userSpaceOnUse"
598 gradientTransform="scale(1.925808,0.519262)"
599 cx="12.575710"
600 cy="67.501709"
601 fx="12.575710"
602 fy="67.501709"
603 r="8.7662794" />
604 <linearGradient
605 inkscape:collect="always"
606 xlink:href="#linearGradient2245"
607 id="linearGradient2838"
608 gradientUnits="userSpaceOnUse"
609 gradientTransform="scale(1.129863,0.885063)"
610 x1="18.316999"
611 y1="48.643234"
612 x2="18.176752"
613 y2="52.536461" />
614 <linearGradient
615 inkscape:collect="always"
616 xlink:href="#linearGradient2253"
617 id="linearGradient2840"
618 gradientUnits="userSpaceOnUse"
619 gradientTransform="scale(1.104397,0.905471)"
620 x1="10.390738"
621 y1="5.3817744"
622 x2="32.536823"
623 y2="31.246054" />
624 <linearGradient
625 inkscape:collect="always"
626 xlink:href="#linearGradient2752"
627 id="linearGradient2842"
628 gradientUnits="userSpaceOnUse"
629 gradientTransform="scale(2.309851,0.432928)"
630 x1="8.1134243"
631 y1="88.509071"
632 x2="8.1134233"
633 y2="100.20015" />
634 <linearGradient
635 inkscape:collect="always"
636 xlink:href="#linearGradient2752"
637 id="linearGradient2844"
638 gradientUnits="userSpaceOnUse"
639 gradientTransform="scale(2.309851,0.432928)"
640 x1="8.1134243"
641 y1="88.509071"
642 x2="8.1134233"
643 y2="100.20015" />
644 <linearGradient
645 inkscape:collect="always"
646 xlink:href="#linearGradient2752"
647 id="linearGradient2846"
648 gradientUnits="userSpaceOnUse"
649 gradientTransform="scale(2.309851,0.432928)"
650 x1="8.1134243"
651 y1="88.509071"
652 x2="8.1134233"
653 y2="100.20015" />
654 <linearGradient
655 inkscape:collect="always"
656 xlink:href="#linearGradient2635"
657 id="linearGradient2848"
658 gradientUnits="userSpaceOnUse"
659 gradientTransform="matrix(2.143634,0.000000,0.000000,0.466498,1.000000,-0.508826)"
660 x1="13.628710"
661 y1="101.28460"
662 x2="8.6485014"
663 y2="74.098007" />
664 <linearGradient
665 inkscape:collect="always"
666 xlink:href="#linearGradient2711"
667 id="linearGradient2850"
668 gradientUnits="userSpaceOnUse"
669 x1="34.300991"
670 y1="3.9384086"
671 x2="35.520542"
672 y2="3.8451097" />
673 <linearGradient
674 inkscape:collect="always"
675 xlink:href="#linearGradient2711"
676 id="linearGradient2852"
677 gradientUnits="userSpaceOnUse"
678 x1="34.300991"
679 y1="3.9384086"
680 x2="35.520542"
681 y2="3.8451097" />
682 <linearGradient
683 inkscape:collect="always"
684 xlink:href="#linearGradient2711"
685 id="linearGradient2854"
686 gradientUnits="userSpaceOnUse"
687 x1="34.300991"
688 y1="3.9384086"
689 x2="35.520542"
690 y2="3.8451097" />
691 <linearGradient
692 inkscape:collect="always"
693 xlink:href="#linearGradient2711"
694 id="linearGradient2856"
695 gradientUnits="userSpaceOnUse"
696 x1="34.300991"
697 y1="3.9384086"
698 x2="35.520542"
699 y2="3.8451097" />
700 <linearGradient
701 inkscape:collect="always"
702 xlink:href="#linearGradient2711"
703 id="linearGradient2858"
704 gradientUnits="userSpaceOnUse"
705 x1="34.300991"
706 y1="3.9384086"
707 x2="35.520542"
708 y2="3.8451097" />
709 <radialGradient
710 inkscape:collect="always"
711 xlink:href="#linearGradient2454"
712 id="radialGradient2916"
713 gradientUnits="userSpaceOnUse"
714 gradientTransform="scale(1.925808,0.519262)"
715 cx="12.575710"
716 cy="67.501709"
717 fx="12.575710"
718 fy="67.501709"
719 r="8.7662794" />
720 <linearGradient
721 inkscape:collect="always"
722 xlink:href="#linearGradient2985"
723 id="linearGradient2918"
724 gradientUnits="userSpaceOnUse"
725 gradientTransform="scale(1.492875,0.669848)"
726 x1="-23.885700"
727 y1="49.953003"
728 x2="-23.885700"
729 y2="44.878883" />
730 <radialGradient
731 inkscape:collect="always"
732 xlink:href="#linearGradient2454"
733 id="radialGradient2920"
734 gradientUnits="userSpaceOnUse"
735 gradientTransform="scale(1.925808,0.519262)"
736 cx="12.575710"
737 cy="67.501709"
738 fx="12.575710"
739 fy="67.501709"
740 r="8.7662794" />
741 <linearGradient
742 inkscape:collect="always"
743 xlink:href="#linearGradient2701"
744 id="linearGradient2922"
745 gradientUnits="userSpaceOnUse"
746 gradientTransform="scale(1.816345,0.550556)"
747 x1="12.206709"
748 y1="53.535141"
749 x2="12.127711"
750 y2="64.892525" />
751 <linearGradient
752 inkscape:collect="always"
753 xlink:href="#linearGradient2245"
754 id="linearGradient2924"
755 gradientUnits="userSpaceOnUse"
756 gradientTransform="matrix(1.129863,0.000000,0.000000,0.885063,-1.625000,-1.304372)"
757 x1="8.6116238"
758 y1="7.2293582"
759 x2="34.784473"
760 y2="33.339787" />
761 <linearGradient
762 inkscape:collect="always"
763 xlink:href="#linearGradient2253"
764 id="linearGradient2926"
765 gradientUnits="userSpaceOnUse"
766 gradientTransform="scale(1.104397,0.905471)"
767 x1="10.390738"
768 y1="5.3817744"
769 x2="32.536823"
770 y2="31.246054" />
771 <linearGradient
772 inkscape:collect="always"
773 xlink:href="#linearGradient2675"
774 id="linearGradient2928"
775 gradientUnits="userSpaceOnUse"
776 gradientTransform="matrix(1.174139,0.000000,0.000000,0.945431,0.721825,-1.331524)"
777 x1="19.150396"
778 y1="32.622238"
779 x2="16.315819"
780 y2="8.8666229" />
781 <linearGradient
782 inkscape:collect="always"
783 xlink:href="#linearGradient2683"
784 id="linearGradient2930"
785 gradientUnits="userSpaceOnUse"
786 gradientTransform="matrix(5.705159,0.000000,0.000000,0.175280,1.000000,-0.679373)"
787 x1="3.7069976"
788 y1="171.29134"
789 x2="3.7069974"
790 y2="162.45061" />
791 <linearGradient
792 inkscape:collect="always"
793 xlink:href="#linearGradient2415"
794 id="linearGradient2932"
795 gradientUnits="userSpaceOnUse"
796 gradientTransform="matrix(1.108069,0.000000,0.000000,0.902471,1.000000,1.000000)"
797 x1="17.698339"
798 y1="13.004725"
799 x2="34.974548"
800 y2="55.200756" />
801 <linearGradient
802 inkscape:collect="always"
803 xlink:href="#linearGradient2667"
804 id="linearGradient2934"
805 gradientUnits="userSpaceOnUse"
806 gradientTransform="matrix(1.238977,0.000000,0.000000,0.895955,0.590553,-1.331524)"
807 x1="11.492236"
808 y1="1.6537577"
809 x2="17.199417"
810 y2="26.729263" />
811 <radialGradient
812 inkscape:collect="always"
813 xlink:href="#linearGradient2454"
814 id="radialGradient2936"
815 gradientUnits="userSpaceOnUse"
816 gradientTransform="scale(1.925808,0.519262)"
817 cx="12.575710"
818 cy="67.501709"
819 fx="12.575710"
820 fy="67.501709"
821 r="8.7662794" />
822 <linearGradient
823 inkscape:collect="always"
824 xlink:href="#linearGradient2245"
825 id="linearGradient2938"
826 gradientUnits="userSpaceOnUse"
827 gradientTransform="scale(1.129863,0.885063)"
828 x1="18.316999"
829 y1="48.643234"
830 x2="18.176752"
831 y2="52.536461" />
832 <linearGradient
833 inkscape:collect="always"
834 xlink:href="#linearGradient2253"
835 id="linearGradient2940"
836 gradientUnits="userSpaceOnUse"
837 gradientTransform="scale(1.104397,0.905471)"
838 x1="10.390738"
839 y1="5.3817744"
840 x2="32.536823"
841 y2="31.246054" />
842 <linearGradient
843 inkscape:collect="always"
844 xlink:href="#linearGradient2752"
845 id="linearGradient2942"
846 gradientUnits="userSpaceOnUse"
847 gradientTransform="scale(2.309851,0.432928)"
848 x1="8.1134243"
849 y1="88.509071"
850 x2="8.1134233"
851 y2="100.20015" />
852 <linearGradient
853 inkscape:collect="always"
854 xlink:href="#linearGradient2752"
855 id="linearGradient2944"
856 gradientUnits="userSpaceOnUse"
857 gradientTransform="scale(2.309851,0.432928)"
858 x1="8.1134243"
859 y1="88.509071"
860 x2="8.1134233"
861 y2="100.20015" />
862 <linearGradient
863 inkscape:collect="always"
864 xlink:href="#linearGradient2752"
865 id="linearGradient2946"
866 gradientUnits="userSpaceOnUse"
867 gradientTransform="scale(2.309851,0.432928)"
868 x1="8.1134243"
869 y1="88.509071"
870 x2="8.1134233"
871 y2="100.20015" />
872 <linearGradient
873 inkscape:collect="always"
874 xlink:href="#linearGradient2635"
875 id="linearGradient2948"
876 gradientUnits="userSpaceOnUse"
877 gradientTransform="matrix(2.143634,0.000000,0.000000,0.466498,1.000000,-0.508826)"
878 x1="13.628710"
879 y1="101.28460"
880 x2="8.6485014"
881 y2="74.098007" />
882 <linearGradient
883 inkscape:collect="always"
884 xlink:href="#linearGradient2711"
885 id="linearGradient2950"
886 gradientUnits="userSpaceOnUse"
887 x1="34.300991"
888 y1="3.9384086"
889 x2="35.520542"
890 y2="3.8451097" />
891 <linearGradient
892 inkscape:collect="always"
893 xlink:href="#linearGradient2711"
894 id="linearGradient2952"
895 gradientUnits="userSpaceOnUse"
896 x1="34.300991"
897 y1="3.9384086"
898 x2="35.520542"
899 y2="3.8451097" />
900 <linearGradient
901 inkscape:collect="always"
902 xlink:href="#linearGradient2711"
903 id="linearGradient2954"
904 gradientUnits="userSpaceOnUse"
905 x1="34.300991"
906 y1="3.9384086"
907 x2="35.520542"
908 y2="3.8451097" />
909 <linearGradient
910 inkscape:collect="always"
911 xlink:href="#linearGradient2711"
912 id="linearGradient2956"
913 gradientUnits="userSpaceOnUse"
914 x1="34.300991"
915 y1="3.9384086"
916 x2="35.520542"
917 y2="3.8451097" />
918 <linearGradient
919 inkscape:collect="always"
920 xlink:href="#linearGradient2711"
921 id="linearGradient2958"
922 gradientUnits="userSpaceOnUse"
923 x1="34.300991"
924 y1="3.9384086"
925 x2="35.520542"
926 y2="3.8451097" />
927 </defs>
928 <sodipodi:namedview
929 id="base"
930 pagecolor="#ffffff"
931 bordercolor="#666666"
932 borderopacity="0.12156863"
933 inkscape:pageopacity="0.0"
934 inkscape:pageshadow="2"
935 inkscape:zoom="8"
936 inkscape:cx="26.385869"
937 inkscape:cy="19.247154"
938 inkscape:current-layer="layer1"
939 showgrid="true"
940 inkscape:grid-bbox="true"
941 inkscape:document-units="px"
942 inkscape:window-width="822"
943 inkscape:window-height="818"
944 inkscape:window-x="388"
945 inkscape:window-y="30"
946 inkscape:showpageshadow="false" />
947 <metadata
948 id="metadata4">
949 <rdf:RDF>
950 <cc:Work
951 rdf:about="">
952 <dc:format>image/svg+xml</dc:format>
953 <dc:type
954 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
955 <dc:title>Computer</dc:title>
956 <dc:date>2005-03-08</dc:date>
957 <dc:creator>
958 <cc:Agent>
959 <dc:title>Jakub Steiner</dc:title>
960 </cc:Agent>
961 </dc:creator>
962 <dc:subject>
963 <rdf:Bag>
964 <rdf:li>workstation</rdf:li>
965 <rdf:li>computer</rdf:li>
966 <rdf:li>node</rdf:li>
967 <rdf:li>client</rdf:li>
968 </rdf:Bag>
969 </dc:subject>
970 <cc:license
971 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
972 <dc:source>http://jimmac.musichall.cz/</dc:source>
973 </cc:Work>
974 <cc:License
975 rdf:about="http://creativecommons.org/licenses/publicdomain/">
976 <cc:permits
977 rdf:resource="http://creativecommons.org/ns#Reproduction" />
978 <cc:permits
979 rdf:resource="http://creativecommons.org/ns#Distribution" />
980 <cc:permits
981 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
982 </cc:License>
983 </rdf:RDF>
984 </metadata>
985 <g
986 id="layer1"
987 inkscape:label="Layer 1"
988 inkscape:groupmode="layer">
989 <g
990 id="g2787"
991 transform="matrix(0.779340,0.000000,0.000000,0.779340,10.13834,0.178534)">
992 <path
993 transform="matrix(1.000000,0.000000,0.000000,1.368932,-1.978553,-13.61713)"
994 d="M 41.100580 35.051105 A 16.882174 4.5520000 0 1 1 7.3362331,35.051105 A 16.882174 4.5520000 0 1 1 41.100580 35.051105 z"
995 sodipodi:ry="4.5520000"
996 sodipodi:rx="16.882174"
997 sodipodi:cy="35.051105"
998 sodipodi:cx="24.218407"
999 id="path2452"
1000 style="color:#000000;fill:url(#radialGradient2816);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.70063692;visibility:visible;display:inline;overflow:visible"
1001 sodipodi:type="arc" />
1002 <path
1003 transform="translate(57.53339,3.203427)"
1004 d="M -26.263968 29.716238 A 9.3944187 3.9395950 0 1 1 -45.052805,29.716238 A 9.3944187 3.9395950 0 1 1 -26.263968 29.716238 z"
1005 sodipodi:ry="3.9395950"
1006 sodipodi:rx="9.3944187"
1007 sodipodi:cy="29.716238"
1008 sodipodi:cx="-35.658386"
1009 id="path2407"
1010 style="color:#000000;fill:#adb0aa;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#4b4d4a;stroke-width:1.2831376;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1011 sodipodi:type="arc" />
1012 <path
1013 sodipodi:type="arc"
1014 style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#7b7f7a;stroke-width:1.2831376;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1015 id="path1825"
1016 sodipodi:cx="-35.658386"
1017 sodipodi:cy="29.716238"
1018 sodipodi:rx="9.3944187"
1019 sodipodi:ry="3.9395950"
1020 d="M -26.263968 29.716238 A 9.3944187 3.9395950 0 1 1 -45.052805,29.716238 A 9.3944187 3.9395950 0 1 1 -26.263968 29.716238 z"
1021 transform="matrix(0.940273,0.000000,0.000000,0.940273,55.40361,4.271194)" />
1022 <path
1023 transform="matrix(0.940273,0.000000,0.000000,0.940273,55.40361,3.521194)"
1024 d="M -26.263968 29.716238 A 9.3944187 3.9395950 0 1 1 -45.052805,29.716238 A 9.3944187 3.9395950 0 1 1 -26.263968 29.716238 z"
1025 sodipodi:ry="3.9395950"
1026 sodipodi:rx="9.3944187"
1027 sodipodi:cy="29.716238"
1028 sodipodi:cx="-35.658386"
1029 id="path2983"
1030 style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2818);stroke-width:0.87337190;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1031 sodipodi:type="arc" />
1032 <path
1033 id="path2411"
1034 d="M 25.687500,28.766243 L 25.625000,29.766243 C 25.625000,29.766243 29.949108,33.365409 34.625000,33.968750 C 36.962946,34.270420 39.378675,34.671162 41.375000,35.156250 C 43.371325,35.641338 44.963356,36.275856 45.500000,36.812500 C 45.810411,37.122911 45.951063,37.386139 46.000000,37.593750 C 46.048937,37.801361 46.038217,37.948565 45.906250,38.156250 C 45.642317,38.571620 44.826393,39.123902 43.437500,39.562500 C 40.659715,40.439695 35.717076,41.000000 28.875000,41.000000 L 28.875000,42.000000 C 35.770998,42.000000 40.738665,41.472329 43.718750,40.531250 C 45.208792,40.060710 46.243692,39.515563 46.750000,38.718750 C 47.003154,38.320344 47.107321,37.830301 47.000000,37.375000 C 46.892679,36.919699 46.615445,36.490445 46.218750,36.093750 C 45.341180,35.216180 43.681912,34.687310 41.625000,34.187500 C 39.568088,33.687690 37.109264,33.273171 34.750000,32.968750 C 30.031473,32.359908 25.687500,28.766243 25.687500,28.766243 z "
1035 style="fill:#d0d0d0;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#979797;stroke-width:0.51325500;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
1036 sodipodi:nodetypes="ccccccccccccccccc" />
1037 <path
1038 sodipodi:type="arc"
1039 style="color:#000000;fill:url(#radialGradient2820);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.70063692;visibility:visible;display:inline;overflow:visible"
1040 id="path2462"
1041 sodipodi:cx="24.218407"
1042 sodipodi:cy="35.051105"
1043 sodipodi:rx="16.882174"
1044 sodipodi:ry="4.5520000"
1045 d="M 41.100580 35.051105 A 16.882174 4.5520000 0 1 1 7.3362331,35.051105 A 16.882174 4.5520000 0 1 1 41.100580 35.051105 z"
1046 transform="matrix(1.000000,0.000000,0.000000,1.368932,-1.978553,-19.02126)" />
1047 <rect
1048 style="color:#000000;fill:url(#linearGradient2822);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.60872948;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1049 id="rect2699"
1050 width="9.0396729"
1051 height="2.7400389"
1052 x="17.472397"
1053 y="30.703611" />
1054 <path
1055 sodipodi:nodetypes="cssssssss"
1056 id="rect2404"
1057 d="M 7.0809024,1.6956221 L 36.669097,1.6956221 C 37.580439,1.6956221 38.293244,2.2791039 38.335849,3.0972091 L 39.667893,28.675323 C 39.726102,29.793058 38.766837,30.695628 37.647588,30.695628 L 6.1024120,30.695628 C 4.9831629,30.695628 4.0238980,29.793058 4.0821068,28.675323 L 5.4141506,3.0972091 C 5.4544343,2.3236745 5.9616533,1.6956221 7.0809024,1.6956221 z "
1058 style="color:#000000;fill:url(#linearGradient2824);fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2826);stroke-width:1.2831376;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
1059 <path
1060 style="fill:url(#linearGradient2828);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000079;stroke-width:0.64156878;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
1061 d="M 8.4105348,4.3058272 L 7.1683398,26.351144 L 34.818729,26.351144 L 33.483712,4.3992558 L 8.4105348,4.3058272 z "
1062 id="path2377"
1063 sodipodi:nodetypes="ccccc" />
1064 <path
1065 id="path2393"
1066 d="M 6.1774331,28.735789 L 37.605910,28.735789"
1067 style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:url(#linearGradient2830);stroke-width:1.2782375;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:0.24840762" />
1068 <path
1069 style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2832);stroke-width:1.2831371;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.70063692;visibility:visible;display:inline;overflow:visible"
1070 d="M 6.9145985,2.7063396 L 36.760101,2.6685383 C 37.043798,2.6681790 37.319403,2.9057881 37.342206,3.3210821 L 38.704098,28.124330 C 38.762137,29.181361 38.164349,29.910201 37.105727,29.910201 L 6.5817583,29.910201 C 5.5231355,29.910201 4.9887439,29.181410 5.0458869,28.124330 L 6.3699773,3.6301633 C 6.4086732,2.9143326 6.5363627,2.7068187 6.9145985,2.7063396 z "
1071 id="path2397"
1072 sodipodi:nodetypes="cssssssss" />
1073 <path
1074 id="path2443"
1075 d="M 8.7115364,4.7463626 L 7.9090069,22.616693 C 18.953645,20.216063 19.330470,12.124494 33.063039,9.4699426 L 32.901567,4.8124267 L 8.7115364,4.7463626 z "
1076 style="opacity:0.53142858;fill:url(#linearGradient2834);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
1077 sodipodi:nodetypes="ccccc" />
1078 <path
1079 sodipodi:type="arc"
1080 style="color:#000000;fill:url(#radialGradient2836);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.70063692;visibility:visible;display:inline;overflow:visible"
1081 id="path2657"
1082 sodipodi:cx="24.218407"
1083 sodipodi:cy="35.051105"
1084 sodipodi:rx="16.882174"
1085 sodipodi:ry="4.5520000"
1086 d="M 41.100580 35.051105 A 16.882174 4.5520000 0 1 1 7.3362331,35.051105 A 16.882174 4.5520000 0 1 1 41.100580 35.051105 z"
1087 transform="matrix(1.264398,0.000000,0.000000,1.291262,-6.216332,-4.000423)" />
1088 <path
1089 style="opacity:1.0000000;color:#000000;fill:url(#linearGradient2838);fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2840);stroke-width:1.2831376;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1090 d="M 6.4621839,36.817452 L 37.464590,36.817452 C 38.583839,36.817452 38.441945,37.088890 38.556817,37.430298 L 41.391463,45.855108 C 41.506335,46.196517 41.418485,46.467954 40.299236,46.467954 L 3.6275382,46.467954 C 2.5082891,46.467954 2.4204387,46.196517 2.5353107,45.855108 L 5.3699564,37.430298 C 5.4848284,37.088889 5.3429348,36.817452 6.4621839,36.817452 z "
1091 id="path2409"
1092 sodipodi:nodetypes="cssssssss" />
1093 <path
1094 style="fill:#7a7d77;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
1095 d="M 6.3916892,38.829113 L 4.6239223,43.955638 L 10.104000,43.955638 L 10.634330,41.922706 L 25.483572,41.922706 L 26.033251,43.997820 L 32.201086,43.997820 L 30.521708,38.829113 L 6.3916892,38.829113 z "
1096 id="path2611"
1097 sodipodi:nodetypes="ccccccccc" />
1098 <path
1099 style="fill:#777874;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
1100 d="M 11.076272,42.276260 L 10.634330,43.955639 L 25.395184,43.955639 L 24.953242,42.187872 L 11.076272,42.276260 z "
1101 id="path2613" />
1102 <path
1103 id="path2619"
1104 d="M 37.592776,38.829114 L 39.272155,43.867250 L 33.792077,43.778861 L 32.289475,38.917502 L 37.592776,38.829114 z "
1105 style="color:#000000;fill:#777a75;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
1106 <path
1107 style="opacity:1.0000000;color:#000000;fill:url(#linearGradient2842);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1108 d="M 37.592776,38.298786 L 39.272155,43.336922 L 33.792077,43.248533 L 32.289475,38.387174 L 37.592776,38.298786 z "
1109 id="path2615" />
1110 <path
1111 sodipodi:nodetypes="ccccccccc"
1112 id="path2617"
1113 d="M 6.3916892,38.210397 L 4.6239223,43.336922 L 10.104000,43.336922 L 10.634330,41.303990 L 25.483572,41.303990 L 26.033251,43.379104 L 32.201086,43.379104 L 30.521708,38.210397 L 6.3916892,38.210397 z "
1114 style="fill:url(#linearGradient2844);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
1115 <path
1116 id="path2621"
1117 d="M 11.076272,41.745932 L 10.634330,43.425311 L 25.395184,43.425311 L 24.953242,41.657544 L 11.076272,41.745932 z "
1118 style="opacity:1.0000000;color:#000000;fill:url(#linearGradient2846);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
1119 <path
1120 sodipodi:nodetypes="ccccc"
1121 id="path2631"
1122 d="M 6.1278189,37.578116 L 37.953634,37.578116 L 40.590813,45.670679 L 3.3297429,45.670679 L 6.1278189,37.578116 z "
1123 style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2848);stroke-width:0.64156878;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
1124 <path
1125 sodipodi:type="arc"
1126 style="color:#000000;fill:url(#linearGradient2850);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.50000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1127 id="path2709"
1128 sodipodi:cx="34.780815"
1129 sodipodi:cy="3.9384086"
1130 sodipodi:rx="0.83968931"
1131 sodipodi:ry="0.83968931"
1132 d="M 35.620504 3.9384086 A 0.83968931 0.83968931 0 1 1 33.941126,3.9384086 A 0.83968931 0.83968931 0 1 1 35.620504 3.9384086 z"
1133 transform="matrix(1.331237,0.000000,0.000000,0.658449,-10.41933,2.853866)" />
1134 <path
1135 transform="matrix(1.331237,0.000000,0.000000,0.658449,-10.30573,4.959651)"
1136 d="M 35.620504 3.9384086 A 0.83968931 0.83968931 0 1 1 33.941126,3.9384086 A 0.83968931 0.83968931 0 1 1 35.620504 3.9384086 z"
1137 sodipodi:ry="0.83968931"
1138 sodipodi:rx="0.83968931"
1139 sodipodi:cy="3.9384086"
1140 sodipodi:cx="34.780815"
1141 id="path2719"
1142 style="color:#000000;fill:url(#linearGradient2852);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.50000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1143 sodipodi:type="arc" />
1144 <path
1145 sodipodi:type="arc"
1146 style="color:#000000;fill:url(#linearGradient2854);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.50000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1147 id="path2723"
1148 sodipodi:cx="34.780815"
1149 sodipodi:cy="3.9384086"
1150 sodipodi:rx="0.83968931"
1151 sodipodi:ry="0.83968931"
1152 d="M 35.620504 3.9384086 A 0.83968931 0.83968931 0 1 1 33.941126,3.9384086 A 0.83968931 0.83968931 0 1 1 35.620504 3.9384086 z"
1153 transform="matrix(1.331237,0.000000,0.000000,0.658449,-10.19213,6.959651)" />
1154 <path
1155 transform="matrix(1.331237,0.000000,0.000000,0.658449,-10.07853,8.959651)"
1156 d="M 35.620504 3.9384086 A 0.83968931 0.83968931 0 1 1 33.941126,3.9384086 A 0.83968931 0.83968931 0 1 1 35.620504 3.9384086 z"
1157 sodipodi:ry="0.83968931"
1158 sodipodi:rx="0.83968931"
1159 sodipodi:cy="3.9384086"
1160 sodipodi:cx="34.780815"
1161 id="path2727"
1162 style="color:#000000;fill:url(#linearGradient2856);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.50000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1163 sodipodi:type="arc" />
1164 <path
1165 sodipodi:type="arc"
1166 style="color:#000000;fill:url(#linearGradient2858);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.50000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1167 id="path2731"
1168 sodipodi:cx="34.780815"
1169 sodipodi:cy="3.9384086"
1170 sodipodi:rx="0.83968931"
1171 sodipodi:ry="0.83968931"
1172 d="M 35.620504 3.9384086 A 0.83968931 0.83968931 0 1 1 33.941126,3.9384086 A 0.83968931 0.83968931 0 1 1 35.620504 3.9384086 z"
1173 transform="matrix(1.331237,0.000000,0.000000,0.658449,-9.964930,10.95965)" />
1174 <path
1175 style="font-size:0.90290260px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;writing-mode:lr-tb;text-anchor:start;fill:#4a4a4a;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
1176 d="M 20.000000,27.317666 L 20.281716,27.317666 C 20.365481,27.317667 20.429701,27.336330 20.474376,27.373656 C 20.519345,27.410690 20.541829,27.463594 20.541830,27.532370 C 20.541829,27.601440 20.519345,27.654638 20.474376,27.691965 C 20.429701,27.728998 20.365481,27.747515 20.281716,27.747515 L 20.169735,27.747515 L 20.169735,27.975885 L 20.000000,27.975885 L 20.000000,27.317666 M 20.169735,27.440669 L 20.169735,27.624512 L 20.263640,27.624512 C 20.296558,27.624512 20.321982,27.616576 20.339911,27.600705 C 20.357839,27.584540 20.366804,27.561762 20.366804,27.532370 C 20.366804,27.502979 20.357839,27.480348 20.339911,27.464476 C 20.321982,27.448605 20.296558,27.440669 20.263640,27.440669 L 20.169735,27.440669 M 20.961979,27.428765 C 20.910250,27.428766 20.870131,27.447870 20.841621,27.486078 C 20.813112,27.524288 20.798857,27.578074 20.798857,27.647437 C 20.798857,27.716507 20.813112,27.770146 20.841621,27.808355 C 20.870131,27.846564 20.910250,27.865668 20.961979,27.865668 C 21.014001,27.865668 21.054267,27.846564 21.082778,27.808355 C 21.111287,27.770146 21.125541,27.716507 21.125542,27.647437 C 21.125541,27.578074 21.111287,27.524288 21.082778,27.486078 C 21.054267,27.447870 21.014001,27.428766 20.961979,27.428765 M 20.961979,27.305762 C 21.067787,27.305763 21.150671,27.336036 21.210630,27.396582 C 21.270588,27.457128 21.300567,27.540747 21.300568,27.647437 C 21.300567,27.753834 21.270588,27.837305 21.210630,27.897851 C 21.150671,27.958398 21.067787,27.988671 20.961979,27.988671 C 20.856464,27.988671 20.773580,27.958398 20.713328,27.897851 C 20.653370,27.837305 20.623391,27.753834 20.623391,27.647437 C 20.623391,27.540747 20.653370,27.457128 20.713328,27.396582 C 20.773580,27.336036 20.856464,27.305763 20.961979,27.305762 M 21.428420,27.317666 L 21.617994,27.317666 L 21.857387,27.769117 L 21.857387,27.317666 L 22.018305,27.317666 L 22.018305,27.975885 L 21.828730,27.975885 L 21.589338,27.524434 L 21.589338,27.975885 L 21.428420,27.975885 L 21.428420,27.317666 M 22.091489,27.317666 L 22.277095,27.317666 L 22.426991,27.552209 L 22.576887,27.317666 L 22.762935,27.317666 L 22.512079,27.698578 L 22.512079,27.975885 L 22.342344,27.975885 L 22.342344,27.698578 L 22.091489,27.317666"
1177 id="text2735" />
1178 </g>
1179 <g
1180 id="g2860"
1181 transform="matrix(0.779340,0.000000,0.000000,0.779340,-0.446279,10.26381)">
1182 <path
1183 transform="matrix(1.000000,0.000000,0.000000,1.368932,-1.978553,-13.61713)"
1184 d="M 41.100580 35.051105 A 16.882174 4.5520000 0 1 1 7.3362331,35.051105 A 16.882174 4.5520000 0 1 1 41.100580 35.051105 z"
1185 sodipodi:ry="4.5520000"
1186 sodipodi:rx="16.882174"
1187 sodipodi:cy="35.051105"
1188 sodipodi:cx="24.218407"
1189 id="path2862"
1190 style="color:#000000;fill:url(#radialGradient2916);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.70063692;visibility:visible;display:inline;overflow:visible"
1191 sodipodi:type="arc" />
1192 <path
1193 transform="translate(57.53339,3.203427)"
1194 d="M -26.263968 29.716238 A 9.3944187 3.9395950 0 1 1 -45.052805,29.716238 A 9.3944187 3.9395950 0 1 1 -26.263968 29.716238 z"
1195 sodipodi:ry="3.9395950"
1196 sodipodi:rx="9.3944187"
1197 sodipodi:cy="29.716238"
1198 sodipodi:cx="-35.658386"
1199 id="path2864"
1200 style="color:#000000;fill:#adb0aa;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#4b4d4a;stroke-width:1.2831376;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1201 sodipodi:type="arc" />
1202 <path
1203 sodipodi:type="arc"
1204 style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#7b7f7a;stroke-width:1.2831376;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1205 id="path2866"
1206 sodipodi:cx="-35.658386"
1207 sodipodi:cy="29.716238"
1208 sodipodi:rx="9.3944187"
1209 sodipodi:ry="3.9395950"
1210 d="M -26.263968 29.716238 A 9.3944187 3.9395950 0 1 1 -45.052805,29.716238 A 9.3944187 3.9395950 0 1 1 -26.263968 29.716238 z"
1211 transform="matrix(0.940273,0.000000,0.000000,0.940273,55.40361,4.271194)" />
1212 <path
1213 transform="matrix(0.940273,0.000000,0.000000,0.940273,55.40361,3.521194)"
1214 d="M -26.263968 29.716238 A 9.3944187 3.9395950 0 1 1 -45.052805,29.716238 A 9.3944187 3.9395950 0 1 1 -26.263968 29.716238 z"
1215 sodipodi:ry="3.9395950"
1216 sodipodi:rx="9.3944187"
1217 sodipodi:cy="29.716238"
1218 sodipodi:cx="-35.658386"
1219 id="path2868"
1220 style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2918);stroke-width:0.87337190;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1221 sodipodi:type="arc" />
1222 <path
1223 id="path2870"
1224 d="M 25.687500,28.766243 L 25.625000,29.766243 C 25.625000,29.766243 29.949108,33.365409 34.625000,33.968750 C 36.962946,34.270420 39.378675,34.671162 41.375000,35.156250 C 43.371325,35.641338 44.963356,36.275856 45.500000,36.812500 C 45.810411,37.122911 45.951063,37.386139 46.000000,37.593750 C 46.048937,37.801361 46.038217,37.948565 45.906250,38.156250 C 45.642317,38.571620 44.826393,39.123902 43.437500,39.562500 C 40.659715,40.439695 35.717076,41.000000 28.875000,41.000000 L 28.875000,42.000000 C 35.770998,42.000000 40.738665,41.472329 43.718750,40.531250 C 45.208792,40.060710 46.243692,39.515563 46.750000,38.718750 C 47.003154,38.320344 47.107321,37.830301 47.000000,37.375000 C 46.892679,36.919699 46.615445,36.490445 46.218750,36.093750 C 45.341180,35.216180 43.681912,34.687310 41.625000,34.187500 C 39.568088,33.687690 37.109264,33.273171 34.750000,32.968750 C 30.031473,32.359908 25.687500,28.766243 25.687500,28.766243 z "
1225 style="fill:#d0d0d0;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#979797;stroke-width:0.51325500;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
1226 sodipodi:nodetypes="ccccccccccccccccc" />
1227 <path
1228 sodipodi:type="arc"
1229 style="color:#000000;fill:url(#radialGradient2920);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.70063692;visibility:visible;display:inline;overflow:visible"
1230 id="path2872"
1231 sodipodi:cx="24.218407"
1232 sodipodi:cy="35.051105"
1233 sodipodi:rx="16.882174"
1234 sodipodi:ry="4.5520000"
1235 d="M 41.100580 35.051105 A 16.882174 4.5520000 0 1 1 7.3362331,35.051105 A 16.882174 4.5520000 0 1 1 41.100580 35.051105 z"
1236 transform="matrix(1.000000,0.000000,0.000000,1.368932,-1.978553,-19.02126)" />
1237 <rect
1238 style="color:#000000;fill:url(#linearGradient2922);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.60872948;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1239 id="rect2874"
1240 width="9.0396729"
1241 height="2.7400389"
1242 x="17.472397"
1243 y="30.703611" />
1244 <path
1245 sodipodi:nodetypes="cssssssss"
1246 id="path2876"
1247 d="M 7.0809024,1.6956221 L 36.669097,1.6956221 C 37.580439,1.6956221 38.293244,2.2791039 38.335849,3.0972091 L 39.667893,28.675323 C 39.726102,29.793058 38.766837,30.695628 37.647588,30.695628 L 6.1024120,30.695628 C 4.9831629,30.695628 4.0238980,29.793058 4.0821068,28.675323 L 5.4141506,3.0972091 C 5.4544343,2.3236745 5.9616533,1.6956221 7.0809024,1.6956221 z "
1248 style="color:#000000;fill:url(#linearGradient2924);fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2926);stroke-width:1.2831376;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
1249 <path
1250 style="fill:url(#linearGradient2928);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000079;stroke-width:0.64156878;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
1251 d="M 8.4105348,4.3058272 L 7.1683398,26.351144 L 34.818729,26.351144 L 33.483712,4.3992558 L 8.4105348,4.3058272 z "
1252 id="path2878"
1253 sodipodi:nodetypes="ccccc" />
1254 <path
1255 id="path2880"
1256 d="M 6.1774331,28.735789 L 37.605910,28.735789"
1257 style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:url(#linearGradient2930);stroke-width:1.2782375;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:0.24840762" />
1258 <path
1259 style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2932);stroke-width:1.2831371;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.70063692;visibility:visible;display:inline;overflow:visible"
1260 d="M 6.9145985,2.7063396 L 36.760101,2.6685383 C 37.043798,2.6681790 37.319403,2.9057881 37.342206,3.3210821 L 38.704098,28.124330 C 38.762137,29.181361 38.164349,29.910201 37.105727,29.910201 L 6.5817583,29.910201 C 5.5231355,29.910201 4.9887439,29.181410 5.0458869,28.124330 L 6.3699773,3.6301633 C 6.4086732,2.9143326 6.5363627,2.7068187 6.9145985,2.7063396 z "
1261 id="path2882"
1262 sodipodi:nodetypes="cssssssss" />
1263 <path
1264 id="path2884"
1265 d="M 8.7115364,4.7463626 L 7.9090069,22.616693 C 18.953645,20.216063 19.330470,12.124494 33.063039,9.4699426 L 32.901567,4.8124267 L 8.7115364,4.7463626 z "
1266 style="opacity:0.53142858;fill:url(#linearGradient2934);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
1267 sodipodi:nodetypes="ccccc" />
1268 <path
1269 sodipodi:type="arc"
1270 style="color:#000000;fill:url(#radialGradient2936);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.70063692;visibility:visible;display:inline;overflow:visible"
1271 id="path2886"
1272 sodipodi:cx="24.218407"
1273 sodipodi:cy="35.051105"
1274 sodipodi:rx="16.882174"
1275 sodipodi:ry="4.5520000"
1276 d="M 41.100580 35.051105 A 16.882174 4.5520000 0 1 1 7.3362331,35.051105 A 16.882174 4.5520000 0 1 1 41.100580 35.051105 z"
1277 transform="matrix(1.264398,0.000000,0.000000,1.291262,-6.216332,-4.000423)" />
1278 <path
1279 style="opacity:1.0000000;color:#000000;fill:url(#linearGradient2938);fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2940);stroke-width:1.2831376;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1280 d="M 6.4621839,36.817452 L 37.464590,36.817452 C 38.583839,36.817452 38.441945,37.088890 38.556817,37.430298 L 41.391463,45.855108 C 41.506335,46.196517 41.418485,46.467954 40.299236,46.467954 L 3.6275382,46.467954 C 2.5082891,46.467954 2.4204387,46.196517 2.5353107,45.855108 L 5.3699564,37.430298 C 5.4848284,37.088889 5.3429348,36.817452 6.4621839,36.817452 z "
1281 id="path2888"
1282 sodipodi:nodetypes="cssssssss" />
1283 <path
1284 style="fill:#7a7d77;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
1285 d="M 6.3916892,38.829113 L 4.6239223,43.955638 L 10.104000,43.955638 L 10.634330,41.922706 L 25.483572,41.922706 L 26.033251,43.997820 L 32.201086,43.997820 L 30.521708,38.829113 L 6.3916892,38.829113 z "
1286 id="path2890"
1287 sodipodi:nodetypes="ccccccccc" />
1288 <path
1289 style="fill:#777874;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
1290 d="M 11.076272,42.276260 L 10.634330,43.955639 L 25.395184,43.955639 L 24.953242,42.187872 L 11.076272,42.276260 z "
1291 id="path2892" />
1292 <path
1293 id="path2894"
1294 d="M 37.592776,38.829114 L 39.272155,43.867250 L 33.792077,43.778861 L 32.289475,38.917502 L 37.592776,38.829114 z "
1295 style="color:#000000;fill:#777a75;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
1296 <path
1297 style="opacity:1.0000000;color:#000000;fill:url(#linearGradient2942);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1298 d="M 37.592776,38.298786 L 39.272155,43.336922 L 33.792077,43.248533 L 32.289475,38.387174 L 37.592776,38.298786 z "
1299 id="path2896" />
1300 <path
1301 sodipodi:nodetypes="ccccccccc"
1302 id="path2898"
1303 d="M 6.3916892,38.210397 L 4.6239223,43.336922 L 10.104000,43.336922 L 10.634330,41.303990 L 25.483572,41.303990 L 26.033251,43.379104 L 32.201086,43.379104 L 30.521708,38.210397 L 6.3916892,38.210397 z "
1304 style="fill:url(#linearGradient2944);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
1305 <path
1306 id="path2900"
1307 d="M 11.076272,41.745932 L 10.634330,43.425311 L 25.395184,43.425311 L 24.953242,41.657544 L 11.076272,41.745932 z "
1308 style="opacity:1.0000000;color:#000000;fill:url(#linearGradient2946);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
1309 <path
1310 sodipodi:nodetypes="ccccc"
1311 id="path2902"
1312 d="M 6.1278189,37.578116 L 37.953634,37.578116 L 40.590813,45.670679 L 3.3297429,45.670679 L 6.1278189,37.578116 z "
1313 style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2948);stroke-width:0.64156878;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
1314 <path
1315 sodipodi:type="arc"
1316 style="color:#000000;fill:url(#linearGradient2950);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.50000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1317 id="path2904"
1318 sodipodi:cx="34.780815"
1319 sodipodi:cy="3.9384086"
1320 sodipodi:rx="0.83968931"
1321 sodipodi:ry="0.83968931"
1322 d="M 35.620504 3.9384086 A 0.83968931 0.83968931 0 1 1 33.941126,3.9384086 A 0.83968931 0.83968931 0 1 1 35.620504 3.9384086 z"
1323 transform="matrix(1.331237,0.000000,0.000000,0.658449,-10.41933,2.853866)" />
1324 <path
1325 transform="matrix(1.331237,0.000000,0.000000,0.658449,-10.30573,4.959651)"
1326 d="M 35.620504 3.9384086 A 0.83968931 0.83968931 0 1 1 33.941126,3.9384086 A 0.83968931 0.83968931 0 1 1 35.620504 3.9384086 z"
1327 sodipodi:ry="0.83968931"
1328 sodipodi:rx="0.83968931"
1329 sodipodi:cy="3.9384086"
1330 sodipodi:cx="34.780815"
1331 id="path2906"
1332 style="color:#000000;fill:url(#linearGradient2952);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.50000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1333 sodipodi:type="arc" />
1334 <path
1335 sodipodi:type="arc"
1336 style="color:#000000;fill:url(#linearGradient2954);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.50000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1337 id="path2908"
1338 sodipodi:cx="34.780815"
1339 sodipodi:cy="3.9384086"
1340 sodipodi:rx="0.83968931"
1341 sodipodi:ry="0.83968931"
1342 d="M 35.620504 3.9384086 A 0.83968931 0.83968931 0 1 1 33.941126,3.9384086 A 0.83968931 0.83968931 0 1 1 35.620504 3.9384086 z"
1343 transform="matrix(1.331237,0.000000,0.000000,0.658449,-10.19213,6.959651)" />
1344 <path
1345 transform="matrix(1.331237,0.000000,0.000000,0.658449,-10.07853,8.959651)"
1346 d="M 35.620504 3.9384086 A 0.83968931 0.83968931 0 1 1 33.941126,3.9384086 A 0.83968931 0.83968931 0 1 1 35.620504 3.9384086 z"
1347 sodipodi:ry="0.83968931"
1348 sodipodi:rx="0.83968931"
1349 sodipodi:cy="3.9384086"
1350 sodipodi:cx="34.780815"
1351 id="path2910"
1352 style="color:#000000;fill:url(#linearGradient2956);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.50000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1353 sodipodi:type="arc" />
1354 <path
1355 sodipodi:type="arc"
1356 style="color:#000000;fill:url(#linearGradient2958);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.50000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
1357 id="path2912"
1358 sodipodi:cx="34.780815"
1359 sodipodi:cy="3.9384086"
1360 sodipodi:rx="0.83968931"
1361 sodipodi:ry="0.83968931"
1362 d="M 35.620504 3.9384086 A 0.83968931 0.83968931 0 1 1 33.941126,3.9384086 A 0.83968931 0.83968931 0 1 1 35.620504 3.9384086 z"
1363 transform="matrix(1.331237,0.000000,0.000000,0.658449,-9.964930,10.95965)" />
1364 <path
1365 style="font-size:0.90290260px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;writing-mode:lr-tb;text-anchor:start;fill:#4a4a4a;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
1366 d="M 20.000000,27.317666 L 20.281716,27.317666 C 20.365481,27.317667 20.429701,27.336330 20.474376,27.373656 C 20.519345,27.410690 20.541829,27.463594 20.541830,27.532370 C 20.541829,27.601440 20.519345,27.654638 20.474376,27.691965 C 20.429701,27.728998 20.365481,27.747515 20.281716,27.747515 L 20.169735,27.747515 L 20.169735,27.975885 L 20.000000,27.975885 L 20.000000,27.317666 M 20.169735,27.440669 L 20.169735,27.624512 L 20.263640,27.624512 C 20.296558,27.624512 20.321982,27.616576 20.339911,27.600705 C 20.357839,27.584540 20.366804,27.561762 20.366804,27.532370 C 20.366804,27.502979 20.357839,27.480348 20.339911,27.464476 C 20.321982,27.448605 20.296558,27.440669 20.263640,27.440669 L 20.169735,27.440669 M 20.961979,27.428765 C 20.910250,27.428766 20.870131,27.447870 20.841621,27.486078 C 20.813112,27.524288 20.798857,27.578074 20.798857,27.647437 C 20.798857,27.716507 20.813112,27.770146 20.841621,27.808355 C 20.870131,27.846564 20.910250,27.865668 20.961979,27.865668 C 21.014001,27.865668 21.054267,27.846564 21.082778,27.808355 C 21.111287,27.770146 21.125541,27.716507 21.125542,27.647437 C 21.125541,27.578074 21.111287,27.524288 21.082778,27.486078 C 21.054267,27.447870 21.014001,27.428766 20.961979,27.428765 M 20.961979,27.305762 C 21.067787,27.305763 21.150671,27.336036 21.210630,27.396582 C 21.270588,27.457128 21.300567,27.540747 21.300568,27.647437 C 21.300567,27.753834 21.270588,27.837305 21.210630,27.897851 C 21.150671,27.958398 21.067787,27.988671 20.961979,27.988671 C 20.856464,27.988671 20.773580,27.958398 20.713328,27.897851 C 20.653370,27.837305 20.623391,27.753834 20.623391,27.647437 C 20.623391,27.540747 20.653370,27.457128 20.713328,27.396582 C 20.773580,27.336036 20.856464,27.305763 20.961979,27.305762 M 21.428420,27.317666 L 21.617994,27.317666 L 21.857387,27.769117 L 21.857387,27.317666 L 22.018305,27.317666 L 22.018305,27.975885 L 21.828730,27.975885 L 21.589338,27.524434 L 21.589338,27.975885 L 21.428420,27.975885 L 21.428420,27.317666 M 22.091489,27.317666 L 22.277095,27.317666 L 22.426991,27.552209 L 22.576887,27.317666 L 22.762935,27.317666 L 22.512079,27.698578 L 22.512079,27.975885 L 22.342344,27.975885 L 22.342344,27.698578 L 22.091489,27.317666"
1367 id="path2914" />
1368 </g>
1369 </g>
1370</svg>
diff --git a/utils/rbutilqt/icons/package-x-generic.svg b/utils/rbutilqt/icons/package-x-generic.svg
new file mode 100644
index 0000000000..47beed790f
--- /dev/null
+++ b/utils/rbutilqt/icons/package-x-generic.svg
@@ -0,0 +1,485 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 sodipodi:docname="package-x-generic.svg"
13 sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/mimetypes"
14 inkscape:version="0.46"
15 sodipodi:version="0.32"
16 id="svg2963"
17 height="48px"
18 width="48px"
19 inkscape:output_extension="org.inkscape.output.svg.inkscape">
20 <defs
21 id="defs3">
22 <inkscape:perspective
23 sodipodi:type="inkscape:persp3d"
24 inkscape:vp_x="0 : 24 : 1"
25 inkscape:vp_y="0 : 1000 : 0"
26 inkscape:vp_z="48 : 24 : 1"
27 inkscape:persp3d-origin="24 : 16 : 1"
28 id="perspective77" />
29 <radialGradient
30 inkscape:collect="always"
31 xlink:href="#linearGradient5060"
32 id="radialGradient6719"
33 gradientUnits="userSpaceOnUse"
34 gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
35 cx="605.71429"
36 cy="486.64789"
37 fx="605.71429"
38 fy="486.64789"
39 r="117.14286" />
40 <linearGradient
41 inkscape:collect="always"
42 id="linearGradient5060">
43 <stop
44 style="stop-color:black;stop-opacity:1;"
45 offset="0"
46 id="stop5062" />
47 <stop
48 style="stop-color:black;stop-opacity:0;"
49 offset="1"
50 id="stop5064" />
51 </linearGradient>
52 <radialGradient
53 inkscape:collect="always"
54 xlink:href="#linearGradient5060"
55 id="radialGradient6717"
56 gradientUnits="userSpaceOnUse"
57 gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
58 cx="605.71429"
59 cy="486.64789"
60 fx="605.71429"
61 fy="486.64789"
62 r="117.14286" />
63 <linearGradient
64 id="linearGradient5048">
65 <stop
66 style="stop-color:black;stop-opacity:0;"
67 offset="0"
68 id="stop5050" />
69 <stop
70 id="stop5056"
71 offset="0.5"
72 style="stop-color:black;stop-opacity:1;" />
73 <stop
74 style="stop-color:black;stop-opacity:0;"
75 offset="1"
76 id="stop5052" />
77 </linearGradient>
78 <linearGradient
79 inkscape:collect="always"
80 xlink:href="#linearGradient5048"
81 id="linearGradient6715"
82 gradientUnits="userSpaceOnUse"
83 gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
84 x1="302.85715"
85 y1="366.64789"
86 x2="302.85715"
87 y2="609.50507" />
88 <linearGradient
89 inkscape:collect="always"
90 id="linearGradient2884">
91 <stop
92 style="stop-color:#000000;stop-opacity:1;"
93 offset="0"
94 id="stop2886" />
95 <stop
96 style="stop-color:#000000;stop-opacity:0;"
97 offset="1"
98 id="stop2888" />
99 </linearGradient>
100 <linearGradient
101 id="linearGradient2869">
102 <stop
103 style="stop-color:#ffffff;stop-opacity:1;"
104 offset="0"
105 id="stop2871" />
106 <stop
107 style="stop-color:#cccccc;stop-opacity:1.0000000;"
108 offset="1.0000000"
109 id="stop2873" />
110 </linearGradient>
111 <linearGradient
112 id="linearGradient4995">
113 <stop
114 id="stop4997"
115 offset="0"
116 style="stop-color:#de9523;stop-opacity:1;" />
117 <stop
118 id="stop4999"
119 offset="1.0000000"
120 style="stop-color:#a36d18;stop-opacity:1.0000000;" />
121 </linearGradient>
122 <linearGradient
123 id="linearGradient4987"
124 inkscape:collect="always">
125 <stop
126 id="stop4989"
127 offset="0"
128 style="stop-color:#a0670c;stop-opacity:1;" />
129 <stop
130 id="stop4991"
131 offset="1"
132 style="stop-color:#a0670c;stop-opacity:0;" />
133 </linearGradient>
134 <linearGradient
135 id="linearGradient4979">
136 <stop
137 id="stop4981"
138 offset="0.0000000"
139 style="stop-color:#fbf0e0;stop-opacity:1.0000000;" />
140 <stop
141 id="stop4983"
142 offset="1.0000000"
143 style="stop-color:#f0ce99;stop-opacity:1.0000000;" />
144 </linearGradient>
145 <linearGradient
146 id="linearGradient4946"
147 inkscape:collect="always">
148 <stop
149 id="stop4948"
150 offset="0"
151 style="stop-color:#000000;stop-opacity:1;" />
152 <stop
153 id="stop4950"
154 offset="1"
155 style="stop-color:#000000;stop-opacity:0;" />
156 </linearGradient>
157 <linearGradient
158 id="linearGradient4222">
159 <stop
160 id="stop4224"
161 offset="0"
162 style="stop-color:#ffffff;stop-opacity:1;" />
163 <stop
164 id="stop4226"
165 offset="1.0000000"
166 style="stop-color:#ffffff;stop-opacity:0.68639052;" />
167 </linearGradient>
168 <linearGradient
169 id="linearGradient4210">
170 <stop
171 id="stop4212"
172 offset="0.0000000"
173 style="stop-color:#eaba6f;stop-opacity:1.0000000;" />
174 <stop
175 id="stop4214"
176 offset="1.0000000"
177 style="stop-color:#b97a1b;stop-opacity:1.0000000;" />
178 </linearGradient>
179 <linearGradient
180 id="linearGradient4192">
181 <stop
182 id="stop4194"
183 offset="0"
184 style="stop-color:#e9b96e;stop-opacity:1;" />
185 <stop
186 id="stop4196"
187 offset="1.0000000"
188 style="stop-color:#f1d19e;stop-opacity:1.0000000;" />
189 </linearGradient>
190 <linearGradient
191 id="linearGradient4182">
192 <stop
193 id="stop4184"
194 offset="0.0000000"
195 style="stop-color:#a36d18;stop-opacity:1.0000000;" />
196 <stop
197 id="stop4186"
198 offset="1.0000000"
199 style="stop-color:#d79020;stop-opacity:1.0000000;" />
200 </linearGradient>
201 <radialGradient
202 inkscape:collect="always"
203 xlink:href="#linearGradient4946"
204 id="radialGradient2252"
205 gradientUnits="userSpaceOnUse"
206 gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,2.658463e-16,23.58206)"
207 cx="22.930462"
208 cy="35.373093"
209 fx="22.930462"
210 fy="35.373093"
211 r="17.576654" />
212 <linearGradient
213 inkscape:collect="always"
214 xlink:href="#linearGradient4979"
215 id="linearGradient2269"
216 gradientUnits="userSpaceOnUse"
217 x1="30.062469"
218 y1="13.444801"
219 x2="17.696169"
220 y2="12.333632" />
221 <linearGradient
222 inkscape:collect="always"
223 xlink:href="#linearGradient4995"
224 id="linearGradient2274"
225 gradientUnits="userSpaceOnUse"
226 x1="36.288929"
227 y1="14.661557"
228 x2="47.065835"
229 y2="15.267649" />
230 <linearGradient
231 inkscape:collect="always"
232 xlink:href="#linearGradient4192"
233 id="linearGradient2277"
234 gradientUnits="userSpaceOnUse"
235 gradientTransform="matrix(1.000000,0.000000,0.000000,0.986355,0.000000,0.316638)"
236 x1="25.381256"
237 y1="24.720648"
238 x2="24.119167"
239 y2="16.170370" />
240 <linearGradient
241 inkscape:collect="always"
242 xlink:href="#linearGradient4182"
243 id="linearGradient2280"
244 gradientUnits="userSpaceOnUse"
245 gradientTransform="matrix(1.000000,0.000000,0.000000,1.039184,0.000000,-4.057054e-2)"
246 x1="16.148972"
247 y1="12.636667"
248 x2="34.193642"
249 y2="12.636667" />
250 <linearGradient
251 inkscape:collect="always"
252 xlink:href="#linearGradient4987"
253 id="linearGradient2282"
254 gradientUnits="userSpaceOnUse"
255 x1="21.906841"
256 y1="9.7577486"
257 x2="22.071806"
258 y2="16.020695" />
259 <linearGradient
260 inkscape:collect="always"
261 xlink:href="#linearGradient4222"
262 id="linearGradient2285"
263 gradientUnits="userSpaceOnUse"
264 x1="18.706615"
265 y1="19.912336"
266 x2="30.014812"
267 y2="47.388485" />
268 <linearGradient
269 inkscape:collect="always"
270 xlink:href="#linearGradient4210"
271 id="linearGradient2288"
272 gradientUnits="userSpaceOnUse"
273 x1="24.990499"
274 y1="34.004856"
275 x2="24.990499"
276 y2="22.585211" />
277 <radialGradient
278 inkscape:collect="always"
279 xlink:href="#linearGradient2884"
280 id="radialGradient2896"
281 gradientUnits="userSpaceOnUse"
282 gradientTransform="matrix(1.353283,5.468101e-16,-1.144754e-13,0.635968,-8.458890,3.413470)"
283 cx="23.943670"
284 cy="20.800287"
285 fx="23.943670"
286 fy="20.800287"
287 r="6.4286140" />
288 <radialGradient
289 inkscape:collect="always"
290 xlink:href="#linearGradient2869"
291 id="radialGradient2898"
292 gradientUnits="userSpaceOnUse"
293 gradientTransform="matrix(0.749420,0.000000,0.000000,0.394055,6.226925,10.09253)"
294 cx="21.578989"
295 cy="9.0255041"
296 fx="21.578989"
297 fy="9.0255041"
298 r="9.5862970" />
299 <radialGradient
300 inkscape:collect="always"
301 xlink:href="#linearGradient2884"
302 id="radialGradient2906"
303 gradientUnits="userSpaceOnUse"
304 gradientTransform="matrix(1.353283,5.468101e-16,-1.144754e-13,0.635968,-8.458890,3.413470)"
305 cx="23.943670"
306 cy="20.800287"
307 fx="23.943670"
308 fy="20.800287"
309 r="6.4286140" />
310 <radialGradient
311 inkscape:collect="always"
312 xlink:href="#linearGradient2869"
313 id="radialGradient2908"
314 gradientUnits="userSpaceOnUse"
315 gradientTransform="matrix(0.749420,0.000000,0.000000,0.394055,6.226925,10.09253)"
316 cx="21.578989"
317 cy="9.8105707"
318 fx="21.578989"
319 fy="9.8105707"
320 r="9.5862970" />
321 </defs>
322 <sodipodi:namedview
323 inkscape:window-y="142"
324 inkscape:window-x="392"
325 inkscape:window-height="706"
326 inkscape:window-width="872"
327 stroke="#c17d11"
328 fill="#e9b96e"
329 inkscape:showpageshadow="false"
330 inkscape:document-units="px"
331 inkscape:grid-bbox="true"
332 showgrid="false"
333 inkscape:current-layer="layer1"
334 inkscape:cy="39.004018"
335 inkscape:cx="74.637005"
336 inkscape:zoom="1"
337 inkscape:pageshadow="2"
338 inkscape:pageopacity="0.0"
339 borderopacity="0.16470588"
340 bordercolor="#666666"
341 pagecolor="#ffffff"
342 id="base" />
343 <metadata
344 id="metadata4">
345 <rdf:RDF>
346 <cc:Work
347 rdf:about="">
348 <dc:format>image/svg+xml</dc:format>
349 <dc:type
350 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
351 <dc:title>Package</dc:title>
352 <dc:creator>
353 <cc:Agent>
354 <dc:title>Jakub Steiner</dc:title>
355 </cc:Agent>
356 </dc:creator>
357 <dc:source>http://jimmac.musichall.cz/</dc:source>
358 <dc:subject>
359 <rdf:Bag>
360 <rdf:li>package</rdf:li>
361 <rdf:li>archive</rdf:li>
362 <rdf:li>tarball</rdf:li>
363 <rdf:li>tar</rdf:li>
364 <rdf:li>bzip</rdf:li>
365 <rdf:li>gzip</rdf:li>
366 <rdf:li>zip</rdf:li>
367 <rdf:li>arj</rdf:li>
368 <rdf:li>tar</rdf:li>
369 <rdf:li>jar</rdf:li>
370 </rdf:Bag>
371 </dc:subject>
372 <cc:license
373 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
374 </cc:Work>
375 <cc:License
376 rdf:about="http://creativecommons.org/licenses/publicdomain/">
377 <cc:permits
378 rdf:resource="http://creativecommons.org/ns#Reproduction" />
379 <cc:permits
380 rdf:resource="http://creativecommons.org/ns#Distribution" />
381 <cc:permits
382 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
383 </cc:License>
384 </rdf:RDF>
385 </metadata>
386 <g
387 inkscape:groupmode="layer"
388 inkscape:label="Layer 1"
389 id="layer1">
390 <g
391 style="display:inline"
392 transform="matrix(2.105461e-2,0,0,2.086758e-2,42.60172,35.4036)"
393 id="g6707">
394 <rect
395 style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
396 id="rect6709"
397 width="1339.6335"
398 height="478.35718"
399 x="-1559.2523"
400 y="-150.69685" />
401 <path
402 style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
403 d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
404 id="path6711"
405 sodipodi:nodetypes="cccc" />
406 <path
407 sodipodi:nodetypes="cccc"
408 id="path6713"
409 d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
410 style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
411 </g>
412 <rect
413 ry="2.3944440"
414 rx="2.4241352"
415 y="15.275433"
416 x="7.4623847"
417 height="23.112879"
418 width="31.978371"
419 id="rect3115"
420 style="opacity:1.0000000;color:#000000;fill:url(#linearGradient2288);fill-opacity:1.0000000;fill-rule:nonzero;stroke:#a0670c;stroke-width:1.0000007;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible" />
421 <rect
422 style="opacity:0.48101267;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#linearGradient2285);stroke-width:1.0000011;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible"
423 id="rect4220"
424 width="29.804138"
425 height="21.075352"
426 x="8.4989996"
427 y="16.243698"
428 rx="1.2846882"
429 ry="1.2846882" />
430 <path
431 sodipodi:nodetypes="ccccc"
432 id="path4162"
433 d="M 8.7697819,16.547178 L 13.819731,9.7363408 L 32.615291,9.6353255 L 37.835264,16.408941 L 8.7697819,16.547178 z "
434 style="fill:url(#linearGradient2280);fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2282);stroke-width:1.0000008;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000" />
435 <path
436 sodipodi:nodetypes="ccccc"
437 id="path4164"
438 d="M 38.276321,16.325703 L 43.469269,23.520364 L 3.9609455,23.520364 L 8.6250143,16.320763 L 38.276321,16.325703 z "
439 style="opacity:1.0000000;color:#000000;fill:url(#linearGradient2277);fill-opacity:1.0000000;fill-rule:nonzero;stroke:#a0670c;stroke-width:1.0000005;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible" />
440 <path
441 sodipodi:nodetypes="ccccc"
442 id="path4178"
443 d="M 32.849333,9.6141009 L 37.532219,16.536370 L 46.565835,20.921197 L 38.451329,12.008545 L 32.849333,9.6141009 z "
444 style="opacity:1.0000000;color:#000000;fill:url(#linearGradient2274);fill-opacity:1.0000000;fill-rule:nonzero;stroke:#a0670c;stroke-width:1.0000005;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible" />
445 <path
446 sodipodi:nodetypes="ccccc"
447 style="opacity:1.0000000;color:#000000;fill:#f8e8cf;fill-opacity:1.0000000;fill-rule:nonzero;stroke:#a0670c;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible"
448 d="M 13.617702,9.7151161 L 9.6419233,16.435355 L 0.50729183,20.820182 L 8.6217973,11.907530 L 13.617702,9.7151161 z "
449 id="path4180" />
450 <path
451 style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:nonzero;stroke:#f4e3ca;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible"
452 d="M 37.024959,16.436050 L 41.478871,22.493011 L 5.6482792,22.493011 L 9.7892982,16.312694 L 37.024959,16.436050 z "
453 id="path4954"
454 sodipodi:nodetypes="ccccc" />
455 <g
456 id="g2892"
457 transform="matrix(0.676538,0.000000,0.000000,1.000000,3.994869,0.000000)">
458 <path
459 style="opacity:1.0000000;color:#000000;fill:url(#radialGradient2896);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:2.0000000;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
460 d="M 23.926073,12.101621 C 18.588065,12.101621 14.282569,14.129809 14.282569,16.641813 L 33.604773,16.641813 C 33.604773,14.129809 29.264081,12.101621 23.926073,12.101621 z "
461 id="path2882" />
462 <path
463 id="path2141"
464 d="M 23.931961,12.861168 C 20.379986,12.861168 17.515057,14.210748 17.515057,15.882266 L 30.372285,15.882266 C 30.372285,14.210748 27.483936,12.861168 23.931961,12.861168 z "
465 style="opacity:1.0000000;color:#000000;fill:url(#radialGradient2898);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:2.0000000;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
466 </g>
467 <g
468 transform="matrix(0.676538,0.000000,0.000000,1.000000,10.49487,0.000000)"
469 id="g2900">
470 <path
471 id="path2902"
472 d="M 23.926073,12.101621 C 18.588065,12.101621 14.282569,14.129809 14.282569,16.641813 L 33.604773,16.641813 C 33.604773,14.129809 29.264081,12.101621 23.926073,12.101621 z "
473 style="opacity:1.0000000;color:#000000;fill:url(#radialGradient2906);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:2.0000000;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
474 <path
475 style="opacity:1.0000000;color:#000000;fill:url(#radialGradient2908);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:2.0000000;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
476 d="M 23.931961,12.861168 C 20.379986,12.861168 17.515057,14.210748 17.515057,15.882266 L 30.372285,15.882266 C 30.372285,14.210748 27.483936,12.861168 23.931961,12.861168 z "
477 id="path2904" />
478 </g>
479 <path
480 style="opacity:0.87974685;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2269);stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
481 d="M 9.6523127,16.371803 L 13.036643,10.593020 L 33.514841,10.517799 L 37.356782,16.369880 L 9.6523127,16.371803 z "
482 id="path4966"
483 sodipodi:nodetypes="ccccc" />
484 </g>
485</svg>
diff --git a/utils/rbutilqt/icons/players/archosfmrecorder-small.png b/utils/rbutilqt/icons/players/archosfmrecorder-small.png
new file mode 100644
index 0000000000..e9e1e6a982
--- /dev/null
+++ b/utils/rbutilqt/icons/players/archosfmrecorder-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/archosondiofm-small.png b/utils/rbutilqt/icons/players/archosondiofm-small.png
new file mode 100644
index 0000000000..8ac3f16ae4
--- /dev/null
+++ b/utils/rbutilqt/icons/players/archosondiofm-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/archosondiosp-small.png b/utils/rbutilqt/icons/players/archosondiosp-small.png
new file mode 100644
index 0000000000..c96c0cb9bb
--- /dev/null
+++ b/utils/rbutilqt/icons/players/archosondiosp-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/archosplayer-small.png b/utils/rbutilqt/icons/players/archosplayer-small.png
new file mode 100644
index 0000000000..87d6cec6a5
--- /dev/null
+++ b/utils/rbutilqt/icons/players/archosplayer-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/archosrecorder-small.png b/utils/rbutilqt/icons/players/archosrecorder-small.png
new file mode 100644
index 0000000000..9e4f5b7d92
--- /dev/null
+++ b/utils/rbutilqt/icons/players/archosrecorder-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/archosrecorderv2-small.png b/utils/rbutilqt/icons/players/archosrecorderv2-small.png
new file mode 100644
index 0000000000..e9e1e6a982
--- /dev/null
+++ b/utils/rbutilqt/icons/players/archosrecorderv2-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/cowond2-small.png b/utils/rbutilqt/icons/players/cowond2-small.png
new file mode 100644
index 0000000000..b365fc36b0
--- /dev/null
+++ b/utils/rbutilqt/icons/players/cowond2-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/fonts-small.png b/utils/rbutilqt/icons/players/fonts-small.png
new file mode 100644
index 0000000000..4c7cdcb426
--- /dev/null
+++ b/utils/rbutilqt/icons/players/fonts-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/gigabeatfx-small.png b/utils/rbutilqt/icons/players/gigabeatfx-small.png
new file mode 100644
index 0000000000..6d3744f106
--- /dev/null
+++ b/utils/rbutilqt/icons/players/gigabeatfx-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/gigabeats-small.png b/utils/rbutilqt/icons/players/gigabeats-small.png
new file mode 100644
index 0000000000..48e905bcb7
--- /dev/null
+++ b/utils/rbutilqt/icons/players/gigabeats-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/gogearhdd1630-small.png b/utils/rbutilqt/icons/players/gogearhdd1630-small.png
new file mode 100644
index 0000000000..ff7b097942
--- /dev/null
+++ b/utils/rbutilqt/icons/players/gogearhdd1630-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/gogearhdd6330-small.png b/utils/rbutilqt/icons/players/gogearhdd6330-small.png
new file mode 100644
index 0000000000..5b7af846b1
--- /dev/null
+++ b/utils/rbutilqt/icons/players/gogearhdd6330-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/gogearsa9200-small.png b/utils/rbutilqt/icons/players/gogearsa9200-small.png
new file mode 100644
index 0000000000..5d8f70a220
--- /dev/null
+++ b/utils/rbutilqt/icons/players/gogearsa9200-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/hifimanhm60x-small.png b/utils/rbutilqt/icons/players/hifimanhm60x-small.png
new file mode 100644
index 0000000000..1220a5c46d
--- /dev/null
+++ b/utils/rbutilqt/icons/players/hifimanhm60x-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/hifimanhm801-small.png b/utils/rbutilqt/icons/players/hifimanhm801-small.png
new file mode 100644
index 0000000000..1a9751661d
--- /dev/null
+++ b/utils/rbutilqt/icons/players/hifimanhm801-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/iaudiom3-small.png b/utils/rbutilqt/icons/players/iaudiom3-small.png
new file mode 100644
index 0000000000..b72cb7dcc2
--- /dev/null
+++ b/utils/rbutilqt/icons/players/iaudiom3-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/iaudiom5-small.png b/utils/rbutilqt/icons/players/iaudiom5-small.png
new file mode 100644
index 0000000000..40cfff4f01
--- /dev/null
+++ b/utils/rbutilqt/icons/players/iaudiom5-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/iaudiox5-small.png b/utils/rbutilqt/icons/players/iaudiox5-small.png
new file mode 100644
index 0000000000..e95e434fd5
--- /dev/null
+++ b/utils/rbutilqt/icons/players/iaudiox5-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/ipod1g2g-small.png b/utils/rbutilqt/icons/players/ipod1g2g-small.png
new file mode 100644
index 0000000000..a573751c2f
--- /dev/null
+++ b/utils/rbutilqt/icons/players/ipod1g2g-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/ipod3g-small.png b/utils/rbutilqt/icons/players/ipod3g-small.png
new file mode 100644
index 0000000000..3efc1de071
--- /dev/null
+++ b/utils/rbutilqt/icons/players/ipod3g-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/ipod4g-small.png b/utils/rbutilqt/icons/players/ipod4g-small.png
new file mode 100644
index 0000000000..76cd554090
--- /dev/null
+++ b/utils/rbutilqt/icons/players/ipod4g-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/ipod6g-small.png b/utils/rbutilqt/icons/players/ipod6g-small.png
new file mode 100644
index 0000000000..b0ab21ee87
--- /dev/null
+++ b/utils/rbutilqt/icons/players/ipod6g-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/ipodcolor-small.png b/utils/rbutilqt/icons/players/ipodcolor-small.png
new file mode 100644
index 0000000000..8d530137c8
--- /dev/null
+++ b/utils/rbutilqt/icons/players/ipodcolor-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/ipodmini1g-small.png b/utils/rbutilqt/icons/players/ipodmini1g-small.png
new file mode 100644
index 0000000000..39f91bdde5
--- /dev/null
+++ b/utils/rbutilqt/icons/players/ipodmini1g-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/ipodnano1g-small.png b/utils/rbutilqt/icons/players/ipodnano1g-small.png
new file mode 100644
index 0000000000..71be0b8ed2
--- /dev/null
+++ b/utils/rbutilqt/icons/players/ipodnano1g-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/ipodnano2g-small.png b/utils/rbutilqt/icons/players/ipodnano2g-small.png
new file mode 100644
index 0000000000..413c041f7b
--- /dev/null
+++ b/utils/rbutilqt/icons/players/ipodnano2g-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/ipodvideo-small.png b/utils/rbutilqt/icons/players/ipodvideo-small.png
new file mode 100644
index 0000000000..40155ba14f
--- /dev/null
+++ b/utils/rbutilqt/icons/players/ipodvideo-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/iriverh10-small.png b/utils/rbutilqt/icons/players/iriverh10-small.png
new file mode 100644
index 0000000000..8ffe9162d3
--- /dev/null
+++ b/utils/rbutilqt/icons/players/iriverh10-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/iriverh100-small.png b/utils/rbutilqt/icons/players/iriverh100-small.png
new file mode 100644
index 0000000000..cc13ecf4c6
--- /dev/null
+++ b/utils/rbutilqt/icons/players/iriverh100-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/iriverh10_5gb-small.png b/utils/rbutilqt/icons/players/iriverh10_5gb-small.png
new file mode 100644
index 0000000000..c034586398
--- /dev/null
+++ b/utils/rbutilqt/icons/players/iriverh10_5gb-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/iriverh300-small.png b/utils/rbutilqt/icons/players/iriverh300-small.png
new file mode 100644
index 0000000000..3c5657bf00
--- /dev/null
+++ b/utils/rbutilqt/icons/players/iriverh300-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/mpiohd200-small.png b/utils/rbutilqt/icons/players/mpiohd200-small.png
new file mode 100644
index 0000000000..d82ba6c015
--- /dev/null
+++ b/utils/rbutilqt/icons/players/mpiohd200-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/mpiohd300-small.png b/utils/rbutilqt/icons/players/mpiohd300-small.png
new file mode 100644
index 0000000000..744dfc09c0
--- /dev/null
+++ b/utils/rbutilqt/icons/players/mpiohd300-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/mrobe100-small.png b/utils/rbutilqt/icons/players/mrobe100-small.png
new file mode 100644
index 0000000000..3ab6206a73
--- /dev/null
+++ b/utils/rbutilqt/icons/players/mrobe100-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/mrobe500-small.png b/utils/rbutilqt/icons/players/mrobe500-small.png
new file mode 100644
index 0000000000..6c08b15495
--- /dev/null
+++ b/utils/rbutilqt/icons/players/mrobe500-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/samsungyh820-small.png b/utils/rbutilqt/icons/players/samsungyh820-small.png
new file mode 100644
index 0000000000..27702e5c61
--- /dev/null
+++ b/utils/rbutilqt/icons/players/samsungyh820-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/samsungyh920-small.png b/utils/rbutilqt/icons/players/samsungyh920-small.png
new file mode 100644
index 0000000000..0188b4186a
--- /dev/null
+++ b/utils/rbutilqt/icons/players/samsungyh920-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/samsungyh925-small.png b/utils/rbutilqt/icons/players/samsungyh925-small.png
new file mode 100644
index 0000000000..733bc6fbbd
--- /dev/null
+++ b/utils/rbutilqt/icons/players/samsungyh925-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/samsungypr0-small.png b/utils/rbutilqt/icons/players/samsungypr0-small.png
new file mode 100644
index 0000000000..2183eec0ba
--- /dev/null
+++ b/utils/rbutilqt/icons/players/samsungypr0-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/sansac200-small.png b/utils/rbutilqt/icons/players/sansac200-small.png
new file mode 100644
index 0000000000..4678c607c1
--- /dev/null
+++ b/utils/rbutilqt/icons/players/sansac200-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/sansaclip-small.png b/utils/rbutilqt/icons/players/sansaclip-small.png
new file mode 100644
index 0000000000..a4e1c4a69b
--- /dev/null
+++ b/utils/rbutilqt/icons/players/sansaclip-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/sansaclipplus-small.png b/utils/rbutilqt/icons/players/sansaclipplus-small.png
new file mode 100644
index 0000000000..edb7691ae8
--- /dev/null
+++ b/utils/rbutilqt/icons/players/sansaclipplus-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/sansaclipzip-small.png b/utils/rbutilqt/icons/players/sansaclipzip-small.png
new file mode 100644
index 0000000000..bc1f2a3fd0
--- /dev/null
+++ b/utils/rbutilqt/icons/players/sansaclipzip-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/sansaconnect-small.png b/utils/rbutilqt/icons/players/sansaconnect-small.png
new file mode 100644
index 0000000000..af348466ee
--- /dev/null
+++ b/utils/rbutilqt/icons/players/sansaconnect-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/sansae200-small.png b/utils/rbutilqt/icons/players/sansae200-small.png
new file mode 100644
index 0000000000..530456be1c
--- /dev/null
+++ b/utils/rbutilqt/icons/players/sansae200-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/sansafuze-small.png b/utils/rbutilqt/icons/players/sansafuze-small.png
new file mode 100644
index 0000000000..8cef62abc6
--- /dev/null
+++ b/utils/rbutilqt/icons/players/sansafuze-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/sansafuzeplus-small.png b/utils/rbutilqt/icons/players/sansafuzeplus-small.png
new file mode 100644
index 0000000000..6d7336f1ec
--- /dev/null
+++ b/utils/rbutilqt/icons/players/sansafuzeplus-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/source-small.png b/utils/rbutilqt/icons/players/source-small.png
new file mode 100644
index 0000000000..4c7cdcb426
--- /dev/null
+++ b/utils/rbutilqt/icons/players/source-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/vibe500-small.png b/utils/rbutilqt/icons/players/vibe500-small.png
new file mode 100644
index 0000000000..901ac676e9
--- /dev/null
+++ b/utils/rbutilqt/icons/players/vibe500-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/vx747-small.png b/utils/rbutilqt/icons/players/vx747-small.png
new file mode 100644
index 0000000000..940babd485
--- /dev/null
+++ b/utils/rbutilqt/icons/players/vx747-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/players/vx777-small.png b/utils/rbutilqt/icons/players/vx777-small.png
new file mode 100644
index 0000000000..2466b9d504
--- /dev/null
+++ b/utils/rbutilqt/icons/players/vx777-small.png
Binary files differ
diff --git a/utils/rbutilqt/icons/preferences-desktop-font.svg b/utils/rbutilqt/icons/preferences-desktop-font.svg
new file mode 100644
index 0000000000..079398021d
--- /dev/null
+++ b/utils/rbutilqt/icons/preferences-desktop-font.svg
@@ -0,0 +1,243 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 inkscape:export-ydpi="90.000000"
13 inkscape:export-xdpi="90.000000"
14 inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
15 width="48px"
16 height="48px"
17 id="svg11300"
18 sodipodi:version="0.32"
19 inkscape:version="0.46"
20 sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/apps"
21 sodipodi:docname="preferences-desktop-font.svg"
22 inkscape:output_extension="org.inkscape.output.svg.inkscape">
23 <defs
24 id="defs3">
25 <inkscape:perspective
26 sodipodi:type="inkscape:persp3d"
27 inkscape:vp_x="0 : 24 : 1"
28 inkscape:vp_y="0 : 1000 : 0"
29 inkscape:vp_z="48 : 24 : 1"
30 inkscape:persp3d-origin="24 : 16 : 1"
31 id="perspective34" />
32 <radialGradient
33 inkscape:collect="always"
34 xlink:href="#linearGradient5060"
35 id="radialGradient6719"
36 gradientUnits="userSpaceOnUse"
37 gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
38 cx="605.71429"
39 cy="486.64789"
40 fx="605.71429"
41 fy="486.64789"
42 r="117.14286" />
43 <linearGradient
44 inkscape:collect="always"
45 id="linearGradient5060">
46 <stop
47 style="stop-color:black;stop-opacity:1;"
48 offset="0"
49 id="stop5062" />
50 <stop
51 style="stop-color:black;stop-opacity:0;"
52 offset="1"
53 id="stop5064" />
54 </linearGradient>
55 <radialGradient
56 inkscape:collect="always"
57 xlink:href="#linearGradient5060"
58 id="radialGradient6717"
59 gradientUnits="userSpaceOnUse"
60 gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
61 cx="605.71429"
62 cy="486.64789"
63 fx="605.71429"
64 fy="486.64789"
65 r="117.14286" />
66 <linearGradient
67 id="linearGradient5048">
68 <stop
69 style="stop-color:black;stop-opacity:0;"
70 offset="0"
71 id="stop5050" />
72 <stop
73 id="stop5056"
74 offset="0.5"
75 style="stop-color:black;stop-opacity:1;" />
76 <stop
77 style="stop-color:black;stop-opacity:0;"
78 offset="1"
79 id="stop5052" />
80 </linearGradient>
81 <linearGradient
82 inkscape:collect="always"
83 xlink:href="#linearGradient5048"
84 id="linearGradient6715"
85 gradientUnits="userSpaceOnUse"
86 gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
87 x1="302.85715"
88 y1="366.64789"
89 x2="302.85715"
90 y2="609.50507" />
91 <linearGradient
92 id="linearGradient11520">
93 <stop
94 id="stop11522"
95 offset="0.0000000"
96 style="stop-color:#ffffff;stop-opacity:1.0000000;" />
97 <stop
98 id="stop11524"
99 offset="1.0000000"
100 style="stop-color:#dcdcdc;stop-opacity:1.0000000;" />
101 </linearGradient>
102 <linearGradient
103 id="linearGradient11508"
104 inkscape:collect="always">
105 <stop
106 id="stop11510"
107 offset="0"
108 style="stop-color:#000000;stop-opacity:1;" />
109 <stop
110 id="stop11512"
111 offset="1"
112 style="stop-color:#000000;stop-opacity:0;" />
113 </linearGradient>
114 <radialGradient
115 inkscape:collect="always"
116 xlink:href="#linearGradient11508"
117 id="radialGradient1348"
118 gradientUnits="userSpaceOnUse"
119 gradientTransform="matrix(1.000000,0.000000,0.000000,0.338462,-1.435476e-15,29.48178)"
120 cx="30.203562"
121 cy="44.565483"
122 fx="30.203562"
123 fy="44.565483"
124 r="6.5659914" />
125 <radialGradient
126 inkscape:collect="always"
127 xlink:href="#linearGradient11520"
128 id="radialGradient1366"
129 gradientUnits="userSpaceOnUse"
130 gradientTransform="matrix(1.995058,-1.651527e-32,0.000000,1.995058,-24.32488,-35.70087)"
131 cx="24.445690"
132 cy="35.878170"
133 fx="24.445690"
134 fy="35.878170"
135 r="20.530962" />
136 </defs>
137 <sodipodi:namedview
138 stroke="#ef2929"
139 fill="#eeeeec"
140 id="base"
141 pagecolor="#ffffff"
142 bordercolor="#666666"
143 borderopacity="0.25490196"
144 inkscape:pageopacity="0.0"
145 inkscape:pageshadow="2"
146 inkscape:zoom="1"
147 inkscape:cx="-138.1819"
148 inkscape:cy="22.612601"
149 inkscape:current-layer="layer1"
150 showgrid="false"
151 inkscape:grid-bbox="true"
152 inkscape:document-units="px"
153 inkscape:showpageshadow="false"
154 inkscape:window-width="872"
155 inkscape:window-height="707"
156 inkscape:window-x="271"
157 inkscape:window-y="141" />
158 <metadata
159 id="metadata4">
160 <rdf:RDF>
161 <cc:Work
162 rdf:about="">
163 <dc:format>image/svg+xml</dc:format>
164 <dc:type
165 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
166 <dc:creator>
167 <cc:Agent>
168 <dc:title>Jakub Steiner</dc:title>
169 </cc:Agent>
170 </dc:creator>
171 <dc:source>http://jimmac.musichall.cz</dc:source>
172 <cc:license
173 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
174 <dc:title>Wi-Fi network</dc:title>
175 </cc:Work>
176 <cc:License
177 rdf:about="http://creativecommons.org/licenses/publicdomain/">
178 <cc:permits
179 rdf:resource="http://creativecommons.org/ns#Reproduction" />
180 <cc:permits
181 rdf:resource="http://creativecommons.org/ns#Distribution" />
182 <cc:permits
183 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
184 </cc:License>
185 </rdf:RDF>
186 </metadata>
187 <g
188 id="layer1"
189 inkscape:label="Layer 1"
190 inkscape:groupmode="layer">
191 <g
192 transform="matrix(2.33489e-2,0,0,2.564584e-2,45.48163,38.7308)"
193 id="g6707">
194 <rect
195 style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
196 id="rect6709"
197 width="1339.6335"
198 height="478.35718"
199 x="-1559.2523"
200 y="-150.69685" />
201 <path
202 style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
203 d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
204 id="path6711"
205 sodipodi:nodetypes="cccc" />
206 <path
207 sodipodi:nodetypes="cccc"
208 id="path6713"
209 d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
210 style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
211 </g>
212 <rect
213 ry="5.4548240"
214 rx="5.4548240"
215 y="3.5233452"
216 x="4.4147282"
217 height="40.061924"
218 width="40.061924"
219 id="rect11518"
220 style="opacity:1.0000000;color:#000000;fill:url(#radialGradient1366);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#9b9b9b;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
221 <rect
222 style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999976;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
223 id="rect11528"
224 width="37.696587"
225 height="37.696587"
226 x="5.5973887"
227 y="4.7060070"
228 rx="4.2426391"
229 ry="4.2426391" />
230 <path
231 style="font-size:24px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:120.00000477%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
232 d="M 19.187523,7.5673065 L 16.902367,15.512619 L 16.644555,16.579025 C 16.621108,16.680589 16.60939,16.766527 16.609398,16.836838 C 16.60939,16.961839 16.648452,17.071214 16.726586,17.164963 C 16.789077,17.235276 16.867202,17.270432 16.960961,17.270432 C 17.062514,17.270432 17.195327,17.207932 17.359398,17.082932 C 17.664076,16.85637 18.070326,16.387621 18.578148,15.676682 L 18.976586,15.957932 C 18.437513,16.770433 17.882826,17.391526 17.312523,17.821213 C 16.742202,18.243088 16.214859,18.454025 15.730492,18.454025 C 15.394547,18.454025 15.140641,18.368088 14.968773,18.196213 C 14.804704,18.03215 14.722673,17.789963 14.72268,17.46965 C 14.722673,17.086839 14.80861,16.582933 14.980492,15.957932 L 15.226586,15.079025 C 14.203142,16.414965 13.261737,17.348557 12.402367,17.879807 C 11.785176,18.262619 11.179708,18.454025 10.585961,18.454025 C 10.015646,18.454025 9.5234593,18.21965 9.1093984,17.7509 C 8.6953351,17.274339 8.4883041,16.621996 8.4883046,15.793869 C 8.4883041,14.551685 8.8593974,13.243093 9.6015859,11.868088 C 10.351583,10.485283 11.300801,9.3798153 12.449242,8.5516815 C 13.347674,7.8954418 14.19533,7.5673171 14.992211,7.5673065 C 15.468766,7.5673171 15.863297,7.692317 16.175805,7.9423065 C 16.496109,8.1923165 16.738296,8.6063786 16.902367,9.184494 L 17.324242,7.8485565 L 19.187523,7.5673065 M 15.015648,8.1766815 C 14.515642,8.1766915 13.984392,8.4110663 13.421898,8.8798065 C 12.625019,9.5438776 11.914082,10.528252 11.289086,11.832932 C 10.671896,13.137624 10.363302,14.31731 10.363305,15.371994 C 10.363302,15.903246 10.496115,16.325121 10.761742,16.637619 C 11.027364,16.942308 11.332051,17.094651 11.675805,17.09465 C 12.527363,17.094651 13.453143,16.465746 14.453148,15.207932 C 15.789078,13.536061 16.457046,11.821219 16.457055,10.0634 C 16.457046,9.3993465 16.32814,8.9188783 16.070336,8.621994 C 15.812515,8.3251289 15.460953,8.1766915 15.015648,8.1766815"
233 id="text3423" />
234 <path
235 style="font-size:29.01771545px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:120.00000477%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Arial Rounded CE"
236 d="M 23.843165,20.148025 L 23.843165,26.056417 C 24.570491,25.300761 25.311991,24.724563 26.067668,24.327823 C 26.823329,23.921665 27.758469,23.718579 28.873091,23.718564 C 30.157718,23.718579 31.281775,24.02557 32.245267,24.639536 C 33.218177,25.244086 33.969123,26.127274 34.498107,27.289103 C 35.036505,28.44151 35.305712,29.81116 35.305729,31.398057 C 35.305712,32.569351 35.154579,33.64618 34.852328,34.628545 C 34.559489,35.601473 34.129703,36.446878 33.562966,37.164761 C 32.996199,37.882649 32.306651,38.439954 31.49432,38.83668 C 30.691409,39.223961 29.803498,39.417601 28.830585,39.417601 C 28.235485,39.417601 27.673456,39.346757 27.144497,39.205069 C 26.624966,39.063381 26.18101,38.879187 25.812629,38.652486 C 25.444233,38.41634 25.127797,38.17547 24.863319,37.929877 C 24.608274,37.684285 24.268223,37.315897 23.843165,36.82471 L 23.843165,37.207268 C 23.843159,37.934601 23.668411,38.487184 23.318919,38.865018 C 22.969417,39.233407 22.525462,39.417601 21.987051,39.417601 C 21.439188,39.417601 20.999955,39.233407 20.669352,38.865018 C 20.348191,38.487184 20.187611,37.934601 20.187613,37.207268 L 20.187613,20.31805 C 20.187611,19.534063 20.343468,18.943696 20.655184,18.54695 C 20.976341,18.140798 21.420296,17.937712 21.987051,17.937691 C 22.582137,17.937712 23.040261,18.131352 23.361426,18.518612 C 23.68258,18.896467 23.843159,19.439604 23.843165,20.148025 M 24.02736,31.638927 C 24.027354,33.178609 24.376851,34.364065 25.075851,35.195297 C 25.784284,36.017091 26.709978,36.427986 27.852937,36.427983 C 28.825851,36.427986 29.66181,36.007645 30.360816,35.166959 C 31.069244,34.316836 31.423463,33.103043 31.423476,31.525576 C 31.423463,30.505431 31.277052,29.626966 30.984243,28.890178 C 30.691409,28.153411 30.275791,27.58666 29.737388,27.189921 C 29.198963,26.783761 28.570813,26.580675 27.852937,26.580663 C 27.11615,26.580675 26.459663,26.783761 25.883473,27.189921 C 25.307268,27.58666 24.853867,28.16758 24.523268,28.932685 C 24.192656,29.688364 24.027354,30.590443 24.02736,31.638927"
237 id="text3427" />
238 <path
239 style="font-size:19.52186584px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:120.00000477%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Carbon Block"
240 d="M 39.201934,12.649522 C 39.201926,12.84475 39.188912,13.13107 39.16289,13.508484 C 39.149868,13.8729 39.143361,14.139699 39.143368,14.308881 L 36.410307,14.308881 L 36.410307,11.907691 C 36.410302,11.439177 36.150011,11.204915 35.629432,11.204904 C 35.108846,11.204915 34.848554,11.439177 34.848558,11.907691 L 34.848558,19.618828 C 34.848554,20.100369 35.108846,20.341139 35.629432,20.341137 C 36.150011,20.341139 36.410302,20.100369 36.410307,19.618828 L 36.410307,17.061464 L 39.143368,17.061464 L 39.143368,19.560263 C 39.143361,20.328124 38.726894,20.913779 37.893969,21.317231 C 37.23022,21.642595 36.475375,21.805277 35.629432,21.805277 C 34.770467,21.805277 34.015622,21.642595 33.364896,21.317231 C 32.531962,20.913779 32.115496,20.328124 32.115496,19.560263 L 32.115496,12.044344 C 32.115496,10.599737 33.286807,9.877429 35.629432,9.8774174 C 36.800739,9.877429 37.6597,10.053126 38.206319,10.404508 C 38.870055,10.833999 39.201926,11.582337 39.201934,12.649522"
241 id="text3431" />
242 </g>
243</svg>
diff --git a/utils/rbutilqt/icons/preferences-desktop-locale.svg b/utils/rbutilqt/icons/preferences-desktop-locale.svg
new file mode 100644
index 0000000000..2e71f18a80
--- /dev/null
+++ b/utils/rbutilqt/icons/preferences-desktop-locale.svg
@@ -0,0 +1,878 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 inkscape:export-ydpi="90.000000"
13 inkscape:export-xdpi="90.000000"
14 inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
15 width="48px"
16 height="48px"
17 id="svg11300"
18 sodipodi:version="0.32"
19 inkscape:version="0.46"
20 sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/apps"
21 sodipodi:docname="preferences-desktop-locale.svg"
22 inkscape:output_extension="org.inkscape.output.svg.inkscape">
23 <defs
24 id="defs3">
25 <inkscape:perspective
26 sodipodi:type="inkscape:persp3d"
27 inkscape:vp_x="0 : 24 : 1"
28 inkscape:vp_y="0 : 1000 : 0"
29 inkscape:vp_z="48 : 24 : 1"
30 inkscape:persp3d-origin="24 : 16 : 1"
31 id="perspective133" />
32 <linearGradient
33 id="linearGradient2913">
34 <stop
35 style="stop-color:white;stop-opacity:0.43877551;"
36 offset="0"
37 id="stop2915" />
38 <stop
39 id="stop2921"
40 offset="0.5"
41 style="stop-color:white;stop-opacity:1;" />
42 <stop
43 style="stop-color:white;stop-opacity:0;"
44 offset="1"
45 id="stop2917" />
46 </linearGradient>
47 <linearGradient
48 id="linearGradient2877">
49 <stop
50 style="stop-color:#75507b;stop-opacity:1;"
51 offset="0"
52 id="stop2879" />
53 <stop
54 id="stop2885"
55 offset="0.25709054"
56 style="stop-color:#a984af;stop-opacity:1;" />
57 <stop
58 style="stop-color:#513755;stop-opacity:1;"
59 offset="0.5655992"
60 id="stop2887" />
61 <stop
62 style="stop-color:#875c8e;stop-opacity:1;"
63 offset="1"
64 id="stop2881" />
65 </linearGradient>
66 <linearGradient
67 id="linearGradient2865">
68 <stop
69 style="stop-color:#73d216;stop-opacity:1;"
70 offset="0"
71 id="stop2867" />
72 <stop
73 id="stop2873"
74 offset="0.25568181"
75 style="stop-color:#9ced4b;stop-opacity:1;" />
76 <stop
77 style="stop-color:#64b813;stop-opacity:1;"
78 offset="0.59400827"
79 id="stop2875" />
80 <stop
81 style="stop-color:#8eea34;stop-opacity:1;"
82 offset="1"
83 id="stop2869" />
84 </linearGradient>
85 <radialGradient
86 inkscape:collect="always"
87 xlink:href="#linearGradient5060"
88 id="radialGradient6719"
89 gradientUnits="userSpaceOnUse"
90 gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
91 cx="605.71429"
92 cy="486.64789"
93 fx="605.71429"
94 fy="486.64789"
95 r="117.14286" />
96 <linearGradient
97 inkscape:collect="always"
98 id="linearGradient5060">
99 <stop
100 style="stop-color:black;stop-opacity:1;"
101 offset="0"
102 id="stop5062" />
103 <stop
104 style="stop-color:black;stop-opacity:0;"
105 offset="1"
106 id="stop5064" />
107 </linearGradient>
108 <radialGradient
109 inkscape:collect="always"
110 xlink:href="#linearGradient5060"
111 id="radialGradient6717"
112 gradientUnits="userSpaceOnUse"
113 gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
114 cx="605.71429"
115 cy="486.64789"
116 fx="605.71429"
117 fy="486.64789"
118 r="117.14286" />
119 <linearGradient
120 id="linearGradient5048">
121 <stop
122 style="stop-color:black;stop-opacity:0;"
123 offset="0"
124 id="stop5050" />
125 <stop
126 id="stop5056"
127 offset="0.5"
128 style="stop-color:black;stop-opacity:1;" />
129 <stop
130 style="stop-color:black;stop-opacity:0;"
131 offset="1"
132 id="stop5052" />
133 </linearGradient>
134 <linearGradient
135 inkscape:collect="always"
136 xlink:href="#linearGradient5048"
137 id="linearGradient6715"
138 gradientUnits="userSpaceOnUse"
139 gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
140 x1="302.85715"
141 y1="366.64789"
142 x2="302.85715"
143 y2="609.50507" />
144 <linearGradient
145 id="linearGradient16542">
146 <stop
147 style="stop-color:#2e3436;stop-opacity:1;"
148 offset="0"
149 id="stop16544" />
150 <stop
151 id="stop16550"
152 offset="0.27272728"
153 style="stop-color:#505a5d;stop-opacity:1;" />
154 <stop
155 style="stop-color:#141717;stop-opacity:1;"
156 offset="0.63636363"
157 id="stop16554" />
158 <stop
159 style="stop-color:#2e3436;stop-opacity:1;"
160 offset="1"
161 id="stop16546" />
162 </linearGradient>
163 <linearGradient
164 id="linearGradient16532">
165 <stop
166 style="stop-color:#cc0000;stop-opacity:1;"
167 offset="0"
168 id="stop16534" />
169 <stop
170 id="stop16540"
171 offset="0.24242425"
172 style="stop-color:#ff4747;stop-opacity:1;" />
173 <stop
174 style="stop-color:#9b1212;stop-opacity:1;"
175 offset="0.6097337"
176 id="stop16552" />
177 <stop
178 style="stop-color:#cc0000;stop-opacity:1;"
179 offset="1"
180 id="stop16536" />
181 </linearGradient>
182 <linearGradient
183 id="linearGradient16522">
184 <stop
185 style="stop-color:#edd400;stop-opacity:1;"
186 offset="0"
187 id="stop16524" />
188 <stop
189 id="stop16530"
190 offset="0.27272728"
191 style="stop-color:#fff491;stop-opacity:1;" />
192 <stop
193 style="stop-color:#edd400;stop-opacity:1;"
194 offset="1"
195 id="stop16526" />
196 </linearGradient>
197 <linearGradient
198 id="linearGradient16514">
199 <stop
200 id="stop16516"
201 offset="0"
202 style="stop-color:#ffffff;stop-opacity:1;" />
203 <stop
204 style="stop-color:#bebebe;stop-opacity:1;"
205 offset="0.42424244"
206 id="stop16518" />
207 <stop
208 id="stop16520"
209 offset="1"
210 style="stop-color:#ebebeb;stop-opacity:1;" />
211 </linearGradient>
212 <linearGradient
213 id="linearGradient16494">
214 <stop
215 style="stop-color:#204a87;stop-opacity:1;"
216 offset="0"
217 id="stop16496" />
218 <stop
219 id="stop16502"
220 offset="0.21212122"
221 style="stop-color:#3f7bd2;stop-opacity:1;" />
222 <stop
223 style="stop-color:#204a87;stop-opacity:1;"
224 offset="1"
225 id="stop16498" />
226 </linearGradient>
227 <linearGradient
228 id="linearGradient16468">
229 <stop
230 style="stop-color:#cc0000;stop-opacity:1;"
231 offset="0"
232 id="stop16470" />
233 <stop
234 id="stop16476"
235 offset="0.15151516"
236 style="stop-color:#ff3737;stop-opacity:1;" />
237 <stop
238 style="stop-color:#b41414;stop-opacity:1;"
239 offset="0.57575756"
240 id="stop16478" />
241 <stop
242 style="stop-color:#ff4c4c;stop-opacity:1;"
243 offset="1"
244 id="stop16472" />
245 </linearGradient>
246 <linearGradient
247 id="linearGradient16451">
248 <stop
249 style="stop-color:#ffffff;stop-opacity:1;"
250 offset="0"
251 id="stop16453" />
252 <stop
253 id="stop16459"
254 offset="0.42424244"
255 style="stop-color:#bebebe;stop-opacity:1;" />
256 <stop
257 style="stop-color:#ebebeb;stop-opacity:1;"
258 offset="1"
259 id="stop16455" />
260 </linearGradient>
261 <linearGradient
262 id="linearGradient11520">
263 <stop
264 id="stop11522"
265 offset="0.0000000"
266 style="stop-color:#ffffff;stop-opacity:1.0000000;" />
267 <stop
268 id="stop11524"
269 offset="1.0000000"
270 style="stop-color:#dcdcdc;stop-opacity:1.0000000;" />
271 </linearGradient>
272 <linearGradient
273 id="linearGradient11508"
274 inkscape:collect="always">
275 <stop
276 id="stop11510"
277 offset="0"
278 style="stop-color:#000000;stop-opacity:1;" />
279 <stop
280 id="stop11512"
281 offset="1"
282 style="stop-color:#000000;stop-opacity:0;" />
283 </linearGradient>
284 <linearGradient
285 id="linearGradient11494"
286 inkscape:collect="always">
287 <stop
288 id="stop11496"
289 offset="0"
290 style="stop-color:#ef2929;stop-opacity:1;" />
291 <stop
292 id="stop11498"
293 offset="1"
294 style="stop-color:#ef2929;stop-opacity:0;" />
295 </linearGradient>
296 <linearGradient
297 id="linearGradient11415">
298 <stop
299 id="stop11417"
300 offset="0.0000000"
301 style="stop-color:#204a87;stop-opacity:0.0000000;" />
302 <stop
303 style="stop-color:#204a87;stop-opacity:1.0000000;"
304 offset="0.50000000"
305 id="stop11423" />
306 <stop
307 id="stop11419"
308 offset="1"
309 style="stop-color:#204a87;stop-opacity:0;" />
310 </linearGradient>
311 <linearGradient
312 id="linearGradient11399"
313 inkscape:collect="always">
314 <stop
315 id="stop11401"
316 offset="0"
317 style="stop-color:#000000;stop-opacity:1;" />
318 <stop
319 id="stop11403"
320 offset="1"
321 style="stop-color:#000000;stop-opacity:0;" />
322 </linearGradient>
323 <linearGradient
324 gradientTransform="translate(-60.28571,-0.285714)"
325 y2="34.462429"
326 x2="43.615788"
327 y1="3.7744560"
328 x1="15.828360"
329 gradientUnits="userSpaceOnUse"
330 id="linearGradient11425"
331 xlink:href="#linearGradient11415"
332 inkscape:collect="always" />
333 <linearGradient
334 gradientTransform="translate(-60.57143,0.000000)"
335 y2="39.033859"
336 x2="35.679932"
337 y1="9.3458843"
338 x1="9.6957054"
339 gradientUnits="userSpaceOnUse"
340 id="linearGradient11427"
341 xlink:href="#linearGradient11415"
342 inkscape:collect="always" />
343 <linearGradient
344 y2="33.462429"
345 x2="26.758644"
346 y1="19.774456"
347 x1="13.267134"
348 gradientTransform="translate(-60.85714,0.428571)"
349 gradientUnits="userSpaceOnUse"
350 id="linearGradient11439"
351 xlink:href="#linearGradient11415"
352 inkscape:collect="always" />
353 <radialGradient
354 r="8.5000000"
355 fy="39.142857"
356 fx="12.071428"
357 cy="39.142857"
358 cx="12.071428"
359 gradientTransform="matrix(1.000000,0.000000,0.000000,0.487395,0.000000,20.06483)"
360 gradientUnits="userSpaceOnUse"
361 id="radialGradient11441"
362 xlink:href="#linearGradient11399"
363 inkscape:collect="always" />
364 <radialGradient
365 gradientTransform="matrix(1.243453,2.106784e-16,-2.106784e-16,1.243453,-6.713754,-3.742847)"
366 gradientUnits="userSpaceOnUse"
367 r="3.8335034"
368 fy="15.048258"
369 fx="27.577173"
370 cy="15.048258"
371 cx="27.577173"
372 id="radialGradient11500"
373 xlink:href="#linearGradient11494"
374 inkscape:collect="always" />
375 <radialGradient
376 r="3.8335034"
377 fy="16.049133"
378 fx="27.577173"
379 cy="16.049133"
380 cx="27.577173"
381 gradientTransform="matrix(1.243453,2.106784e-16,-2.106784e-16,1.243453,-6.713754,-3.742847)"
382 gradientUnits="userSpaceOnUse"
383 id="radialGradient11504"
384 xlink:href="#linearGradient11494"
385 inkscape:collect="always" />
386 <radialGradient
387 gradientUnits="userSpaceOnUse"
388 gradientTransform="matrix(1.000000,0.000000,0.000000,0.338462,2.166583e-14,29.48178)"
389 r="6.5659914"
390 fy="44.565483"
391 fx="30.203562"
392 cy="44.565483"
393 cx="30.203562"
394 id="radialGradient11514"
395 xlink:href="#linearGradient11508"
396 inkscape:collect="always" />
397 <radialGradient
398 gradientTransform="matrix(1.995058,-1.651527e-32,0.000000,1.995058,-24.32488,-35.70087)"
399 gradientUnits="userSpaceOnUse"
400 r="20.530962"
401 fy="35.878170"
402 fx="24.445690"
403 cy="35.878170"
404 cx="24.445690"
405 id="radialGradient11526"
406 xlink:href="#linearGradient11520"
407 inkscape:collect="always" />
408 <radialGradient
409 r="6.5659914"
410 fy="44.565483"
411 fx="30.203562"
412 cy="44.565483"
413 cx="30.203562"
414 gradientTransform="matrix(1.000000,0.000000,0.000000,0.338462,3.185827e-15,29.48178)"
415 gradientUnits="userSpaceOnUse"
416 id="radialGradient11532"
417 xlink:href="#linearGradient11508"
418 inkscape:collect="always" />
419 <radialGradient
420 inkscape:collect="always"
421 xlink:href="#linearGradient11508"
422 id="radialGradient1348"
423 gradientUnits="userSpaceOnUse"
424 gradientTransform="matrix(1.000000,0.000000,0.000000,0.338462,-1.353344e-14,29.48178)"
425 cx="30.203562"
426 cy="44.565483"
427 fx="30.203562"
428 fy="44.565483"
429 r="6.5659914" />
430 <radialGradient
431 inkscape:collect="always"
432 xlink:href="#linearGradient11520"
433 id="radialGradient1350"
434 gradientUnits="userSpaceOnUse"
435 gradientTransform="matrix(1.995058,-1.651527e-32,0.000000,1.995058,-24.32488,-35.70087)"
436 cx="24.445690"
437 cy="35.878170"
438 fx="24.445690"
439 fy="35.878170"
440 r="20.530962" />
441 <radialGradient
442 inkscape:collect="always"
443 xlink:href="#linearGradient11494"
444 id="radialGradient1352"
445 gradientUnits="userSpaceOnUse"
446 gradientTransform="matrix(1.243453,2.106784e-16,-2.106784e-16,1.243453,-6.713754,-3.742847)"
447 cx="27.577173"
448 cy="16.049133"
449 fx="27.577173"
450 fy="16.049133"
451 r="3.8335034" />
452 <radialGradient
453 inkscape:collect="always"
454 xlink:href="#linearGradient11494"
455 id="radialGradient1354"
456 gradientUnits="userSpaceOnUse"
457 gradientTransform="matrix(1.243453,2.106784e-16,-2.106784e-16,1.243453,-6.713754,-3.742847)"
458 cx="27.577173"
459 cy="15.048258"
460 fx="27.577173"
461 fy="15.048258"
462 r="3.8335034" />
463 <radialGradient
464 inkscape:collect="always"
465 xlink:href="#linearGradient11508"
466 id="radialGradient1356"
467 gradientUnits="userSpaceOnUse"
468 gradientTransform="matrix(1.000000,0.000000,0.000000,0.338462,2.220359e-14,29.48178)"
469 cx="30.203562"
470 cy="44.565483"
471 fx="30.203562"
472 fy="44.565483"
473 r="6.5659914" />
474 <radialGradient
475 inkscape:collect="always"
476 xlink:href="#linearGradient11520"
477 id="radialGradient1366"
478 gradientUnits="userSpaceOnUse"
479 gradientTransform="matrix(2.049266,-1.696401e-32,0.000000,2.049266,-25.65002,-37.31089)"
480 cx="24.445690"
481 cy="35.878170"
482 fx="24.445690"
483 fy="35.878170"
484 r="20.530962" />
485 <linearGradient
486 inkscape:collect="always"
487 xlink:href="#linearGradient16451"
488 id="linearGradient16457"
489 x1="0.91421354"
490 y1="16.710525"
491 x2="37.623106"
492 y2="16.710525"
493 gradientUnits="userSpaceOnUse" />
494 <linearGradient
495 inkscape:collect="always"
496 xlink:href="#linearGradient16451"
497 id="linearGradient16464"
498 gradientUnits="userSpaceOnUse"
499 x1="0.91421354"
500 y1="16.710525"
501 x2="37.623106"
502 y2="16.710525"
503 gradientTransform="matrix(0.98006,0,0,1,0.116103,0)" />
504 <linearGradient
505 inkscape:collect="always"
506 xlink:href="#linearGradient16468"
507 id="linearGradient16474"
508 x1="2"
509 y1="23.791154"
510 x2="36"
511 y2="23.791154"
512 gradientUnits="userSpaceOnUse" />
513 <linearGradient
514 inkscape:collect="always"
515 xlink:href="#linearGradient16468"
516 id="linearGradient16482"
517 gradientUnits="userSpaceOnUse"
518 x1="2"
519 y1="23.791154"
520 x2="36"
521 y2="23.791154"
522 gradientTransform="translate(0,-5.624133)" />
523 <linearGradient
524 inkscape:collect="always"
525 xlink:href="#linearGradient16468"
526 id="linearGradient16486"
527 gradientUnits="userSpaceOnUse"
528 gradientTransform="translate(0,-11.24827)"
529 x1="2"
530 y1="23.791154"
531 x2="36"
532 y2="23.791154" />
533 <linearGradient
534 inkscape:collect="always"
535 xlink:href="#linearGradient16468"
536 id="linearGradient16490"
537 gradientUnits="userSpaceOnUse"
538 gradientTransform="translate(0,-16.8724)"
539 x1="2"
540 y1="23.791154"
541 x2="36"
542 y2="23.791154" />
543 <linearGradient
544 inkscape:collect="always"
545 xlink:href="#linearGradient16494"
546 id="linearGradient16500"
547 x1="2"
548 y1="8.5017858"
549 x2="19"
550 y2="8.5017858"
551 gradientUnits="userSpaceOnUse" />
552 <linearGradient
553 inkscape:collect="always"
554 xlink:href="#linearGradient16522"
555 id="linearGradient16528"
556 x1="11.002116"
557 y1="29.756583"
558 x2="46.998972"
559 y2="29.756583"
560 gradientUnits="userSpaceOnUse" />
561 <linearGradient
562 inkscape:collect="always"
563 xlink:href="#linearGradient16532"
564 id="linearGradient16538"
565 x1="11.976621"
566 y1="29.748671"
567 x2="46.138718"
568 y2="29.748671"
569 gradientUnits="userSpaceOnUse" />
570 <linearGradient
571 inkscape:collect="always"
572 xlink:href="#linearGradient16542"
573 id="linearGradient16548"
574 x1="11.976621"
575 y1="21.723522"
576 x2="46.138718"
577 y2="21.723522"
578 gradientUnits="userSpaceOnUse" />
579 <linearGradient
580 inkscape:collect="always"
581 xlink:href="#linearGradient16451"
582 id="linearGradient16577"
583 gradientUnits="userSpaceOnUse"
584 gradientTransform="matrix(0.98006,0,0,1,0.116103,0)"
585 x1="0.91421354"
586 y1="16.710525"
587 x2="37.623106"
588 y2="16.710525" />
589 <linearGradient
590 inkscape:collect="always"
591 xlink:href="#linearGradient16468"
592 id="linearGradient16579"
593 gradientUnits="userSpaceOnUse"
594 x1="2"
595 y1="23.791154"
596 x2="36"
597 y2="23.791154" />
598 <linearGradient
599 inkscape:collect="always"
600 xlink:href="#linearGradient16468"
601 id="linearGradient16581"
602 gradientUnits="userSpaceOnUse"
603 gradientTransform="translate(0,-11.24827)"
604 x1="2"
605 y1="23.791154"
606 x2="36"
607 y2="23.791154" />
608 <linearGradient
609 inkscape:collect="always"
610 xlink:href="#linearGradient16468"
611 id="linearGradient16583"
612 gradientUnits="userSpaceOnUse"
613 gradientTransform="translate(0,-5.624133)"
614 x1="2"
615 y1="23.791154"
616 x2="36"
617 y2="23.791154" />
618 <linearGradient
619 inkscape:collect="always"
620 xlink:href="#linearGradient16468"
621 id="linearGradient16585"
622 gradientUnits="userSpaceOnUse"
623 gradientTransform="translate(0,-16.8724)"
624 x1="2"
625 y1="23.791154"
626 x2="36"
627 y2="23.791154" />
628 <linearGradient
629 inkscape:collect="always"
630 xlink:href="#linearGradient16494"
631 id="linearGradient16587"
632 gradientUnits="userSpaceOnUse"
633 x1="2"
634 y1="8.5017858"
635 x2="19"
636 y2="8.5017858" />
637 <linearGradient
638 inkscape:collect="always"
639 xlink:href="#linearGradient5048"
640 id="linearGradient6761"
641 gradientUnits="userSpaceOnUse"
642 gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
643 x1="302.85715"
644 y1="366.64789"
645 x2="302.85715"
646 y2="609.50507" />
647 <radialGradient
648 inkscape:collect="always"
649 xlink:href="#linearGradient5060"
650 id="radialGradient6763"
651 gradientUnits="userSpaceOnUse"
652 gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
653 cx="605.71429"
654 cy="486.64789"
655 fx="605.71429"
656 fy="486.64789"
657 r="117.14286" />
658 <radialGradient
659 inkscape:collect="always"
660 xlink:href="#linearGradient5060"
661 id="radialGradient6765"
662 gradientUnits="userSpaceOnUse"
663 gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
664 cx="605.71429"
665 cy="486.64789"
666 fx="605.71429"
667 fy="486.64789"
668 r="117.14286" />
669 <linearGradient
670 inkscape:collect="always"
671 xlink:href="#linearGradient16494"
672 id="linearGradient2006"
673 gradientUnits="userSpaceOnUse"
674 x1="2"
675 y1="8.5017858"
676 x2="19"
677 y2="8.5017858"
678 gradientTransform="translate(2.121318,2.032932)" />
679 <linearGradient
680 inkscape:collect="always"
681 xlink:href="#linearGradient16468"
682 id="linearGradient2010"
683 gradientUnits="userSpaceOnUse"
684 gradientTransform="translate(2.121318,-14.83947)"
685 x1="2"
686 y1="23.791154"
687 x2="36"
688 y2="23.791154" />
689 <linearGradient
690 inkscape:collect="always"
691 xlink:href="#linearGradient16468"
692 id="linearGradient2013"
693 gradientUnits="userSpaceOnUse"
694 gradientTransform="translate(2.121318,-3.591201)"
695 x1="2"
696 y1="23.791154"
697 x2="36"
698 y2="23.791154" />
699 <linearGradient
700 inkscape:collect="always"
701 xlink:href="#linearGradient16468"
702 id="linearGradient2016"
703 gradientUnits="userSpaceOnUse"
704 gradientTransform="translate(2.121318,-9.215338)"
705 x1="2"
706 y1="23.791154"
707 x2="36"
708 y2="23.791154" />
709 <linearGradient
710 inkscape:collect="always"
711 xlink:href="#linearGradient16468"
712 id="linearGradient2019"
713 gradientUnits="userSpaceOnUse"
714 x1="2"
715 y1="23.791154"
716 x2="36"
717 y2="23.791154"
718 gradientTransform="translate(2.121318,2.032932)" />
719 <linearGradient
720 inkscape:collect="always"
721 xlink:href="#linearGradient2865"
722 id="linearGradient2871"
723 x1="10.029842"
724 y1="28.695923"
725 x2="46.026698"
726 y2="28.695923"
727 gradientUnits="userSpaceOnUse" />
728 <linearGradient
729 inkscape:collect="always"
730 xlink:href="#linearGradient2877"
731 id="linearGradient2883"
732 x1="3.1234348"
733 y1="17.789515"
734 x2="39.12029"
735 y2="17.789515"
736 gradientUnits="userSpaceOnUse" />
737 <linearGradient
738 inkscape:collect="always"
739 xlink:href="#linearGradient2913"
740 id="linearGradient2919"
741 x1="10.964451"
742 y1="28.712873"
743 x2="36.336609"
744 y2="27.445059"
745 gradientUnits="userSpaceOnUse" />
746 <linearGradient
747 inkscape:collect="always"
748 xlink:href="#linearGradient2913"
749 id="linearGradient3205"
750 gradientUnits="userSpaceOnUse"
751 x1="4.1213179"
752 y1="24.253414"
753 x2="33.066338"
754 y2="25.661276" />
755 </defs>
756 <sodipodi:namedview
757 stroke="#ef2929"
758 fill="#edd400"
759 id="base"
760 pagecolor="#ffffff"
761 bordercolor="#666666"
762 borderopacity="0.25490196"
763 inkscape:pageopacity="0.0"
764 inkscape:pageshadow="2"
765 inkscape:zoom="1"
766 inkscape:cx="-139"
767 inkscape:cy="14.5"
768 inkscape:current-layer="layer1"
769 showgrid="false"
770 inkscape:grid-bbox="true"
771 inkscape:document-units="px"
772 inkscape:showpageshadow="false"
773 inkscape:window-width="804"
774 inkscape:window-height="688"
775 inkscape:window-x="630"
776 inkscape:window-y="30" />
777 <metadata
778 id="metadata4">
779 <rdf:RDF>
780 <cc:Work
781 rdf:about="">
782 <dc:format>image/svg+xml</dc:format>
783 <dc:type
784 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
785 <dc:creator>
786 <cc:Agent>
787 <dc:title>Jakub Steiner</dc:title>
788 </cc:Agent>
789 </dc:creator>
790 <dc:source>http://jimmac.musichall.cz</dc:source>
791 <cc:license
792 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
793 <dc:title>Locale Preferences</dc:title>
794 <dc:subject>
795 <rdf:Bag>
796 <rdf:li>locale preferences</rdf:li>
797 </rdf:Bag>
798 </dc:subject>
799 </cc:Work>
800 <cc:License
801 rdf:about="http://creativecommons.org/licenses/publicdomain/">
802 <cc:permits
803 rdf:resource="http://creativecommons.org/ns#Reproduction" />
804 <cc:permits
805 rdf:resource="http://creativecommons.org/ns#Distribution" />
806 <cc:permits
807 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
808 </cc:License>
809 </rdf:RDF>
810 </metadata>
811 <g
812 id="layer1"
813 inkscape:label="Layer 1"
814 inkscape:groupmode="layer">
815 <g
816 id="g6753"
817 transform="matrix(1.971468e-2,0,0,3.343226e-2,38.92492,24.71253)">
818 <rect
819 y="-150.69685"
820 x="-1559.2523"
821 height="478.35718"
822 width="1339.6335"
823 id="rect6755"
824 style="opacity:0.40206185;color:black;fill:url(#linearGradient6761);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
825 <path
826 sodipodi:nodetypes="cccc"
827 id="path6757"
828 d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
829 style="opacity:0.40206185;color:black;fill:url(#radialGradient6763);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
830 <path
831 style="opacity:0.40206185;color:black;fill:url(#radialGradient6765);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
832 d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
833 id="path6759"
834 sodipodi:nodetypes="cccc" />
835 </g>
836 <g
837 transform="matrix(1.971468e-2,0,0,3.343226e-2,46.17276,35.14236)"
838 id="g6707">
839 <rect
840 style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
841 id="rect6709"
842 width="1339.6335"
843 height="478.35718"
844 x="-1559.2523"
845 y="-150.69685" />
846 <path
847 style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
848 d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
849 id="path6711"
850 sodipodi:nodetypes="cccc" />
851 <path
852 sodipodi:nodetypes="cccc"
853 id="path6713"
854 d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
855 style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
856 </g>
857 <path
858 style="color:black;fill:url(#linearGradient2883);fill-opacity:1.0;fill-rule:evenodd;stroke:#5c3566;stroke-width:0.9999994;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
859 d="M 3.6234345,6.1923115 C 12.805777,-0.3484262 29.264695,8.1368552 38.62029,6.1923115 L 38.62029,31.294603 C 29.611199,34.299807 14.01854,24.930642 3.6234345,31.294603 L 3.6234345,6.1923115 z "
860 id="rect15576"
861 sodipodi:nodetypes="ccccc" />
862 <path
863 sodipodi:nodetypes="ccccc"
864 id="path16462"
865 d="M 4.6213179,6.8032613 C 12.598466,1.0750243 28.454913,8.7478053 37.656867,7.3032613 L 37.531867,30.593053 C 30.717023,32.785757 14.794159,24.888617 4.6838179,29.468053 L 4.6213179,6.8032613 z "
866 style="opacity:0.62921346;color:black;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3205);stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible;stroke-dasharray:none" />
867 <path
868 sodipodi:nodetypes="ccccc"
869 id="path16504"
870 d="M 10.529842,17.09872 C 19.712185,10.557982 36.171103,19.043263 45.526698,17.09872 L 45.526698,42.201011 C 36.517607,45.206215 20.924948,35.83705 10.529842,42.201011 L 10.529842,17.09872 z "
871 style="color:black;fill:url(#linearGradient2871);fill-opacity:1.0;fill-rule:evenodd;stroke:#4e9a06;stroke-width:0.9999994;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible" />
872 <path
873 style="opacity:0.62921346;color:black;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2919);stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
874 d="M 11.464451,17.654135 C 19.441599,11.925898 35.298046,19.598679 44.5,18.154135 L 44.375,41.532315 C 37.560156,43.725019 21.637292,35.827879 11.526951,40.407315 L 11.464451,17.654135 z "
875 id="path16506"
876 sodipodi:nodetypes="ccccc" />
877 </g>
878</svg>
diff --git a/utils/rbutilqt/icons/preferences-desktop-theme.svg b/utils/rbutilqt/icons/preferences-desktop-theme.svg
new file mode 100644
index 0000000000..45ed886eae
--- /dev/null
+++ b/utils/rbutilqt/icons/preferences-desktop-theme.svg
@@ -0,0 +1,882 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 inkscape:export-ydpi="90.000000"
13 inkscape:export-xdpi="90.000000"
14 inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
15 width="48px"
16 height="48px"
17 id="svg11300"
18 sodipodi:version="0.32"
19 inkscape:version="0.46"
20 sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/apps"
21 sodipodi:docname="preferences-desktop-theme.svg"
22 inkscape:output_extension="org.inkscape.output.svg.inkscape">
23 <defs
24 id="defs3">
25 <inkscape:perspective
26 sodipodi:type="inkscape:persp3d"
27 inkscape:vp_x="0 : 24 : 1"
28 inkscape:vp_y="0 : 1000 : 0"
29 inkscape:vp_z="48 : 24 : 1"
30 inkscape:persp3d-origin="24 : 16 : 1"
31 id="perspective135" />
32 <radialGradient
33 inkscape:collect="always"
34 xlink:href="#linearGradient5060"
35 id="radialGradient5031"
36 gradientUnits="userSpaceOnUse"
37 gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
38 cx="605.71429"
39 cy="486.64789"
40 fx="605.71429"
41 fy="486.64789"
42 r="117.14286" />
43 <linearGradient
44 inkscape:collect="always"
45 id="linearGradient5060">
46 <stop
47 style="stop-color:black;stop-opacity:1;"
48 offset="0"
49 id="stop5062" />
50 <stop
51 style="stop-color:black;stop-opacity:0;"
52 offset="1"
53 id="stop5064" />
54 </linearGradient>
55 <radialGradient
56 inkscape:collect="always"
57 xlink:href="#linearGradient5060"
58 id="radialGradient5029"
59 gradientUnits="userSpaceOnUse"
60 gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
61 cx="605.71429"
62 cy="486.64789"
63 fx="605.71429"
64 fy="486.64789"
65 r="117.14286" />
66 <linearGradient
67 id="linearGradient5048">
68 <stop
69 style="stop-color:black;stop-opacity:0;"
70 offset="0"
71 id="stop5050" />
72 <stop
73 id="stop5056"
74 offset="0.5"
75 style="stop-color:black;stop-opacity:1;" />
76 <stop
77 style="stop-color:black;stop-opacity:0;"
78 offset="1"
79 id="stop5052" />
80 </linearGradient>
81 <linearGradient
82 inkscape:collect="always"
83 xlink:href="#linearGradient5048"
84 id="linearGradient5027"
85 gradientUnits="userSpaceOnUse"
86 gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
87 x1="302.85715"
88 y1="366.64789"
89 x2="302.85715"
90 y2="609.50507" />
91 <linearGradient
92 id="linearGradient4649">
93 <stop
94 id="stop4651"
95 offset="0"
96 style="stop-color:#80837d;stop-opacity:1;" />
97 <stop
98 id="stop4653"
99 offset="1"
100 style="stop-color:#4c4d4a;stop-opacity:1;" />
101 </linearGradient>
102 <linearGradient
103 id="linearGradient4639">
104 <stop
105 style="stop-color:#555753;stop-opacity:1;"
106 offset="0"
107 id="stop4641" />
108 <stop
109 style="stop-color:#7c7f79;stop-opacity:1;"
110 offset="1"
111 id="stop4643" />
112 </linearGradient>
113 <linearGradient
114 inkscape:collect="always"
115 id="linearGradient4633">
116 <stop
117 style="stop-color:#ffffff;stop-opacity:1;"
118 offset="0"
119 id="stop4635" />
120 <stop
121 style="stop-color:#ffffff;stop-opacity:0;"
122 offset="1"
123 id="stop4637" />
124 </linearGradient>
125 <linearGradient
126 id="linearGradient4596">
127 <stop
128 style="stop-color:#75507b;stop-opacity:1;"
129 offset="0"
130 id="stop4598" />
131 <stop
132 style="stop-color:#543958;stop-opacity:1;"
133 offset="1"
134 id="stop4600" />
135 </linearGradient>
136 <linearGradient
137 id="linearGradient4586">
138 <stop
139 style="stop-color:#204a87;stop-opacity:1;"
140 offset="0"
141 id="stop4588" />
142 <stop
143 style="stop-color:#142e55;stop-opacity:1;"
144 offset="1"
145 id="stop4590" />
146 </linearGradient>
147 <linearGradient
148 id="linearGradient3697">
149 <stop
150 style="stop-color:#c8d5e6;stop-opacity:1;"
151 offset="0"
152 id="stop3699" />
153 <stop
154 style="stop-color:#427ebf;stop-opacity:1;"
155 offset="1"
156 id="stop3701" />
157 </linearGradient>
158 <linearGradient
159 id="linearGradient3689">
160 <stop
161 id="stop3691"
162 offset="0"
163 style="stop-color:#5079ad;stop-opacity:1;" />
164 <stop
165 id="stop3693"
166 offset="1"
167 style="stop-color:#729fcf" />
168 </linearGradient>
169 <linearGradient
170 id="linearGradient3568">
171 <stop
172 style="stop-color:#d6d6d6;stop-opacity:1;"
173 offset="0"
174 id="stop3570" />
175 <stop
176 style="stop-color:#f0f0f0;stop-opacity:1;"
177 offset="1"
178 id="stop3572" />
179 </linearGradient>
180 <linearGradient
181 id="linearGradient3560">
182 <stop
183 style="stop-color:#f0f0f0;stop-opacity:1;"
184 offset="0"
185 id="stop3562" />
186 <stop
187 style="stop-color:#c9c9c9;stop-opacity:1;"
188 offset="1"
189 id="stop3564" />
190 </linearGradient>
191 <linearGradient
192 id="linearGradient3550">
193 <stop
194 id="stop3552"
195 offset="0"
196 style="stop-color:#8b8b8b;stop-opacity:1;" />
197 <stop
198 id="stop3554"
199 offset="1"
200 style="stop-color:#a9a9a9;stop-opacity:1;" />
201 </linearGradient>
202 <linearGradient
203 id="linearGradient3536">
204 <stop
205 style="stop-color:#b0b0b0;stop-opacity:1;"
206 offset="0"
207 id="stop3538" />
208 <stop
209 style="stop-color:#757575;stop-opacity:1;"
210 offset="1"
211 id="stop3540" />
212 </linearGradient>
213 <linearGradient
214 inkscape:collect="always"
215 id="linearGradient3528">
216 <stop
217 style="stop-color:#000000;stop-opacity:1;"
218 offset="0"
219 id="stop3530" />
220 <stop
221 style="stop-color:#000000;stop-opacity:0;"
222 offset="1"
223 id="stop3532" />
224 </linearGradient>
225 <linearGradient
226 inkscape:collect="always"
227 id="linearGradient3518">
228 <stop
229 style="stop-color:#ffffff;stop-opacity:1;"
230 offset="0"
231 id="stop3520" />
232 <stop
233 style="stop-color:#ffffff;stop-opacity:0;"
234 offset="1"
235 id="stop3522" />
236 </linearGradient>
237 <linearGradient
238 id="linearGradient3508">
239 <stop
240 style="stop-color:#b0b0b0;stop-opacity:1;"
241 offset="0"
242 id="stop3510" />
243 <stop
244 style="stop-color:#939393;stop-opacity:1;"
245 offset="1"
246 id="stop3512" />
247 </linearGradient>
248 <linearGradient
249 inkscape:collect="always"
250 xlink:href="#linearGradient3508"
251 id="linearGradient3514"
252 x1="16.940231"
253 y1="27.853085"
254 x2="16.940231"
255 y2="24.135145"
256 gradientUnits="userSpaceOnUse"
257 gradientTransform="translate(-2.121319,3.005205)" />
258 <linearGradient
259 inkscape:collect="always"
260 xlink:href="#linearGradient3518"
261 id="linearGradient3524"
262 x1="17.456696"
263 y1="37.661667"
264 x2="17.456696"
265 y2="27.231844"
266 gradientUnits="userSpaceOnUse"
267 gradientTransform="translate(-2.121319,3.005205)" />
268 <radialGradient
269 inkscape:collect="always"
270 xlink:href="#linearGradient3528"
271 id="radialGradient3534"
272 cx="17.014757"
273 cy="39.249554"
274 fx="17.014757"
275 fy="39.249554"
276 r="9.5017471"
277 gradientTransform="matrix(1.000000,0.000000,0.000000,0.502326,-2.992397e-15,19.53350)"
278 gradientUnits="userSpaceOnUse" />
279 <radialGradient
280 inkscape:collect="always"
281 xlink:href="#linearGradient3536"
282 id="radialGradient3542"
283 cx="18.163805"
284 cy="22.531874"
285 fx="18.163805"
286 fy="22.531874"
287 r="2.8422911"
288 gradientTransform="matrix(1.000000,0.000000,0.000000,0.860061,0.000000,3.253760)"
289 gradientUnits="userSpaceOnUse" />
290 <radialGradient
291 inkscape:collect="always"
292 xlink:href="#linearGradient3550"
293 id="radialGradient3548"
294 cx="17.097467"
295 cy="19.777185"
296 fx="17.097467"
297 fy="19.777185"
298 r="4.5473714"
299 gradientTransform="matrix(1.208333,0.000000,0.000000,0.636493,-5.683292,8.681835)"
300 gradientUnits="userSpaceOnUse" />
301 <radialGradient
302 inkscape:collect="always"
303 xlink:href="#linearGradient3560"
304 id="radialGradient3566"
305 cx="12.91097"
306 cy="13.001998"
307 fx="12.91097"
308 fy="13.001998"
309 r="7.4889511"
310 gradientTransform="matrix(1.802725,2.307502e-23,-2.636931e-23,1.503342,-12.48525,-2.659143)"
311 gradientUnits="userSpaceOnUse" />
312 <linearGradient
313 inkscape:collect="always"
314 xlink:href="#linearGradient3568"
315 id="linearGradient3574"
316 x1="14.883313"
317 y1="27.847456"
318 x2="13.400961"
319 y2="20.069281"
320 gradientUnits="userSpaceOnUse"
321 gradientTransform="translate(-2.121319,3.005205)" />
322 <radialGradient
323 inkscape:collect="always"
324 xlink:href="#linearGradient3550"
325 id="radialGradient3610"
326 gradientUnits="userSpaceOnUse"
327 gradientTransform="matrix(1.208333,0.000000,0.000000,0.636493,-5.683292,8.681835)"
328 cx="17.097467"
329 cy="19.777185"
330 fx="17.097467"
331 fy="19.777185"
332 r="4.5473714" />
333 <radialGradient
334 inkscape:collect="always"
335 xlink:href="#linearGradient3560"
336 id="radialGradient3612"
337 gradientUnits="userSpaceOnUse"
338 gradientTransform="matrix(1.802725,2.307502e-23,-2.636931e-23,1.503342,-12.48525,-2.659143)"
339 cx="12.91097"
340 cy="13.001998"
341 fx="12.91097"
342 fy="13.001998"
343 r="7.4889511" />
344 <linearGradient
345 inkscape:collect="always"
346 xlink:href="#linearGradient3518"
347 id="linearGradient3616"
348 gradientUnits="userSpaceOnUse"
349 x1="17.456696"
350 y1="37.661667"
351 x2="17.456696"
352 y2="27.231844"
353 gradientTransform="translate(-2.121319,3.005205)" />
354 <linearGradient
355 inkscape:collect="always"
356 xlink:href="#linearGradient3568"
357 id="linearGradient3620"
358 gradientUnits="userSpaceOnUse"
359 x1="14.883313"
360 y1="27.847456"
361 x2="13.400961"
362 y2="20.069281"
363 gradientTransform="translate(-2.121319,3.005205)" />
364 <radialGradient
365 inkscape:collect="always"
366 xlink:href="#linearGradient3528"
367 id="radialGradient3661"
368 gradientUnits="userSpaceOnUse"
369 gradientTransform="matrix(1.000000,0.000000,0.000000,0.502326,5.762756e-15,19.53350)"
370 cx="17.014757"
371 cy="39.249554"
372 fx="17.014757"
373 fy="39.249554"
374 r="9.5017471" />
375 <linearGradient
376 inkscape:collect="always"
377 xlink:href="#linearGradient3568"
378 id="linearGradient3663"
379 gradientUnits="userSpaceOnUse"
380 gradientTransform="translate(15.99833,-9.914664)"
381 x1="14.883313"
382 y1="27.847456"
383 x2="13.400961"
384 y2="20.069281" />
385 <linearGradient
386 inkscape:collect="always"
387 xlink:href="#linearGradient3508"
388 id="linearGradient3665"
389 gradientUnits="userSpaceOnUse"
390 gradientTransform="translate(15.99833,-9.914664)"
391 x1="16.940231"
392 y1="27.853085"
393 x2="16.940231"
394 y2="24.135145" />
395 <linearGradient
396 inkscape:collect="always"
397 xlink:href="#linearGradient3518"
398 id="linearGradient3667"
399 gradientUnits="userSpaceOnUse"
400 gradientTransform="translate(15.99833,-9.914664)"
401 x1="17.456696"
402 y1="37.661667"
403 x2="17.456696"
404 y2="27.231844" />
405 <radialGradient
406 inkscape:collect="always"
407 xlink:href="#linearGradient3536"
408 id="radialGradient3669"
409 gradientUnits="userSpaceOnUse"
410 gradientTransform="matrix(1.000000,0.000000,0.000000,0.860061,0.000000,3.253760)"
411 cx="18.163805"
412 cy="22.531874"
413 fx="18.163805"
414 fy="22.531874"
415 r="2.8422911" />
416 <radialGradient
417 inkscape:collect="always"
418 xlink:href="#linearGradient3560"
419 id="radialGradient3671"
420 gradientUnits="userSpaceOnUse"
421 gradientTransform="matrix(1.802725,2.307502e-23,-2.636931e-23,1.503342,5.634344,-15.57903)"
422 cx="12.91097"
423 cy="13.001998"
424 fx="12.91097"
425 fy="13.001998"
426 r="7.4889511" />
427 <radialGradient
428 inkscape:collect="always"
429 xlink:href="#linearGradient3550"
430 id="radialGradient3673"
431 gradientUnits="userSpaceOnUse"
432 gradientTransform="matrix(1.208333,0.000000,0.000000,0.636493,12.43635,-4.238032)"
433 cx="17.097467"
434 cy="19.777185"
435 fx="17.097467"
436 fy="19.777185"
437 r="4.5473714" />
438 <radialGradient
439 inkscape:collect="always"
440 xlink:href="#linearGradient3528"
441 id="radialGradient3675"
442 gradientUnits="userSpaceOnUse"
443 gradientTransform="matrix(1.000000,0.000000,0.000000,0.502326,5.762756e-15,19.53350)"
444 cx="17.014757"
445 cy="39.249554"
446 fx="17.014757"
447 fy="39.249554"
448 r="9.5017471" />
449 <linearGradient
450 inkscape:collect="always"
451 xlink:href="#linearGradient3689"
452 id="linearGradient3677"
453 gradientUnits="userSpaceOnUse"
454 gradientTransform="translate(15.99833,-9.914664)"
455 x1="14.883313"
456 y1="27.847456"
457 x2="13.400961"
458 y2="20.069281" />
459 <linearGradient
460 inkscape:collect="always"
461 xlink:href="#linearGradient3518"
462 id="linearGradient3681"
463 gradientUnits="userSpaceOnUse"
464 gradientTransform="translate(15.99833,-9.914664)"
465 x1="17.456696"
466 y1="37.661667"
467 x2="17.456696"
468 y2="27.231844" />
469 <radialGradient
470 inkscape:collect="always"
471 xlink:href="#linearGradient3697"
472 id="radialGradient3705"
473 cx="27.8486"
474 cy="4.607163"
475 fx="27.8486"
476 fy="4.607163"
477 r="7.4889512"
478 gradientTransform="matrix(1.000000,0.000000,0.000000,0.833928,2.121324,0.655729)"
479 gradientUnits="userSpaceOnUse" />
480 <radialGradient
481 inkscape:collect="always"
482 xlink:href="#linearGradient4586"
483 id="radialGradient4594"
484 cx="30.974438"
485 cy="12.172572"
486 fx="30.974438"
487 fy="12.172572"
488 r="4.890574"
489 gradientTransform="matrix(2.132075,-4.734158e-15,2.267378e-15,1.021136,-32.94404,-3.689447)"
490 gradientUnits="userSpaceOnUse" />
491 <radialGradient
492 inkscape:collect="always"
493 xlink:href="#linearGradient4596"
494 id="radialGradient4602"
495 cx="18.163805"
496 cy="22.429104"
497 fx="18.163805"
498 fy="22.429104"
499 r="2.8422911"
500 gradientTransform="matrix(1.870990,-2.499894e-15,2.150062e-15,1.609166,-15.82050,-13.54799)"
501 gradientUnits="userSpaceOnUse" />
502 <linearGradient
503 inkscape:collect="always"
504 xlink:href="#linearGradient4633"
505 id="linearGradient4619"
506 x1="31.643028"
507 y1="13.616933"
508 x2="31.643028"
509 y2="9.6384754"
510 gradientUnits="userSpaceOnUse"
511 gradientTransform="translate(2.121324,-0.883885)" />
512 <linearGradient
513 inkscape:collect="always"
514 xlink:href="#linearGradient4633"
515 id="linearGradient4621"
516 x1="31.643028"
517 y1="13.616933"
518 x2="31.643028"
519 y2="9.6384754"
520 gradientUnits="userSpaceOnUse"
521 gradientTransform="translate(2.121324,-0.883885)" />
522 <linearGradient
523 inkscape:collect="always"
524 xlink:href="#linearGradient4639"
525 id="linearGradient4645"
526 x1="15.335379"
527 y1="28.377787"
528 x2="15.335379"
529 y2="34.388195"
530 gradientUnits="userSpaceOnUse" />
531 <radialGradient
532 inkscape:collect="always"
533 xlink:href="#linearGradient4649"
534 id="radialGradient4647"
535 cx="18.163805"
536 cy="22.223564"
537 fx="18.163805"
538 fy="22.223564"
539 r="2.8422911"
540 gradientTransform="matrix(1.000000,0.000000,0.000000,0.860061,0.000000,3.253760)"
541 gradientUnits="userSpaceOnUse" />
542 <linearGradient
543 inkscape:collect="always"
544 xlink:href="#linearGradient5048"
545 id="linearGradient6715"
546 gradientUnits="userSpaceOnUse"
547 gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
548 x1="302.85715"
549 y1="366.64789"
550 x2="302.85715"
551 y2="609.50507" />
552 <radialGradient
553 inkscape:collect="always"
554 xlink:href="#linearGradient5060"
555 id="radialGradient6717"
556 gradientUnits="userSpaceOnUse"
557 gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
558 cx="605.71429"
559 cy="486.64789"
560 fx="605.71429"
561 fy="486.64789"
562 r="117.14286" />
563 <radialGradient
564 inkscape:collect="always"
565 xlink:href="#linearGradient5060"
566 id="radialGradient6719"
567 gradientUnits="userSpaceOnUse"
568 gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
569 cx="605.71429"
570 cy="486.64789"
571 fx="605.71429"
572 fy="486.64789"
573 r="117.14286" />
574 </defs>
575 <sodipodi:namedview
576 stroke="#2e3436"
577 fill="#555753"
578 id="base"
579 pagecolor="#ffffff"
580 bordercolor="#666666"
581 borderopacity="0.25490196"
582 inkscape:pageopacity="0.0"
583 inkscape:pageshadow="2"
584 inkscape:zoom="1"
585 inkscape:cx="-124.63746"
586 inkscape:cy="8.081426"
587 inkscape:current-layer="layer2"
588 showgrid="false"
589 inkscape:grid-bbox="true"
590 inkscape:document-units="px"
591 inkscape:showpageshadow="false"
592 inkscape:window-width="872"
593 inkscape:window-height="703"
594 inkscape:window-x="234"
595 inkscape:window-y="145" />
596 <metadata
597 id="metadata4">
598 <rdf:RDF>
599 <cc:Work
600 rdf:about="">
601 <dc:format>image/svg+xml</dc:format>
602 <dc:type
603 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
604 <dc:creator>
605 <cc:Agent>
606 <dc:title>Jakub Steiner</dc:title>
607 </cc:Agent>
608 </dc:creator>
609 <dc:source>http://jimmac.musichall.cz</dc:source>
610 <cc:license
611 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
612 <dc:title>Themes</dc:title>
613 <dc:subject>
614 <rdf:Bag>
615 <rdf:li>skin</rdf:li>
616 <rdf:li>color</rdf:li>
617 <rdf:li>theme</rdf:li>
618 <rdf:li>customize</rdf:li>
619 <rdf:li>flavor</rdf:li>
620 </rdf:Bag>
621 </dc:subject>
622 </cc:Work>
623 <cc:License
624 rdf:about="http://creativecommons.org/licenses/publicdomain/">
625 <cc:permits
626 rdf:resource="http://creativecommons.org/ns#Reproduction" />
627 <cc:permits
628 rdf:resource="http://creativecommons.org/ns#Distribution" />
629 <cc:permits
630 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
631 </cc:License>
632 </rdf:RDF>
633 </metadata>
634 <g
635 inkscape:groupmode="layer"
636 id="layer2"
637 inkscape:label="blue shirt">
638 <g
639 transform="matrix(1.518738e-2,0,0,2.086758e-2,45.6332,27.4036)"
640 id="g6707">
641 <rect
642 style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
643 id="rect6709"
644 width="1339.6335"
645 height="478.35718"
646 x="-1559.2523"
647 y="-150.69685" />
648 <path
649 style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
650 d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
651 id="path6711"
652 sodipodi:nodetypes="cccc" />
653 <path
654 sodipodi:nodetypes="cccc"
655 id="path6713"
656 d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
657 style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
658 </g>
659 <path
660 style="color:#000000;fill:url(#linearGradient3663);fill-opacity:1;fill-rule:evenodd;stroke:#949494;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
661 d="M 31.205998,5.2048743 L 34.908493,5.2048743 C 39.19495,5.2048743 44.455603,6.5223903 44.455603,7.0610293 L 44.455603,29.688444 C 44.455603,30.227083 44.018726,30.660716 43.476057,30.660716 L 22.638435,30.660716 C 22.095767,30.660716 21.658889,30.227083 21.658889,29.688444 L 21.658889,7.0610293 C 21.658889,6.5223903 26.830568,5.2048743 31.205998,5.2048743 z "
662 id="path3627"
663 sodipodi:nodetypes="ccccccccc" />
664 <path
665 sodipodi:nodetypes="ccccccc"
666 id="path3629"
667 d="M 31.363447,6.0663853 L 34.751056,6.0663853 C 38.672963,6.0663853 43.486213,7.5879023 43.486213,7.5879023 L 43.486213,29.657422 C 43.486213,29.657422 22.628291,29.657422 22.628291,29.657422 L 22.628291,7.5879023 C 22.628291,7.5879023 27.360135,6.0663853 31.363447,6.0663853 z "
668 style="opacity:0.61988304;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
669 <path
670 style="opacity:1;color:#000000;fill:url(#linearGradient3665);fill-opacity:1;fill-rule:evenodd;stroke:#949494;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
671 d="M 33.410797,10.508173 L 30.405594,17.314076 L 30.405594,29.600057 L 33.587574,32.428484 L 36.50439,29.600057 L 36.50439,17.1373 L 33.410797,10.508173 z "
672 id="path3631" />
673 <path
674 id="path3633"
675 d="M 33.422901,13.510439 L 31.417678,17.921699 L 31.417678,28.969769 L 33.551254,31.023416 L 35.492301,28.969769 L 35.492301,17.793346 L 33.422901,13.510439 z "
676 style="opacity:0.46783627;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3667);stroke-width:0.99999976;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
677 sodipodi:nodetypes="ccccccc" />
678 <path
679 sodipodi:type="arc"
680 style="opacity:1;color:#000000;fill:url(#radialGradient3669);fill-opacity:1;fill-rule:evenodd;stroke:#949494;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
681 id="path3635"
682 sodipodi:cx="18.163805"
683 sodipodi:cy="23.251263"
684 sodipodi:rx="2.3422911"
685 sodipodi:ry="1.9445436"
686 d="M 20.506096 23.251263 A 2.3422911 1.9445436 0 1 1 15.821514,23.251263 A 2.3422911 1.9445436 0 1 1 20.506096 23.251263 z"
687 transform="translate(15.11444,-11.15211)" />
688 <path
689 style="opacity:1;color:#000000;fill:url(#radialGradient3671);fill-opacity:1;fill-rule:evenodd;stroke:#949494;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
690 d="M 33.057245,10.331398 L 28.019109,14.132097 C 28.019109,14.132097 26.162954,8.5652093 26.162954,6.0887583 C 26.162955,3.6138843 27.48878,2.6416133 28.902993,2.6416133 C 28.902993,2.6416133 37.299886,2.6416133 37.299886,2.6416133 C 38.256463,2.6416133 39.929439,3.0393603 40.128313,5.9119823 C 40.327187,8.7846031 38.095381,14.132097 38.095381,14.132097 L 33.057245,10.331398 z "
691 id="path3637"
692 sodipodi:nodetypes="cczcczcc" />
693 <path
694 style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
695 d="M 29.915116,5.0280943 C 29.915116,5.0280943 28.099472,5.5160723 28.41988,6.6872173 C 28.740287,7.8583633 31.196747,9.7126756 31.196747,9.7126756 L 35.789258,9.7126756 C 35.789258,9.7126756 37.898608,8.1511493 38.138915,6.9800043 C 38.379221,5.8088583 36.750481,5.0280943 36.750481,5.0280943 L 29.915116,5.0280943 z "
696 id="path3639"
697 sodipodi:nodetypes="csccscc" />
698 <path
699 sodipodi:nodetypes="csccscc"
700 id="path3641"
701 d="M 29.73834,4.0558263 C 29.73834,4.0558263 27.922696,4.5438043 28.243104,5.7149493 C 28.563511,6.8860953 31.019971,8.7404084 31.019971,8.7404084 L 35.612482,8.7404084 C 35.612482,8.7404084 37.721832,7.1788813 37.962139,6.0077363 C 38.202445,4.8365903 36.573705,4.0558263 36.573705,4.0558263 L 29.73834,4.0558263 z "
702 style="opacity:1;color:#000000;fill:url(#radialGradient3673);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
703 <path
704 sodipodi:nodetypes="ccccccccc"
705 id="path3645"
706 d="M 31.205998,5.2048743 L 34.908493,5.2048743 C 39.19495,5.2048743 44.455603,6.5223903 44.455603,7.0610293 L 44.455603,29.688444 C 44.455603,30.227083 44.018726,30.660716 43.476057,30.660716 L 22.638435,30.660716 C 22.095767,30.660716 21.658889,30.227083 21.658889,29.688444 L 21.658889,7.0610293 C 21.658889,6.5223903 26.830568,5.2048743 31.205998,5.2048743 z "
707 style="color:#000000;fill:url(#linearGradient3677);fill-opacity:1;fill-rule:evenodd;stroke:#3465a4;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
708 <path
709 style="opacity:0.26315792;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
710 d="M 31.363447,6.0663853 L 34.751056,6.0663853 C 38.672963,6.0663853 43.486213,7.5879023 43.486213,7.5879023 L 43.486213,29.657422 C 43.486213,29.657422 22.628291,29.657422 22.628291,29.657422 L 22.628291,7.5879023 C 22.628291,7.5879023 27.360135,6.0663853 31.363447,6.0663853 z "
711 id="path3647"
712 sodipodi:nodetypes="ccccccc" />
713 <path
714 id="path3649"
715 d="M 33.410797,10.508173 C 33.410797,10.508173 30.405594,15.439076 30.405594,17.314076 L 30.405594,29.600057 L 33.587574,32.428484 L 36.50439,29.600057 L 36.50439,17.1373 C 36.50439,15.3873 33.410797,10.508173 33.410797,10.508173 z "
716 style="opacity:1;color:#000000;fill:#75507b;fill-opacity:1;fill-rule:evenodd;stroke:#5c3566;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
717 sodipodi:nodetypes="ccccccc" />
718 <path
719 sodipodi:nodetypes="ccccccc"
720 style="opacity:0.25146197;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3681);stroke-width:0.99999976;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
721 d="M 33.422901,13.510439 L 31.417678,17.921699 L 31.417678,28.969769 L 33.551254,31.023416 L 35.492301,28.969769 L 35.492301,17.793346 L 33.422901,13.510439 z "
722 id="path3651" />
723 <path
724 transform="translate(15.11444,-11.15211)"
725 d="M 20.506096 23.251263 A 2.3422911 1.9445436 0 1 1 15.821514,23.251263 A 2.3422911 1.9445436 0 1 1 20.506096 23.251263 z"
726 sodipodi:ry="1.9445436"
727 sodipodi:rx="2.3422911"
728 sodipodi:cy="23.251263"
729 sodipodi:cx="18.163805"
730 id="path3653"
731 style="opacity:1;color:#000000;fill:url(#radialGradient4602);fill-opacity:1;fill-rule:evenodd;stroke:#5c3566;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
732 sodipodi:type="arc" />
733 <path
734 sodipodi:nodetypes="cczcczcc"
735 id="path3655"
736 d="M 33.057245,10.331398 L 28.019109,14.132097 C 28.019109,14.132097 26.162954,8.5652093 26.162954,6.0887583 C 26.162955,3.6138843 27.48878,2.6416133 28.902993,2.6416133 C 28.902993,2.6416133 37.299886,2.6416133 37.299886,2.6416133 C 38.256463,2.6416133 39.929439,3.0393603 40.128313,5.9119823 C 40.327187,8.7846031 38.095381,14.132097 38.095381,14.132097 L 33.057245,10.331398 z "
737 style="opacity:1;color:#000000;fill:url(#radialGradient3705);fill-opacity:1;fill-rule:evenodd;stroke:#3465a4;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
738 <path
739 sodipodi:nodetypes="csccscc"
740 id="path3657"
741 d="M 29.915116,5.0280943 C 29.915116,5.0280943 28.099472,5.5160723 28.41988,6.6872173 C 28.740287,7.8583633 30.696747,9.7126756 31.196747,9.7126756 L 35.789258,9.7126756 C 36.539258,9.6501756 37.898608,8.1511493 38.138915,6.9800043 C 38.379221,5.8088583 36.750481,5.0280943 36.750481,5.0280943 L 29.915116,5.0280943 z "
742 style="opacity:0.33333333;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
743 <path
744 style="opacity:1;color:#000000;fill:url(#radialGradient4594);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
745 d="M 29.73834,4.0558263 C 29.23834,4.0558263 27.922696,4.5438043 28.243104,5.7149493 C 28.563511,6.8860953 30.142741,8.7404084 31.019971,8.7404084 L 35.612482,8.7404084 C 36.302817,8.7404084 37.721832,7.1788813 37.962139,6.0077363 C 38.202445,4.8365903 37.073705,4.0558263 36.573705,4.0558263 L 29.73834,4.0558263 z "
746 id="path3659"
747 sodipodi:nodetypes="csccscc" />
748 <path
749 style="opacity:0.28654971;color:#000000;fill:url(#linearGradient4619);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
750 d="M 33.145635,9.6836496 L 37.830218,13.219183 L 39.067654,9.7720386 L 37.565053,12.246911 L 33.145635,9.6836496 z "
751 id="path4609" />
752 <path
753 id="path4611"
754 d="M 32.792081,9.8604263 L 28.372663,13.219183 L 26.870062,6.5900599 L 28.902993,11.981746 L 32.792081,9.8604263 z "
755 style="opacity:0.28654971;color:#000000;fill:url(#linearGradient4621);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
756 sodipodi:nodetypes="ccccc" />
757 </g>
758 <g
759 id="layer1"
760 inkscape:label="grey shirt"
761 inkscape:groupmode="layer">
762 <path
763 style="color:#000000;fill:url(#linearGradient3574);fill-opacity:1;fill-rule:evenodd;stroke:#949494;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
764 d="M 13.086385,18.12474 L 16.78888,18.12474 C 21.075337,18.12474 26.33599,19.442256 26.33599,19.980895 L 26.33599,42.608311 C 26.33599,43.14695 25.899113,43.580583 25.356444,43.580583 L 4.5188213,43.580583 C 3.9761532,43.580583 3.5392748,43.14695 3.5392748,42.608311 L 3.5392748,19.980895 C 3.5392748,19.442256 8.7109537,18.12474 13.086385,18.12474 z "
765 id="rect2564"
766 sodipodi:nodetypes="ccccccccc" />
767 <path
768 sodipodi:nodetypes="ccccccc"
769 id="path3576"
770 d="M 13.243834,18.986251 L 16.631443,18.986251 C 20.55335,18.986251 25.3666,20.507768 25.3666,20.507768 L 25.3666,42.577289 C 25.3666,42.577289 4.5086772,42.577289 4.5086772,42.577289 L 4.5086772,20.507768 C 4.5086772,20.507768 9.2405207,18.986251 13.243834,18.986251 z "
771 style="opacity:0.61988304;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
772 <g
773 id="g5022"
774 transform="matrix(1.518738e-2,0,0,2.086758e-2,28.3832,40.0286)">
775 <rect
776 y="-150.69685"
777 x="-1559.2523"
778 height="478.35718"
779 width="1339.6335"
780 id="rect4173"
781 style="opacity:0.40206185;color:black;fill:url(#linearGradient5027);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
782 <path
783 sodipodi:nodetypes="cccc"
784 id="path5058"
785 d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
786 style="opacity:0.40206185;color:black;fill:url(#radialGradient5029);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
787 <path
788 style="opacity:0.40206185;color:black;fill:url(#radialGradient5031);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
789 d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
790 id="path5018"
791 sodipodi:nodetypes="cccc" />
792 </g>
793 <path
794 style="opacity:1;color:#000000;fill:url(#linearGradient3514);fill-opacity:1;fill-rule:evenodd;stroke:#949494;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
795 d="M 15.291184,23.42804 L 12.285981,30.233943 L 12.285981,42.519924 L 15.467961,45.348351 L 18.384777,42.519924 L 18.384777,30.057167 L 15.291184,23.42804 z "
796 id="path3446" />
797 <path
798 id="path3516"
799 d="M 15.303288,26.430306 L 13.298065,30.841566 L 13.298065,41.889636 L 15.431641,43.943283 L 17.372688,41.889636 L 17.372688,30.713213 L 15.303288,26.430306 z "
800 style="opacity:0.46783627;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3524);stroke-width:0.99999976;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
801 sodipodi:nodetypes="ccccccc" />
802 <path
803 sodipodi:type="arc"
804 style="opacity:1;color:#000000;fill:url(#radialGradient3542);fill-opacity:1;fill-rule:evenodd;stroke:#949494;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
805 id="path3444"
806 sodipodi:cx="18.163805"
807 sodipodi:cy="23.251263"
808 sodipodi:rx="2.3422911"
809 sodipodi:ry="1.9445436"
810 d="M 20.506096 23.251263 A 2.3422911 1.9445436 0 1 1 15.821514,23.251263 A 2.3422911 1.9445436 0 1 1 20.506096 23.251263 z"
811 transform="translate(-3.005208,1.767768)" />
812 <path
813 style="opacity:1;color:#000000;fill:url(#radialGradient3566);fill-opacity:1;fill-rule:evenodd;stroke:#949494;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
814 d="M 14.937632,23.251265 L 9.8994947,27.051964 C 9.8994947,27.051964 8.0433397,21.485075 8.0433397,19.008624 C 8.0433407,16.53375 9.3691657,15.561479 10.78338,15.561479 C 10.78338,15.561479 19.180273,15.561479 19.180273,15.561479 C 20.13685,15.561479 21.809826,15.959226 22.0087,18.831848 C 22.207574,21.704469 19.975768,27.051964 19.975768,27.051964 L 14.937632,23.251265 z "
815 id="path3440"
816 sodipodi:nodetypes="cczcczcc" />
817 <path
818 style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
819 d="M 11.795503,17.94796 C 11.795503,17.94796 9.9798577,18.435938 10.300266,19.607083 C 10.620674,20.778229 13.077134,22.632542 13.077134,22.632542 L 17.669645,22.632542 C 17.669645,22.632542 19.778995,21.071015 20.019302,19.89987 C 20.259608,18.728724 18.630868,17.94796 18.630868,17.94796 L 11.795503,17.94796 z "
820 id="path3442"
821 sodipodi:nodetypes="csccscc" />
822 <path
823 sodipodi:nodetypes="csccscc"
824 id="path3556"
825 d="M 11.618727,16.975692 C 11.618727,16.975692 9.8030817,17.46367 10.12349,18.634815 C 10.443897,19.805961 12.900358,21.660274 12.900358,21.660274 L 17.492869,21.660274 C 17.492869,21.660274 19.602219,20.098747 19.842526,18.927602 C 20.082832,17.756456 18.454092,16.975692 18.454092,16.975692 L 11.618727,16.975692 z "
826 style="opacity:1;color:#000000;fill:url(#radialGradient3548);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
827 <path
828 sodipodi:nodetypes="ccccccccc"
829 id="path3580"
830 d="M 13.086385,18.12474 L 16.78888,18.12474 C 21.075337,18.12474 26.33599,19.442256 26.33599,19.980895 L 26.33599,42.608311 C 26.33599,43.14695 25.899113,43.580583 25.356444,43.580583 L 4.5188213,43.580583 C 3.9761532,43.580583 3.5392748,43.14695 3.5392748,42.608311 L 3.5392748,19.980895 C 3.5392748,19.442256 8.7109537,18.12474 13.086385,18.12474 z "
831 style="color:#000000;fill:url(#linearGradient3620);fill-opacity:1;fill-rule:evenodd;stroke:#949494;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
832 <path
833 style="opacity:0.61988304;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
834 d="M 13.243834,18.986251 L 16.631443,18.986251 C 20.55335,18.986251 25.3666,20.507768 25.3666,20.507768 L 25.3666,42.577289 C 25.3666,42.577289 4.5086772,42.577289 4.5086772,42.577289 L 4.5086772,20.507768 C 4.5086772,20.507768 9.2405207,18.986251 13.243834,18.986251 z "
835 id="path3582"
836 sodipodi:nodetypes="ccccccc" />
837 <path
838 id="path3584"
839 d="M 15.291184,23.42804 C 15.291184,23.42804 12.285981,27.845821 12.285981,30.233943 L 12.285981,42.519924 L 15.467961,45.348351 L 18.384777,42.519924 L 18.384777,30.057167 C 18.384777,28.057167 15.291184,23.42804 15.291184,23.42804 z "
840 style="opacity:1;color:#000000;fill:url(#linearGradient4645);fill-opacity:1.0;fill-rule:evenodd;stroke:#2e3436;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
841 sodipodi:nodetypes="ccccccc" />
842 <path
843 sodipodi:nodetypes="ccccccc"
844 style="opacity:0.46783627;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3616);stroke-width:0.99999976;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
845 d="M 15.303288,26.430306 L 13.298065,30.841566 L 13.298065,41.889636 L 15.431641,43.943283 L 17.372688,41.889636 L 17.372688,30.713213 L 15.303288,26.430306 z "
846 id="path3586" />
847 <path
848 transform="translate(-3.005208,1.767768)"
849 d="M 20.506096 23.251263 A 2.3422911 1.9445436 0 1 1 15.821514,23.251263 A 2.3422911 1.9445436 0 1 1 20.506096 23.251263 z"
850 sodipodi:ry="1.9445436"
851 sodipodi:rx="2.3422911"
852 sodipodi:cy="23.251263"
853 sodipodi:cx="18.163805"
854 id="path3588"
855 style="opacity:1;color:#000000;fill:url(#radialGradient4647);fill-opacity:1.0;fill-rule:evenodd;stroke:#2e3436;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
856 sodipodi:type="arc" />
857 <path
858 sodipodi:nodetypes="cczcczcc"
859 id="path3590"
860 d="M 14.937632,23.251265 L 9.8994947,27.051964 C 9.8994947,27.051964 8.0433397,21.485075 8.0433397,19.008624 C 8.0433407,16.53375 9.3691657,15.561479 10.78338,15.561479 C 10.78338,15.561479 19.180273,15.561479 19.180273,15.561479 C 20.13685,15.561479 21.809826,15.959226 22.0087,18.831848 C 22.207574,21.704469 19.975768,27.051964 19.975768,27.051964 L 14.937632,23.251265 z "
861 style="opacity:1;color:#000000;fill:url(#radialGradient3612);fill-opacity:1;fill-rule:evenodd;stroke:#949494;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
862 <path
863 sodipodi:nodetypes="csccscc"
864 id="path3592"
865 d="M 11.795503,17.94796 C 11.795503,17.94796 9.9798577,18.435938 10.300266,19.607083 C 10.620674,20.778229 12.007307,22.632542 13.077134,22.632542 L 17.669645,22.632542 C 18.546875,22.632542 19.778995,21.071015 20.019302,19.89987 C 20.259608,18.728724 18.630868,17.94796 18.630868,17.94796 L 11.795503,17.94796 z "
866 style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
867 <path
868 style="opacity:1;color:#000000;fill:url(#radialGradient3610);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
869 d="M 11.618727,16.975692 C 11.618727,16.975692 9.8030817,17.46367 10.12349,18.634815 C 10.443897,19.805961 11.775358,21.660274 12.900358,21.660274 L 17.492869,21.660274 C 18.242869,21.660274 19.602219,20.098747 19.842526,18.927602 C 20.082832,17.756456 18.454092,16.975692 18.454092,16.975692 L 11.618727,16.975692 z "
870 id="path3594"
871 sodipodi:nodetypes="csccscc" />
872 <path
873 style="opacity:0.61988304;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
874 d="M 14.937632,22.720934 L 19.622215,26.256468 L 20.859651,22.809323 L 19.35705,25.284196 L 14.937632,22.720934 z "
875 id="path4604" />
876 <path
877 id="path4607"
878 d="M 14.584078,22.897711 L 10.164659,26.256468 L 8.6620577,19.627343 L 10.69499,25.019031 L 14.584078,22.897711 z "
879 style="opacity:0.61988304;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
880 sodipodi:nodetypes="ccccc" />
881 </g>
882</svg>
diff --git a/utils/rbutilqt/icons/preferences-system.svg b/utils/rbutilqt/icons/preferences-system.svg
new file mode 100644
index 0000000000..d41028fc8d
--- /dev/null
+++ b/utils/rbutilqt/icons/preferences-system.svg
@@ -0,0 +1,398 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 inkscape:export-ydpi="90.000000"
13 inkscape:export-xdpi="90.000000"
14 inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
15 width="48px"
16 height="48px"
17 id="svg11300"
18 sodipodi:version="0.32"
19 inkscape:version="0.46"
20 sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/categories"
21 sodipodi:docname="preferences-system.svg"
22 inkscape:output_extension="org.inkscape.output.svg.inkscape">
23 <defs
24 id="defs3">
25 <inkscape:perspective
26 sodipodi:type="inkscape:persp3d"
27 inkscape:vp_x="0 : 24 : 1"
28 inkscape:vp_y="0 : 1000 : 0"
29 inkscape:vp_z="48 : 24 : 1"
30 inkscape:persp3d-origin="24 : 16 : 1"
31 id="perspective60" />
32 <linearGradient
33 inkscape:collect="always"
34 id="linearGradient2250">
35 <stop
36 style="stop-color:#ffffff;stop-opacity:1;"
37 offset="0"
38 id="stop2252" />
39 <stop
40 style="stop-color:#ffffff;stop-opacity:0;"
41 offset="1"
42 id="stop2254" />
43 </linearGradient>
44 <linearGradient
45 inkscape:collect="always"
46 id="linearGradient2265">
47 <stop
48 style="stop-color:#000000;stop-opacity:1;"
49 offset="0"
50 id="stop2267" />
51 <stop
52 style="stop-color:#000000;stop-opacity:0;"
53 offset="1"
54 id="stop2269" />
55 </linearGradient>
56 <linearGradient
57 inkscape:collect="always"
58 id="linearGradient2257">
59 <stop
60 style="stop-color:#ffffff;stop-opacity:1;"
61 offset="0"
62 id="stop2259" />
63 <stop
64 style="stop-color:#ffffff;stop-opacity:0;"
65 offset="1"
66 id="stop2261" />
67 </linearGradient>
68 <linearGradient
69 id="linearGradient3087">
70 <stop
71 style="stop-color:#3465a4;stop-opacity:1;"
72 offset="0"
73 id="stop3089" />
74 <stop
75 id="stop3095"
76 offset="0"
77 style="stop-color:#9fbce1;stop-opacity:1;" />
78 <stop
79 style="stop-color:#6b95ca;stop-opacity:1;"
80 offset="0"
81 id="stop2242" />
82 <stop
83 id="stop2244"
84 offset="0.75"
85 style="stop-color:#3d6aa5;stop-opacity:1;" />
86 <stop
87 style="stop-color:#386eb4;stop-opacity:1;"
88 offset="1"
89 id="stop3091" />
90 </linearGradient>
91 <linearGradient
92 id="linearGradient3077">
93 <stop
94 style="stop-color:#98a0a9;stop-opacity:1;"
95 offset="0"
96 id="stop3079" />
97 <stop
98 style="stop-color:#c3d0dd;stop-opacity:1;"
99 offset="1"
100 id="stop3081" />
101 </linearGradient>
102 <linearGradient
103 id="linearGradient3061">
104 <stop
105 style="stop-color:#ffffff;stop-opacity:1;"
106 offset="0"
107 id="stop3063" />
108 <stop
109 style="stop-color:#000000;stop-opacity:1;"
110 offset="1"
111 id="stop3065" />
112 </linearGradient>
113 <linearGradient
114 id="linearGradient3049">
115 <stop
116 style="stop-color:#b6b6b6;stop-opacity:1;"
117 offset="0"
118 id="stop3051" />
119 <stop
120 id="stop2262"
121 offset="0.5"
122 style="stop-color:#f2f2f2;stop-opacity:1;" />
123 <stop
124 style="stop-color:#fafafa;stop-opacity:1;"
125 offset="0.67612958"
126 id="stop2264" />
127 <stop
128 id="stop2268"
129 offset="0.84051722"
130 style="stop-color:#d8d8d8;stop-opacity:1;" />
131 <stop
132 id="stop2266"
133 offset="0.875"
134 style="stop-color:#f2f2f2;stop-opacity:1;" />
135 <stop
136 style="stop-color:#dbdbdb;stop-opacity:1;"
137 offset="1"
138 id="stop3053" />
139 </linearGradient>
140 <linearGradient
141 inkscape:collect="always"
142 id="linearGradient3041">
143 <stop
144 style="stop-color:#000000;stop-opacity:1;"
145 offset="0"
146 id="stop3043" />
147 <stop
148 style="stop-color:#000000;stop-opacity:0;"
149 offset="1"
150 id="stop3045" />
151 </linearGradient>
152 <radialGradient
153 inkscape:collect="always"
154 xlink:href="#linearGradient3041"
155 id="radialGradient3047"
156 cx="24.8125"
157 cy="39.125"
158 fx="24.8125"
159 fy="39.125"
160 r="17.6875"
161 gradientTransform="matrix(1.000000,0.000000,0.000000,0.374558,7.194333e-15,24.47041)"
162 gradientUnits="userSpaceOnUse" />
163 <linearGradient
164 inkscape:collect="always"
165 xlink:href="#linearGradient3049"
166 id="linearGradient3055"
167 x1="19.648342"
168 y1="42.253601"
169 x2="20.631224"
170 y2="6.7758031"
171 gradientUnits="userSpaceOnUse"
172 gradientTransform="matrix(0.878270,0.000000,0.000000,0.878270,2.536988,4.967681)" />
173 <linearGradient
174 inkscape:collect="always"
175 xlink:href="#linearGradient3061"
176 id="linearGradient3067"
177 x1="50.152931"
178 y1="-3.6324477"
179 x2="25.291086"
180 y2="-4.3002653"
181 gradientUnits="userSpaceOnUse"
182 gradientTransform="matrix(0.878270,-1.375944e-15,1.375944e-15,0.878270,5.328299,1.650243)" />
183 <linearGradient
184 inkscape:collect="always"
185 xlink:href="#linearGradient3077"
186 id="linearGradient3083"
187 x1="38.227654"
188 y1="13.602527"
189 x2="37.53537"
190 y2="6.6285896"
191 gradientUnits="userSpaceOnUse"
192 gradientTransform="matrix(0.878270,0.000000,0.000000,0.878270,2.847503,5.588712)" />
193 <linearGradient
194 inkscape:collect="always"
195 xlink:href="#linearGradient3087"
196 id="linearGradient3093"
197 x1="9.7503242"
198 y1="32.28376"
199 x2="16.915297"
200 y2="39.443218"
201 gradientUnits="userSpaceOnUse"
202 gradientTransform="matrix(0.878270,0.000000,0.000000,0.878270,2.536988,4.967681)" />
203 <linearGradient
204 inkscape:collect="always"
205 xlink:href="#linearGradient2257"
206 id="linearGradient2263"
207 x1="12.004697"
208 y1="35.688461"
209 x2="10.650805"
210 y2="33.194965"
211 gradientUnits="userSpaceOnUse"
212 gradientTransform="matrix(1.007254,-2.636526e-2,2.636526e-2,1.007254,1.593411,7.919100e-2)" />
213 <linearGradient
214 inkscape:collect="always"
215 xlink:href="#linearGradient2265"
216 id="linearGradient2271"
217 x1="14.017542"
218 y1="36.942543"
219 x2="15.415793"
220 y2="38.268368"
221 gradientUnits="userSpaceOnUse"
222 gradientTransform="matrix(0.878099,-1.732370e-2,1.732370e-2,0.878099,2.163687,4.067899)" />
223 <linearGradient
224 inkscape:collect="always"
225 xlink:href="#linearGradient2250"
226 id="linearGradient2256"
227 x1="31.177404"
228 y1="19.821514"
229 x2="40.859177"
230 y2="9.6568537"
231 gradientUnits="userSpaceOnUse" />
232 <radialGradient
233 inkscape:collect="always"
234 xlink:href="#linearGradient3041"
235 id="radialGradient2260"
236 gradientUnits="userSpaceOnUse"
237 gradientTransform="matrix(1.000000,0.000000,0.000000,0.374558,7.272829e-15,24.47041)"
238 cx="24.8125"
239 cy="39.125"
240 fx="24.8125"
241 fy="39.125"
242 r="17.6875" />
243 </defs>
244 <sodipodi:namedview
245 stroke="#204a87"
246 fill="#3465a4"
247 id="base"
248 pagecolor="#ffffff"
249 bordercolor="#666666"
250 borderopacity="0.25490196"
251 inkscape:pageopacity="0.0"
252 inkscape:pageshadow="2"
253 inkscape:zoom="4"
254 inkscape:cx="19.425317"
255 inkscape:cy="26.37487"
256 inkscape:current-layer="layer1"
257 showgrid="false"
258 inkscape:grid-bbox="true"
259 inkscape:document-units="px"
260 inkscape:showpageshadow="false"
261 inkscape:window-width="1034"
262 inkscape:window-height="818"
263 inkscape:window-x="400"
264 inkscape:window-y="30" />
265 <metadata
266 id="metadata4">
267 <rdf:RDF>
268 <cc:Work
269 rdf:about="">
270 <dc:format>image/svg+xml</dc:format>
271 <dc:type
272 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
273 <dc:creator>
274 <cc:Agent>
275 <dc:title>Jakub Steiner</dc:title>
276 </cc:Agent>
277 </dc:creator>
278 <dc:source>http://jimmac.musichall.cz</dc:source>
279 <cc:license
280 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
281 <dc:title>Preferences System</dc:title>
282 <dc:subject>
283 <rdf:Bag>
284 <rdf:li>preferences</rdf:li>
285 <rdf:li>settings</rdf:li>
286 <rdf:li>control panel</rdf:li>
287 <rdf:li>tweaks</rdf:li>
288 <rdf:li>system</rdf:li>
289 </rdf:Bag>
290 </dc:subject>
291 </cc:Work>
292 <cc:License
293 rdf:about="http://creativecommons.org/licenses/publicdomain/">
294 <cc:permits
295 rdf:resource="http://creativecommons.org/ns#Reproduction" />
296 <cc:permits
297 rdf:resource="http://creativecommons.org/ns#Distribution" />
298 <cc:permits
299 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
300 </cc:License>
301 </rdf:RDF>
302 </metadata>
303 <g
304 id="layer1"
305 inkscape:label="Layer 1"
306 inkscape:groupmode="layer">
307 <path
308 transform="matrix(0.751118,0.000000,0.000000,0.578703,17.04087,19.36341)"
309 d="M 42.5 39.125 A 17.6875 6.625 0 1 1 7.125,39.125 A 17.6875 6.625 0 1 1 42.5 39.125 z"
310 sodipodi:ry="6.625"
311 sodipodi:rx="17.6875"
312 sodipodi:cy="39.125"
313 sodipodi:cx="24.8125"
314 id="path2258"
315 style="opacity:0.19886367;color:#000000;fill:url(#radialGradient2260);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
316 sodipodi:type="arc" />
317 <path
318 sodipodi:type="arc"
319 style="opacity:0.3125;color:#000000;fill:url(#radialGradient3047);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
320 id="path3039"
321 sodipodi:cx="24.8125"
322 sodipodi:cy="39.125"
323 sodipodi:rx="17.6875"
324 sodipodi:ry="6.625"
325 d="M 42.5 39.125 A 17.6875 6.625 0 1 1 7.125,39.125 A 17.6875 6.625 0 1 1 42.5 39.125 z"
326 transform="matrix(0.836071,0.000000,0.000000,0.685436,-7.959607,15.71781)" />
327 <path
328 style="opacity:1;color:#000000;fill:url(#linearGradient3055);fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
329 d="M 17.906713,21.215676 L 36.899302,40.6474 C 37.667788,41.52567 40.102812,42.204461 41.729787,40.6474 C 43.300913,39.143787 42.937408,37.024536 41.400436,35.487563 L 23.176333,15.946056 C 25.426333,9.696056 20.872444,4.446488 14.997444,5.571488 L 13.73493,6.7242174 L 17.687145,10.456865 L 17.906713,13.750381 L 14.955871,16.443984 L 11.429472,16.05584 L 7.8066086,12.652544 C 7.8066086,12.652544 6.5364873,13.907448 6.5364873,13.907448 C 5.9457238,19.548765 11.844213,24.590676 17.906713,21.215676 z "
330 id="path2140"
331 sodipodi:nodetypes="cczcccccccccsc" />
332 <path
333 sodipodi:nodetypes="cczccccccccccc"
334 id="path3057"
335 d="M 18.117385,19.9401 L 37.320267,39.967712 C 37.915174,40.647605 39.800194,41.173077 41.059681,39.967712 C 42.275934,38.803723 41.994534,37.163152 40.804721,35.973338 L 22.313189,16.352183 C 23.813189,9.852183 20.454401,6.3475455 15.454401,6.4725455 L 15.18427,6.7459223 L 18.787193,9.982189 L 18.917359,14.163983 L 15.303442,17.462466 L 11.061136,17.004257 L 7.8845536,14.012776 L 7.5319165,14.442835 C 7.2194165,20.411585 14.023635,23.1276 18.117385,19.9401 z "
336 style="opacity:0.42613639;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.99999917;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
337 <rect
338 style="opacity:0.17045456;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3067);stroke-width:0.9999972;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
339 id="rect3059"
340 width="23.268276"
341 height="2.0554912"
342 x="28.185335"
343 y="-2.6184492"
344 rx="0.88388073"
345 ry="0.88388073"
346 transform="matrix(0.697938,0.716158,-0.716158,0.697938,0.000000,0.000000)" />
347 <path
348 style="opacity:1;color:#000000;fill:url(#linearGradient3083);fill-opacity:1;fill-rule:nonzero;stroke:#878f9d;stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
349 d="M 22.498794,30.12538 C 23.332335,29.410917 35.782628,16.676871 35.782628,16.676871 L 38.856573,16.457303 L 43.687058,9.7604906 L 39.662731,6.1752987 L 33.405057,11.554705 L 33.405057,14.628651 L 20.670142,27.857593 C 20.066332,28.461403 21.730308,30.784082 22.498794,30.12538 z "
350 id="path2144"
351 sodipodi:nodetypes="ccccccccc" />
352 <path
353 sodipodi:nodetypes="ccccccccc"
354 id="path3085"
355 d="M 22.401987,29.085455 C 23.04876,28.531078 35.426388,15.855648 35.426388,15.855648 L 38.354971,15.607649 L 42.568887,9.945584 L 39.679156,7.3965946 L 34.202578,12.114067 L 34.357836,14.965022 L 21.681731,28.257345 C 21.213213,28.725863 21.805692,29.596565 22.401987,29.085455 z "
356 style="opacity:0.53977272;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2256);stroke-width:1.00000024;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
357 <path
358 style="color:#000000;fill:url(#linearGradient3093);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible"
359 d="M 8.4653111,43.611561 C 9.7818986,45.07679 13.438996,45.739726 15.060755,42.901647 C 15.767862,41.664211 17.154698,38.198845 23.341883,32.630379 C 24.381029,31.696208 25.481792,29.559241 24.54863,28.406512 L 22.133387,25.991269 C 21.145334,24.893432 18.398973,25.40552 17.272212,26.942145 C 13.913455,31.538339 8.4261393,35.197025 7.1887023,35.638967 C 4.8207828,36.484652 5.0872917,39.975116 6.6538792,41.635454 L 8.4653111,43.611561 z "
360 id="path2142"
361 sodipodi:nodetypes="ccccccscc" />
362 <path
363 sodipodi:type="arc"
364 style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#a1a1a1;stroke-width:1.13860166;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
365 id="path2146"
366 sodipodi:cx="41.875"
367 sodipodi:cy="37.5"
368 sodipodi:rx="1.375"
369 sodipodi:ry="1.375"
370 d="M 43.25 37.5 A 1.375 1.375 0 1 1 40.5,37.5 A 1.375 1.375 0 1 1 43.25 37.5 z"
371 transform="matrix(0.878270,0.000000,0.000000,0.878270,2.427204,5.077464)" />
372 <path
373 sodipodi:type="arc"
374 style="opacity:0.60227272;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
375 id="path3101"
376 sodipodi:cx="19.003494"
377 sodipodi:cy="28.20101"
378 sodipodi:rx="1.767767"
379 sodipodi:ry="1.767767"
380 d="M 20.771261 28.20101 A 1.767767 1.767767 0 1 1 17.235727,28.20101 A 1.767767 1.767767 0 1 1 20.771261 28.20101 z"
381 transform="matrix(0.570876,0.000000,0.000000,0.570876,9.154848,11.25111)" />
382 <path
383 style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2263);stroke-width:2.29450917;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
384 d="M 18.678905,29.624807 C 18.678905,29.624807 11.509014,36.92442 8.1502573,38.161857"
385 id="path3103"
386 sodipodi:nodetypes="cc" />
387 <path
388 sodipodi:nodetypes="csccccscc"
389 id="path2270"
390 d="M 8.8060013,42.48669 C 10.247267,44.232307 13.405535,44.647919 14.397161,42.116101 C 15.078468,40.376589 17.730783,36.450314 22.594745,32.072748 C 23.411654,31.338363 24.277003,29.658419 23.543411,28.752218 L 21.644704,26.853511 C 20.867961,25.990463 18.708951,26.393033 17.823164,27.601028 C 15.182728,31.214257 9.3398194,35.940582 7.9274145,36.406654 C 5.7406198,37.128264 6.1504221,39.627953 7.3819713,40.933203 L 8.8060013,42.48669 z "
391 style="color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.99999946;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;opacity:0.19886364" />
392 <path
393 style="opacity:0.27840911;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2271);stroke-width:2.29450917;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
394 d="M 20.824602,31.261024 C 20.824602,31.261024 13.501839,37.878429 11.910849,42.121069"
395 id="path2247"
396 sodipodi:nodetypes="cc" />
397 </g>
398</svg>
diff --git a/utils/rbutilqt/icons/process-stop.svg b/utils/rbutilqt/icons/process-stop.svg
new file mode 100644
index 0000000000..04ce3a79fe
--- /dev/null
+++ b/utils/rbutilqt/icons/process-stop.svg
@@ -0,0 +1,336 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="48.000000px"
13 height="48.000000px"
14 id="svg6361"
15 sodipodi:version="0.32"
16 inkscape:version="0.46"
17 sodipodi:docbase="/home/jimmac/gfx/ximian/tango-icon-theme/scalable/actions"
18 sodipodi:docname="process-stop.svg"
19 inkscape:output_extension="org.inkscape.output.svg.inkscape">
20 <defs
21 id="defs3">
22 <inkscape:perspective
23 sodipodi:type="inkscape:persp3d"
24 inkscape:vp_x="0 : 24 : 1"
25 inkscape:vp_y="0 : 1000 : 0"
26 inkscape:vp_z="48 : 24 : 1"
27 inkscape:persp3d-origin="24 : 16 : 1"
28 id="perspective52" />
29 <linearGradient
30 id="linearGradient2256">
31 <stop
32 style="stop-color:#ff0202;stop-opacity:1;"
33 offset="0"
34 id="stop2258" />
35 <stop
36 style="stop-color:#ff9b9b;stop-opacity:1;"
37 offset="1"
38 id="stop2260" />
39 </linearGradient>
40 <linearGradient
41 inkscape:collect="always"
42 id="linearGradient2248">
43 <stop
44 style="stop-color:#ffffff;stop-opacity:1;"
45 offset="0"
46 id="stop2250" />
47 <stop
48 style="stop-color:#ffffff;stop-opacity:0;"
49 offset="1"
50 id="stop2252" />
51 </linearGradient>
52 <linearGradient
53 id="linearGradient9647">
54 <stop
55 style="stop-color:#ffffff;stop-opacity:1;"
56 offset="0"
57 id="stop9649" />
58 <stop
59 style="stop-color:#dbdbdb;stop-opacity:1;"
60 offset="1"
61 id="stop9651" />
62 </linearGradient>
63 <linearGradient
64 inkscape:collect="always"
65 id="linearGradient21644">
66 <stop
67 style="stop-color:#000000;stop-opacity:1;"
68 offset="0"
69 id="stop21646" />
70 <stop
71 style="stop-color:#000000;stop-opacity:0;"
72 offset="1"
73 id="stop21648" />
74 </linearGradient>
75 <radialGradient
76 inkscape:collect="always"
77 xlink:href="#linearGradient21644"
78 id="radialGradient21650"
79 cx="25.125"
80 cy="36.75"
81 fx="25.125"
82 fy="36.75"
83 r="15.75"
84 gradientTransform="matrix(1.000000,0.000000,0.000000,0.595238,-2.300678e-15,14.87500)"
85 gradientUnits="userSpaceOnUse" />
86 <linearGradient
87 inkscape:collect="always"
88 id="linearGradient7895">
89 <stop
90 style="stop-color:#ffffff;stop-opacity:1;"
91 offset="0"
92 id="stop7897" />
93 <stop
94 style="stop-color:#ffffff;stop-opacity:0;"
95 offset="1"
96 id="stop7899" />
97 </linearGradient>
98 <linearGradient
99 id="linearGradient4981">
100 <stop
101 style="stop-color:#cc0000;stop-opacity:1;"
102 offset="0"
103 id="stop4983" />
104 <stop
105 style="stop-color:#b30000;stop-opacity:1.0000000;"
106 offset="1.0000000"
107 id="stop4985" />
108 </linearGradient>
109 <linearGradient
110 id="linearGradient15762"
111 inkscape:collect="always">
112 <stop
113 id="stop15764"
114 offset="0"
115 style="stop-color:#ffffff;stop-opacity:1;" />
116 <stop
117 id="stop15766"
118 offset="1"
119 style="stop-color:#ffffff;stop-opacity:0;" />
120 </linearGradient>
121 <linearGradient
122 id="linearGradient14236">
123 <stop
124 id="stop14238"
125 offset="0.0000000"
126 style="stop-color:#ed4040;stop-opacity:1.0000000;" />
127 <stop
128 id="stop14240"
129 offset="1.0000000"
130 style="stop-color:#a40000;stop-opacity:1.0000000;" />
131 </linearGradient>
132 <linearGradient
133 id="linearGradient11780">
134 <stop
135 style="stop-color:#ff8b8b;stop-opacity:1.0000000;"
136 offset="0.0000000"
137 id="stop11782" />
138 <stop
139 style="stop-color:#ec1b1b;stop-opacity:1.0000000;"
140 offset="1.0000000"
141 id="stop11784" />
142 </linearGradient>
143 <linearGradient
144 id="linearGradient11014">
145 <stop
146 style="stop-color:#a80000;stop-opacity:1.0000000;"
147 offset="0.0000000"
148 id="stop11016" />
149 <stop
150 style="stop-color:#c60000;stop-opacity:1.0000000;"
151 offset="0.0000000"
152 id="stop13245" />
153 <stop
154 style="stop-color:#e50000;stop-opacity:1.0000000;"
155 offset="1.0000000"
156 id="stop11018" />
157 </linearGradient>
158 <linearGradient
159 y2="9.6507530"
160 x2="9.8940229"
161 y1="5.3855424"
162 x1="5.7365270"
163 gradientTransform="matrix(-1.000000,0.000000,0.000000,-1.000000,31.72170,31.29079)"
164 gradientUnits="userSpaceOnUse"
165 id="linearGradient15772"
166 xlink:href="#linearGradient15762"
167 inkscape:collect="always" />
168 <linearGradient
169 inkscape:collect="always"
170 xlink:href="#linearGradient11780"
171 id="linearGradient2057"
172 x1="15.737001"
173 y1="12.503600"
174 x2="53.570126"
175 y2="47.374317"
176 gradientUnits="userSpaceOnUse"
177 gradientTransform="translate(0.000000,-2.000000)" />
178 <linearGradient
179 inkscape:collect="always"
180 xlink:href="#linearGradient4981"
181 id="linearGradient4987"
182 x1="23.995985"
183 y1="20.105337"
184 x2="41.047836"
185 y2="37.959785"
186 gradientUnits="userSpaceOnUse"
187 gradientTransform="translate(0.000000,-2.000000)" />
188 <linearGradient
189 inkscape:collect="always"
190 xlink:href="#linearGradient7895"
191 id="linearGradient7901"
192 x1="15.578875"
193 y1="16.285088"
194 x2="32.166405"
195 y2="28.394291"
196 gradientUnits="userSpaceOnUse" />
197 <radialGradient
198 inkscape:collect="always"
199 xlink:href="#linearGradient9647"
200 id="radialGradient2239"
201 cx="24.30225"
202 cy="33.30225"
203 fx="24.30225"
204 fy="33.30225"
205 r="12.30225"
206 gradientUnits="userSpaceOnUse"
207 gradientTransform="matrix(1.693981,-5.775714e-16,5.775714e-16,1.693981,-16.86529,-25.11111)" />
208 <linearGradient
209 inkscape:collect="always"
210 xlink:href="#linearGradient4981"
211 id="linearGradient2243"
212 gradientUnits="userSpaceOnUse"
213 x1="23.995985"
214 y1="20.105337"
215 x2="41.047836"
216 y2="37.959785"
217 gradientTransform="matrix(0.988373,0.000000,0.000000,0.988373,0.279002,0.278984)" />
218 <radialGradient
219 inkscape:collect="always"
220 xlink:href="#linearGradient2248"
221 id="radialGradient2254"
222 cx="16.75"
223 cy="10.666344"
224 fx="16.75"
225 fy="10.666344"
226 r="21.25"
227 gradientTransform="matrix(4.154957,-2.979206e-24,3.255657e-24,3.198723,-52.84553,-23.50921)"
228 gradientUnits="userSpaceOnUse" />
229 <linearGradient
230 inkscape:collect="always"
231 xlink:href="#linearGradient2256"
232 id="linearGradient2262"
233 x1="21.75"
234 y1="15.80225"
235 x2="24.30225"
236 y2="35.05225"
237 gradientUnits="userSpaceOnUse"
238 gradientTransform="translate(0.000000,-2.000000)" />
239 </defs>
240 <sodipodi:namedview
241 inkscape:guide-bbox="true"
242 showguides="true"
243 id="base"
244 pagecolor="#ffffff"
245 bordercolor="#666666"
246 borderopacity="0.15294118"
247 inkscape:pageopacity="0.0"
248 inkscape:pageshadow="2"
249 inkscape:zoom="4"
250 inkscape:cx="0.007276"
251 inkscape:cy="7.0544576"
252 inkscape:current-layer="layer1"
253 showgrid="false"
254 inkscape:grid-bbox="true"
255 inkscape:document-units="px"
256 inkscape:window-width="786"
257 inkscape:window-height="688"
258 inkscape:window-x="488"
259 inkscape:window-y="160"
260 inkscape:showpageshadow="false" />
261 <metadata
262 id="metadata4">
263 <rdf:RDF>
264 <cc:Work
265 rdf:about="">
266 <dc:format>image/svg+xml</dc:format>
267 <dc:type
268 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
269 <dc:title>Stop</dc:title>
270 <dc:date>2005-10-16</dc:date>
271 <dc:creator>
272 <cc:Agent>
273 <dc:title>Andreas Nilsson</dc:title>
274 </cc:Agent>
275 </dc:creator>
276 <dc:subject>
277 <rdf:Bag>
278 <rdf:li>stop</rdf:li>
279 <rdf:li>halt</rdf:li>
280 <rdf:li>error</rdf:li>
281 </rdf:Bag>
282 </dc:subject>
283 <cc:license
284 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
285 <dc:contributor>
286 <cc:Agent>
287 <dc:title>Jakub Steiner</dc:title>
288 </cc:Agent>
289 </dc:contributor>
290 </cc:Work>
291 <cc:License
292 rdf:about="http://creativecommons.org/licenses/publicdomain/">
293 <cc:permits
294 rdf:resource="http://creativecommons.org/ns#Reproduction" />
295 <cc:permits
296 rdf:resource="http://creativecommons.org/ns#Distribution" />
297 <cc:permits
298 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
299 </cc:License>
300 </rdf:RDF>
301 </metadata>
302 <g
303 id="layer1"
304 inkscape:label="Layer 1"
305 inkscape:groupmode="layer">
306 <path
307 sodipodi:type="arc"
308 style="opacity:0.63068183;color:#000000;fill:url(#radialGradient21650);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
309 id="path21642"
310 sodipodi:cx="25.125"
311 sodipodi:cy="36.75"
312 sodipodi:rx="15.75"
313 sodipodi:ry="9.375"
314 d="M 40.875 36.75 A 15.75 9.375 0 1 1 9.375,36.75 A 15.75 9.375 0 1 1 40.875 36.75 z"
315 transform="matrix(1.173803,0.000000,0.000000,0.600000,-5.265866,19.57500)" />
316 <path
317 style="fill:url(#linearGradient4987);fill-opacity:1;fill-rule:evenodd;stroke:#860000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
318 d="M 15.591006,0.4919213 L 32.676311,0.4919213 L 45.497585,13.586385 L 45.497585,31.48003 L 32.848986,43.496929 L 15.418649,43.496929 L 2.4943857,30.658264 L 2.4943857,13.464078 L 15.591006,0.4919213 z "
319 id="path9480"
320 sodipodi:nodetypes="ccccccccc" />
321 <path
322 style="opacity:0.81318683;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2057);stroke-width:1.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
323 d="M 16.020655,1.5003424 L 32.248563,1.5003424 L 44.496456,13.922717 L 44.496456,31.037001 L 32.638472,42.48783 L 15.870253,42.48783 L 3.5090792,30.208718 L 3.5090792,13.84561 L 16.020655,1.5003424 z "
324 id="path9482"
325 sodipodi:nodetypes="ccccccccc" />
326 <path
327 style="opacity:0.28977272;fill:url(#radialGradient2254);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
328 d="M 15.6875,0.75 L 2.75,13.5625 L 2.75,30.5625 L 5.6875,33.46875 C 22.450041,33.526299 22.164665,20.450067 45.25,21.59375 L 45.25,13.6875 L 32.5625,0.75 L 15.6875,0.75 z "
329 id="path2241"
330 sodipodi:nodetypes="cccccccc" />
331 <path
332 style="fill:url(#radialGradient2239);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2262);stroke-width:0.99999958;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
333 d="M 16.767175,10.5 L 12.5,14.767175 L 20.035075,22.30225 L 12.5,29.837325 L 16.767175,34.104501 L 24.30225,26.569425 L 31.837325,34.104501 L 36.104501,29.837325 L 28.569425,22.30225 L 36.104501,14.767175 L 31.837325,10.5 L 24.30225,18.035075 L 16.767175,10.5 z "
334 id="path2787" />
335 </g>
336</svg>
diff --git a/utils/rbutilqt/icons/rbutilqt.icns b/utils/rbutilqt/icons/rbutilqt.icns
new file mode 100644
index 0000000000..571ee36fcc
--- /dev/null
+++ b/utils/rbutilqt/icons/rbutilqt.icns
Binary files differ
diff --git a/utils/rbutilqt/icons/rockbox.ico b/utils/rbutilqt/icons/rockbox.ico
new file mode 100644
index 0000000000..fa3021631b
--- /dev/null
+++ b/utils/rbutilqt/icons/rockbox.ico
Binary files differ
diff --git a/utils/rbutilqt/icons/system-installer.svg b/utils/rbutilqt/icons/system-installer.svg
new file mode 100644
index 0000000000..3200740972
--- /dev/null
+++ b/utils/rbutilqt/icons/system-installer.svg
@@ -0,0 +1,497 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="48.000000px"
13 height="48.000000px"
14 id="svg14603"
15 sodipodi:version="0.32"
16 inkscape:version="0.46"
17 sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/apps"
18 sodipodi:docname="system-installer.svg"
19 inkscape:output_extension="org.inkscape.output.svg.inkscape">
20 <defs
21 id="defs3">
22 <inkscape:perspective
23 sodipodi:type="inkscape:persp3d"
24 inkscape:vp_x="0 : 24 : 1"
25 inkscape:vp_y="0 : 1000 : 0"
26 inkscape:vp_z="48 : 24 : 1"
27 inkscape:persp3d-origin="24 : 16 : 1"
28 id="perspective79" />
29 <radialGradient
30 inkscape:collect="always"
31 xlink:href="#linearGradient5060"
32 id="radialGradient5031"
33 gradientUnits="userSpaceOnUse"
34 gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
35 cx="605.71429"
36 cy="486.64789"
37 fx="605.71429"
38 fy="486.64789"
39 r="117.14286" />
40 <linearGradient
41 inkscape:collect="always"
42 id="linearGradient5060">
43 <stop
44 style="stop-color:black;stop-opacity:1;"
45 offset="0"
46 id="stop5062" />
47 <stop
48 style="stop-color:black;stop-opacity:0;"
49 offset="1"
50 id="stop5064" />
51 </linearGradient>
52 <radialGradient
53 inkscape:collect="always"
54 xlink:href="#linearGradient5060"
55 id="radialGradient5029"
56 gradientUnits="userSpaceOnUse"
57 gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
58 cx="605.71429"
59 cy="486.64789"
60 fx="605.71429"
61 fy="486.64789"
62 r="117.14286" />
63 <linearGradient
64 id="linearGradient5048">
65 <stop
66 style="stop-color:black;stop-opacity:0;"
67 offset="0"
68 id="stop5050" />
69 <stop
70 id="stop5056"
71 offset="0.5"
72 style="stop-color:black;stop-opacity:1;" />
73 <stop
74 style="stop-color:black;stop-opacity:0;"
75 offset="1"
76 id="stop5052" />
77 </linearGradient>
78 <linearGradient
79 inkscape:collect="always"
80 xlink:href="#linearGradient5048"
81 id="linearGradient5027"
82 gradientUnits="userSpaceOnUse"
83 gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
84 x1="302.85715"
85 y1="366.64789"
86 x2="302.85715"
87 y2="609.50507" />
88 <linearGradient
89 id="linearGradient7844"
90 inkscape:collect="always">
91 <stop
92 id="stop7846"
93 offset="0"
94 style="stop-color:#000000;stop-opacity:1;" />
95 <stop
96 id="stop7848"
97 offset="1"
98 style="stop-color:#000000;stop-opacity:0;" />
99 </linearGradient>
100 <linearGradient
101 id="linearGradient7834"
102 inkscape:collect="always">
103 <stop
104 id="stop7836"
105 offset="0"
106 style="stop-color:#ffffff;stop-opacity:1;" />
107 <stop
108 id="stop7838"
109 offset="1"
110 style="stop-color:#ffffff;stop-opacity:0;" />
111 </linearGradient>
112 <linearGradient
113 id="linearGradient7670">
114 <stop
115 id="stop7672"
116 offset="0"
117 style="stop-color:#dfdfdf;stop-opacity:1;" />
118 <stop
119 id="stop7674"
120 offset="1.0000000"
121 style="stop-color:#c0c0c0;stop-opacity:1.0000000;" />
122 </linearGradient>
123 <linearGradient
124 gradientTransform="matrix(1.008511,0.000000,0.000000,1.000000,-47.59576,-0.285714)"
125 gradientUnits="userSpaceOnUse"
126 y2="40.857143"
127 x2="72.857140"
128 y1="9.7142859"
129 x1="64.571426"
130 id="linearGradient7676"
131 xlink:href="#linearGradient7670"
132 inkscape:collect="always" />
133 <linearGradient
134 gradientTransform="translate(-2.000000,0.000000)"
135 gradientUnits="userSpaceOnUse"
136 y2="0.50379461"
137 x2="19.323767"
138 y1="11.312428"
139 x1="19.362535"
140 id="linearGradient7840"
141 xlink:href="#linearGradient7834"
142 inkscape:collect="always" />
143 <radialGradient
144 gradientUnits="userSpaceOnUse"
145 gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,1.298874e-16,25.06362)"
146 r="22.728432"
147 fy="37.595428"
148 fx="24.546707"
149 cy="37.595428"
150 cx="24.546707"
151 id="radialGradient7850"
152 xlink:href="#linearGradient7844"
153 inkscape:collect="always" />
154 <linearGradient
155 id="aigrd1"
156 gradientUnits="userSpaceOnUse"
157 x1="14.9966"
158 y1="11.1885"
159 x2="32.511"
160 y2="34.3075">
161 <stop
162 offset="0"
163 style="stop-color:#EBEBEB"
164 id="stop3034" />
165 <stop
166 offset="0.5"
167 style="stop-color:#FFFFFF"
168 id="stop3036" />
169 <stop
170 offset="1"
171 style="stop-color:#EBEBEB"
172 id="stop3038" />
173 </linearGradient>
174 <linearGradient
175 id="aigrd2"
176 gradientUnits="userSpaceOnUse"
177 x1="12.2744"
178 y1="32.4165"
179 x2="35.3912"
180 y2="14.2033">
181 <stop
182 offset="0"
183 style="stop-color:#FBFBFB"
184 id="stop3043" />
185 <stop
186 offset="0.5"
187 style="stop-color:#B6B6B6"
188 id="stop3045" />
189 <stop
190 offset="1"
191 style="stop-color:#E4E4E4"
192 id="stop3047" />
193 </linearGradient>
194 <linearGradient
195 id="linearGradient4236">
196 <stop
197 style="stop-color:#ffffff;stop-opacity:0.32673267;"
198 offset="0.0000000"
199 id="stop4238" />
200 <stop
201 style="stop-color:#ffffff;stop-opacity:0.60396039;"
202 offset="1.0000000"
203 id="stop4240" />
204 </linearGradient>
205 <linearGradient
206 inkscape:collect="always"
207 id="linearGradient6028">
208 <stop
209 style="stop-color:#ffffff;stop-opacity:1;"
210 offset="0"
211 id="stop6030" />
212 <stop
213 style="stop-color:#ffffff;stop-opacity:0;"
214 offset="1"
215 id="stop6032" />
216 </linearGradient>
217 <linearGradient
218 inkscape:collect="always"
219 id="linearGradient6036">
220 <stop
221 style="stop-color:#ffffff;stop-opacity:1;"
222 offset="0"
223 id="stop6038" />
224 <stop
225 style="stop-color:#ffffff;stop-opacity:0;"
226 offset="1"
227 id="stop6040" />
228 </linearGradient>
229 <linearGradient
230 y2="14.2033"
231 x2="35.3912"
232 y1="32.4165"
233 x1="12.2744"
234 gradientUnits="userSpaceOnUse"
235 id="linearGradient3394">
236 <stop
237 id="stop3396"
238 style="stop-color:#fff307;stop-opacity:1.0000000;"
239 offset="0.0000000" />
240 <stop
241 id="stop3398"
242 style="stop-color:#166eff;stop-opacity:1.0000000;"
243 offset="0.50000000" />
244 <stop
245 id="stop3400"
246 style="stop-color:#ffffff;stop-opacity:0.0000000;"
247 offset="1.0000000" />
248 </linearGradient>
249 <radialGradient
250 r="22.728432"
251 fy="37.595428"
252 fx="24.546707"
253 cy="37.595428"
254 cx="24.546707"
255 gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,1.121564e-14,25.06362)"
256 gradientUnits="userSpaceOnUse"
257 id="radialGradient10566"
258 xlink:href="#linearGradient7844"
259 inkscape:collect="always" />
260 <linearGradient
261 y2="34.3075"
262 x2="32.511"
263 y1="11.1885"
264 x1="14.9966"
265 gradientTransform="matrix(0.683145,0.000000,0.000000,0.683145,18.55581,18.12886)"
266 gradientUnits="userSpaceOnUse"
267 id="linearGradient10568"
268 xlink:href="#aigrd1"
269 inkscape:collect="always" />
270 <linearGradient
271 y2="14.2033"
272 x2="35.3912"
273 y1="32.4165"
274 x1="12.2744"
275 gradientTransform="matrix(0.705308,0.000000,0.000000,0.705308,18.02392,17.61692)"
276 gradientUnits="userSpaceOnUse"
277 id="linearGradient10570"
278 xlink:href="#aigrd2"
279 inkscape:collect="always" />
280 <linearGradient
281 y2="28.000000"
282 x2="29.000000"
283 y1="14.625000"
284 x1="21.125000"
285 gradientTransform="matrix(0.717302,0.000000,0.000000,0.717302,17.73603,18.06909)"
286 gradientUnits="userSpaceOnUse"
287 id="linearGradient10572"
288 xlink:href="#linearGradient4236"
289 inkscape:collect="always" />
290 <linearGradient
291 y2="28.000000"
292 x2="29.000000"
293 y1="14.625000"
294 x1="21.125000"
295 gradientTransform="matrix(0.717302,0.000000,0.000000,0.717302,17.73603,18.06909)"
296 gradientUnits="userSpaceOnUse"
297 id="linearGradient10574"
298 xlink:href="#linearGradient4236"
299 inkscape:collect="always" />
300 <linearGradient
301 y2="54.698483"
302 x2="48.798885"
303 y1="3.6100161"
304 x1="10.501720"
305 gradientTransform="matrix(0.573842,0.000000,0.000000,0.573842,20.97995,19.56347)"
306 gradientUnits="userSpaceOnUse"
307 id="linearGradient10576"
308 xlink:href="#linearGradient6036"
309 inkscape:collect="always" />
310 <linearGradient
311 y2="18.366575"
312 x2="17.742729"
313 y1="31.494707"
314 x1="28.702885"
315 gradientUnits="userSpaceOnUse"
316 id="linearGradient10578"
317 xlink:href="#linearGradient6028"
318 inkscape:collect="always" />
319 <radialGradient
320 r="21.333334"
321 fy="27.569166"
322 fx="37.751469"
323 cy="27.569166"
324 cx="37.751469"
325 gradientTransform="matrix(0.441746,0.498655,-0.407098,0.360624,32.00755,10.21308)"
326 gradientUnits="userSpaceOnUse"
327 id="radialGradient10580"
328 xlink:href="#linearGradient3394"
329 inkscape:collect="always" />
330 </defs>
331 <sodipodi:namedview
332 fill="#a40000"
333 id="base"
334 pagecolor="#ffffff"
335 bordercolor="#666666"
336 borderopacity="0.26666667"
337 inkscape:pageopacity="0.0"
338 inkscape:pageshadow="2"
339 inkscape:zoom="1"
340 inkscape:cx="-127.33612"
341 inkscape:cy="17.441956"
342 inkscape:current-layer="layer1"
343 showgrid="false"
344 inkscape:grid-bbox="true"
345 inkscape:document-units="px"
346 inkscape:showpageshadow="false"
347 inkscape:window-width="872"
348 inkscape:window-height="688"
349 inkscape:window-x="213"
350 inkscape:window-y="160" />
351 <metadata
352 id="metadata4">
353 <rdf:RDF>
354 <cc:Work
355 rdf:about="">
356 <dc:format>image/svg+xml</dc:format>
357 <dc:type
358 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
359 <dc:title>System - Installer</dc:title>
360 <dc:creator>
361 <cc:Agent>
362 <dc:title>jakub Steiner</dc:title>
363 </cc:Agent>
364 </dc:creator>
365 <dc:source>http://jimmac.musichall.cz</dc:source>
366 <cc:license
367 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
368 </cc:Work>
369 <cc:License
370 rdf:about="http://creativecommons.org/licenses/publicdomain/">
371 <cc:permits
372 rdf:resource="http://creativecommons.org/ns#Reproduction" />
373 <cc:permits
374 rdf:resource="http://creativecommons.org/ns#Distribution" />
375 <cc:permits
376 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
377 </cc:License>
378 </rdf:RDF>
379 </metadata>
380 <g
381 id="layer1"
382 inkscape:label="Layer 1"
383 inkscape:groupmode="layer">
384 <path
385 sodipodi:nodetypes="ccccc"
386 id="path7822"
387 d="M 7.0663522,9.8326324 L 11.142857,5.5714286 L 34.714286,5.5714286 L 39.034663,9.9336477 L 7.0663522,9.8326324 z "
388 style="opacity:1.0000000;color:#000000;fill:#6b6c69;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#606060;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
389 <g
390 id="g5022"
391 transform="matrix(2.01828e-2,0,0,2.086758e-2,41.09416,37.29644)">
392 <rect
393 y="-150.69685"
394 x="-1559.2523"
395 height="478.35718"
396 width="1339.6335"
397 id="rect4173"
398 style="opacity:0.40206185;color:black;fill:url(#linearGradient5027);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
399 <path
400 sodipodi:nodetypes="cccc"
401 id="path5058"
402 d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
403 style="opacity:0.40206185;color:black;fill:url(#radialGradient5029);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
404 <path
405 style="opacity:0.40206185;color:black;fill:url(#radialGradient5031);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
406 d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
407 id="path5018"
408 sodipodi:nodetypes="cccc" />
409 </g>
410 <rect
411 ry="1.4285715"
412 rx="1.4285721"
413 y="9.4285717"
414 x="6.5756874"
415 height="31.142857"
416 width="32.848644"
417 id="rect6910"
418 style="opacity:1.0000000;color:#000000;fill:url(#linearGradient7676);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#606060;stroke-width:1.0000001;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
419 <path
420 sodipodi:nodetypes="cccccc"
421 id="rect7826"
422 d="M 38.857143,22.756128 L 38.857143,39.184701 C 38.857143,39.659558 38.494011,40.041844 38.042945,40.041844 L 15.874474,40.041844 L 15.923863,22.756128 C 15.923863,22.756128 38.857143,22.756128 38.857143,22.756128 z "
423 style="color:#000000;fill:#a40000;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:1.0000000 1.0000000 ;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
424 <path
425 sodipodi:nodetypes="cc"
426 id="path7824"
427 d="M 15.379549,11.285714 L 15.379549,39.285714"
428 style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#606060;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:1.0000000 1.0000000 ;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
429 <path
430 style="color:#000000;fill:#f0f0f0;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:1.0000000 1.0000000 ;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
431 d="M 38.857143,22.613273 L 38.857143,11.470414 C 38.857143,10.995557 38.494011,10.613271 38.042945,10.613271 L 15.874474,10.613271 L 15.923863,22.613273 C 15.923863,22.613273 38.857143,22.613273 38.857143,22.613273 z "
432 id="path10582"
433 sodipodi:nodetypes="cccccc" />
434 <path
435 sodipodi:nodetypes="ccccccccs"
436 id="rect7829"
437 d="M 11.512932,6.5274685 C 11.512932,6.5274685 34.285047,6.5274685 34.285047,6.5274685 C 34.285047,6.5274685 38.542046,10.784467 38.542046,10.784467 L 38.542046,39.215524 C 38.542046,39.503290 38.310378,39.734958 38.022612,39.734958 L 7.9773979,39.734958 C 7.6896315,39.734958 7.4579639,39.503290 7.4579639,39.215524 L 7.4579639,10.784467 C 7.4579639,10.784467 11.512932,6.5274685 11.512932,6.5274685 z "
438 style="opacity:0.62566847;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient7840);stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
439 <g
440 transform="translate(-0.999997,-0.285714)"
441 id="g10554">
442 <path
443 transform="matrix(0.550240,0.000000,0.000000,0.550240,19.89726,20.62321)"
444 d="M 47.275139 37.595428 A 22.728432 7.5761442 0 1 1 1.8182755,37.595428 A 22.728432 7.5761442 0 1 1 47.275139 37.595428 z"
445 sodipodi:ry="7.5761442"
446 sodipodi:rx="22.728432"
447 sodipodi:cy="37.595428"
448 sodipodi:cx="24.546707"
449 id="path10170"
450 style="opacity:0.62566847;color:#000000;fill:url(#radialGradient10566);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:1.0000000 1.0000000 ;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
451 sodipodi:type="arc" />
452 <g
453 id="g10156"
454 transform="translate(-1.642857,-2.642857)">
455 <path
456 style="fill:url(#linearGradient10568);fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
457 d="M 34.951289,21.954475 C 28.324780,21.954475 22.996247,27.283008 22.996247,33.909517 C 22.996247,40.536026 28.324780,45.864559 34.951289,45.864559 C 41.577799,45.864559 46.906332,40.536026 46.906332,33.909517 C 46.906332,27.283008 41.577799,21.954475 34.951289,21.954475 L 34.951289,21.954475 z M 34.951289,36.778727 C 33.380055,36.778727 32.082079,35.480751 32.082079,33.909517 C 32.082079,32.338283 33.380055,31.040307 34.951289,31.040307 C 36.522523,31.040307 37.820499,32.338283 37.820499,33.909517 C 37.820499,35.480751 36.522523,36.778727 34.951289,36.778727 z "
458 id="path3040" />
459 <path
460 style="fill:url(#linearGradient10570);fill-rule:nonzero;stroke:#808080;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
461 d="M 34.951305,21.566644 C 28.109819,21.566644 22.608417,27.068045 22.608417,33.909532 C 22.608417,40.751018 28.109819,46.252419 34.951305,46.252419 C 41.792792,46.252419 47.294193,40.751018 47.294193,33.909532 C 47.294193,27.068045 41.792792,21.566644 34.951305,21.566644 L 34.951305,21.566644 z M 34.951305,36.871824 C 33.329097,36.871824 31.989012,35.531740 31.989012,33.909532 C 31.989012,32.287324 33.329097,30.947239 34.951305,30.947239 C 36.573513,30.947239 37.913598,32.287324 37.913598,33.909532 C 37.913598,35.531740 36.573513,36.871824 34.951305,36.871824 z "
462 id="path3049" />
463 <path
464 style="opacity:0.10999996;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
465 d="M 34.951289,28.111323 C 31.713337,28.111323 29.153095,30.746866 29.153095,33.909517 C 29.153095,37.147471 31.788638,39.707712 34.951289,39.707712 C 38.189242,39.707712 40.749484,37.072169 40.749484,33.909517 C 40.749484,30.671564 38.113940,28.111323 34.951289,28.111323 L 34.951289,28.111323 z M 34.951289,37.072169 C 33.219361,37.072169 31.788638,35.641446 31.788638,33.909517 C 31.788638,32.177589 33.219361,30.746866 34.951289,30.746866 C 36.683217,30.746866 38.113940,32.177589 38.113940,33.909517 C 38.113940,35.641446 36.683217,37.072169 34.951289,37.072169 z "
466 id="path3051" />
467 <path
468 id="path3916"
469 d="M 38.150519,22.816711 L 36.086643,30.847436 C 36.732045,31.019312 37.248181,31.418679 37.598790,31.971330 L 44.709966,27.639233 C 43.255134,25.269429 40.920193,23.525895 38.150519,22.816711 z "
470 style="fill:url(#linearGradient10572);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
471 <path
472 style="fill:url(#linearGradient10574);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
473 d="M 30.911911,44.678269 L 33.629199,36.844465 C 33.000117,36.620097 32.518571,36.179639 32.214597,35.600027 L 24.771257,39.332667 C 26.026282,41.814082 28.209936,43.743724 30.911911,44.678269 z "
474 id="path4214" />
475 <path
476 sodipodi:nodetypes="cccccc"
477 id="path5264"
478 d="M 34.951287,22.548803 C 28.654207,22.548803 23.590575,27.612435 23.590575,33.909515 C 23.590575,40.206596 28.654207,45.270227 34.951287,45.270227 C 41.248368,45.270227 46.311999,40.206596 46.311999,33.909515 C 46.311999,27.612435 41.248368,22.548803 34.951287,22.548803 L 34.951287,22.548803 z "
479 style="opacity:0.54644811;fill:none;fill-rule:nonzero;stroke:url(#linearGradient10576);stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
480 <path
481 transform="matrix(0.573842,0.000000,0.000000,0.573842,21.03068,19.61419)"
482 d="M 30.405591 24.930641 A 6.0987959 6.0987959 0 1 1 18.207999,24.930641 A 6.0987959 6.0987959 0 1 1 30.405591 24.930641 z"
483 sodipodi:ry="6.0987959"
484 sodipodi:rx="6.0987959"
485 sodipodi:cy="24.930641"
486 sodipodi:cx="24.306795"
487 id="path6026"
488 style="opacity:0.67213112;color:#000000;fill:none;fill-opacity:0.31638417;fill-rule:nonzero;stroke:url(#linearGradient10578);stroke-width:1.6215941;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
489 sodipodi:type="arc" />
490 <path
491 id="path3390"
492 d="M 34.951289,23.065643 C 28.940684,23.065643 24.107415,27.898912 24.107415,33.909517 C 24.107415,39.920122 28.940684,44.753391 34.951289,44.753391 C 40.961895,44.753391 45.795164,39.920122 45.795164,33.909517 C 45.795164,27.898912 40.961895,23.065643 34.951289,23.065643 L 34.951289,23.065643 z M 34.951289,36.512047 C 33.526094,36.512047 32.348759,35.334712 32.348759,33.909517 C 32.348759,32.484322 33.526094,31.306987 34.951289,31.306987 C 36.376484,31.306987 37.553819,32.484322 37.553819,33.909517 C 37.553819,35.334712 36.376484,36.512047 34.951289,36.512047 z "
493 style="opacity:0.11428566;fill:url(#radialGradient10580);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
494 </g>
495 </g>
496 </g>
497</svg>
diff --git a/utils/rbutilqt/icons/system-search.svg b/utils/rbutilqt/icons/system-search.svg
new file mode 100644
index 0000000000..1a4c1cd776
--- /dev/null
+++ b/utils/rbutilqt/icons/system-search.svg
@@ -0,0 +1,313 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 sodipodi:docname="system-search.svg"
13 sodipodi:docbase="/home/tigert/cvs/freedesktop.org/tango-icon-theme/scalable/actions"
14 inkscape:version="0.46"
15 sodipodi:version="0.32"
16 id="svg11300"
17 height="48px"
18 width="48px"
19 inkscape:output_extension="org.inkscape.output.svg.inkscape">
20 <defs
21 id="defs3">
22 <inkscape:perspective
23 sodipodi:type="inkscape:persp3d"
24 inkscape:vp_x="0 : 24 : 1"
25 inkscape:vp_y="0 : 1000 : 0"
26 inkscape:vp_z="48 : 24 : 1"
27 inkscape:persp3d-origin="24 : 16 : 1"
28 id="perspective47" />
29 <linearGradient
30 id="linearGradient2846">
31 <stop
32 id="stop2848"
33 offset="0.0000000"
34 style="stop-color:#8a8a8a;stop-opacity:1.0000000;" />
35 <stop
36 id="stop2850"
37 offset="1.0000000"
38 style="stop-color:#484848;stop-opacity:1.0000000;" />
39 </linearGradient>
40 <linearGradient
41 id="linearGradient2366">
42 <stop
43 id="stop2368"
44 offset="0"
45 style="stop-color:#ffffff;stop-opacity:1;" />
46 <stop
47 style="stop-color:#ffffff;stop-opacity:0.21904762;"
48 offset="0.50000000"
49 id="stop2374" />
50 <stop
51 id="stop2370"
52 offset="1.0000000"
53 style="stop-color:#ffffff;stop-opacity:1.0000000;" />
54 </linearGradient>
55 <linearGradient
56 inkscape:collect="always"
57 id="linearGradient4487">
58 <stop
59 style="stop-color:#ffffff;stop-opacity:1;"
60 offset="0"
61 id="stop4489" />
62 <stop
63 style="stop-color:#ffffff;stop-opacity:0;"
64 offset="1"
65 id="stop4491" />
66 </linearGradient>
67 <linearGradient
68 inkscape:collect="always"
69 id="linearGradient4477">
70 <stop
71 style="stop-color:#000000;stop-opacity:1;"
72 offset="0"
73 id="stop4479" />
74 <stop
75 style="stop-color:#000000;stop-opacity:0;"
76 offset="1"
77 id="stop4481" />
78 </linearGradient>
79 <linearGradient
80 id="linearGradient4467">
81 <stop
82 style="stop-color:#ffffff;stop-opacity:1;"
83 offset="0"
84 id="stop4469" />
85 <stop
86 style="stop-color:#ffffff;stop-opacity:0.24761905;"
87 offset="1.0000000"
88 id="stop4471" />
89 </linearGradient>
90 <linearGradient
91 id="linearGradient4454">
92 <stop
93 style="stop-color:#729fcf;stop-opacity:0.20784314;"
94 offset="0.0000000"
95 id="stop4456" />
96 <stop
97 style="stop-color:#729fcf;stop-opacity:0.67619050;"
98 offset="1.0000000"
99 id="stop4458" />
100 </linearGradient>
101 <linearGradient
102 id="linearGradient4440">
103 <stop
104 style="stop-color:#7d7d7d;stop-opacity:1;"
105 offset="0"
106 id="stop4442" />
107 <stop
108 id="stop4448"
109 offset="0.50000000"
110 style="stop-color:#b1b1b1;stop-opacity:1.0000000;" />
111 <stop
112 style="stop-color:#686868;stop-opacity:1.0000000;"
113 offset="1.0000000"
114 id="stop4444" />
115 </linearGradient>
116 <linearGradient
117 inkscape:collect="always"
118 xlink:href="#linearGradient4440"
119 id="linearGradient4446"
120 x1="30.656250"
121 y1="34.000000"
122 x2="33.218750"
123 y2="31.062500"
124 gradientUnits="userSpaceOnUse"
125 gradientTransform="matrix(1.334593,0.000000,0.000000,1.291292,-6.973842,-7.460658)" />
126 <radialGradient
127 inkscape:collect="always"
128 xlink:href="#linearGradient4454"
129 id="radialGradient4460"
130 cx="18.240929"
131 cy="21.817987"
132 fx="18.240929"
133 fy="21.817987"
134 r="8.3085051"
135 gradientUnits="userSpaceOnUse" />
136 <radialGradient
137 inkscape:collect="always"
138 xlink:href="#linearGradient4467"
139 id="radialGradient4473"
140 cx="15.414371"
141 cy="13.078408"
142 fx="15.414371"
143 fy="13.078408"
144 r="6.6562500"
145 gradientTransform="matrix(2.592963,-7.746900e-24,-5.714443e-24,2.252104,-25.05975,-18.94100)"
146 gradientUnits="userSpaceOnUse" />
147 <radialGradient
148 inkscape:collect="always"
149 xlink:href="#linearGradient4487"
150 id="radialGradient4493"
151 cx="24.130018"
152 cy="37.967922"
153 fx="24.130018"
154 fy="37.967922"
155 r="16.528622"
156 gradientTransform="matrix(1.000000,0.000000,0.000000,0.237968,3.152859e-15,28.93278)"
157 gradientUnits="userSpaceOnUse" />
158 <linearGradient
159 gradientUnits="userSpaceOnUse"
160 y2="25.743469"
161 x2="17.500893"
162 y1="13.602121"
163 x1="18.292673"
164 id="linearGradient2372"
165 xlink:href="#linearGradient2366"
166 inkscape:collect="always" />
167 <radialGradient
168 r="16.528622"
169 fy="37.967922"
170 fx="24.130018"
171 cy="37.967922"
172 cx="24.130018"
173 gradientTransform="matrix(1.000000,0.000000,0.000000,0.237968,-2.471981e-16,28.93278)"
174 gradientUnits="userSpaceOnUse"
175 id="radialGradient2842"
176 xlink:href="#linearGradient4477"
177 inkscape:collect="always" />
178 <linearGradient
179 gradientUnits="userSpaceOnUse"
180 y2="30.557772"
181 x2="31.335964"
182 y1="26.580296"
183 x1="27.366341"
184 id="linearGradient2852"
185 xlink:href="#linearGradient2846"
186 inkscape:collect="always" />
187 </defs>
188 <sodipodi:namedview
189 stroke="#3465a4"
190 inkscape:window-y="94"
191 inkscape:window-x="239"
192 inkscape:window-height="754"
193 inkscape:window-width="691"
194 inkscape:showpageshadow="false"
195 inkscape:document-units="px"
196 inkscape:grid-bbox="true"
197 showgrid="false"
198 inkscape:current-layer="layer1"
199 inkscape:cy="23.07052"
200 inkscape:cx="9.502648"
201 inkscape:zoom="11.313708"
202 inkscape:pageshadow="2"
203 inkscape:pageopacity="0.0"
204 borderopacity="0.25490196"
205 bordercolor="#666666"
206 pagecolor="#ffffff"
207 id="base"
208 fill="#729fcf" />
209 <metadata
210 id="metadata4">
211 <rdf:RDF>
212 <cc:Work
213 rdf:about="">
214 <dc:format>image/svg+xml</dc:format>
215 <dc:type
216 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
217 <dc:creator>
218 <cc:Agent>
219 <dc:title>Jakub Steiner</dc:title>
220 </cc:Agent>
221 </dc:creator>
222 <dc:source>http://jimmac.musichall.cz</dc:source>
223 <cc:license
224 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
225 </cc:Work>
226 <cc:License
227 rdf:about="http://creativecommons.org/licenses/publicdomain/">
228 <cc:permits
229 rdf:resource="http://creativecommons.org/ns#Reproduction" />
230 <cc:permits
231 rdf:resource="http://creativecommons.org/ns#Distribution" />
232 <cc:permits
233 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
234 </cc:License>
235 </rdf:RDF>
236 </metadata>
237 <g
238 inkscape:groupmode="layer"
239 inkscape:label="Layer 1"
240 id="layer1">
241 <g
242 id="g1772">
243 <path
244 sodipodi:type="arc"
245 style="opacity:0.17112298;color:#000000;fill:url(#radialGradient2842);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;"
246 id="path4475"
247 sodipodi:cx="24.130018"
248 sodipodi:cy="37.967922"
249 sodipodi:rx="16.528622"
250 sodipodi:ry="3.9332814"
251 d="M 40.658640 37.967922 A 16.528622 3.9332814 0 1 1 7.6013966,37.967922 A 16.528622 3.9332814 0 1 1 40.658640 37.967922 z"
252 transform="matrix(1.446431,0.000000,0.000000,1.519990,-10.97453,-17.75168)" />
253 <path
254 sodipodi:nodetypes="csscccscccscczzzz"
255 id="path2844"
256 d="M 18.627569,3.1435548 C 10.488439,3.1435548 3.8827682,9.7492259 3.8827682,17.888356 C 3.8827682,26.027486 10.488439,32.633158 18.627569,32.633158 C 22.107124,32.633158 25.178570,31.248765 27.701292,29.230511 C 27.495915,30.237392 27.623257,31.265879 28.457436,31.990436 L 39.421520,41.517846 C 40.654936,42.589175 42.508982,42.448806 43.580310,41.215389 C 44.651638,39.981971 44.511269,38.127927 43.277853,37.056599 L 32.313769,27.529188 C 31.642242,26.945909 30.820891,26.773219 30.007531,26.886466 C 31.994231,24.374044 33.372370,21.337663 33.372370,17.888356 C 33.372370,9.7492259 26.766699,3.1435548 18.627569,3.1435548 z M 18.551954,4.3697381 C 26.191413,4.3697381 31.843729,9.1586886 31.843729,17.661513 C 31.843729,26.336626 26.027039,30.953288 18.551954,30.953288 C 11.249005,30.953288 5.2601806,25.475196 5.2601806,17.661513 C 5.2601806,9.6774061 11.084819,4.3697380 18.551954,4.3697381 z "
257 style="opacity:1.0000000;color:#000000;fill:#dcdcdc;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2852);stroke-width:2.0000010;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;" />
258 <path
259 style="opacity:1.0000000;color:#000000;fill:#dcdcdc;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000004;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;"
260 d="M 18.602905,3.0803551 C 10.437465,3.0803551 3.8104408,9.7073791 3.8104408,17.872819 C 3.8104408,26.038259 10.437465,32.665283 18.602905,32.665283 C 22.093708,32.665283 25.175082,31.276416 27.705960,29.251638 C 27.499919,30.261774 27.627672,31.293585 28.464547,32.020484 L 39.464073,41.578691 C 40.701476,42.653483 42.561515,42.512661 43.636306,41.275256 C 44.711097,40.037852 44.570274,38.177814 43.332871,37.103023 L 32.333346,27.544815 C 31.659648,26.959651 30.835642,26.786402 30.019653,26.900016 C 32.012775,24.379472 33.395369,21.333276 33.395369,17.872819 C 33.395369,9.7073791 26.768345,3.0803551 18.602905,3.0803551 z M 18.527046,6.2664243 C 24.808154,6.2664245 29.905864,11.364135 29.905864,17.645243 C 29.905864,23.926351 24.808154,29.024061 18.527046,29.024061 C 12.245938,29.024061 7.1482276,23.926351 7.1482276,17.645243 C 7.1482278,11.364135 12.245938,6.2664243 18.527046,6.2664243 z "
261 id="path4430" />
262 <path
263 style="opacity:1.0000000;color:#000000;fill:url(#linearGradient4446);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;"
264 d="M 39.507004,41.577690 C 39.028332,39.304503 40.904334,36.766268 43.091057,36.789315 C 43.091057,36.789315 32.330690,27.531204 32.330690,27.531204 C 29.385899,27.474498 28.061188,29.803820 28.553876,32.131126 L 39.507004,41.577690 z "
265 id="path4438"
266 sodipodi:nodetypes="ccccc" />
267 <path
268 sodipodi:type="arc"
269 style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2372);stroke-width:0.80273360;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;"
270 id="path4450"
271 sodipodi:cx="17.500893"
272 sodipodi:cy="18.920233"
273 sodipodi:rx="11.048544"
274 sodipodi:ry="11.048544"
275 d="M 28.549437 18.920233 A 11.048544 11.048544 0 1 1 6.4523487,18.920233 A 11.048544 11.048544 0 1 1 28.549437 18.920233 z"
276 transform="matrix(1.245743,0.000000,0.000000,1.245743,-3.425346,-6.177033)" />
277 <path
278 transform="matrix(0.497764,0.000000,0.000000,0.609621,8.973526,15.61929)"
279 d="M 40.658640 37.967922 A 16.528622 3.9332814 0 1 1 7.6013966,37.967922 A 16.528622 3.9332814 0 1 1 40.658640 37.967922 z"
280 sodipodi:ry="3.9332814"
281 sodipodi:rx="16.528622"
282 sodipodi:cy="37.967922"
283 sodipodi:cx="24.130018"
284 id="path4485"
285 style="opacity:1.0000000;color:#000000;fill:url(#radialGradient4493);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;"
286 sodipodi:type="arc" />
287 <rect
288 style="opacity:0.43315509;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000311;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;"
289 id="rect4495"
290 width="19.048439"
291 height="4.4404783"
292 x="40.373337"
293 y="0.14086054"
294 rx="2.1366608"
295 ry="1.8879365"
296 transform="matrix(0.752986,0.658037,-0.648902,0.760872,0.000000,0.000000)" />
297 <path
298 sodipodi:type="arc"
299 style="color:#000000;fill:url(#radialGradient4460);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#3063a3;stroke-width:0.71499395;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10.000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;"
300 id="path4452"
301 sodipodi:cx="17.589281"
302 sodipodi:cy="18.478292"
303 sodipodi:rx="8.3085051"
304 sodipodi:ry="8.3085051"
305 d="M 25.897786 18.478292 A 8.3085051 8.3085051 0 1 1 9.2807760,18.478292 A 8.3085051 8.3085051 0 1 1 25.897786 18.478292 z"
306 transform="matrix(1.398614,0.000000,0.000000,1.398614,-6.224338,-8.298958)" />
307 <path
308 style="opacity:0.83422458;color:#000000;fill:url(#radialGradient4473);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;"
309 d="M 18.156915,7.3966938 C 12.949325,7.3966938 8.7323681,11.613651 8.7323681,16.821241 C 8.7323681,18.325216 9.1526753,19.709014 9.7795400,20.971144 C 11.031920,21.432757 12.362297,21.746827 13.774307,21.746827 C 19.945262,21.746827 24.873589,16.885190 25.254413,10.809698 C 23.523449,8.7641668 21.044374,7.3966938 18.156915,7.3966938 z "
310 id="path4462" />
311 </g>
312 </g>
313</svg>
diff --git a/utils/rbutilqt/icons/user-trash-full.svg b/utils/rbutilqt/icons/user-trash-full.svg
new file mode 100644
index 0000000000..393285f545
--- /dev/null
+++ b/utils/rbutilqt/icons/user-trash-full.svg
@@ -0,0 +1,728 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:i="&amp;ns_ai;"
5 xmlns:dc="http://purl.org/dc/elements/1.1/"
6 xmlns:cc="http://creativecommons.org/ns#"
7 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8 xmlns:svg="http://www.w3.org/2000/svg"
9 xmlns="http://www.w3.org/2000/svg"
10 xmlns:xlink="http://www.w3.org/1999/xlink"
11 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
12 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
13 width="48px"
14 height="48px"
15 id="svg57"
16 sodipodi:version="0.32"
17 inkscape:version="0.46"
18 sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/status"
19 sodipodi:docname="user-trash-full.svg"
20 inkscape:output_extension="org.inkscape.output.svg.inkscape">
21 <defs
22 id="defs3">
23 <inkscape:perspective
24 sodipodi:type="inkscape:persp3d"
25 inkscape:vp_x="0 : 24 : 1"
26 inkscape:vp_y="0 : 1000 : 0"
27 inkscape:vp_z="48 : 24 : 1"
28 inkscape:persp3d-origin="24 : 16 : 1"
29 id="perspective120" />
30 <radialGradient
31 inkscape:collect="always"
32 xlink:href="#linearGradient5060"
33 id="radialGradient6719"
34 gradientUnits="userSpaceOnUse"
35 gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
36 cx="605.71429"
37 cy="486.64789"
38 fx="605.71429"
39 fy="486.64789"
40 r="117.14286" />
41 <linearGradient
42 inkscape:collect="always"
43 id="linearGradient5060">
44 <stop
45 style="stop-color:black;stop-opacity:1;"
46 offset="0"
47 id="stop5062" />
48 <stop
49 style="stop-color:black;stop-opacity:0;"
50 offset="1"
51 id="stop5064" />
52 </linearGradient>
53 <radialGradient
54 inkscape:collect="always"
55 xlink:href="#linearGradient5060"
56 id="radialGradient6717"
57 gradientUnits="userSpaceOnUse"
58 gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
59 cx="605.71429"
60 cy="486.64789"
61 fx="605.71429"
62 fy="486.64789"
63 r="117.14286" />
64 <linearGradient
65 id="linearGradient5048">
66 <stop
67 style="stop-color:black;stop-opacity:0;"
68 offset="0"
69 id="stop5050" />
70 <stop
71 id="stop5056"
72 offset="0.5"
73 style="stop-color:black;stop-opacity:1;" />
74 <stop
75 style="stop-color:black;stop-opacity:0;"
76 offset="1"
77 id="stop5052" />
78 </linearGradient>
79 <linearGradient
80 inkscape:collect="always"
81 xlink:href="#linearGradient5048"
82 id="linearGradient6715"
83 gradientUnits="userSpaceOnUse"
84 gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
85 x1="302.85715"
86 y1="366.64789"
87 x2="302.85715"
88 y2="609.50507" />
89 <linearGradient
90 id="linearGradient381"
91 inkscape:collect="always">
92 <stop
93 id="stop382"
94 offset="0"
95 style="stop-color:#ffffff;stop-opacity:1;" />
96 <stop
97 id="stop383"
98 offset="1"
99 style="stop-color:#ffffff;stop-opacity:0;" />
100 </linearGradient>
101 <linearGradient
102 id="linearGradient368">
103 <stop
104 style="stop-color:#ffffff;stop-opacity:0.10309278;"
105 offset="0.0000000"
106 id="stop369" />
107 <stop
108 style="stop-color:#ffffff;stop-opacity:0.0000000;"
109 offset="1.0000000"
110 id="stop372" />
111 </linearGradient>
112 <linearGradient
113 id="linearGradient1065">
114 <stop
115 style="stop-color:#b5c051;stop-opacity:1.0000000;"
116 offset="0.0000000"
117 id="stop1066" />
118 <stop
119 style="stop-color:#858e3f;stop-opacity:1.0000000;"
120 offset="1.0000000"
121 id="stop1067" />
122 </linearGradient>
123 <linearGradient
124 style="fill-rule:nonzero;"
125 y2="72.608902"
126 x2="192.38570"
127 y1="72.608902"
128 x1="78.245598"
129 gradientUnits="userSpaceOnUse"
130 id="linearGradient641">
131 <stop
132 id="stop642"
133 style="stop-color:#f9feff;stop-opacity:1.0000000;"
134 offset="0.0000000" />
135 <stop
136 id="stop643"
137 style="stop-color:#afb4b6;stop-opacity:1.0000000;"
138 offset="1.0000000" />
139 </linearGradient>
140 <linearGradient
141 y2="137.97153"
142 x2="136.98560"
143 y1="67.364906"
144 x1="81.307533"
145 gradientTransform="scale(1.244363,0.803624)"
146 gradientUnits="userSpaceOnUse"
147 id="linearGradient234"
148 xlink:href="#linearGradient177"
149 inkscape:collect="always" />
150 <linearGradient
151 id="linearGradient513">
152 <stop
153 id="stop514"
154 offset="0.0000000"
155 style="stop-color:#696969;stop-opacity:1.0000000;" />
156 <stop
157 id="stop515"
158 offset="1.0000000"
159 style="stop-color:#ffffff;stop-opacity:1.0000000;" />
160 </linearGradient>
161 <linearGradient
162 id="linearGradient508">
163 <stop
164 id="stop509"
165 offset="0.0000000"
166 style="stop-color:#b0b0b0;stop-opacity:1.0000000;" />
167 <stop
168 id="stop510"
169 offset="1.0000000"
170 style="stop-color:#b0b0b0;stop-opacity:1.0000000;" />
171 </linearGradient>
172 <linearGradient
173 style="fill-rule:nonzero;"
174 y2="72.608902"
175 x2="192.38570"
176 y1="72.608902"
177 x1="78.245598"
178 gradientUnits="userSpaceOnUse"
179 id="linearGradient477">
180 <stop
181 id="stop478"
182 style="stop-color:#e4e9ea;stop-opacity:1.0000000;"
183 offset="0.0000000" />
184 <stop
185 id="stop479"
186 style="stop-color:#85898A;fill-rule:nonzero;"
187 offset="1" />
188 </linearGradient>
189 <linearGradient
190 id="linearGradient454">
191 <stop
192 id="stop455"
193 offset="0.0000000"
194 style="stop-color:#ffffff;stop-opacity:1.0000000;" />
195 <stop
196 id="stop457"
197 offset="0.50000000"
198 style="stop-color:#bebebe;stop-opacity:1.0000000;" />
199 <stop
200 id="stop456"
201 offset="1.0000000"
202 style="stop-color:#b0b0b0;stop-opacity:1.0000000;" />
203 </linearGradient>
204 <linearGradient
205 id="linearGradient177">
206 <stop
207 id="stop178"
208 offset="0.0000000"
209 style="stop-color:#ffffff;stop-opacity:1.0000000;" />
210 <stop
211 id="stop179"
212 offset="1.0000000"
213 style="stop-color:#b0b0b0;stop-opacity:1.0000000;" />
214 </linearGradient>
215 <linearGradient
216 id="linearGradient172">
217 <stop
218 id="stop173"
219 offset="0.0000000"
220 style="stop-color:#616c08;stop-opacity:1.0000000;" />
221 <stop
222 id="stop174"
223 offset="1.0000000"
224 style="stop-color:#495106;stop-opacity:1.0000000;" />
225 </linearGradient>
226 <linearGradient
227 id="linearGradient161">
228 <stop
229 id="stop162"
230 offset="0.0000000"
231 style="stop-color:#575955;stop-opacity:1.0000000;" />
232 <stop
233 id="stop163"
234 offset="1.0000000"
235 style="stop-color:#7c7e79;stop-opacity:1.0000000;" />
236 </linearGradient>
237 <linearGradient
238 id="linearGradient157">
239 <stop
240 id="stop158"
241 offset="0.0000000"
242 style="stop-color:#babdb6;stop-opacity:1.0000000;" />
243 <stop
244 id="stop159"
245 offset="1.0000000"
246 style="stop-color:#f1f5ec;stop-opacity:1.0000000;" />
247 </linearGradient>
248 <linearGradient
249 id="linearGradient149"
250 inkscape:collect="always">
251 <stop
252 id="stop150"
253 offset="0"
254 style="stop-color:#000000;stop-opacity:1;" />
255 <stop
256 id="stop151"
257 offset="1"
258 style="stop-color:#000000;stop-opacity:0;" />
259 </linearGradient>
260 <linearGradient
261 id="linearGradient1869">
262 <stop
263 style="stop-color:#eff3f4;stop-opacity:1.0000000;"
264 offset="0.0000000"
265 id="stop1870" />
266 <stop
267 style="stop-color:#939596;stop-opacity:1.0000000;"
268 offset="1.0000000"
269 id="stop1871" />
270 </linearGradient>
271 <linearGradient
272 inkscape:collect="always"
273 xlink:href="#linearGradient1869"
274 id="linearGradient1872"
275 gradientTransform="matrix(1.464893,0.000000,0.000000,0.475906,30.56501,-34.34268)"
276 x1="-4.6375198"
277 y1="104.38752"
278 x2="-4.5239210"
279 y2="110.61378"
280 gradientUnits="userSpaceOnUse" />
281 <linearGradient
282 gradientUnits="userSpaceOnUse"
283 y2="69.460503"
284 x2="7.5291119"
285 y1="27.376621"
286 x1="7.3738608"
287 gradientTransform="matrix(3.495016,0.000000,0.000000,0.344323,-2.972087,-3.408148e-2)"
288 id="linearGradient152"
289 xlink:href="#linearGradient149"
290 inkscape:collect="always" />
291 <linearGradient
292 gradientUnits="userSpaceOnUse"
293 y2="6.8897981"
294 x2="60.685901"
295 y1="6.8897981"
296 x1="55.208272"
297 gradientTransform="matrix(0.772488,0.000000,0.000000,1.557840,-2.795310,-0.166664)"
298 id="linearGradient160"
299 xlink:href="#linearGradient157"
300 inkscape:collect="always" />
301 <linearGradient
302 gradientUnits="userSpaceOnUse"
303 y2="21.169637"
304 x2="19.737664"
305 y1="21.169637"
306 x1="2.9325605"
307 gradientTransform="matrix(2.374946,0.000000,0.000000,0.506711,-2.795310,-0.166664)"
308 id="linearGradient164"
309 xlink:href="#linearGradient161"
310 inkscape:collect="always" />
311 <radialGradient
312 r="5.6434927"
313 fy="20.452780"
314 fx="16.280994"
315 cy="20.452780"
316 cx="16.280994"
317 gradientTransform="matrix(2.202254,0.000000,0.000000,0.574568,-13.83631,0.652472)"
318 gradientUnits="userSpaceOnUse"
319 id="radialGradient605"
320 xlink:href="#linearGradient477"
321 inkscape:collect="always" />
322 <linearGradient
323 y2="14.748880"
324 x2="18.086929"
325 y1="11.165159"
326 x1="14.248631"
327 gradientTransform="matrix(1.399756,0.000000,0.000000,0.903977,-3.993120,0.751900)"
328 gradientUnits="userSpaceOnUse"
329 id="linearGradient606"
330 xlink:href="#linearGradient454"
331 inkscape:collect="always" />
332 <linearGradient
333 y2="122.61145"
334 x2="132.98843"
335 y1="116.66409"
336 x1="128.35213"
337 gradientTransform="scale(1.244363,0.803624)"
338 gradientUnits="userSpaceOnUse"
339 id="linearGradient607"
340 xlink:href="#linearGradient177"
341 inkscape:collect="always" />
342 <linearGradient
343 y2="14.744809"
344 x2="20.135639"
345 y1="8.7251825"
346 x1="9.9626188"
347 gradientTransform="matrix(1.399756,0.000000,0.000000,0.903977,-3.993120,0.797381)"
348 gradientUnits="userSpaceOnUse"
349 id="linearGradient608"
350 xlink:href="#linearGradient177"
351 inkscape:collect="always" />
352 <linearGradient
353 y2="10.115389"
354 x2="40.437176"
355 y1="2.3488793"
356 x1="24.162909"
357 gradientTransform="matrix(1.124876,0.000000,0.000000,1.124876,-3.993120,0.751900)"
358 gradientUnits="userSpaceOnUse"
359 id="linearGradient609"
360 xlink:href="#linearGradient477"
361 inkscape:collect="always" />
362 <linearGradient
363 y2="24.077389"
364 x2="-36.301399"
365 y1="18.817307"
366 x1="-32.400455"
367 gradientTransform="matrix(-1.449414,0.286552,-0.469381,0.965804,-2.700590,0.453616)"
368 gradientUnits="userSpaceOnUse"
369 id="linearGradient610"
370 xlink:href="#linearGradient513"
371 inkscape:collect="always" />
372 <linearGradient
373 y2="20.664473"
374 x2="45.130928"
375 y1="13.131673"
376 x1="36.155384"
377 gradientTransform="matrix(0.826490,0.763061,0.763061,-0.826490,-30.95946,-9.495656)"
378 gradientUnits="userSpaceOnUse"
379 id="linearGradient611"
380 xlink:href="#linearGradient477"
381 inkscape:collect="always" />
382 <linearGradient
383 y2="9.3615303"
384 x2="13.763388"
385 y1="14.035932"
386 x1="16.551964"
387 gradientTransform="matrix(1.399756,0.000000,0.000000,0.903977,-2.860350,0.227876)"
388 gradientUnits="userSpaceOnUse"
389 id="linearGradient612"
390 xlink:href="#linearGradient177"
391 inkscape:collect="always" />
392 <linearGradient
393 y2="14.744809"
394 x2="20.135639"
395 y1="8.7251825"
396 x1="9.9626188"
397 gradientTransform="matrix(1.027326,-0.134612,0.528454,0.536480,8.122160,4.863400)"
398 gradientUnits="userSpaceOnUse"
399 id="linearGradient613"
400 xlink:href="#linearGradient508"
401 inkscape:collect="always" />
402 <linearGradient
403 y2="137.97153"
404 x2="136.98560"
405 y1="67.364906"
406 x1="81.307533"
407 gradientTransform="scale(1.244363,0.803624)"
408 gradientUnits="userSpaceOnUse"
409 id="linearGradient632"
410 xlink:href="#linearGradient177"
411 inkscape:collect="always" />
412 <radialGradient
413 gradientUnits="userSpaceOnUse"
414 r="13.265761"
415 fy="8.9303417"
416 fx="39.147720"
417 cy="8.9303417"
418 cx="39.147720"
419 gradientTransform="matrix(0.878817,0.000000,0.000000,1.025708,1.243280,2.850095)"
420 id="radialGradient640"
421 xlink:href="#linearGradient641"
422 inkscape:collect="always" />
423 <linearGradient
424 inkscape:collect="always"
425 xlink:href="#linearGradient1065"
426 id="linearGradient1068"
427 gradientTransform="scale(1.175635,0.850604)"
428 x1="10.861447"
429 y1="33.139202"
430 x2="30.587307"
431 y2="37.720802"
432 gradientUnits="userSpaceOnUse" />
433 <linearGradient
434 gradientUnits="userSpaceOnUse"
435 y2="52.625473"
436 x2="19.672924"
437 y1="23.114082"
438 x1="19.347122"
439 gradientTransform="scale(1.175635,0.850604)"
440 id="linearGradient101"
441 xlink:href="#linearGradient172"
442 inkscape:collect="always" />
443 <linearGradient
444 y2="48.805084"
445 x2="25.312450"
446 y1="25.335417"
447 x1="17.573946"
448 gradientTransform="scale(1.175636,0.850604)"
449 gradientUnits="userSpaceOnUse"
450 id="linearGradient374"
451 xlink:href="#linearGradient368"
452 inkscape:collect="always" />
453 <linearGradient
454 gradientUnits="userSpaceOnUse"
455 y2="23.600779"
456 x2="19.857769"
457 y1="38.962704"
458 x1="19.977491"
459 gradientTransform="scale(1.215669,0.822592)"
460 id="linearGradient384"
461 xlink:href="#linearGradient381"
462 inkscape:collect="always" />
463 </defs>
464 <sodipodi:namedview
465 showborder="true"
466 id="base"
467 pagecolor="#ffffff"
468 bordercolor="#666666"
469 borderopacity="1.0"
470 inkscape:pageopacity="0.0"
471 inkscape:pageshadow="2"
472 inkscape:zoom="7.9999999"
473 inkscape:cx="33.002182"
474 inkscape:cy="10.152647"
475 inkscape:current-layer="layer1"
476 showgrid="false"
477 inkscape:grid-bbox="true"
478 inkscape:document-units="px"
479 inkscape:window-width="872"
480 inkscape:window-height="818"
481 inkscape:window-x="257"
482 inkscape:window-y="30"
483 inkscape:showpageshadow="false" />
484 <metadata
485 id="metadata4">
486 <rdf:RDF>
487 <cc:Work
488 rdf:about="">
489 <dc:format>image/svg+xml</dc:format>
490 <dc:type
491 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
492 <dc:title>Trash Full</dc:title>
493 <dc:date>2003-02-03</dc:date>
494 <dc:creator>
495 <cc:Agent>
496 <dc:title>Jakub Steiner</dc:title>
497 </cc:Agent>
498 </dc:creator>
499 <dc:subject>
500 <rdf:Bag>
501 <rdf:li>trash</rdf:li>
502 <rdf:li>delete</rdf:li>
503 <rdf:li>deleted files</rdf:li>
504 <rdf:li>waste</rdf:li>
505 <rdf:li>recycle</rdf:li>
506 <rdf:li>bin</rdf:li>
507 <rdf:li>full</rdf:li>
508 </rdf:Bag>
509 </dc:subject>
510 <dc:publisher>
511 <cc:Agent>
512 <dc:title>Novell, Inc.</dc:title>
513 </cc:Agent>
514 </dc:publisher>
515 <cc:license
516 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
517 </cc:Work>
518 <cc:License
519 rdf:about="http://creativecommons.org/licenses/publicdomain/">
520 <cc:permits
521 rdf:resource="http://creativecommons.org/ns#Reproduction" />
522 <cc:permits
523 rdf:resource="http://creativecommons.org/ns#Distribution" />
524 <cc:permits
525 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
526 </cc:License>
527 </rdf:RDF>
528 </metadata>
529 <g
530 id="layer1"
531 inkscape:label="Layer 1"
532 inkscape:groupmode="layer">
533 <g
534 style="display:inline"
535 transform="matrix(2.262383e-2,0,0,2.086758e-2,44.25843,41.86962)"
536 id="g6707">
537 <rect
538 style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
539 id="rect6709"
540 width="1339.6335"
541 height="478.35718"
542 x="-1559.2523"
543 y="-150.69685" />
544 <path
545 style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
546 d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
547 id="path6711"
548 sodipodi:nodetypes="cccc" />
549 <path
550 sodipodi:nodetypes="cccc"
551 id="path6713"
552 d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
553 style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
554 </g>
555 <path
556 style="fill:url(#linearGradient1068);fill-opacity:1.0;fill-rule:evenodd;stroke:url(#linearGradient101);stroke-width:1.2500000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
557 d="M 3.8366970,16.810238 C 3.7926080,16.775175 5.5686600,42.034206 5.5691660,42.041863 C 5.7357800,44.564407 7.1344330,45.486354 8.6999290,45.490110 C 8.7558700,45.490239 38.069409,45.486863 38.693936,45.484234 C 41.330302,45.473139 41.976184,43.867694 42.149611,42.113575 C 42.163521,42.078990 43.938664,16.844824 43.952571,16.810238 C 30.580614,16.810238 17.208657,16.810238 3.8366970,16.810238 z "
558 id="path1751"
559 sodipodi:nodetypes="ccccccc" />
560 <path
561 style="stroke-opacity:1.0000000;stroke-miterlimit:4.0000000;stroke-linejoin:miter;stroke-linecap:butt;stroke-width:1.2500000;stroke:#4d5506;fill-rule:evenodd;fill-opacity:1.0000000;fill:url(#linearGradient1872)"
562 d="M 7.5384920,4.7306315 C 6.4941670,4.7330003 5.6201490,4.7569809 5.1440780,5.7442051 C 5.0613330,5.9157934 2.5391290,12.879834 2.4178690,13.145414 C 1.3797640,15.419016 2.3371090,18.283038 4.3421790,18.263863 C 4.7234940,18.260334 43.852401,18.281621 44.459163,18.263863 C 46.165984,18.214785 46.384401,14.898279 45.649626,13.406336 C 45.607999,13.321814 42.197827,5.6492999 42.110852,5.5134018 C 41.708578,4.9064789 40.807722,4.6404880 40.138555,4.6654006 C 40.006734,4.6704304 7.6689550,4.7303368 7.5384920,4.7306315 z "
563 id="path1841"
564 sodipodi:nodetypes="cssssscss" />
565 <path
566 style="color:#000000;fill:url(#linearGradient164);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
567 d="M 7.7204500,6.3900545 C 6.7355240,6.3773223 6.6713880,6.3392466 6.4496770,7.0362462 C 6.3984970,7.1971422 4.3364820,13.531607 4.2556550,13.777418 C 3.9807760,14.613371 4.3694800,14.833988 5.3234030,14.816995 C 5.6613270,14.810975 42.670159,14.816995 43.208169,14.816995 C 43.971941,14.816995 44.198501,14.565395 44.025974,13.971598 C 43.955868,13.730313 41.085266,6.9669634 41.008179,6.8465153 C 40.651639,6.3085929 40.713471,6.3101594 40.090720,6.3025755 C 39.973809,6.3011510 7.8360710,6.3915492 7.7204500,6.3900545 z "
568 id="path1864"
569 sodipodi:nodetypes="cssssscss" />
570 <path
571 style="color:#000000;fill:#2e3436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
572 d="M 7.1914370,6.3869852 C 6.8205620,6.4152986 6.6421770,6.5251871 6.4869440,7.0132015 C 6.4357640,7.1740974 4.3760140,13.499216 4.2951860,13.745027 C 4.0203070,14.580975 4.3849570,14.805712 5.3388810,14.788720 C 5.3554040,14.788428 7.2922140,14.788962 7.4755480,14.788720 L 7.1914370,6.3869852 z "
573 id="path1880"
574 sodipodi:nodetypes="cccccc" />
575 <path
576 style="color:#000000;fill:url(#linearGradient160);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
577 d="M 40.143457,6.2999077 C 40.594213,6.3037596 40.726578,6.2947269 41.014741,6.8394315 C 41.054147,6.9139229 43.889138,13.632601 43.990928,13.878411 C 44.337098,14.825515 43.677798,14.805712 42.632092,14.833183 C 42.433434,14.832890 40.083238,14.811194 39.852358,14.810950 L 40.143457,6.2999077 z "
578 id="path1888"
579 sodipodi:nodetypes="cscccc" />
580 <path
581 style="color:#000000;fill:url(#linearGradient152);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:0.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
582 d="M 43.188383,18.930946 L 7.1998593,18.907789 C 34.314156,19.538355 39.641346,22.517229 42.946375,22.365024 L 43.188383,18.930946 z "
583 id="path1893"
584 sodipodi:nodetypes="cccc" />
585 <g
586 style="fill:#ffffff;fill-opacity:0.48809519"
587 transform="matrix(1.420021,0.000000,0.000000,1.420021,-67.25409,-7.484740)"
588 id="g144">
589 <path
590 sodipodi:nodetypes="ccccccscc"
591 id="path41"
592 d="M 64.131147,25.325447 L 67.928133,25.615144 L 69.396397,22.040585 L 67.659134,23.261574 C 67.659134,23.261574 66.914226,21.524169 66.378823,21.384498 C 65.843421,21.244828 63.559132,21.291385 63.559132,21.291385 C 64.285695,21.471073 64.850367,22.719512 64.859047,22.733674 C 65.085717,23.103530 65.720220,24.348057 65.720220,24.348057 L 64.131147,25.325447 z "
593 style="fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
594 <path
595 sodipodi:nodetypes="ccczc"
596 id="path130"
597 d="M 64.600893,22.852762 L 63.344021,25.250434 L 60.760121,23.620948 C 60.760121,23.620948 61.931819,21.409503 62.855175,21.409503 C 63.786342,21.409503 64.202456,22.212137 64.600893,22.852762 z "
598 style="color:#000000;fill-opacity:0.30952379;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
599 <path
600 sodipodi:nodetypes="ccccccscc"
601 id="path139"
602 d="M 66.450976,28.545542 L 64.002948,31.471279 L 66.339076,34.488059 L 66.382284,32.587938 C 66.382284,32.587938 68.103047,32.750329 68.497986,32.362789 C 68.892923,31.975249 70.535933,30.021270 70.535933,30.021270 C 70.008436,30.552239 68.647269,30.395144 68.630659,30.395314 C 68.196893,30.399717 66.480102,30.359654 66.480102,30.359654 L 66.450976,28.545542 z "
603 style="fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
604 <path
605 sodipodi:nodetypes="ccczc"
606 id="path140"
607 d="M 68.748409,30.061355 L 67.337346,27.751062 L 70.062991,26.371707 C 70.062991,26.371707 71.358061,28.513238 70.883591,29.305365 C 70.405109,30.104193 69.502725,30.048732 68.748409,30.061355 z "
608 style="color:#000000;fill-opacity:0.30952379;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
609 <path
610 sodipodi:nodetypes="ccccccscc"
611 id="path142"
612 d="M 62.170193,28.375650 L 60.961696,25.192931 L 57.437755,25.441971 L 58.884372,26.495777 C 58.884372,26.495777 57.885335,27.906210 58.024237,28.441813 C 58.163139,28.977415 58.946780,31.196407 58.946780,31.196407 C 58.749682,30.474372 59.564769,29.372969 59.572907,29.358488 C 59.785446,28.980335 60.676477,27.512330 60.676477,27.512330 L 62.170193,28.375650 z "
613 style="fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
614 <path
615 sodipodi:nodetypes="ccczc"
616 id="path143"
617 d="M 59.752772,29.661147 L 62.458980,29.590480 L 62.294995,32.640869 C 62.294995,32.640869 59.792913,32.695178 59.343013,31.888843 C 58.889308,31.075686 59.387472,30.321230 59.752772,29.661147 z "
618 style="color:#000000;fill-opacity:0.30952379;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
619 </g>
620 <path
621 sodipodi:nodetypes="cccssssc"
622 id="path344"
623 d="M 41.624730,23.651808 C 36.299359,25.986218 29.004203,28.320991 23.056218,28.370558 C 16.516233,28.425058 11.697549,31.531025 6.8162911,33.914752 C 7.0109680,36.794969 7.2256820,38.805946 7.4908471,42.031519 C 7.6231144,43.640472 8.1287711,43.602252 10.431218,43.602252 C 19.542668,43.602252 31.496634,43.615196 38.688801,43.615196 C 40.449339,43.615196 40.248374,42.363465 40.343480,41.164752 C 40.803877,35.361894 41.217727,29.476257 41.624730,23.651808 z "
624 style="fill:url(#linearGradient374);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:14.962102;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000;opacity:1.0000000" />
625 <path
626 style="stroke-opacity:0.28571430;stroke-miterlimit:4.0000000;stroke-linejoin:miter;stroke-linecap:butt;stroke-width:1.1400000;stroke:url(#linearGradient384);fill-rule:evenodd;fill-opacity:1.0000000;fill:none;stroke-dasharray:none"
627 d="M 5.2098606,19.402822 C 5.1584543,19.402690 6.0490537,32.078422 6.7566249,40.968384 C 6.9391608,43.250374 7.3101511,44.179154 8.7477790,44.179154 C 20.599078,44.179154 37.441889,44.264299 38.015405,44.262223 C 40.789981,44.252176 40.738055,43.236189 40.967844,41.077514 C 41.051496,40.291680 42.504818,19.491210 42.490953,19.491210 C 32.560989,19.491210 17.478660,19.434440 5.2098606,19.402822 z "
628 id="path375"
629 sodipodi:nodetypes="cssssss" />
630 </g>
631 <g
632 inkscape:label="trash"
633 id="layer2"
634 inkscape:groupmode="layer">
635 <path
636 sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccccc"
637 id="path614"
638 d="M 14.683580,0.65454850 C 14.845171,0.46120460 14.801218,0.46855512 14.357215,0.80289630 C 12.581203,2.1402589 9.6397580,4.8379548 9.6397580,4.8379548 C 9.6397580,4.8379548 9.8901250,5.6304193 9.1650440,6.8554841 C 8.4399620,8.0805496 6.2574300,6.3214330 6.2574280,6.3214322 C 5.4646320,5.7873138 5.9660030,7.7425067 6.9398280,9.8817780 C 5.9093780,10.653086 5.1596550,11.417736 5.1596550,11.988316 C 5.1596540,13.337978 5.0681580,13.210890 4.9816380,13.471793 C 4.4377130,13.543124 3.8227540,13.554785 2.9047700,13.471793 C 4.9027490,13.367699 6.1365210,11.732319 6.6282980,11.988316 C 6.6789350,12.019796 5.3654150,13.365863 5.4266810,13.367950 C 5.4060550,13.403135 4.8629600,13.798158 4.8629600,13.798158 L 17.175822,13.738820 C 17.174772,13.748760 17.177692,13.758516 17.175822,13.768488 L 28.776616,13.768488 C 28.752139,13.804272 28.376076,13.560801 28.376076,13.560801 L 30.052406,13.768488 L 34.087465,13.768488 C 34.102886,13.771773 34.070513,13.795551 34.087465,13.798158 C 34.087466,13.798159 36.877985,14.572071 36.579707,15.964035 C 36.281428,17.355999 35.570942,17.773878 35.570942,17.773878 C 35.570944,17.773876 35.885306,21.728103 36.283011,23.915474 C 36.680710,26.102843 35.988821,20.239615 37.380784,19.643059 C 38.772749,19.046504 42.435948,20.636395 44.026763,17.951894 C 45.617578,15.267395 45.136538,15.673669 44.738832,14.480558 C 44.728301,14.448963 44.662039,14.395477 44.649823,14.361880 L 44.857510,14.361880 C 45.423484,13.683414 46.064296,12.893294 47.053056,11.246578 C 44.617517,13.309298 44.722808,13.313289 44.264119,13.798158 C 43.949052,13.168833 43.460436,12.430841 42.721303,11.899307 L 42.869650,11.869637 C 42.869650,11.869637 42.725891,11.787663 43.522381,10.148803 C 44.318869,8.5099463 38.321600,6.2986915 39.546661,7.5378837 C 40.213016,8.2119245 38.613114,9.2835811 36.876402,10.030126 C 36.668622,9.8723870 34.768632,8.4893106 33.138040,7.8345791 C 32.801547,7.5029371 32.684136,7.2328940 32.277621,6.8851536 C 36.469487,3.9415860 28.880112,4.9623731 24.088826,1.8710001 C 27.405728,4.0477071 27.493158,6.3681734 26.343713,8.3389614 C 25.064056,8.0431223 24.017756,7.5762176 24.326183,6.9444927 C 24.922809,5.7224729 22.053310,7.8726397 21.359228,9.4960737 C 21.233442,9.5038360 21.136179,9.3922848 21.003194,9.4367349 C 20.994194,8.9678567 21.067422,8.5210916 20.943855,8.0422660 C 20.191093,5.1253211 17.583214,5.6731208 15.365980,7.9235877 C 14.388050,6.5405367 12.659858,5.6049187 12.250677,4.6896070 C 11.787135,3.6526938 14.198810,1.2345801 14.683580,0.65454850 z M 18.659300,9.6444220 C 18.841909,9.6444220 18.612218,10.084611 18.510952,10.386160 C 18.460565,10.394114 18.413582,10.409158 18.362605,10.415830 C 18.334820,9.9791160 18.375241,9.6444220 18.659300,9.6444220 z M 36.401689,10.237813 C 36.126408,10.340829 35.899103,10.519094 35.630281,10.593847 C 35.582748,10.523279 35.472269,10.427971 35.422595,10.356490 L 36.401689,10.237813 z "
639 style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#6d6d6d;stroke-width:1.1867819;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
640 <path
641 id="path506"
642 d="M 22.582910,12.099667 L 37.046182,10.137900 C 37.046182,10.137900 31.999224,6.2689160 31.234723,7.8347725 C 30.470223,9.4006303 23.573952,8.5054651 24.338452,6.9396087 C 25.102953,5.3737509 20.128156,9.3567054 21.406868,10.654837 C 22.685578,11.952969 22.582910,12.099667 22.582910,12.099667 z "
643 style="color:#000000;fill:url(#linearGradient613);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:2.2107496;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
644 <path
645 id="path459"
646 d="M 14.985644,8.2500958 C 17.272440,5.6650218 20.155793,4.9690408 20.951201,8.0512436 C 21.746608,11.133448 19.758089,14.712782 19.161534,13.320818 C 18.564977,11.928855 17.868997,9.6420590 18.664404,9.6420590 C 19.459811,9.6420590 16.974163,13.221392 16.974163,13.221392 L 14.985644,8.2500958 z "
647 style="color:#000000;fill:url(#linearGradient612);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:2.2107496;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
648 <path
649 id="path504"
650 d="M 6.2634240,6.3236344 C 6.2634240,6.3236344 8.4437740,8.0660076 9.1688560,6.8409412 C 9.8939390,5.6158760 9.6523580,4.8515475 9.6523580,4.8515475 C 9.6523580,4.8515475 12.569336,2.1318013 14.345348,0.79443850 C 16.121359,-0.54292429 11.630704,3.2950286 12.248761,4.6775799 C 12.866816,6.0601312 16.648873,7.3867839 15.996675,10.438320 C 15.344477,13.489855 15.248998,12.860420 14.147442,13.467262 C 13.045887,14.074103 10.056022,14.967380 8.0443720,12.162867 C 6.0327190,9.3583516 5.1788560,5.5929465 6.2634240,6.3236344 z "
651 style="color:#000000;fill:url(#linearGradient611);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
652 <path
653 sodipodi:nodetypes="cccccc"
654 id="path511"
655 d="M 42.868406,11.879622 L 28.433335,14.245072 C 28.284988,13.829698 32.082024,9.3659433 33.307082,10.605134 C 34.532143,11.844326 40.780116,8.7910135 39.555055,7.5518224 C 38.329995,6.3126298 44.317196,8.4957384 43.520708,10.134596 C 42.724218,11.773455 42.868406,11.879622 42.868406,11.879622 z "
656 style="color:#000000;fill:url(#linearGradient610);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:2.2107496;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
657 <path
658 id="path458"
659 d="M 19.262424,8.9416055 L 20.256683,9.8364390 L 12.899163,14.012328 L 19.262424,8.9416055 z "
660 style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
661 <path
662 id="path355"
663 d="M 24.090190,1.8593282 C 33.573585,8.0827818 18.370146,16.975685 15.864536,11.209860 C 17.268433,12.244016 17.363811,13.314834 17.165173,14.373572 L 39.486930,14.373572 C 38.674224,14.132354 37.957211,13.851570 36.674740,13.811135 C 37.723323,13.467437 36.156452,10.201523 32.280694,6.8861174 C 36.472557,3.9425500 28.881475,4.9507009 24.090190,1.8593282 z M 47.044689,11.245012 C 44.067783,13.766232 44.531608,13.489912 43.634909,14.373572 L 44.865242,14.373572 C 45.431213,13.695108 46.055929,12.891728 47.044689,11.245012 z "
664 style="font-size:12.000000;fill:url(#linearGradient609);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;overflow:visible" />
665 <path
666 id="path442"
667 d="M 4.8557800,14.424497 L 24.641538,14.325070 C 24.641538,14.325070 23.150151,7.5641088 20.366224,9.7514780 C 17.582298,11.938849 10.324205,9.2543498 13.108133,7.0669788 C 15.892058,4.8796081 5.1540580,9.8509050 5.1540580,12.038274 C 5.1540580,14.225646 4.8557800,14.424497 4.8557800,14.424497 z "
668 style="color:#000000;fill:url(#linearGradient608);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:2.2107496;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
669 <g
670 transform="matrix(0.273209,0.000000,0.000000,0.273209,-37.63912,-13.12876)"
671 id="g378"
672 style="font-size:12.000000;color:#000000;fill:url(#linearGradient234);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:2.1333332;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible"
673 i:knockout="Off">
674 <path
675 sodipodi:nodetypes="cccc"
676 id="path379"
677 d="M 163.66854,88.723079 C 164.69803,92.209992 156.20500,98.079000 148.42900,97.376000 C 155.74200,96.995000 153.18000,98.302000 154.98000,99.239000 C 157.13700,100.58000 168.86508,95.534348 163.66854,88.723079 z "
678 style="color:#000000;fill:url(#linearGradient607);stroke-dashoffset:0.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible"
679 i:knockout="Off" />
680 </g>
681 <path
682 id="path448"
683 d="M 20.763929,10.203126 C 19.272539,10.799682 17.980002,13.683034 15.494354,13.782461 C 13.008705,13.881887 20.763929,14.478441 21.559335,13.782461 C 22.354742,13.086478 20.763929,10.203126 20.763929,10.203126 z "
684 style="color:#000000;fill:url(#linearGradient606);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:2.2107496;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
685 <path
686 id="path491"
687 d="M 19.869095,14.279591 L 30.209392,14.279591 C 30.209392,14.279591 31.899633,11.296812 28.022021,11.495664 C 24.144410,11.694515 25.436947,12.887628 23.448428,13.285331 C 21.459910,13.683036 19.869095,14.279591 19.869095,14.279591 z "
688 style="color:#000000;fill:url(#radialGradient605);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
689 <path
690 id="path498"
691 d="M 34.087002,14.379015 C 34.087002,14.379015 36.870928,14.577867 36.572651,15.969831 C 36.274374,17.361794 35.578390,17.759498 35.578390,17.759498 C 35.578390,17.759498 35.876668,21.736535 36.274374,23.923906 C 36.672077,26.111275 35.976095,20.245145 37.368058,19.648590 C 38.760022,19.052034 42.438779,20.642849 44.029594,17.958349 C 45.620410,15.273849 45.123280,15.671552 44.725575,14.478441 C 44.327872,13.285331 42.737057,10.600831 39.356577,11.296812 C 35.976095,11.992793 32.794465,14.180164 34.087002,14.379015 z "
692 style="color:#000000;fill:url(#radialGradient640);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
693 <g
694 transform="matrix(0.273209,0.000000,0.000000,0.273209,6.153125,9.657440)"
695 id="g620"
696 style="font-size:12.000000;color:#000000;fill:url(#linearGradient632);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:2.1333332;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible"
697 i:knockout="Off" />
698 <path
699 sodipodi:nodetypes="cccscscc"
700 id="path644"
701 d="M 4.8817920,14.402387 L 19.686008,14.356905 C 19.686008,14.356905 21.090649,14.068164 21.795612,13.886239 C 22.521554,13.515497 23.638840,13.523499 24.421209,13.120100 C 25.830655,12.393376 25.568039,11.516694 28.798888,11.495714 C 24.875714,11.076124 25.118043,12.880828 23.661030,13.228829 C 22.478564,13.511254 20.209045,14.311423 19.708749,14.243201 C 19.208453,14.174979 4.8817920,14.402387 4.8817920,14.402387 z "
702 style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
703 <path
704 sodipodi:nodetypes="cscccss"
705 id="path645"
706 d="M 13.182159,9.2629815 C 13.182159,9.2629815 15.278147,10.868162 18.435268,10.513721 C 19.837866,10.356256 20.686600,9.3994254 21.255119,9.3312039 C 21.823637,9.2629815 22.278451,9.6040920 22.278451,9.6040920 C 22.278451,9.6040920 21.755415,9.3539444 21.277858,9.4676479 C 20.800303,9.5813510 19.708660,10.789633 18.094157,10.741129 C 14.410068,10.630448 13.182159,9.2629815 13.182159,9.2629815 z "
707 style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
708 <path
709 sodipodi:nodetypes="cccsc"
710 id="path646"
711 d="M 24.110972,1.8899041 C 24.110972,1.8899041 27.509658,4.0717762 27.173984,6.7991161 C 26.838312,9.5264560 23.733341,11.582450 23.733341,11.582450 C 23.733341,11.582450 27.834670,9.0099309 27.551616,6.5473617 C 27.132026,2.8969219 24.110972,1.8899041 24.110972,1.8899041 z "
712 style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
713 <path
714 sodipodi:nodetypes="cccc"
715 id="path647"
716 d="M 32.334952,6.9249934 C 31.957320,6.2116891 30.153079,4.7850805 28.600593,4.4494078 C 30.824424,5.0368350 32.796501,6.5054026 32.796501,6.5054026 L 32.334952,6.9249934 z "
717 style="color:#000000;fill:#000000;fill-opacity:0.17857142;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible" />
718 <path
719 sodipodi:nodetypes="ccccc"
720 id="path648"
721 d="M 15.395649,7.8345790 C 15.395649,7.8345790 16.345074,8.9916917 15.989040,10.356490 C 16.849458,10.534507 17.205491,10.564177 17.205491,10.564177 L 17.976901,9.9411180 C 17.976901,9.9411180 17.976901,8.1016049 15.395649,7.8345790 z "
722 style="fill:#000000;fill-opacity:0.17857142;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
723 <path
724 id="path649"
725 d="M 12.716747,7.5165492 C 12.716747,7.5165492 14.407911,6.9231581 13.962869,7.3385318 C 13.517826,7.7539055 16.069406,9.6230870 16.069406,9.6230870 C 16.069406,9.6230870 16.069406,10.216478 15.950729,10.364826 C 15.832049,10.513174 11.589305,9.2967226 12.716747,7.5165492 z "
726 style="fill:#000000;fill-opacity:0.071428545;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
727 </g>
728</svg>
diff --git a/utils/rbutilqt/icons/view-refresh.svg b/utils/rbutilqt/icons/view-refresh.svg
new file mode 100644
index 0000000000..565f6dadec
--- /dev/null
+++ b/utils/rbutilqt/icons/view-refresh.svg
@@ -0,0 +1,393 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 inkscape:export-ydpi="90.000000"
13 inkscape:export-xdpi="90.000000"
14 inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
15 width="48px"
16 height="48px"
17 id="svg11300"
18 sodipodi:version="0.32"
19 inkscape:version="0.46"
20 sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
21 sodipodi:docname="view-refresh.svg"
22 inkscape:output_extension="org.inkscape.output.svg.inkscape">
23 <defs
24 id="defs3">
25 <inkscape:perspective
26 sodipodi:type="inkscape:persp3d"
27 inkscape:vp_x="0 : 24 : 1"
28 inkscape:vp_y="0 : 1000 : 0"
29 inkscape:vp_z="48 : 24 : 1"
30 inkscape:persp3d-origin="24 : 16 : 1"
31 id="perspective58" />
32 <linearGradient
33 inkscape:collect="always"
34 id="linearGradient2690">
35 <stop
36 style="stop-color:#c4d7eb;stop-opacity:1;"
37 offset="0"
38 id="stop2692" />
39 <stop
40 style="stop-color:#c4d7eb;stop-opacity:0;"
41 offset="1"
42 id="stop2694" />
43 </linearGradient>
44 <linearGradient
45 id="linearGradient2682">
46 <stop
47 style="stop-color:#3977c3;stop-opacity:1;"
48 offset="0"
49 id="stop2684" />
50 <stop
51 style="stop-color:#89aedc;stop-opacity:0;"
52 offset="1"
53 id="stop2686" />
54 </linearGradient>
55 <linearGradient
56 id="linearGradient2402">
57 <stop
58 style="stop-color:#729fcf;stop-opacity:1;"
59 offset="0"
60 id="stop2404" />
61 <stop
62 style="stop-color:#528ac5;stop-opacity:1;"
63 offset="1"
64 id="stop2406" />
65 </linearGradient>
66 <linearGradient
67 id="linearGradient2380">
68 <stop
69 style="stop-color:#b9cfe7;stop-opacity:1"
70 offset="0"
71 id="stop2382" />
72 <stop
73 style="stop-color:#729fcf;stop-opacity:1"
74 offset="1"
75 id="stop2384" />
76 </linearGradient>
77 <linearGradient
78 inkscape:collect="always"
79 id="linearGradient2871">
80 <stop
81 style="stop-color:#3465a4;stop-opacity:1;"
82 offset="0"
83 id="stop2873" />
84 <stop
85 style="stop-color:#3465a4;stop-opacity:1"
86 offset="1"
87 id="stop2875" />
88 </linearGradient>
89 <linearGradient
90 inkscape:collect="always"
91 id="linearGradient2847">
92 <stop
93 style="stop-color:#3465a4;stop-opacity:1;"
94 offset="0"
95 id="stop2849" />
96 <stop
97 style="stop-color:#3465a4;stop-opacity:0;"
98 offset="1"
99 id="stop2851" />
100 </linearGradient>
101 <linearGradient
102 id="linearGradient2831">
103 <stop
104 style="stop-color:#3465a4;stop-opacity:1;"
105 offset="0"
106 id="stop2833" />
107 <stop
108 id="stop2855"
109 offset="0.33333334"
110 style="stop-color:#5b86be;stop-opacity:1;" />
111 <stop
112 style="stop-color:#83a8d8;stop-opacity:0;"
113 offset="1"
114 id="stop2835" />
115 </linearGradient>
116 <linearGradient
117 inkscape:collect="always"
118 id="linearGradient2797">
119 <stop
120 style="stop-color:#ffffff;stop-opacity:1;"
121 offset="0"
122 id="stop2799" />
123 <stop
124 style="stop-color:#ffffff;stop-opacity:0;"
125 offset="1"
126 id="stop2801" />
127 </linearGradient>
128 <linearGradient
129 inkscape:collect="always"
130 id="linearGradient8662">
131 <stop
132 style="stop-color:#000000;stop-opacity:1;"
133 offset="0"
134 id="stop8664" />
135 <stop
136 style="stop-color:#000000;stop-opacity:0;"
137 offset="1"
138 id="stop8666" />
139 </linearGradient>
140 <linearGradient
141 inkscape:collect="always"
142 xlink:href="#linearGradient2831"
143 id="linearGradient1486"
144 gradientUnits="userSpaceOnUse"
145 gradientTransform="translate(0.465413,-0.277593)"
146 x1="13.478554"
147 y1="10.612206"
148 x2="15.419417"
149 y2="19.115122" />
150 <linearGradient
151 inkscape:collect="always"
152 xlink:href="#linearGradient2847"
153 id="linearGradient1488"
154 gradientUnits="userSpaceOnUse"
155 gradientTransform="matrix(-1,0,0,-1,47.52791,45.84741)"
156 x1="37.128052"
157 y1="29.729605"
158 x2="37.065414"
159 y2="26.194071" />
160 <linearGradient
161 inkscape:collect="always"
162 xlink:href="#linearGradient2797"
163 id="linearGradient1491"
164 gradientUnits="userSpaceOnUse"
165 x1="5.9649176"
166 y1="26.048164"
167 x2="52.854097"
168 y2="26.048164" />
169 <linearGradient
170 inkscape:collect="always"
171 xlink:href="#linearGradient2797"
172 id="linearGradient1493"
173 gradientUnits="userSpaceOnUse"
174 x1="5.9649176"
175 y1="26.048164"
176 x2="52.854097"
177 y2="26.048164" />
178 <linearGradient
179 inkscape:collect="always"
180 xlink:href="#linearGradient2871"
181 id="linearGradient1501"
182 gradientUnits="userSpaceOnUse"
183 x1="46.834816"
184 y1="45.264122"
185 x2="45.380436"
186 y2="50.939667" />
187 <radialGradient
188 inkscape:collect="always"
189 xlink:href="#linearGradient8662"
190 id="radialGradient1503"
191 gradientUnits="userSpaceOnUse"
192 gradientTransform="matrix(1,0,0,0.536723,-9.680928e-14,16.87306)"
193 cx="24.837126"
194 cy="36.421127"
195 fx="24.837126"
196 fy="36.421127"
197 r="15.644737" />
198 <linearGradient
199 inkscape:collect="always"
200 xlink:href="#linearGradient2380"
201 id="linearGradient2386"
202 x1="62.513836"
203 y1="36.061237"
204 x2="15.984863"
205 y2="20.60858"
206 gradientUnits="userSpaceOnUse" />
207 <linearGradient
208 inkscape:collect="always"
209 xlink:href="#linearGradient2402"
210 id="linearGradient2408"
211 x1="18.935766"
212 y1="23.667896"
213 x2="53.588622"
214 y2="26.649362"
215 gradientUnits="userSpaceOnUse" />
216 <linearGradient
217 inkscape:collect="always"
218 xlink:href="#linearGradient2682"
219 id="linearGradient2688"
220 x1="36.713837"
221 y1="31.455952"
222 x2="37.124462"
223 y2="24.842253"
224 gradientUnits="userSpaceOnUse" />
225 <linearGradient
226 inkscape:collect="always"
227 xlink:href="#linearGradient2690"
228 id="linearGradient2696"
229 x1="32.647972"
230 y1="30.748846"
231 x2="37.124462"
232 y2="24.842253"
233 gradientUnits="userSpaceOnUse" />
234 </defs>
235 <sodipodi:namedview
236 stroke="#3465a4"
237 fill="#729fcf"
238 id="base"
239 pagecolor="#ffffff"
240 bordercolor="#666666"
241 borderopacity="0.25490196"
242 inkscape:pageopacity="0.0"
243 inkscape:pageshadow="2"
244 inkscape:zoom="5.6568542"
245 inkscape:cx="2.4438651"
246 inkscape:cy="18.153347"
247 inkscape:current-layer="layer1"
248 showgrid="false"
249 inkscape:grid-bbox="true"
250 inkscape:document-units="px"
251 inkscape:showpageshadow="false"
252 inkscape:window-width="891"
253 inkscape:window-height="818"
254 inkscape:window-x="0"
255 inkscape:window-y="30" />
256 <metadata
257 id="metadata4">
258 <rdf:RDF>
259 <cc:Work
260 rdf:about="">
261 <dc:format>image/svg+xml</dc:format>
262 <dc:type
263 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
264 <dc:creator>
265 <cc:Agent>
266 <dc:title>Jakub Steiner</dc:title>
267 </cc:Agent>
268 </dc:creator>
269 <dc:source>http://jimmac.musichall.cz</dc:source>
270 <cc:license
271 rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
272 <dc:title>View Refresh</dc:title>
273 <dc:subject>
274 <rdf:Bag>
275 <rdf:li>reload</rdf:li>
276 <rdf:li>refresh</rdf:li>
277 <rdf:li>view</rdf:li>
278 </rdf:Bag>
279 </dc:subject>
280 </cc:Work>
281 <cc:License
282 rdf:about="http://creativecommons.org/licenses/publicdomain/">
283 <cc:permits
284 rdf:resource="http://creativecommons.org/ns#Reproduction" />
285 <cc:permits
286 rdf:resource="http://creativecommons.org/ns#Distribution" />
287 <cc:permits
288 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
289 </cc:License>
290 </rdf:RDF>
291 </metadata>
292 <g
293 id="layer1"
294 inkscape:label="Layer 1"
295 inkscape:groupmode="layer">
296 <path
297 transform="matrix(-1.489736,0,0,-1.001252,61.20865,75.2819)"
298 d="M 40.481863 36.421127 A 15.644737 8.3968935 0 1 1 9.1923885,36.421127 A 15.644737 8.3968935 0 1 1 40.481863 36.421127 z"
299 sodipodi:ry="8.3968935"
300 sodipodi:rx="15.644737"
301 sodipodi:cy="36.421127"
302 sodipodi:cx="24.837126"
303 id="path8660"
304 style="opacity:0.38333333;color:#000000;fill:url(#radialGradient1503);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
305 sodipodi:type="arc"
306 inkscape:r_cx="true"
307 inkscape:r_cy="true" />
308 <path
309 style="color:#000000;fill:url(#linearGradient1486);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient1488);stroke-width:0.99999958;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
310 d="M 20.152913,10.409904 C 20.152913,10.409904 11.215413,9.784904 13.965413,20.284904 L 6.2779132,20.284904 C 6.2779132,20.284904 6.7779132,8.409904 20.152913,10.409904 z "
311 id="path2865"
312 inkscape:r_cx="true"
313 inkscape:r_cy="true"
314 sodipodi:nodetypes="cccc" />
315 <g
316 id="g1878"
317 transform="matrix(-0.579051,-0.489228,-0.489228,0.579051,56.91585,13.37137)"
318 inkscape:r_cx="true"
319 inkscape:r_cy="true"
320 style="fill:url(#linearGradient2386);fill-opacity:1.0;stroke:#3465a4;stroke-opacity:1">
321 <path
322 sodipodi:nodetypes="ccccccc"
323 id="path1880"
324 d="M 44.306783,50.229694 C 62.821497,35.818859 49.664587,13.411704 22.462411,12.49765 L 22.113843,3.1515478 L 7.6245439,20.496754 L 22.714328,33.219189 C 22.714328,33.219189 22.462411,23.337969 22.462411,23.337969 C 41.292171,24.336946 55.444038,37.409698 44.306783,50.229694 z "
325 style="opacity:1;color:#000000;fill:url(#linearGradient2386);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient1501);stroke-width:1.31916928;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
326 inkscape:r_cx="true"
327 inkscape:r_cy="true" />
328 </g>
329 <path
330 sodipodi:nodetypes="cccc"
331 inkscape:r_cy="true"
332 inkscape:r_cx="true"
333 id="path2839"
334 d="M 28.375,33.4375 C 28.375,33.4375 37.3125,34.0625 34.5625,23.5625 L 42.338388,23.5625 C 42.338388,25.065102 41.75,35.4375 28.375,33.4375 z "
335 style="color:#000000;fill:url(#linearGradient2696);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient2688);stroke-width:0.99999958;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible" />
336 <g
337 style="color:#000000;fill:url(#linearGradient2408);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient1501);stroke-width:1.31916928;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible;opacity:1"
338 inkscape:r_cy="true"
339 inkscape:r_cx="true"
340 transform="matrix(0.579051,0.489228,0.489228,-0.579051,-7.921023,30.53599)"
341 id="g2779">
342 <path
343 inkscape:r_cy="true"
344 inkscape:r_cx="true"
345 style="opacity:1;color:#000000;fill:url(#linearGradient2408);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient1501);stroke-width:1.31916928;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
346 d="M 44.306783,50.229694 C 62.821497,35.818859 49.664587,13.411704 22.462411,12.49765 L 22.399432,3.0690297 L 7.793943,20.424005 L 22.462411,33.006349 C 22.462411,33.006349 22.462411,23.337969 22.462411,23.337969 C 41.292171,24.336946 55.444038,37.409698 44.306783,50.229694 z "
347 id="path2781"
348 sodipodi:nodetypes="ccccccc" />
349 </g>
350 <path
351 style="opacity:0.27222224;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
352 d="M 7.0625,38.1875 L 7.125,23.3125 L 20.0625,22.9375 L 15.673627,28.116317 L 19.540852,30.489516 C 16.540852,32.739516 14.991304,32.911644 13.991304,35.474144 L 11.174446,33.363872 L 7.0625,38.1875 z "
353 id="path2791"
354 inkscape:r_cx="true"
355 inkscape:r_cy="true"
356 sodipodi:nodetypes="cccccccc" />
357 <g
358 id="g2793"
359 transform="matrix(0.508536,0.429651,0.429651,-0.508536,-3.973188,30.54119)"
360 inkscape:r_cx="true"
361 inkscape:r_cy="true"
362 style="opacity:0.5;fill:none;fill-opacity:1;stroke:#ffffff;stroke-opacity:1">
363 <path
364 sodipodi:nodetypes="ccccccc"
365 id="path2795"
366 d="M 51.090265,45.943705 C 60.210465,30.723955 46.631614,12.20113 19.485058,11.948579 L 19.513464,3.7032834 L 6.5341979,19.296639 L 19.367661,30.26876 C 19.367661,30.26876 19.423281,21.261882 19.423281,21.261882 C 36.951096,21.037973 54.618466,31.365254 51.090265,45.943705 z "
367 style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient1493);stroke-width:1.50208926;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
368 inkscape:r_cx="true"
369 inkscape:r_cy="true" />
370 </g>
371 <g
372 style="opacity:0.5;fill:none;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"
373 inkscape:r_cy="true"
374 inkscape:r_cx="true"
375 transform="matrix(-0.508536,-0.429651,-0.429651,0.508536,53.049,13.36548)"
376 id="g2805">
377 <path
378 inkscape:r_cy="true"
379 inkscape:r_cx="true"
380 style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient1491);stroke-width:1.50208926;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
381 d="M 51.389927,46.505946 C 60.510127,31.286196 47.050763,12.432359 19.628482,12.069755 L 19.342824,4.0507204 L 6.3413093,19.379475 L 19.809059,30.764589 C 19.809059,30.764589 19.627294,21.311346 19.627294,21.311346 C 37.872231,21.693318 54.411175,32.236592 51.389927,46.505946 z "
382 id="path2807"
383 sodipodi:nodetypes="ccccccc" />
384 </g>
385 <path
386 style="opacity:0.27222224;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
387 d="M 6.8125,16.5 C 10.405935,6.0587275 23.256282,10.355393 27,12 C 31.175307,12.211475 32.674736,9.164996 36,9 C 21.950264,-0.7899963 7.1875,2.5 6.8125,16.5 z "
388 id="path2811"
389 inkscape:r_cx="true"
390 inkscape:r_cy="true"
391 sodipodi:nodetypes="cccc" />
392 </g>
393</svg>
diff --git a/utils/rbutilqt/icons/wizard.jpg b/utils/rbutilqt/icons/wizard.jpg
new file mode 100644
index 0000000000..d4a9625678
--- /dev/null
+++ b/utils/rbutilqt/icons/wizard.jpg
Binary files differ
diff --git a/utils/rbutilqt/installtalkfrm.ui b/utils/rbutilqt/installtalkfrm.ui
new file mode 100644
index 0000000000..7cde2b09d1
--- /dev/null
+++ b/utils/rbutilqt/installtalkfrm.ui
@@ -0,0 +1,246 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>InstallTalkFrm</class>
4 <widget class="QDialog" name="InstallTalkFrm">
5 <property name="windowModality">
6 <enum>Qt::WindowModal</enum>
7 </property>
8 <property name="geometry">
9 <rect>
10 <x>0</x>
11 <y>0</y>
12 <width>722</width>
13 <height>448</height>
14 </rect>
15 </property>
16 <property name="windowTitle">
17 <string>Install Talk Files</string>
18 </property>
19 <layout class="QGridLayout" name="gridLayout_2">
20 <item row="0" column="0" rowspan="4">
21 <widget class="QLabel" name="label">
22 <property name="text">
23 <string/>
24 </property>
25 <property name="pixmap">
26 <pixmap resource="rbutilqt.qrc">:/icons/wizard.jpg</pixmap>
27 </property>
28 <property name="alignment">
29 <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
30 </property>
31 </widget>
32 </item>
33 <item row="2" column="1" colspan="3">
34 <widget class="QGroupBox" name="groupBox">
35 <property name="title">
36 <string>Generation options</string>
37 </property>
38 <layout class="QGridLayout" name="gridLayout">
39 <item row="7" column="0">
40 <widget class="QCheckBox" name="StripExtensions">
41 <property name="text">
42 <string>Strip Extensions</string>
43 </property>
44 <property name="checked">
45 <bool>false</bool>
46 </property>
47 </widget>
48 </item>
49 <item row="1" column="0">
50 <widget class="QCheckBox" name="talkFiles">
51 <property name="text">
52 <string>Generate for files</string>
53 </property>
54 <property name="checked">
55 <bool>true</bool>
56 </property>
57 <property name="tristate">
58 <bool>false</bool>
59 </property>
60 </widget>
61 </item>
62 <item row="0" column="1">
63 <spacer name="horizontalSpacer">
64 <property name="orientation">
65 <enum>Qt::Horizontal</enum>
66 </property>
67 <property name="sizeHint" stdset="0">
68 <size>
69 <width>40</width>
70 <height>20</height>
71 </size>
72 </property>
73 </spacer>
74 </item>
75 <item row="0" column="0">
76 <widget class="QLabel" name="labelTtsProfile">
77 <property name="text">
78 <string>TTS profile:</string>
79 </property>
80 </widget>
81 </item>
82 <item row="1" column="1" colspan="2">
83 <widget class="QCheckBox" name="talkFolders">
84 <property name="text">
85 <string>Generate for folders</string>
86 </property>
87 <property name="checked">
88 <bool>true</bool>
89 </property>
90 </widget>
91 </item>
92 <item row="4" column="0">
93 <widget class="QCheckBox" name="recursive">
94 <property name="text">
95 <string>Recurse into folders</string>
96 </property>
97 <property name="checked">
98 <bool>true</bool>
99 </property>
100 </widget>
101 </item>
102 <item row="0" column="2">
103 <widget class="QPushButton" name="change">
104 <property name="sizePolicy">
105 <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
106 <horstretch>0</horstretch>
107 <verstretch>0</verstretch>
108 </sizepolicy>
109 </property>
110 <property name="icon">
111 <iconset resource="rbutilqt.qrc">
112 <normaloff>:/icons/preferences-system.svg</normaloff>:/icons/preferences-system.svg</iconset>
113 </property>
114 <property name="text">
115 <string>Change</string>
116 </property>
117 </widget>
118 </item>
119 <item row="8" column="0">
120 <widget class="QCheckBox" name="ignoreEnabled">
121 <property name="text">
122 <string>Ignore files</string>
123 </property>
124 </widget>
125 </item>
126 <item row="8" column="1" colspan="2">
127 <widget class="QLineEdit" name="ignoreFiles"/>
128 </item>
129 <item row="4" column="1" colspan="2">
130 <widget class="QCheckBox" name="GenerateOnlyNew">
131 <property name="text">
132 <string>Skip existing</string>
133 </property>
134 <property name="checked">
135 <bool>true</bool>
136 </property>
137 </widget>
138 </item>
139 </layout>
140 </widget>
141 </item>
142 <item row="3" column="2" colspan="2">
143 <layout class="QHBoxLayout">
144 <item>
145 <widget class="QPushButton" name="buttonOk">
146 <property name="text">
147 <string>&amp;Install</string>
148 </property>
149 <property name="icon">
150 <iconset resource="rbutilqt.qrc">
151 <normaloff>:/icons/go-next.svg</normaloff>:/icons/go-next.svg</iconset>
152 </property>
153 </widget>
154 </item>
155 <item>
156 <widget class="QPushButton" name="buttonCancel">
157 <property name="text">
158 <string>&amp;Cancel</string>
159 </property>
160 <property name="icon">
161 <iconset resource="rbutilqt.qrc">
162 <normaloff>:/icons/process-stop.svg</normaloff>:/icons/process-stop.svg</iconset>
163 </property>
164 </widget>
165 </item>
166 </layout>
167 </item>
168 <item row="1" column="1" colspan="3">
169 <widget class="QTreeView" name="treeView"/>
170 </item>
171 <item row="0" column="1" colspan="3">
172 <widget class="QLabel" name="label_2">
173 <property name="text">
174 <string>Select folders for Talkfile generation (Ctrl for multiselect)</string>
175 </property>
176 </widget>
177 </item>
178 <item row="3" column="1">
179 <spacer>
180 <property name="orientation">
181 <enum>Qt::Horizontal</enum>
182 </property>
183 <property name="sizeType">
184 <enum>QSizePolicy::Expanding</enum>
185 </property>
186 <property name="sizeHint" stdset="0">
187 <size>
188 <width>20</width>
189 <height>20</height>
190 </size>
191 </property>
192 </spacer>
193 </item>
194 </layout>
195 </widget>
196 <tabstops>
197 <tabstop>buttonOk</tabstop>
198 <tabstop>buttonCancel</tabstop>
199 <tabstop>treeView</tabstop>
200 <tabstop>change</tabstop>
201 <tabstop>talkFiles</tabstop>
202 <tabstop>talkFolders</tabstop>
203 <tabstop>recursive</tabstop>
204 <tabstop>GenerateOnlyNew</tabstop>
205 <tabstop>StripExtensions</tabstop>
206 <tabstop>ignoreEnabled</tabstop>
207 <tabstop>ignoreFiles</tabstop>
208 </tabstops>
209 <resources>
210 <include location="rbutilqt.qrc"/>
211 </resources>
212 <connections>
213 <connection>
214 <sender>buttonOk</sender>
215 <signal>clicked()</signal>
216 <receiver>InstallTalkFrm</receiver>
217 <slot>accept()</slot>
218 <hints>
219 <hint type="sourcelabel">
220 <x>624</x>
221 <y>437</y>
222 </hint>
223 <hint type="destinationlabel">
224 <x>382</x>
225 <y>328</y>
226 </hint>
227 </hints>
228 </connection>
229 <connection>
230 <sender>buttonCancel</sender>
231 <signal>clicked()</signal>
232 <receiver>InstallTalkFrm</receiver>
233 <slot>reject()</slot>
234 <hints>
235 <hint type="sourcelabel">
236 <x>711</x>
237 <y>437</y>
238 </hint>
239 <hint type="destinationlabel">
240 <x>522</x>
241 <y>332</y>
242 </hint>
243 </hints>
244 </connection>
245 </connections>
246</ui>
diff --git a/utils/rbutilqt/installtalkwindow.cpp b/utils/rbutilqt/installtalkwindow.cpp
new file mode 100644
index 0000000000..5499b9533c
--- /dev/null
+++ b/utils/rbutilqt/installtalkwindow.cpp
@@ -0,0 +1,188 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QMessageBox>
20#include "installtalkwindow.h"
21#include "ui_installtalkfrm.h"
22
23#include "configure.h"
24#include "rbsettings.h"
25#include "Logger.h"
26
27InstallTalkWindow::InstallTalkWindow(QWidget *parent) : QDialog(parent)
28{
29 ui.setupUi(this);
30 talkcreator = new TalkFileCreator(this);
31
32 connect(ui.change,SIGNAL(clicked()),this,SLOT(change()));
33
34 ui.recursive->setChecked(true);
35 ui.GenerateOnlyNew->setChecked(true);
36 ui.StripExtensions->setChecked(true);
37
38 fsm = new QFileSystemModel(this);
39 QString mp = RbSettings::value(RbSettings::Mountpoint).toString();
40 fsm->setRootPath(mp);
41 ui.treeView->setModel(fsm);
42 ui.treeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
43 ui.treeView->setRootIndex(fsm->index(mp));
44 fsm->setFilter(QDir::AllDirs | QDir::NoDotAndDotDot);
45 for(int i = 1; i < fsm->columnCount(); i++)
46 ui.treeView->setColumnHidden(i, true);
47 ui.treeView->setHeaderHidden(true);
48
49 updateSettings();
50}
51
52
53void InstallTalkWindow::saveSettings(void)
54{
55 QString mp = RbSettings::value(RbSettings::Mountpoint).toString();
56 QModelIndexList si = ui.treeView->selectionModel()->selectedIndexes();
57 QStringList foldersToTalk;
58 for(int i = 0; i < si.size(); i++) {
59 if(si.at(i).column() == 0) {
60 QString current = fsm->filePath(si.at(i));
61 foldersToTalk.append(current.remove(QRegExp("^" + mp)));
62 }
63 }
64 RbSettings::setValue(RbSettings::TalkFolders, foldersToTalk);
65
66 RbSettings::setValue(RbSettings::TalkSkipExisting, ui.GenerateOnlyNew->isChecked());
67 RbSettings::setValue(RbSettings::TalkRecursive, ui.recursive->isChecked());
68 RbSettings::setValue(RbSettings::TalkStripExtensions, ui.StripExtensions->isChecked());
69 RbSettings::setValue(RbSettings::TalkProcessFolders, ui.talkFolders->isChecked());
70 RbSettings::setValue(RbSettings::TalkProcessFiles, ui.talkFiles->isChecked());
71 RbSettings::setValue(RbSettings::TalkIgnoreWildcards, ui.ignoreFiles->text());
72 RbSettings::setValue(RbSettings::TalkIgnoreFiles, ui.ignoreEnabled->isChecked());
73
74 RbSettings::sync();
75}
76
77
78void InstallTalkWindow::change()
79{
80 Config *cw = new Config(this, 4);
81
82 // make sure the current selected folder doesn't get lost on settings
83 // changes.
84 connect(cw, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
85
86 cw->show();
87}
88
89void InstallTalkWindow::accept()
90{
91 saveSettings();
92 QStringList foldersToTalk
93 = RbSettings::value(RbSettings::TalkFolders).toStringList();
94 if(foldersToTalk.size() == 0) {
95 QMessageBox::information(this, tr("Empty selection"),
96 tr("No files or folders selected. Please select files or "
97 "folders first."));
98 return;
99 }
100
101 logger = new ProgressLoggerGui(this);
102
103 connect(logger,SIGNAL(closed()),this,SLOT(close()));
104 logger->show();
105
106 talkcreator->setMountPoint(RbSettings::value(RbSettings::Mountpoint).toString());
107
108 talkcreator->setGenerateOnlyNew(ui.GenerateOnlyNew->isChecked());
109 talkcreator->setRecursive(ui.recursive->isChecked());
110 talkcreator->setStripExtensions(ui.StripExtensions->isChecked());
111 talkcreator->setTalkFolders(ui.talkFolders->isChecked());
112 talkcreator->setTalkFiles(ui.talkFiles->isChecked());
113#if QT_VERSION >= 0x050e00
114 talkcreator->setIgnoreFiles(ui.ignoreFiles->text().split(",", Qt::SkipEmptyParts));
115#else
116 talkcreator->setIgnoreFiles(ui.ignoreFiles->text().split(",", QString::SkipEmptyParts));
117#endif
118
119 connect(talkcreator, SIGNAL(done(bool)), logger, SLOT(setFinished()));
120 connect(talkcreator, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
121 connect(talkcreator, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
122 connect(logger,SIGNAL(aborted()),talkcreator,SLOT(abort()));
123
124 for(int i = 0; i < foldersToTalk.size(); i++) {
125 LOG_INFO() << "creating talk files for folder"
126 << foldersToTalk.at(i);
127 talkcreator->setDir(foldersToTalk.at(i));
128 talkcreator->createTalkFiles();
129 }
130}
131
132
133void InstallTalkWindow::updateSettings(void)
134{
135 QString mp = RbSettings::value(RbSettings::Mountpoint).toString();
136 QString ttsName = RbSettings::value(RbSettings::Tts).toString();
137 TTSBase* tts = TTSBase::getTTS(this,ttsName);
138 if(!tts)
139 {
140 QMessageBox::critical(this, tr("TTS error"),
141 tr("The selected TTS failed to initialize. You can't use this TTS."));
142 return;
143 }
144 if(tts->configOk())
145 ui.labelTtsProfile->setText(QString("<b>%1</b>")
146 .arg(TTSBase::getTTSName(ttsName)));
147 else
148 ui.labelTtsProfile->setText(QString("<b>%1</b>")
149 .arg("Invalid TTS configuration!"));
150
151 QStringList folders = RbSettings::value(RbSettings::TalkFolders).toStringList();
152 for(int i = 0; i < folders.size(); ++i) {
153 QModelIndex mi = fsm->index(mp + folders.at(i));
154 ui.treeView->selectionModel()->select(mi, QItemSelectionModel::Select);
155 // make sure all parent items are expanded.
156 while((mi = mi.parent()) != QModelIndex()) {
157 ui.treeView->setExpanded(mi, true);
158 }
159 }
160 ui.GenerateOnlyNew->setChecked(
161 RbSettings::value(RbSettings::TalkSkipExisting).toBool());
162 ui.recursive->setChecked(
163 RbSettings::value(RbSettings::TalkRecursive).toBool());
164 ui.StripExtensions->setChecked(
165 RbSettings::value(RbSettings::TalkStripExtensions).toBool());
166 ui.talkFolders->setChecked(
167 RbSettings::value(RbSettings::TalkProcessFolders).toBool());
168 ui.talkFiles->setChecked(
169 RbSettings::value(RbSettings::TalkProcessFiles).toBool());
170 ui.ignoreFiles->setText(
171 RbSettings::value(RbSettings::TalkIgnoreWildcards).toString());
172 ui.ignoreEnabled->setChecked(
173 RbSettings::value(RbSettings::TalkIgnoreFiles).toBool());
174
175 emit settingsUpdated();
176}
177
178
179void InstallTalkWindow::changeEvent(QEvent *e)
180{
181 if(e->type() == QEvent::LanguageChange) {
182 ui.retranslateUi(this);
183 updateSettings();
184 } else {
185 QWidget::changeEvent(e);
186 }
187}
188
diff --git a/utils/rbutilqt/installtalkwindow.h b/utils/rbutilqt/installtalkwindow.h
new file mode 100644
index 0000000000..f965e4cb09
--- /dev/null
+++ b/utils/rbutilqt/installtalkwindow.h
@@ -0,0 +1,56 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#ifndef INSTALLTALKWINDOW_H
22#define INSTALLTALKWINDOW_H
23
24#include <QDialog>
25#include <QFileSystemModel>
26
27#include "ui_installtalkfrm.h"
28#include "progressloggergui.h"
29#include "talkfile.h"
30
31class InstallTalkWindow : public QDialog
32{
33 Q_OBJECT
34 public:
35 InstallTalkWindow(QWidget *parent = nullptr);
36
37 public slots:
38 void accept(void);
39 void change(void);
40
41 private slots:
42 void updateSettings(void);
43 void saveSettings(void);
44
45 signals:
46 void settingsUpdated(void);
47
48 private:
49 void changeEvent(QEvent *event);
50 TalkFileCreator* talkcreator;
51 Ui::InstallTalkFrm ui;
52 ProgressLoggerGui* logger;
53 QFileSystemModel *fsm;
54};
55
56#endif
diff --git a/utils/rbutilqt/irivertools/h100sums.h b/utils/rbutilqt/irivertools/h100sums.h
new file mode 100644
index 0000000000..d52ca0d13b
--- /dev/null
+++ b/utils/rbutilqt/irivertools/h100sums.h
@@ -0,0 +1,23 @@
1/* Checksums of firmwares for ihp_100 */
2/* order: unpatched, patched */
3
4/* 1.63eu */
5{"86103cb05658970b43ce1f40f93d53a8", "6922876c5ef94bf4bab484e3a4f89c71"},
6/* 1.63k */
7{"70127fa9ee69afab7645297fbb61636d", "a4e7bb3b5d79ea8a0c9ef911e39b07a6"},
8/* 1.63us */
9{"7a504a450c76a0dda757fdb6b5531b22", "cc826c4bafb51d98a06b839c3afc0042"},
10/* 1.65eu */
11{"478dc657b97e77d1b4944ef26c3dcb8e", "8b1daa624b183cc8bc92edf65d1ef3a7"},
12/* 1.65k */
13{"97ba82fb8099bb23ca0c78fc119f8cce", "992121c09393f833f8ef17a540436457"},
14/* 1.65us */
15{"d3725865e0948cd5f604b00db2ec89aa", "274ac6548283fa105b71176b30a53632"},
16/* 1.66eu */
17{"fc59f742fe383da3e4d17a660c46afb9", "90920de15cdd91c454dae42a82999591"},
18/* 1.66k */
19{"22d214401994c276ec6878288caa0dba", "45a6ab666cc563b5e93e4a629839b3a9"},
20/* 1.66us */
21{"0ae247f567aeafcafecf823a50cbf33e", "124ddbaeb475583afa5f16fb3954d8a3"},
22/* 1.66jp */
23{"8bfc8ae5805c270597232efeafade5fd", "05841b026cdbcb478fc6c635edd6a5f4"},
diff --git a/utils/rbutilqt/irivertools/h120sums.h b/utils/rbutilqt/irivertools/h120sums.h
new file mode 100644
index 0000000000..118b40b549
--- /dev/null
+++ b/utils/rbutilqt/irivertools/h120sums.h
@@ -0,0 +1,23 @@
1/* Checksums of firmwares for ihp_120 */
2/* order: unpatched, patched */
3
4/* 1.63eu */
5{"14488347a171480c63c94bc7b885225d", "5bbcb9c060abaecc2e51a42cdbd9db8c"},
6/* 1.63k */
7{"3401fe8845e569156abfaddf05ca7771", "ed1c05a9830589abc95e79bfa7cbed5b"},
8/* 1.63us */
9{"d9078209105c186cee5246055fdb99c9", "f3dc2ba361db1d0b99fda54c2b54e2d3"},
10/* 1.65eu */
11{"c9e71aac4a498f1e2f0e684c2d554ea1", "821e3338e198f10fca214407fcbf148e"},
12/* 1.65k */
13{"360c0c565266f84e9bca610c596f3207", "a5ce6655ff9f20786c23101f76b84768"},
14/* 1.65us */
15{"b9e516d4b8a0265605f46f254897bfb0", "4e2e14122d4856247aab4070c912c56e"},
16/* 1.66eu */
17{"a094999b41781f4322a57b9be7fa4534", "63afa15e3305a737e931f61affb5266a"},
18/* 1.66k */
19{"79daba973bb31b60b4b87c2ef497587d", "a3e592920dc600a5e51cf0288f55712d"},
20/* 1.66us */
21{"7fa020a3104c76fbbfcb8313e287dbe2", "3046fec093a8b7f24c394d4a67ee8a31"},
22/* 1.66jp */
23{"271d151eb6586929da24b3458ea965fe", "47820bbef1550ec0fb2815fa599d32be"},
diff --git a/utils/rbutilqt/irivertools/h300sums.h b/utils/rbutilqt/irivertools/h300sums.h
new file mode 100644
index 0000000000..e4e321b0e7
--- /dev/null
+++ b/utils/rbutilqt/irivertools/h300sums.h
@@ -0,0 +1,19 @@
1/* Checksums of firmwares for ihp_300 */
2/* order: unpatched, patched */
3
4/* 1.28eu */
5{"0b2083d37f24899b82d21a14d2b38060", "371d2f6dae171ccaaa57894640be2f10"},
6/* 1.28k */
7{"c6f854ae3d8f48e8982819a4b5302fb0", "5dc417d14ba6de264f1c2f9fc4cae420"},
8/* 1.28jp */
9{"7fcd7bca6b98a34134e2518a616f4e85", "87183596af1574335bc91755b96ce978"},
10/* 1.29eu */
11{"27d90fc316709c096979ab24c914ee31", "9d5c8655a35b1a7373daf6e7a3bb76db"},
12/* 1.29k */
13{"44416d97737fc47cd417a64d44064768", "90b976d1a7078848382c6ff7f63132d9"},
14/* 1.29jp */
15{"1ac242c645572a0a5de99ae2b23453b8", "ea96dbef4d52409d9d1510959abcf795"},
16/* 1.30eu */
17{"8d2d775b018f0532235d38f5317ae10c", "d88b2e853a38672e8547a07f05f9a197"},
18/* 1.31k */
19{"8241f66c5b64beeeeeb8fdfc8263f75f", "e77be3b112a7eb65ef75f886b3a55984"},
diff --git a/utils/rbutilqt/irivertools/mksums.pl b/utils/rbutilqt/irivertools/mksums.pl
new file mode 100755
index 0000000000..99786fe161
--- /dev/null
+++ b/utils/rbutilqt/irivertools/mksums.pl
@@ -0,0 +1,69 @@
1#!/usr/bin/perl
2
3# This script creates the h100sums.h and h300sums.h files for fwpatcher.
4#
5# It expects a file tree with scrambled and descrambled
6# firmwares like this:
7# orig-firmware/
8# h1xx/
9# 1.66jp/
10# ihp_100.bin
11# ihp_100.hex
12# ihp_120.bin
13# ihp_120.hex
14# h3xx/
15# 1.29jp/
16# H300.bin
17# H300.hex
18# etc.
19#
20# It also expects the bootloader binaries in the current directory:
21# bootloader-h100.bin
22# bootloader-h120.bin
23# bootloader-h300.bin
24
25$orig_path = "~/orig-firmware";
26
27mksumfile("100");
28mksumfile("120");
29mksumfile("300");
30
31sub mksumfile {
32 ($model) = @_;
33
34 open FILE, ">h${model}sums.h" or die "Can't open h${model}sums.h";
35
36 print FILE "/* Checksums of firmwares for ihp_$model */\n";
37 print FILE "/* order: unpatched, patched */\n\n";
38
39 if($model < 300) {
40 foreach("1.63eu","1.63k", "1.63us", "1.65eu","1.65k", "1.65us",
41 "1.66eu", "1.66k", "1.66us", "1.66jp") {
42 `../mkboot $orig_path/h1xx/$_/ihp_$model.bin bootloader-h$model.bin ihp_$model.bin`;
43 `../scramble -iriver ihp_$model.bin ihp_$model.hex`;
44 $origsum = `md5sum $orig_path/h1xx/$_/ihp_$model.hex`;
45 chomp $origsum;
46 ($os, $or) = split / /, $origsum;
47 $sum = `md5sum ihp_$model.hex`;
48 chomp $sum;
49 ($s, $r) = split / /, $sum;
50 print FILE "/* $_ */\n";
51 print FILE "{\"$os\", \"$s\"},\n";
52 }
53 } else {
54 foreach("1.28eu", "1.28k", "1.28jp", "1.29eu", "1.29k", "1.29jp",
55 "1.30eu") {
56 `../mkboot -h300 $orig_path/h3xx/$_/H$model.bin bootloader-h$model.bin H$model.bin`;
57 `../scramble -iriver H$model.bin H$model.hex`;
58 $origsum = `md5sum $orig_path/h3xx/$_/H$model.hex`;
59 chomp $origsum;
60 ($os, $or) = split / /, $origsum;
61 $sum = `md5sum H$model.hex`;
62 chomp $sum;
63 ($s, $r) = split / /, $sum;
64 print FILE "/* $_ */\n";
65 print FILE "{\"$os\", \"$s\"},\n";
66 }
67 }
68 close FILE;
69}
diff --git a/utils/rbutilqt/lame/lame.h b/utils/rbutilqt/lame/lame.h
new file mode 100644
index 0000000000..0550b4b61c
--- /dev/null
+++ b/utils/rbutilqt/lame/lame.h
@@ -0,0 +1,1243 @@
1/*
2 * Interface to MP3 LAME encoding engine
3 *
4 * Copyright (c) 1999 Mark Taylor
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22/* $Id: lame.h,v 1.170.2.4 2009/01/18 15:44:28 robert Exp $ */
23
24#ifndef LAME_LAME_H
25#define LAME_LAME_H
26
27/* for size_t typedef */
28#include <stddef.h>
29/* for va_list typedef */
30#include <stdarg.h>
31/* for FILE typedef, TODO: remove when removing lame_mp3_tags_fid */
32#include <stdio.h>
33
34#if defined(__cplusplus)
35extern "C" {
36#endif
37
38#if defined(WIN32) || defined(_WIN32)
39#undef CDECL
40#define CDECL __cdecl
41#else
42#define CDECL
43#endif
44
45
46#define DEPRECATED_OR_OBSOLETE_CODE_REMOVED 1
47
48
49typedef enum vbr_mode_e {
50 vbr_off=0,
51 vbr_mt, /* obsolete, same as vbr_mtrh */
52 vbr_rh,
53 vbr_abr,
54 vbr_mtrh,
55 vbr_max_indicator, /* Don't use this! It's used for sanity checks. */
56 vbr_default=vbr_mtrh /* change this to change the default VBR mode of LAME */
57} vbr_mode;
58
59
60/* MPEG modes */
61typedef enum MPEG_mode_e {
62 STEREO = 0,
63 JOINT_STEREO,
64 DUAL_CHANNEL, /* LAME doesn't supports this! */
65 MONO,
66 NOT_SET,
67 MAX_INDICATOR /* Don't use this! It's used for sanity checks. */
68} MPEG_mode;
69
70/* Padding types */
71typedef enum Padding_type_e {
72 PAD_NO = 0,
73 PAD_ALL,
74 PAD_ADJUST,
75 PAD_MAX_INDICATOR /* Don't use this! It's used for sanity checks. */
76} Padding_type;
77
78
79
80/*presets*/
81typedef enum preset_mode_e {
82 /*values from 8 to 320 should be reserved for abr bitrates*/
83 /*for abr I'd suggest to directly use the targeted bitrate as a value*/
84 ABR_8 = 8,
85 ABR_320 = 320,
86
87 V9 = 410, /*Vx to match Lame and VBR_xx to match FhG*/
88 VBR_10 = 410,
89 V8 = 420,
90 VBR_20 = 420,
91 V7 = 430,
92 VBR_30 = 430,
93 V6 = 440,
94 VBR_40 = 440,
95 V5 = 450,
96 VBR_50 = 450,
97 V4 = 460,
98 VBR_60 = 460,
99 V3 = 470,
100 VBR_70 = 470,
101 V2 = 480,
102 VBR_80 = 480,
103 V1 = 490,
104 VBR_90 = 490,
105 V0 = 500,
106 VBR_100 = 500,
107
108
109
110 /*still there for compatibility*/
111 R3MIX = 1000,
112 STANDARD = 1001,
113 EXTREME = 1002,
114 INSANE = 1003,
115 STANDARD_FAST = 1004,
116 EXTREME_FAST = 1005,
117 MEDIUM = 1006,
118 MEDIUM_FAST = 1007
119} preset_mode;
120
121
122/*asm optimizations*/
123typedef enum asm_optimizations_e {
124 MMX = 1,
125 AMD_3DNOW = 2,
126 SSE = 3
127} asm_optimizations;
128
129
130/* psychoacoustic model */
131typedef enum Psy_model_e {
132 PSY_GPSYCHO = 1,
133 PSY_NSPSYTUNE = 2
134} Psy_model;
135
136
137struct lame_global_struct;
138typedef struct lame_global_struct lame_global_flags;
139typedef lame_global_flags *lame_t;
140
141
142
143
144/***********************************************************************
145 *
146 * The LAME API
147 * These functions should be called, in this order, for each
148 * MP3 file to be encoded. See the file "API" for more documentation
149 *
150 ***********************************************************************/
151
152
153/*
154 * REQUIRED:
155 * initialize the encoder. sets default for all encoder parameters,
156 * returns NULL if some malloc()'s failed
157 * otherwise returns pointer to structure needed for all future
158 * API calls.
159 */
160lame_global_flags * CDECL lame_init(void);
161#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
162#else
163/* obsolete version */
164int CDECL lame_init_old(lame_global_flags *);
165#endif
166
167/*
168 * OPTIONAL:
169 * set as needed to override defaults
170 */
171
172/********************************************************************
173 * input stream description
174 ***********************************************************************/
175/* number of samples. default = 2^32-1 */
176int CDECL lame_set_num_samples(lame_global_flags *, unsigned long);
177unsigned long CDECL lame_get_num_samples(const lame_global_flags *);
178
179/* input sample rate in Hz. default = 44100hz */
180int CDECL lame_set_in_samplerate(lame_global_flags *, int);
181int CDECL lame_get_in_samplerate(const lame_global_flags *);
182
183/* number of channels in input stream. default=2 */
184int CDECL lame_set_num_channels(lame_global_flags *, int);
185int CDECL lame_get_num_channels(const lame_global_flags *);
186
187/*
188 scale the input by this amount before encoding. default=0 (disabled)
189 (not used by decoding routines)
190*/
191int CDECL lame_set_scale(lame_global_flags *, float);
192float CDECL lame_get_scale(const lame_global_flags *);
193
194/*
195 scale the channel 0 (left) input by this amount before encoding.
196 default=0 (disabled)
197 (not used by decoding routines)
198*/
199int CDECL lame_set_scale_left(lame_global_flags *, float);
200float CDECL lame_get_scale_left(const lame_global_flags *);
201
202/*
203 scale the channel 1 (right) input by this amount before encoding.
204 default=0 (disabled)
205 (not used by decoding routines)
206*/
207int CDECL lame_set_scale_right(lame_global_flags *, float);
208float CDECL lame_get_scale_right(const lame_global_flags *);
209
210/*
211 output sample rate in Hz. default = 0, which means LAME picks best value
212 based on the amount of compression. MPEG only allows:
213 MPEG1 32, 44.1, 48khz
214 MPEG2 16, 22.05, 24
215 MPEG2.5 8, 11.025, 12
216 (not used by decoding routines)
217*/
218int CDECL lame_set_out_samplerate(lame_global_flags *, int);
219int CDECL lame_get_out_samplerate(const lame_global_flags *);
220
221
222/********************************************************************
223 * general control parameters
224 ***********************************************************************/
225/* 1=cause LAME to collect data for an MP3 frame analyzer. default=0 */
226int CDECL lame_set_analysis(lame_global_flags *, int);
227int CDECL lame_get_analysis(const lame_global_flags *);
228
229/*
230 1 = write a Xing VBR header frame.
231 default = 1
232 this variable must have been added by a Hungarian notation Windows programmer :-)
233*/
234int CDECL lame_set_bWriteVbrTag(lame_global_flags *, int);
235int CDECL lame_get_bWriteVbrTag(const lame_global_flags *);
236
237/* 1=decode only. use lame/mpglib to convert mp3/ogg to wav. default=0 */
238int CDECL lame_set_decode_only(lame_global_flags *, int);
239int CDECL lame_get_decode_only(const lame_global_flags *);
240
241#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
242#else
243/* 1=encode a Vorbis .ogg file. default=0 */
244/* DEPRECATED */
245int CDECL lame_set_ogg(lame_global_flags *, int);
246int CDECL lame_get_ogg(const lame_global_flags *);
247#endif
248
249/*
250 internal algorithm selection. True quality is determined by the bitrate
251 but this variable will effect quality by selecting expensive or cheap algorithms.
252 quality=0..9. 0=best (very slow). 9=worst.
253 recommended: 2 near-best quality, not too slow
254 5 good quality, fast
255 7 ok quality, really fast
256*/
257int CDECL lame_set_quality(lame_global_flags *, int);
258int CDECL lame_get_quality(const lame_global_flags *);
259
260/*
261 mode = 0,1,2,3 = stereo, jstereo, dual channel (not supported), mono
262 default: lame picks based on compression ration and input channels
263*/
264int CDECL lame_set_mode(lame_global_flags *, MPEG_mode);
265MPEG_mode CDECL lame_get_mode(const lame_global_flags *);
266
267#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
268#else
269/*
270 mode_automs. Use a M/S mode with a switching threshold based on
271 compression ratio
272 DEPRECATED
273*/
274int CDECL lame_set_mode_automs(lame_global_flags *, int);
275int CDECL lame_get_mode_automs(const lame_global_flags *);
276#endif
277
278/*
279 force_ms. Force M/S for all frames. For testing only.
280 default = 0 (disabled)
281*/
282int CDECL lame_set_force_ms(lame_global_flags *, int);
283int CDECL lame_get_force_ms(const lame_global_flags *);
284
285/* use free_format? default = 0 (disabled) */
286int CDECL lame_set_free_format(lame_global_flags *, int);
287int CDECL lame_get_free_format(const lame_global_flags *);
288
289/* perform ReplayGain analysis? default = 0 (disabled) */
290int CDECL lame_set_findReplayGain(lame_global_flags *, int);
291int CDECL lame_get_findReplayGain(const lame_global_flags *);
292
293/* decode on the fly. Search for the peak sample. If the ReplayGain
294 * analysis is enabled then perform the analysis on the decoded data
295 * stream. default = 0 (disabled)
296 * NOTE: if this option is set the build-in decoder should not be used */
297int CDECL lame_set_decode_on_the_fly(lame_global_flags *, int);
298int CDECL lame_get_decode_on_the_fly(const lame_global_flags *);
299
300#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
301#else
302/* DEPRECATED: now does the same as lame_set_findReplayGain()
303 default = 0 (disabled) */
304int CDECL lame_set_ReplayGain_input(lame_global_flags *, int);
305int CDECL lame_get_ReplayGain_input(const lame_global_flags *);
306
307/* DEPRECATED: now does the same as
308 lame_set_decode_on_the_fly() && lame_set_findReplayGain()
309 default = 0 (disabled) */
310int CDECL lame_set_ReplayGain_decode(lame_global_flags *, int);
311int CDECL lame_get_ReplayGain_decode(const lame_global_flags *);
312
313/* DEPRECATED: now does the same as lame_set_decode_on_the_fly()
314 default = 0 (disabled) */
315int CDECL lame_set_findPeakSample(lame_global_flags *, int);
316int CDECL lame_get_findPeakSample(const lame_global_flags *);
317#endif
318
319/* counters for gapless encoding */
320int CDECL lame_set_nogap_total(lame_global_flags*, int);
321int CDECL lame_get_nogap_total(const lame_global_flags*);
322
323int CDECL lame_set_nogap_currentindex(lame_global_flags* , int);
324int CDECL lame_get_nogap_currentindex(const lame_global_flags*);
325
326
327/*
328 * OPTIONAL:
329 * Set printf like error/debug/message reporting functions.
330 * The second argument has to be a pointer to a function which looks like
331 * void my_debugf(const char *format, va_list ap)
332 * {
333 * (void) vfprintf(stdout, format, ap);
334 * }
335 * If you use NULL as the value of the pointer in the set function, the
336 * lame buildin function will be used (prints to stderr).
337 * To quiet any output you have to replace the body of the example function
338 * with just "return;" and use it in the set function.
339 */
340int CDECL lame_set_errorf(lame_global_flags *,
341 void (*func)(const char *, va_list));
342int CDECL lame_set_debugf(lame_global_flags *,
343 void (*func)(const char *, va_list));
344int CDECL lame_set_msgf (lame_global_flags *,
345 void (*func)(const char *, va_list));
346
347
348
349/* set one of brate compression ratio. default is compression ratio of 11. */
350int CDECL lame_set_brate(lame_global_flags *, int);
351int CDECL lame_get_brate(const lame_global_flags *);
352int CDECL lame_set_compression_ratio(lame_global_flags *, float);
353float CDECL lame_get_compression_ratio(const lame_global_flags *);
354
355
356int CDECL lame_set_preset( lame_global_flags* gfp, int );
357int CDECL lame_set_asm_optimizations( lame_global_flags* gfp, int, int );
358
359
360
361/********************************************************************
362 * frame params
363 ***********************************************************************/
364/* mark as copyright. default=0 */
365int CDECL lame_set_copyright(lame_global_flags *, int);
366int CDECL lame_get_copyright(const lame_global_flags *);
367
368/* mark as original. default=1 */
369int CDECL lame_set_original(lame_global_flags *, int);
370int CDECL lame_get_original(const lame_global_flags *);
371
372/* error_protection. Use 2 bytes from each frame for CRC checksum. default=0 */
373int CDECL lame_set_error_protection(lame_global_flags *, int);
374int CDECL lame_get_error_protection(const lame_global_flags *);
375
376#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
377#else
378/* padding_type. 0=pad no frames 1=pad all frames 2=adjust padding(default) */
379int CDECL lame_set_padding_type(lame_global_flags *, Padding_type);
380Padding_type CDECL lame_get_padding_type(const lame_global_flags *);
381#endif
382
383/* MP3 'private extension' bit Meaningless. default=0 */
384int CDECL lame_set_extension(lame_global_flags *, int);
385int CDECL lame_get_extension(const lame_global_flags *);
386
387/* enforce strict ISO compliance. default=0 */
388int CDECL lame_set_strict_ISO(lame_global_flags *, int);
389int CDECL lame_get_strict_ISO(const lame_global_flags *);
390
391
392/********************************************************************
393 * quantization/noise shaping
394 ***********************************************************************/
395
396/* disable the bit reservoir. For testing only. default=0 */
397int CDECL lame_set_disable_reservoir(lame_global_flags *, int);
398int CDECL lame_get_disable_reservoir(const lame_global_flags *);
399
400/* select a different "best quantization" function. default=0 */
401int CDECL lame_set_quant_comp(lame_global_flags *, int);
402int CDECL lame_get_quant_comp(const lame_global_flags *);
403int CDECL lame_set_quant_comp_short(lame_global_flags *, int);
404int CDECL lame_get_quant_comp_short(const lame_global_flags *);
405
406int CDECL lame_set_experimentalX(lame_global_flags *, int); /* compatibility*/
407int CDECL lame_get_experimentalX(const lame_global_flags *);
408
409/* another experimental option. for testing only */
410int CDECL lame_set_experimentalY(lame_global_flags *, int);
411int CDECL lame_get_experimentalY(const lame_global_flags *);
412
413/* another experimental option. for testing only */
414int CDECL lame_set_experimentalZ(lame_global_flags *, int);
415int CDECL lame_get_experimentalZ(const lame_global_flags *);
416
417/* Naoki's psycho acoustic model. default=0 */
418int CDECL lame_set_exp_nspsytune(lame_global_flags *, int);
419int CDECL lame_get_exp_nspsytune(const lame_global_flags *);
420
421void CDECL lame_set_msfix(lame_global_flags *, double);
422float CDECL lame_get_msfix(const lame_global_flags *);
423
424
425/********************************************************************
426 * VBR control
427 ***********************************************************************/
428/* Types of VBR. default = vbr_off = CBR */
429int CDECL lame_set_VBR(lame_global_flags *, vbr_mode);
430vbr_mode CDECL lame_get_VBR(const lame_global_flags *);
431
432/* VBR quality level. 0=highest 9=lowest */
433int CDECL lame_set_VBR_q(lame_global_flags *, int);
434int CDECL lame_get_VBR_q(const lame_global_flags *);
435
436/* VBR quality level. 0=highest 9=lowest, Range [0,...,10[ */
437int CDECL lame_set_VBR_quality(lame_global_flags *, float);
438float CDECL lame_get_VBR_quality(const lame_global_flags *);
439
440/* Ignored except for VBR=vbr_abr (ABR mode) */
441int CDECL lame_set_VBR_mean_bitrate_kbps(lame_global_flags *, int);
442int CDECL lame_get_VBR_mean_bitrate_kbps(const lame_global_flags *);
443
444int CDECL lame_set_VBR_min_bitrate_kbps(lame_global_flags *, int);
445int CDECL lame_get_VBR_min_bitrate_kbps(const lame_global_flags *);
446
447int CDECL lame_set_VBR_max_bitrate_kbps(lame_global_flags *, int);
448int CDECL lame_get_VBR_max_bitrate_kbps(const lame_global_flags *);
449
450/*
451 1=strictly enforce VBR_min_bitrate. Normally it will be violated for
452 analog silence
453*/
454int CDECL lame_set_VBR_hard_min(lame_global_flags *, int);
455int CDECL lame_get_VBR_hard_min(const lame_global_flags *);
456
457/* for preset */
458#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
459#else
460int CDECL lame_set_preset_expopts(lame_global_flags *, int);
461#endif
462
463/********************************************************************
464 * Filtering control
465 ***********************************************************************/
466/* freq in Hz to apply lowpass. Default = 0 = lame chooses. -1 = disabled */
467int CDECL lame_set_lowpassfreq(lame_global_flags *, int);
468int CDECL lame_get_lowpassfreq(const lame_global_flags *);
469/* width of transition band, in Hz. Default = one polyphase filter band */
470int CDECL lame_set_lowpasswidth(lame_global_flags *, int);
471int CDECL lame_get_lowpasswidth(const lame_global_flags *);
472
473/* freq in Hz to apply highpass. Default = 0 = lame chooses. -1 = disabled */
474int CDECL lame_set_highpassfreq(lame_global_flags *, int);
475int CDECL lame_get_highpassfreq(const lame_global_flags *);
476/* width of transition band, in Hz. Default = one polyphase filter band */
477int CDECL lame_set_highpasswidth(lame_global_flags *, int);
478int CDECL lame_get_highpasswidth(const lame_global_flags *);
479
480
481/********************************************************************
482 * psycho acoustics and other arguments which you should not change
483 * unless you know what you are doing
484 ***********************************************************************/
485
486/* only use ATH for masking */
487int CDECL lame_set_ATHonly(lame_global_flags *, int);
488int CDECL lame_get_ATHonly(const lame_global_flags *);
489
490/* only use ATH for short blocks */
491int CDECL lame_set_ATHshort(lame_global_flags *, int);
492int CDECL lame_get_ATHshort(const lame_global_flags *);
493
494/* disable ATH */
495int CDECL lame_set_noATH(lame_global_flags *, int);
496int CDECL lame_get_noATH(const lame_global_flags *);
497
498/* select ATH formula */
499int CDECL lame_set_ATHtype(lame_global_flags *, int);
500int CDECL lame_get_ATHtype(const lame_global_flags *);
501
502/* lower ATH by this many db */
503int CDECL lame_set_ATHlower(lame_global_flags *, float);
504float CDECL lame_get_ATHlower(const lame_global_flags *);
505
506/* select ATH adaptive adjustment type */
507int CDECL lame_set_athaa_type( lame_global_flags *, int);
508int CDECL lame_get_athaa_type( const lame_global_flags *);
509
510/* select the loudness approximation used by the ATH adaptive auto-leveling */
511int CDECL lame_set_athaa_loudapprox( lame_global_flags *, int);
512int CDECL lame_get_athaa_loudapprox( const lame_global_flags *);
513
514/* adjust (in dB) the point below which adaptive ATH level adjustment occurs */
515int CDECL lame_set_athaa_sensitivity( lame_global_flags *, float);
516float CDECL lame_get_athaa_sensitivity( const lame_global_flags* );
517
518#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
519#else
520/* OBSOLETE: predictability limit (ISO tonality formula) */
521int CDECL lame_set_cwlimit(lame_global_flags *, int);
522int CDECL lame_get_cwlimit(const lame_global_flags *);
523#endif
524
525/*
526 allow blocktypes to differ between channels?
527 default: 0 for jstereo, 1 for stereo
528*/
529int CDECL lame_set_allow_diff_short(lame_global_flags *, int);
530int CDECL lame_get_allow_diff_short(const lame_global_flags *);
531
532/* use temporal masking effect (default = 1) */
533int CDECL lame_set_useTemporal(lame_global_flags *, int);
534int CDECL lame_get_useTemporal(const lame_global_flags *);
535
536/* use temporal masking effect (default = 1) */
537int CDECL lame_set_interChRatio(lame_global_flags *, float);
538float CDECL lame_get_interChRatio(const lame_global_flags *);
539
540/* disable short blocks */
541int CDECL lame_set_no_short_blocks(lame_global_flags *, int);
542int CDECL lame_get_no_short_blocks(const lame_global_flags *);
543
544/* force short blocks */
545int CDECL lame_set_force_short_blocks(lame_global_flags *, int);
546int CDECL lame_get_force_short_blocks(const lame_global_flags *);
547
548/* Input PCM is emphased PCM (for instance from one of the rarely
549 emphased CDs), it is STRONGLY not recommended to use this, because
550 psycho does not take it into account, and last but not least many decoders
551 ignore these bits */
552int CDECL lame_set_emphasis(lame_global_flags *, int);
553int CDECL lame_get_emphasis(const lame_global_flags *);
554
555
556
557/************************************************************************/
558/* internal variables, cannot be set... */
559/* provided because they may be of use to calling application */
560/************************************************************************/
561/* version 0=MPEG-2 1=MPEG-1 (2=MPEG-2.5) */
562int CDECL lame_get_version(const lame_global_flags *);
563
564/* encoder delay */
565int CDECL lame_get_encoder_delay(const lame_global_flags *);
566
567/*
568 padding appended to the input to make sure decoder can fully decode
569 all input. Note that this value can only be calculated during the
570 call to lame_encoder_flush(). Before lame_encoder_flush() has
571 been called, the value of encoder_padding = 0.
572*/
573int CDECL lame_get_encoder_padding(const lame_global_flags *);
574
575/* size of MPEG frame */
576int CDECL lame_get_framesize(const lame_global_flags *);
577
578/* number of PCM samples buffered, but not yet encoded to mp3 data. */
579int CDECL lame_get_mf_samples_to_encode( const lame_global_flags* gfp );
580
581/*
582 size (bytes) of mp3 data buffered, but not yet encoded.
583 this is the number of bytes which would be output by a call to
584 lame_encode_flush_nogap. NOTE: lame_encode_flush() will return
585 more bytes than this because it will encode the reamining buffered
586 PCM samples before flushing the mp3 buffers.
587*/
588int CDECL lame_get_size_mp3buffer( const lame_global_flags* gfp );
589
590/* number of frames encoded so far */
591int CDECL lame_get_frameNum(const lame_global_flags *);
592
593/*
594 lame's estimate of the total number of frames to be encoded
595 only valid if calling program set num_samples
596*/
597int CDECL lame_get_totalframes(const lame_global_flags *);
598
599/* RadioGain value. Multiplied by 10 and rounded to the nearest. */
600int CDECL lame_get_RadioGain(const lame_global_flags *);
601
602/* AudiophileGain value. Multipled by 10 and rounded to the nearest. */
603int CDECL lame_get_AudiophileGain(const lame_global_flags *);
604
605/* the peak sample */
606float CDECL lame_get_PeakSample(const lame_global_flags *);
607
608/* Gain change required for preventing clipping. The value is correct only if
609 peak sample searching was enabled. If negative then the waveform
610 already does not clip. The value is multiplied by 10 and rounded up. */
611int CDECL lame_get_noclipGainChange(const lame_global_flags *);
612
613/* user-specified scale factor required for preventing clipping. Value is
614 correct only if peak sample searching was enabled and no user-specified
615 scaling was performed. If negative then either the waveform already does
616 not clip or the value cannot be determined */
617float CDECL lame_get_noclipScale(const lame_global_flags *);
618
619
620
621
622
623
624
625/*
626 * REQUIRED:
627 * sets more internal configuration based on data provided above.
628 * returns -1 if something failed.
629 */
630int CDECL lame_init_params(lame_global_flags *);
631
632
633/*
634 * OPTIONAL:
635 * get the version number, in a string. of the form:
636 * "3.63 (beta)" or just "3.63".
637 */
638const char* CDECL get_lame_version ( void );
639const char* CDECL get_lame_short_version ( void );
640const char* CDECL get_lame_very_short_version ( void );
641const char* CDECL get_psy_version ( void );
642const char* CDECL get_lame_url ( void );
643const char* CDECL get_lame_os_bitness ( void );
644
645/*
646 * OPTIONAL:
647 * get the version numbers in numerical form.
648 */
649typedef struct {
650 /* generic LAME version */
651 int major;
652 int minor;
653 int alpha; /* 0 if not an alpha version */
654 int beta; /* 0 if not a beta version */
655
656 /* version of the psy model */
657 int psy_major;
658 int psy_minor;
659 int psy_alpha; /* 0 if not an alpha version */
660 int psy_beta; /* 0 if not a beta version */
661
662 /* compile time features */
663 const char *features; /* Don't make assumptions about the contents! */
664} lame_version_t;
665void CDECL get_lame_version_numerical(lame_version_t *);
666
667
668/*
669 * OPTIONAL:
670 * print internal lame configuration to message handler
671 */
672void CDECL lame_print_config(const lame_global_flags* gfp);
673
674void CDECL lame_print_internals( const lame_global_flags *gfp);
675
676
677/*
678 * input pcm data, output (maybe) mp3 frames.
679 * This routine handles all buffering, resampling and filtering for you.
680 *
681 * return code number of bytes output in mp3buf. Can be 0
682 * -1: mp3buf was too small
683 * -2: malloc() problem
684 * -3: lame_init_params() not called
685 * -4: psycho acoustic problems
686 *
687 * The required mp3buf_size can be computed from num_samples,
688 * samplerate and encoding rate, but here is a worst case estimate:
689 *
690 * mp3buf_size in bytes = 1.25*num_samples + 7200
691 *
692 * I think a tighter bound could be: (mt, March 2000)
693 * MPEG1:
694 * num_samples*(bitrate/8)/samplerate + 4*1152*(bitrate/8)/samplerate + 512
695 * MPEG2:
696 * num_samples*(bitrate/8)/samplerate + 4*576*(bitrate/8)/samplerate + 256
697 *
698 * but test first if you use that!
699 *
700 * set mp3buf_size = 0 and LAME will not check if mp3buf_size is
701 * large enough.
702 *
703 * NOTE:
704 * if gfp->num_channels=2, but gfp->mode = 3 (mono), the L & R channels
705 * will be averaged into the L channel before encoding only the L channel
706 * This will overwrite the data in buffer_l[] and buffer_r[].
707 *
708*/
709int CDECL lame_encode_buffer (
710 lame_global_flags* gfp, /* global context handle */
711 const short int buffer_l [], /* PCM data for left channel */
712 const short int buffer_r [], /* PCM data for right channel */
713 const int nsamples, /* number of samples per channel */
714 unsigned char* mp3buf, /* pointer to encoded MP3 stream */
715 const int mp3buf_size ); /* number of valid octets in this
716 stream */
717
718/*
719 * as above, but input has L & R channel data interleaved.
720 * NOTE:
721 * num_samples = number of samples in the L (or R)
722 * channel, not the total number of samples in pcm[]
723 */
724int CDECL lame_encode_buffer_interleaved(
725 lame_global_flags* gfp, /* global context handlei */
726 short int pcm[], /* PCM data for left and right
727 channel, interleaved */
728 int num_samples, /* number of samples per channel,
729 _not_ number of samples in
730 pcm[] */
731 unsigned char* mp3buf, /* pointer to encoded MP3 stream */
732 int mp3buf_size ); /* number of valid octets in this
733 stream */
734
735
736/* as lame_encode_buffer, but for 'float's.
737 * !! NOTE: !! data must still be scaled to be in the same range as
738 * short int, +/- 32768
739 */
740int CDECL lame_encode_buffer_float(
741 lame_global_flags* gfp, /* global context handle */
742 const float buffer_l [], /* PCM data for left channel */
743 const float buffer_r [], /* PCM data for right channel */
744 const int nsamples, /* number of samples per channel */
745 unsigned char* mp3buf, /* pointer to encoded MP3 stream */
746 const int mp3buf_size ); /* number of valid octets in this
747 stream */
748
749
750/* as lame_encode_buffer, but for long's
751 * !! NOTE: !! data must still be scaled to be in the same range as
752 * short int, +/- 32768
753 *
754 * This scaling was a mistake (doesn't allow one to exploit full
755 * precision of type 'long'. Use lame_encode_buffer_long2() instead.
756 *
757 */
758int CDECL lame_encode_buffer_long(
759 lame_global_flags* gfp, /* global context handle */
760 const long buffer_l [], /* PCM data for left channel */
761 const long buffer_r [], /* PCM data for right channel */
762 const int nsamples, /* number of samples per channel */
763 unsigned char* mp3buf, /* pointer to encoded MP3 stream */
764 const int mp3buf_size ); /* number of valid octets in this
765 stream */
766
767/* Same as lame_encode_buffer_long(), but with correct scaling.
768 * !! NOTE: !! data must still be scaled to be in the same range as
769 * type 'long'. Data should be in the range: +/- 2^(8*size(long)-1)
770 *
771 */
772int CDECL lame_encode_buffer_long2(
773 lame_global_flags* gfp, /* global context handle */
774 const long buffer_l [], /* PCM data for left channel */
775 const long buffer_r [], /* PCM data for right channel */
776 const int nsamples, /* number of samples per channel */
777 unsigned char* mp3buf, /* pointer to encoded MP3 stream */
778 const int mp3buf_size ); /* number of valid octets in this
779 stream */
780
781/* as lame_encode_buffer, but for int's
782 * !! NOTE: !! input should be scaled to the maximum range of 'int'
783 * If int is 4 bytes, then the values should range from
784 * +/- 2147483648.
785 *
786 * This routine does not (and cannot, without loosing precision) use
787 * the same scaling as the rest of the lame_encode_buffer() routines.
788 *
789 */
790int CDECL lame_encode_buffer_int(
791 lame_global_flags* gfp, /* global context handle */
792 const int buffer_l [], /* PCM data for left channel */
793 const int buffer_r [], /* PCM data for right channel */
794 const int nsamples, /* number of samples per channel */
795 unsigned char* mp3buf, /* pointer to encoded MP3 stream */
796 const int mp3buf_size ); /* number of valid octets in this
797 stream */
798
799
800
801
802
803/*
804 * REQUIRED:
805 * lame_encode_flush will flush the intenal PCM buffers, padding with
806 * 0's to make sure the final frame is complete, and then flush
807 * the internal MP3 buffers, and thus may return a
808 * final few mp3 frames. 'mp3buf' should be at least 7200 bytes long
809 * to hold all possible emitted data.
810 *
811 * will also write id3v1 tags (if any) into the bitstream
812 *
813 * return code = number of bytes output to mp3buf. Can be 0
814 */
815int CDECL lame_encode_flush(
816 lame_global_flags * gfp, /* global context handle */
817 unsigned char* mp3buf, /* pointer to encoded MP3 stream */
818 int size); /* number of valid octets in this stream */
819
820/*
821 * OPTIONAL:
822 * lame_encode_flush_nogap will flush the internal mp3 buffers and pad
823 * the last frame with ancillary data so it is a complete mp3 frame.
824 *
825 * 'mp3buf' should be at least 7200 bytes long
826 * to hold all possible emitted data.
827 *
828 * After a call to this routine, the outputed mp3 data is complete, but
829 * you may continue to encode new PCM samples and write future mp3 data
830 * to a different file. The two mp3 files will play back with no gaps
831 * if they are concatenated together.
832 *
833 * This routine will NOT write id3v1 tags into the bitstream.
834 *
835 * return code = number of bytes output to mp3buf. Can be 0
836 */
837int CDECL lame_encode_flush_nogap(
838 lame_global_flags * gfp, /* global context handle */
839 unsigned char* mp3buf, /* pointer to encoded MP3 stream */
840 int size); /* number of valid octets in this stream */
841
842/*
843 * OPTIONAL:
844 * Normally, this is called by lame_init_params(). It writes id3v2 and
845 * Xing headers into the front of the bitstream, and sets frame counters
846 * and bitrate histogram data to 0. You can also call this after
847 * lame_encode_flush_nogap().
848 */
849int CDECL lame_init_bitstream(
850 lame_global_flags * gfp); /* global context handle */
851
852
853
854/*
855 * OPTIONAL: some simple statistics
856 * a bitrate histogram to visualize the distribution of used frame sizes
857 * a stereo mode histogram to visualize the distribution of used stereo
858 * modes, useful in joint-stereo mode only
859 * 0: LR left-right encoded
860 * 1: LR-I left-right and intensity encoded (currently not supported)
861 * 2: MS mid-side encoded
862 * 3: MS-I mid-side and intensity encoded (currently not supported)
863 *
864 * attention: don't call them after lame_encode_finish
865 * suggested: lame_encode_flush -> lame_*_hist -> lame_close
866 */
867
868void CDECL lame_bitrate_hist(
869 const lame_global_flags * gfp,
870 int bitrate_count[14] );
871void CDECL lame_bitrate_kbps(
872 const lame_global_flags * gfp,
873 int bitrate_kbps [14] );
874void CDECL lame_stereo_mode_hist(
875 const lame_global_flags * gfp,
876 int stereo_mode_count[4] );
877
878void CDECL lame_bitrate_stereo_mode_hist (
879 const lame_global_flags * gfp,
880 int bitrate_stmode_count[14][4] );
881
882void CDECL lame_block_type_hist (
883 const lame_global_flags * gfp,
884 int btype_count[6] );
885
886void CDECL lame_bitrate_block_type_hist (
887 const lame_global_flags * gfp,
888 int bitrate_btype_count[14][6] );
889
890#if (DEPRECATED_OR_OBSOLETE_CODE_REMOVED && 0)
891#else
892/*
893 * OPTIONAL:
894 * lame_mp3_tags_fid will rewrite a Xing VBR tag to the mp3 file with file
895 * pointer fid. These calls perform forward and backwards seeks, so make
896 * sure fid is a real file. Make sure lame_encode_flush has been called,
897 * and all mp3 data has been written to the file before calling this
898 * function.
899 * NOTE:
900 * if VBR tags are turned off by the user, or turned off by LAME because
901 * the output is not a regular file, this call does nothing
902 * NOTE:
903 * LAME wants to read from the file to skip an optional ID3v2 tag, so
904 * make sure you opened the file for writing and reading.
905 * NOTE:
906 * You can call lame_get_lametag_frame instead, if you want to insert
907 * the lametag yourself.
908*/
909void CDECL lame_mp3_tags_fid(lame_global_flags *, FILE* fid);
910#endif
911
912/*
913 * OPTIONAL:
914 * lame_get_lametag_frame copies the final LAME-tag into 'buffer'.
915 * The function returns the number of bytes copied into buffer, or
916 * the required buffer size, if the provided buffer is too small.
917 * Function failed, if the return value is larger than 'size'!
918 * Make sure lame_encode flush has been called before calling this function.
919 * NOTE:
920 * if VBR tags are turned off by the user, or turned off by LAME,
921 * this call does nothing and returns 0.
922 * NOTE:
923 * LAME inserted an empty frame in the beginning of mp3 audio data,
924 * which you have to replace by the final LAME-tag frame after encoding.
925 * In case there is no ID3v2 tag, usually this frame will be the very first
926 * data in your mp3 file. If you put some other leading data into your
927 * file, you'll have to do some bookkeeping about where to write this buffer.
928 */
929size_t CDECL lame_get_lametag_frame(
930 const lame_global_flags *, unsigned char* buffer, size_t size);
931
932/*
933 * REQUIRED:
934 * final call to free all remaining buffers
935 */
936int CDECL lame_close (lame_global_flags *);
937
938#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
939#else
940/*
941 * OBSOLETE:
942 * lame_encode_finish combines lame_encode_flush() and lame_close() in
943 * one call. However, once this call is made, the statistics routines
944 * will no longer work because the data will have been cleared, and
945 * lame_mp3_tags_fid() cannot be called to add data to the VBR header
946 */
947int CDECL lame_encode_finish(
948 lame_global_flags* gfp,
949 unsigned char* mp3buf,
950 int size );
951#endif
952
953
954
955
956
957
958/*********************************************************************
959 *
960 * decoding
961 *
962 * a simple interface to mpglib, part of mpg123, is also included if
963 * libmp3lame is compiled with HAVE_MPGLIB
964 *
965 *********************************************************************/
966
967struct hip_global_struct;
968typedef struct hip_global_struct hip_global_flags;
969typedef hip_global_flags *hip_t;
970
971
972typedef struct {
973 int header_parsed; /* 1 if header was parsed and following data was
974 computed */
975 int stereo; /* number of channels */
976 int samplerate; /* sample rate */
977 int bitrate; /* bitrate */
978 int mode; /* mp3 frame type */
979 int mode_ext; /* mp3 frame type */
980 int framesize; /* number of samples per mp3 frame */
981
982 /* this data is only computed if mpglib detects a Xing VBR header */
983 unsigned long nsamp; /* number of samples in mp3 file. */
984 int totalframes; /* total number of frames in mp3 file */
985
986 /* this data is not currently computed by the mpglib routines */
987 int framenum; /* frames decoded counter */
988} mp3data_struct;
989
990/* required call to initialize decoder */
991hip_t CDECL hip_decode_init(void);
992
993/* cleanup call to exit decoder */
994int CDECL hip_decode_exit(hip_t gfp);
995
996/*********************************************************************
997 * input 1 mp3 frame, output (maybe) pcm data.
998 *
999 * nout = hip_decode(hip, mp3buf,len,pcm_l,pcm_r);
1000 *
1001 * input:
1002 * len : number of bytes of mp3 data in mp3buf
1003 * mp3buf[len] : mp3 data to be decoded
1004 *
1005 * output:
1006 * nout: -1 : decoding error
1007 * 0 : need more data before we can complete the decode
1008 * >0 : returned 'nout' samples worth of data in pcm_l,pcm_r
1009 * pcm_l[nout] : left channel data
1010 * pcm_r[nout] : right channel data
1011 *
1012 *********************************************************************/
1013int CDECL hip_decode( hip_t gfp
1014 , unsigned char * mp3buf
1015 , size_t len
1016 , short pcm_l[]
1017 , short pcm_r[]
1018 );
1019
1020/* same as hip_decode, and also returns mp3 header data */
1021int CDECL hip_decode_headers( hip_t gfp
1022 , unsigned char* mp3buf
1023 , size_t len
1024 , short pcm_l[]
1025 , short pcm_r[]
1026 , mp3data_struct* mp3data
1027 );
1028
1029/* same as hip_decode, but returns at most one frame */
1030int CDECL hip_decode1( hip_t gfp
1031 , unsigned char* mp3buf
1032 , size_t len
1033 , short pcm_l[]
1034 , short pcm_r[]
1035 );
1036
1037/* same as hip_decode1, but returns at most one frame and mp3 header data */
1038int CDECL hip_decode1_headers( hip_t gfp
1039 , unsigned char* mp3buf
1040 , size_t len
1041 , short pcm_l[]
1042 , short pcm_r[]
1043 , mp3data_struct* mp3data
1044 );
1045
1046/* same as hip_decode1_headers, but also returns enc_delay and enc_padding
1047 from VBR Info tag, (-1 if no info tag was found) */
1048int CDECL hip_decode1_headersB( hip_t gfp
1049 , unsigned char* mp3buf
1050 , size_t len
1051 , short pcm_l[]
1052 , short pcm_r[]
1053 , mp3data_struct* mp3data
1054 , int *enc_delay
1055 , int *enc_padding
1056 );
1057
1058
1059
1060/* OBSOLETE:
1061 * lame_decode... functions are there to keep old code working
1062 * but it is strongly recommended to replace calls by hip_decode...
1063 * function calls, see above.
1064 */
1065#if 1
1066int CDECL lame_decode_init(void);
1067int CDECL lame_decode(
1068 unsigned char * mp3buf,
1069 int len,
1070 short pcm_l[],
1071 short pcm_r[] );
1072int CDECL lame_decode_headers(
1073 unsigned char* mp3buf,
1074 int len,
1075 short pcm_l[],
1076 short pcm_r[],
1077 mp3data_struct* mp3data );
1078int CDECL lame_decode1(
1079 unsigned char* mp3buf,
1080 int len,
1081 short pcm_l[],
1082 short pcm_r[] );
1083int CDECL lame_decode1_headers(
1084 unsigned char* mp3buf,
1085 int len,
1086 short pcm_l[],
1087 short pcm_r[],
1088 mp3data_struct* mp3data );
1089int CDECL lame_decode1_headersB(
1090 unsigned char* mp3buf,
1091 int len,
1092 short pcm_l[],
1093 short pcm_r[],
1094 mp3data_struct* mp3data,
1095 int *enc_delay,
1096 int *enc_padding );
1097int CDECL lame_decode_exit(void);
1098
1099#endif /* obsolete lame_decode API calls */
1100
1101
1102/*********************************************************************
1103 *
1104 * id3tag stuff
1105 *
1106 *********************************************************************/
1107
1108/*
1109 * id3tag.h -- Interface to write ID3 version 1 and 2 tags.
1110 *
1111 * Copyright (C) 2000 Don Melton.
1112 *
1113 * This library is free software; you can redistribute it and/or
1114 * modify it under the terms of the GNU Library General Public
1115 * License as published by the Free Software Foundation; either
1116 * version 2 of the License, or (at your option) any later version.
1117 *
1118 * This library is distributed in the hope that it will be useful,
1119 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1120 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1121 * Library General Public License for more details.
1122 *
1123 * You should have received a copy of the GNU Library General Public
1124 * License along with this library; if not, write to the Free Software
1125 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
1126 */
1127
1128/* utility to obtain alphabetically sorted list of genre names with numbers */
1129void CDECL id3tag_genre_list(
1130 void (*handler)(int, const char *, void *),
1131 void* cookie);
1132
1133void CDECL id3tag_init (lame_t gfp);
1134
1135/* force addition of version 2 tag */
1136void CDECL id3tag_add_v2 (lame_t gfp);
1137
1138/* add only a version 1 tag */
1139void CDECL id3tag_v1_only (lame_t gfp);
1140
1141/* add only a version 2 tag */
1142void CDECL id3tag_v2_only (lame_t gfp);
1143
1144/* pad version 1 tag with spaces instead of nulls */
1145void CDECL id3tag_space_v1 (lame_t gfp);
1146
1147/* pad version 2 tag with extra 128 bytes */
1148void CDECL id3tag_pad_v2 (lame_t gfp);
1149
1150/* pad version 2 tag with extra n bytes */
1151void CDECL id3tag_set_pad (lame_t gfp, size_t n);
1152
1153void CDECL id3tag_set_title(lame_t gfp, const char* title);
1154void CDECL id3tag_set_artist(lame_t gfp, const char* artist);
1155void CDECL id3tag_set_album(lame_t gfp, const char* album);
1156void CDECL id3tag_set_year(lame_t gfp, const char* year);
1157void CDECL id3tag_set_comment(lame_t gfp, const char* comment);
1158
1159/* return -1 result if track number is out of ID3v1 range
1160 and ignored for ID3v1 */
1161int CDECL id3tag_set_track(lame_t gfp, const char* track);
1162
1163/* return non-zero result if genre name or number is invalid
1164 result 0: OK
1165 result -1: genre number out of range
1166 result -2: no valid ID3v1 genre name, mapped to ID3v1 'Other'
1167 but taken as-is for ID3v2 genre tag */
1168int CDECL id3tag_set_genre(lame_t gfp, const char* genre);
1169
1170/* return non-zero result if field name is invalid */
1171int CDECL id3tag_set_fieldvalue(lame_t gfp, const char* fieldvalue);
1172
1173/* return non-zero result if image type is invalid */
1174int CDECL id3tag_set_albumart(lame_t gfp, const char* image, size_t size);
1175
1176/* lame_get_id3v1_tag copies ID3v1 tag into buffer.
1177 * Function returns number of bytes copied into buffer, or number
1178 * of bytes rquired if buffer 'size' is too small.
1179 * Function fails, if returned value is larger than 'size'.
1180 * NOTE:
1181 * This functions does nothing, if user/LAME disabled ID3v1 tag.
1182 */
1183size_t CDECL lame_get_id3v1_tag(lame_t gfp, unsigned char* buffer, size_t size);
1184
1185/* lame_get_id3v2_tag copies ID3v2 tag into buffer.
1186 * Function returns number of bytes copied into buffer, or number
1187 * of bytes rquired if buffer 'size' is too small.
1188 * Function fails, if returned value is larger than 'size'.
1189 * NOTE:
1190 * This functions does nothing, if user/LAME disabled ID3v2 tag.
1191 */
1192size_t CDECL lame_get_id3v2_tag(lame_t gfp, unsigned char* buffer, size_t size);
1193
1194/* normaly lame_init_param writes ID3v2 tags into the audio stream
1195 * Call lame_set_write_id3tag_automatic(gfp, 0) before lame_init_param
1196 * to turn off this behaviour and get ID3v2 tag with above function
1197 * write it yourself into your file.
1198 */
1199void CDECL lame_set_write_id3tag_automatic(lame_global_flags * gfp, int);
1200int CDECL lame_get_write_id3tag_automatic(lame_global_flags const* gfp);
1201
1202/***********************************************************************
1203*
1204* list of valid bitrates [kbps] & sample frequencies [Hz].
1205* first index: 0: MPEG-2 values (sample frequencies 16...24 kHz)
1206* 1: MPEG-1 values (sample frequencies 32...48 kHz)
1207* 2: MPEG-2.5 values (sample frequencies 8...12 kHz)
1208***********************************************************************/
1209extern const int bitrate_table [3] [16];
1210extern const int samplerate_table [3] [ 4];
1211
1212
1213
1214/* maximum size of albumart image (128KB), which affects LAME_MAXMP3BUFFER
1215 as well since lame_encode_buffer() also returns ID3v2 tag data */
1216#define LAME_MAXALBUMART (128 * 1024)
1217
1218/* maximum size of mp3buffer needed if you encode at most 1152 samples for
1219 each call to lame_encode_buffer. see lame_encode_buffer() below
1220 (LAME_MAXMP3BUFFER is now obsolete) */
1221#define LAME_MAXMP3BUFFER (16384 + LAME_MAXALBUMART)
1222
1223
1224typedef enum {
1225 LAME_OKAY = 0,
1226 LAME_NOERROR = 0,
1227 LAME_GENERICERROR = -1,
1228 LAME_NOMEM = -10,
1229 LAME_BADBITRATE = -11,
1230 LAME_BADSAMPFREQ = -12,
1231 LAME_INTERNALERROR = -13,
1232
1233 FRONTEND_READERROR = -80,
1234 FRONTEND_WRITEERROR = -81,
1235 FRONTEND_FILETOOLARGE = -82
1236
1237} lame_errorcodes_t;
1238
1239#if defined(__cplusplus)
1240}
1241#endif
1242#endif /* LAME_LAME_H */
1243
diff --git a/utils/rbutilqt/lang/rbutil_cs.ts b/utils/rbutilqt/lang/rbutil_cs.ts
new file mode 100644
index 0000000000..a6e38d2555
--- /dev/null
+++ b/utils/rbutilqt/lang/rbutil_cs.ts
@@ -0,0 +1,3863 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE TS>
3<TS version="2.1" language="cs_CZ">
4<context>
5 <name>BackupDialog</name>
6 <message>
7 <location filename="../gui/backupdialogfrm.ui" line="17"/>
8 <location filename="../gui/backupdialogfrm.ui" line="43"/>
9 <source>Backup</source>
10 <translation>Vytvořit zálohu</translation>
11 </message>
12 <message>
13 <location filename="../gui/backupdialogfrm.ui" line="33"/>
14 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This dialog will create a backup by archiving the contents of the Rockbox installation on the player into a zip file. This will include installed themes and settings stored below the .rockbox folder on the player.&lt;/p&gt;&lt;p&gt;The backup filename will be created based on the installed version. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
15 <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Vytvoření zálohy archivací instalace Rockboxu na vašem přehrávači do souboru zip. Ten obsáhne nainstalovaná témata a nastavení obsažená v adresáři .rockbox na vašem přehrávači.&lt;/p&gt;&lt;p&gt;Záloha bude pojmenována podle instalované verze. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
16 </message>
17 <message>
18 <location filename="../gui/backupdialogfrm.ui" line="49"/>
19 <source>Size: unknown</source>
20 <translation>Velikost: neznámá</translation>
21 </message>
22 <message>
23 <location filename="../gui/backupdialogfrm.ui" line="56"/>
24 <source>Backup to: unknown</source>
25 <translation>Zálohovat do: neznámé</translation>
26 </message>
27 <message>
28 <location filename="../gui/backupdialogfrm.ui" line="76"/>
29 <source>&amp;Change</source>
30 <translation>Z&amp;měnit</translation>
31 </message>
32 <message>
33 <location filename="../gui/backupdialogfrm.ui" line="116"/>
34 <source>&amp;Backup</source>
35 <translation>&amp;Zálohovat</translation>
36 </message>
37 <message>
38 <location filename="../gui/backupdialogfrm.ui" line="127"/>
39 <source>&amp;Cancel</source>
40 <translation>Z&amp;rušit</translation>
41 </message>
42 <message>
43 <location filename="../gui/backupdialog.cpp" line="70"/>
44 <source>Installation size: calculating ...</source>
45 <translation>Počítám celikost instalace ...</translation>
46 </message>
47 <message>
48 <location filename="../gui/backupdialog.cpp" line="89"/>
49 <source>Select Backup Filename</source>
50 <translation>Vyberte pojmenování zálohy</translation>
51 </message>
52 <message>
53 <location filename="../gui/backupdialog.cpp" line="109"/>
54 <source>Installation size: %L1 %2</source>
55 <translation>Velikost instalace: %L1 %2</translation>
56 </message>
57 <message>
58 <location filename="../gui/backupdialog.cpp" line="116"/>
59 <source>File exists</source>
60 <translation>Soubor už existuje</translation>
61 </message>
62 <message>
63 <location filename="../gui/backupdialog.cpp" line="117"/>
64 <source>The selected backup file already exists. Overwrite?</source>
65 <translation>Soubor se zálohou již existuje. Přepsat?</translation>
66 </message>
67 <message>
68 <location filename="../gui/backupdialog.cpp" line="125"/>
69 <source>Starting backup ...</source>
70 <translation>Spouštím zálohování ...</translation>
71 </message>
72 <message>
73 <location filename="../gui/backupdialog.cpp" line="144"/>
74 <source>Backup successful.</source>
75 <translation>Zálohování úspěšné.</translation>
76 </message>
77 <message>
78 <location filename="../gui/backupdialog.cpp" line="147"/>
79 <source>Backup failed!</source>
80 <translation>Zálohování selhalo!</translation>
81 </message>
82</context>
83<context>
84 <name>BootloaderInstallAms</name>
85 <message>
86 <location filename="../base/bootloaderinstallams.cpp" line="33"/>
87 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; This file is not present on your player and will disappear automatically after installing it.&lt;br/&gt;&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
88 <translation>Instalace zavaděče vyžaduje kopii původního firmware Sandisk (soubor bin). Ten bude opatchován a instalován do vašeho přehrávače spolu se zavaděčem Rockboxu. Z právních důvodů si tento soubor musíte stáhnou sami. Navštivte prosím &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;fórum Sansa Sandisk&lt;/a&gt; nebo se podívejte do &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;příručky&lt;/a&gt; a na &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki stránce jak ho získat. &lt;br/&gt;&lt;b&gt;Poznámka:&lt;/b&gt; Tento soubor se nenachází na vašem přehrávači a po instalaci bude automaticky smazán.&lt;br/&gt;&lt;br/&gt;Vyberte OK pro pokračování a vyberte umístění souboru ve vašem počítači.</translation>
89 </message>
90 <message>
91 <location filename="../base/bootloaderinstallams.cpp" line="58"/>
92 <source>Downloading bootloader file</source>
93 <translation>Stahuji soubor zavaděče</translation>
94 </message>
95 <message>
96 <location filename="../base/bootloaderinstallams.cpp" line="100"/>
97 <location filename="../base/bootloaderinstallams.cpp" line="113"/>
98 <source>Could not load %1</source>
99 <translation>Nelze načíst %1</translation>
100 </message>
101 <message>
102 <location filename="../base/bootloaderinstallams.cpp" line="127"/>
103 <source>No room to insert bootloader, try another firmware version</source>
104 <translation>Není místo na uložení zavaděče, vyzkoušejte jinou verzi firmware</translation>
105 </message>
106 <message>
107 <location filename="../base/bootloaderinstallams.cpp" line="137"/>
108 <source>Patching Firmware...</source>
109 <translation>Patchuji firmware...</translation>
110 </message>
111 <message>
112 <location filename="../base/bootloaderinstallams.cpp" line="148"/>
113 <source>Could not open %1 for writing</source>
114 <translation>Nelze otevřít %1 pro zápis</translation>
115 </message>
116 <message>
117 <location filename="../base/bootloaderinstallams.cpp" line="161"/>
118 <source>Could not write firmware file</source>
119 <translation>Nelze zapsat do souboru firmwaru</translation>
120 </message>
121 <message>
122 <location filename="../base/bootloaderinstallams.cpp" line="177"/>
123 <source>Success: modified firmware file created</source>
124 <translation>Firmware úspěšně opatchován</translation>
125 </message>
126 <message>
127 <location filename="../base/bootloaderinstallams.cpp" line="185"/>
128 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
129 <translation>Pro odinstalaci proveďte běžnou aktualizaci s neupravovaným původním firmware</translation>
130 </message>
131</context>
132<context>
133 <name>BootloaderInstallBase</name>
134 <message>
135 <location filename="../base/bootloaderinstallbase.cpp" line="78"/>
136 <source>Download error: received HTTP error %1.</source>
137 <translation>Chyba stahování: chyba HTTP %1.</translation>
138 </message>
139 <message>
140 <location filename="../base/bootloaderinstallbase.cpp" line="84"/>
141 <source>Download error: %1</source>
142 <translation>Chyba stahování: %1</translation>
143 </message>
144 <message>
145 <location filename="../base/bootloaderinstallbase.cpp" line="90"/>
146 <source>Download finished (cache used).</source>
147 <translation>Stahování dokončeno (použita vyrovnávací paměť).</translation>
148 </message>
149 <message>
150 <location filename="../base/bootloaderinstallbase.cpp" line="92"/>
151 <source>Download finished.</source>
152 <translation>Stahování dokončeno.</translation>
153 </message>
154 <message>
155 <location filename="../base/bootloaderinstallbase.cpp" line="120"/>
156 <source>Creating backup of original firmware file.</source>
157 <translation>Vytváří se záloha původního souboru firmware.</translation>
158 </message>
159 <message>
160 <location filename="../base/bootloaderinstallbase.cpp" line="122"/>
161 <source>Creating backup folder failed</source>
162 <translation>Vytvoření záložního adresáře selhalo</translation>
163 </message>
164 <message>
165 <location filename="../base/bootloaderinstallbase.cpp" line="128"/>
166 <source>Creating backup copy failed.</source>
167 <translation>Vytvoření záložní kopie selhalo.</translation>
168 </message>
169 <message>
170 <location filename="../base/bootloaderinstallbase.cpp" line="131"/>
171 <source>Backup created.</source>
172 <translation>Záloha vytvořena.</translation>
173 </message>
174 <message>
175 <location filename="../base/bootloaderinstallbase.cpp" line="144"/>
176 <source>Creating installation log</source>
177 <translation>Vytváření instalačního výpisu</translation>
178 </message>
179 <message>
180 <location filename="../base/bootloaderinstallbase.cpp" line="156"/>
181 <source>Installation log created</source>
182 <translation>Instalační výpis vytvořen</translation>
183 </message>
184 <message>
185 <location filename="../base/bootloaderinstallbase.cpp" line="233"/>
186 <source>Zip file format detected</source>
187 <translation>Zjištěn formát zip</translation>
188 </message>
189 <message>
190 <location filename="../base/bootloaderinstallbase.cpp" line="245"/>
191 <source>CAB file format detected</source>
192 <translation>Zjištěn formát CAB</translation>
193 </message>
194 <message>
195 <location filename="../base/bootloaderinstallbase.cpp" line="266"/>
196 <source>Extracting firmware %1 from archive</source>
197 <translation>Rozbaluji firmware %1 z archivu</translation>
198 </message>
199 <message>
200 <location filename="../base/bootloaderinstallbase.cpp" line="273"/>
201 <source>Error extracting firmware from archive</source>
202 <translation>Chyba rozbalování fimware z archivu</translation>
203 </message>
204 <message>
205 <location filename="../base/bootloaderinstallbase.cpp" line="282"/>
206 <source>Could not find firmware in archive</source>
207 <translation>Firmware v archivu nenalezen</translation>
208 </message>
209 <message>
210 <location filename="../base/bootloaderinstallbase.cpp" line="166"/>
211 <source>Waiting for system to remount player</source>
212 <translation>Čekám na znovupřipojení přehrávače</translation>
213 </message>
214 <message>
215 <location filename="../base/bootloaderinstallbase.cpp" line="196"/>
216 <source>Player remounted</source>
217 <translation>Přehrávač znovupřipojen</translation>
218 </message>
219 <message>
220 <location filename="../base/bootloaderinstallbase.cpp" line="201"/>
221 <source>Timeout on remount</source>
222 <translation>Vypršel limit znovuzavedení</translation>
223 </message>
224</context>
225<context>
226 <name>BootloaderInstallChinaChip</name>
227 <message>
228 <location filename="../base/bootloaderinstallchinachip.cpp" line="33"/>
229 <source>Bootloader installation requires you to provide a firmware file of the original firmware (HXF file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
230 <translation>Instalace zavaděče vyžaduje poskytnutí firmware souboru původního firmware (HXF soubor) Tento soubor si z právních důvodů musíte stáhnout sami. Podívejte se do &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;příručky&lt;/a&gt; a na &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki stránku jak získat tento soubor.&lt;br/&gt;Stiskněte Ok pro pokračování a vyberte umístění souboru ve vašem počítači.</translation>
231 </message>
232 <message>
233 <location filename="../base/bootloaderinstallchinachip.cpp" line="50"/>
234 <source>Downloading bootloader file</source>
235 <translation>Stahuji soubor zavaděče</translation>
236 </message>
237 <message>
238 <location filename="../base/bootloaderinstallchinachip.cpp" line="75"/>
239 <source>Could not open firmware file</source>
240 <translation>Soubor s firmware nelze otevřít</translation>
241 </message>
242 <message>
243 <location filename="../base/bootloaderinstallchinachip.cpp" line="78"/>
244 <source>Could not open bootloader file</source>
245 <translation>Soubor se zavaděčem nelze otevřít</translation>
246 </message>
247 <message>
248 <location filename="../base/bootloaderinstallchinachip.cpp" line="81"/>
249 <source>Could not allocate memory</source>
250 <translation>Nepodařilo se přidělit paměť</translation>
251 </message>
252 <message>
253 <location filename="../base/bootloaderinstallchinachip.cpp" line="84"/>
254 <source>Could not load firmware file</source>
255 <translation>Nepodařilo se načíst soubor s firmwarem</translation>
256 </message>
257 <message>
258 <location filename="../base/bootloaderinstallchinachip.cpp" line="87"/>
259 <source>File is not a valid ChinaChip firmware</source>
260 <translation>Toto není ChinaChip firmware</translation>
261 </message>
262 <message>
263 <location filename="../base/bootloaderinstallchinachip.cpp" line="90"/>
264 <source>Could not find ccpmp.bin in input file</source>
265 <translation>Ve vstupním souboru nelze nalézt ccpmp.bin</translation>
266 </message>
267 <message>
268 <location filename="../base/bootloaderinstallchinachip.cpp" line="93"/>
269 <source>Could not open backup file for ccpmp.bin</source>
270 <translation>Nepodařilo se otevřít záložní soubor pro ccpmp.bin</translation>
271 </message>
272 <message>
273 <location filename="../base/bootloaderinstallchinachip.cpp" line="96"/>
274 <source>Could not write backup file for ccpmp.bin</source>
275 <translation>Nepodařilo se zapsat záložní soubor pro ccpmp.bin</translation>
276 </message>
277 <message>
278 <location filename="../base/bootloaderinstallchinachip.cpp" line="99"/>
279 <source>Could not load bootloader file</source>
280 <translation>Nepodařilo se načíst soubor zavaděče</translation>
281 </message>
282 <message>
283 <location filename="../base/bootloaderinstallchinachip.cpp" line="102"/>
284 <source>Could not get current time</source>
285 <translation>Nepodařilo se načíst aktuální čas</translation>
286 </message>
287 <message>
288 <location filename="../base/bootloaderinstallchinachip.cpp" line="105"/>
289 <source>Could not open output file</source>
290 <translation>Nelze otevřít výstupní soubor</translation>
291 </message>
292 <message>
293 <location filename="../base/bootloaderinstallchinachip.cpp" line="108"/>
294 <source>Could not write output file</source>
295 <translation>Selhal zápis do výstupního souboru</translation>
296 </message>
297 <message>
298 <location filename="../base/bootloaderinstallchinachip.cpp" line="111"/>
299 <source>Unexpected error from chinachippatcher</source>
300 <translation>Neočekávaná chyba chinachip patcheru</translation>
301 </message>
302</context>
303<context>
304 <name>BootloaderInstallFile</name>
305 <message>
306 <location filename="../base/bootloaderinstallfile.cpp" line="34"/>
307 <source>Downloading bootloader</source>
308 <translation>Stahuji zavaděč</translation>
309 </message>
310 <message>
311 <location filename="../base/bootloaderinstallfile.cpp" line="43"/>
312 <source>Installing Rockbox bootloader</source>
313 <translation>Instaluji zavaděč Rockboxu</translation>
314 </message>
315 <message>
316 <location filename="../base/bootloaderinstallfile.cpp" line="75"/>
317 <source>Error accessing output folder</source>
318 <translation>Chyba přístupu do výstupní složky</translation>
319 </message>
320 <message>
321 <location filename="../base/bootloaderinstallfile.cpp" line="89"/>
322 <source>A firmware file is already present on player</source>
323 <translation>Soubor s firmwarem už v přehrávači existuje</translation>
324 </message>
325 <message>
326 <location filename="../base/bootloaderinstallfile.cpp" line="94"/>
327 <source>Bootloader successful installed</source>
328 <translation>Zavaděč úspěšně nainstalován</translation>
329 </message>
330 <message>
331 <location filename="../base/bootloaderinstallfile.cpp" line="97"/>
332 <source>Copying modified firmware file failed</source>
333 <translation>Kopírování upraveného firmware selhalo</translation>
334 </message>
335 <message>
336 <location filename="../base/bootloaderinstallfile.cpp" line="111"/>
337 <source>Removing Rockbox bootloader</source>
338 <translation>Odstraňuje se zavaděč Rockboxu</translation>
339 </message>
340 <message>
341 <location filename="../base/bootloaderinstallfile.cpp" line="115"/>
342 <source>No original firmware file found.</source>
343 <translation>Nenalezen původní soubor.firmwaru.</translation>
344 </message>
345 <message>
346 <location filename="../base/bootloaderinstallfile.cpp" line="121"/>
347 <source>Can&apos;t remove Rockbox bootloader file.</source>
348 <translation>Nelze odstranit soubor zavaděče Rockboxu.</translation>
349 </message>
350 <message>
351 <location filename="../base/bootloaderinstallfile.cpp" line="126"/>
352 <source>Can&apos;t restore bootloader file.</source>
353 <translation>Nelze obnovit soubor zavaděče.</translation>
354 </message>
355 <message>
356 <location filename="../base/bootloaderinstallfile.cpp" line="130"/>
357 <source>Original bootloader restored successfully.</source>
358 <translation>Původní zavaděč úspěšně obnoven.</translation>
359 </message>
360</context>
361<context>
362 <name>BootloaderInstallHex</name>
363 <message>
364 <location filename="../base/bootloaderinstallhex.cpp" line="50"/>
365 <source>Bootloader installation requires you to provide a firmware file of the original firmware (hex file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
366 <translation>Instalace zavaděče vyžaduje poskytnutí firmware souboru původního firmware (hex soubor) Tento soubor si z právních důvodů musíte stáhnout sami. Podívejte se do &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;příručky&lt;/a&gt; a na &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki stránku jak získat tento soubor.&lt;br/&gt;Stiskněte Ok pro pokračování a vyberte umístění souboru ve vašem počítači.</translation>
367 </message>
368 <message>
369 <location filename="../base/bootloaderinstallhex.cpp" line="69"/>
370 <source>checking MD5 hash of input file ...</source>
371 <translation>kontrola MD5 hashe ze vstupního souboru ...</translation>
372 </message>
373 <message>
374 <location filename="../base/bootloaderinstallhex.cpp" line="80"/>
375 <source>Could not verify original firmware file</source>
376 <translation>Nelze ověřit původní soubor s firmwarem</translation>
377 </message>
378 <message>
379 <location filename="../base/bootloaderinstallhex.cpp" line="95"/>
380 <source>Firmware file not recognized.</source>
381 <translation>Soubor firmware nerozpoznán.</translation>
382 </message>
383 <message>
384 <location filename="../base/bootloaderinstallhex.cpp" line="99"/>
385 <source>MD5 hash ok</source>
386 <translation>MD5 hash v pořádku</translation>
387 </message>
388 <message>
389 <location filename="../base/bootloaderinstallhex.cpp" line="106"/>
390 <source>Firmware file doesn&apos;t match selected player.</source>
391 <translation>Firmware neodpovídá vybranému přehrávači.</translation>
392 </message>
393 <message>
394 <location filename="../base/bootloaderinstallhex.cpp" line="111"/>
395 <source>Descrambling file</source>
396 <translation>Dekóduji soubor</translation>
397 </message>
398 <message>
399 <location filename="../base/bootloaderinstallhex.cpp" line="119"/>
400 <source>Error in descramble: %1</source>
401 <translation>Chyba dekódování: %1</translation>
402 </message>
403 <message>
404 <location filename="../base/bootloaderinstallhex.cpp" line="124"/>
405 <source>Downloading bootloader file</source>
406 <translation>Stahuji soubor zavaděče</translation>
407 </message>
408 <message>
409 <location filename="../base/bootloaderinstallhex.cpp" line="134"/>
410 <source>Adding bootloader to firmware file</source>
411 <translation>Přidávám zavaděč do souboru firmwaru</translation>
412 </message>
413 <message>
414 <location filename="../base/bootloaderinstallhex.cpp" line="172"/>
415 <source>could not open input file</source>
416 <translation>nelze otevřít vstupní soubor</translation>
417 </message>
418 <message>
419 <location filename="../base/bootloaderinstallhex.cpp" line="173"/>
420 <source>reading header failed</source>
421 <translation>čtení záhlaví selhalo</translation>
422 </message>
423 <message>
424 <location filename="../base/bootloaderinstallhex.cpp" line="174"/>
425 <source>reading firmware failed</source>
426 <translation>čtení firmware selhalo</translation>
427 </message>
428 <message>
429 <location filename="../base/bootloaderinstallhex.cpp" line="175"/>
430 <source>can&apos;t open bootloader file</source>
431 <translation>nelze otevřít soubor zavaděče</translation>
432 </message>
433 <message>
434 <location filename="../base/bootloaderinstallhex.cpp" line="176"/>
435 <source>reading bootloader file failed</source>
436 <translation>čtení souboru zavaděče selhalo</translation>
437 </message>
438 <message>
439 <location filename="../base/bootloaderinstallhex.cpp" line="177"/>
440 <source>can&apos;t open output file</source>
441 <translation>nelze otevřít výstupní soubor</translation>
442 </message>
443 <message>
444 <location filename="../base/bootloaderinstallhex.cpp" line="178"/>
445 <source>writing output file failed</source>
446 <translation>zápis výstupního souboru selhalo</translation>
447 </message>
448 <message>
449 <location filename="../base/bootloaderinstallhex.cpp" line="180"/>
450 <source>Error in patching: %1</source>
451 <translation>Chyba patchování: %1</translation>
452 </message>
453 <message>
454 <location filename="../base/bootloaderinstallhex.cpp" line="191"/>
455 <source>Error in scramble: %1</source>
456 <translation>Chyba šifrování: %1</translation>
457 </message>
458 <message>
459 <location filename="../base/bootloaderinstallhex.cpp" line="206"/>
460 <source>Checking modified firmware file</source>
461 <translation>Kontroluji modifikovaný soubor firmwaru</translation>
462 </message>
463 <message>
464 <location filename="../base/bootloaderinstallhex.cpp" line="208"/>
465 <source>Error: modified file checksum wrong</source>
466 <translation>Chyba: modifikovaný soubor má špatný kontrolní součet</translation>
467 </message>
468 <message>
469 <location filename="../base/bootloaderinstallhex.cpp" line="215"/>
470 <source>A firmware file is already present on player</source>
471 <translation>Soubor s firmware už v přehrávači existuje</translation>
472 </message>
473 <message>
474 <location filename="../base/bootloaderinstallhex.cpp" line="220"/>
475 <source>Success: modified firmware file created</source>
476 <translation>Úspěch: Vytvořen modifikovaný firmware</translation>
477 </message>
478 <message>
479 <location filename="../base/bootloaderinstallhex.cpp" line="223"/>
480 <source>Copying modified firmware file failed</source>
481 <translation>Kopírování upraveného firmware selhalo</translation>
482 </message>
483 <message>
484 <location filename="../base/bootloaderinstallhex.cpp" line="237"/>
485 <source>Uninstallation not possible, only installation info removed</source>
486 <translation>Odinstalace není možná, bylo odstraněna pouze informace o instalaci</translation>
487 </message>
488 <message>
489 <location filename="../base/bootloaderinstallhex.cpp" line="259"/>
490 <source>Can&apos;t open input file</source>
491 <translation>Nelze otevřít vstupní soubor</translation>
492 </message>
493 <message>
494 <location filename="../base/bootloaderinstallhex.cpp" line="260"/>
495 <source>Can&apos;t open output file</source>
496 <translation>Nelze otevřít výstupní soubor</translation>
497 </message>
498 <message>
499 <location filename="../base/bootloaderinstallhex.cpp" line="261"/>
500 <source>invalid file: header length wrong</source>
501 <translation>neplatný soubor: chybná délka záhlaví</translation>
502 </message>
503 <message>
504 <location filename="../base/bootloaderinstallhex.cpp" line="262"/>
505 <source>invalid file: unrecognized header</source>
506 <translation>neplatný soubor: nerozpoznané záhlaví</translation>
507 </message>
508 <message>
509 <location filename="../base/bootloaderinstallhex.cpp" line="263"/>
510 <source>invalid file: &quot;length&quot; field wrong</source>
511 <translation>neplatný soubor: chybná &quot;length&quot; hodnota</translation>
512 </message>
513 <message>
514 <location filename="../base/bootloaderinstallhex.cpp" line="264"/>
515 <source>invalid file: &quot;length2&quot; field wrong</source>
516 <translation>neplatný soubor: chybná &quot;length2&quot; hodnota</translation>
517 </message>
518 <message>
519 <location filename="../base/bootloaderinstallhex.cpp" line="265"/>
520 <source>invalid file: internal checksum error</source>
521 <translation>neplatný soubor: vnitřní chyba kontrolního součtu</translation>
522 </message>
523 <message>
524 <location filename="../base/bootloaderinstallhex.cpp" line="266"/>
525 <source>invalid file: &quot;length3&quot; field wrong</source>
526 <translation>neplatný soubor: chybná &quot;length3&quot; hodnota</translation>
527 </message>
528 <message>
529 <location filename="../base/bootloaderinstallhex.cpp" line="267"/>
530 <source>unknown</source>
531 <translation>neznámý</translation>
532 </message>
533</context>
534<context>
535 <name>BootloaderInstallImx</name>
536 <message>
537 <location filename="../base/bootloaderinstallimx.cpp" line="72"/>
538 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (firmware.sb file). This file will be patched with the Rockbox bootloader and installed to your player. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
539 <translation>Instalace zavaděče vyžaduje kopii původního firmware Sandisk (soubor firmware.sb). Ten bude opatchován a instalován do vašeho přehrávače spolu se zavaděčem Rockboxu. Z právních důvodů si tento soubor musíte stáhnou sami. Navštivte prosím &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;fórum Sansa Sandisk&lt;/a&gt; nebo se podívejte na &lt;a href=&apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wiki stránku jak ho získat. &lt;br/&gt;Vyberte OK pro pokračování a vyberte umístění souboru ve vašem počítači.</translation>
540 </message>
541 <message>
542 <location filename="../base/bootloaderinstallimx.cpp" line="94"/>
543 <source>Could not read original firmware file</source>
544 <translation>Nepodařilo se přečíst původní firmware</translation>
545 </message>
546 <message>
547 <location filename="../base/bootloaderinstallimx.cpp" line="100"/>
548 <source>Downloading bootloader file</source>
549 <translation>Stahuji soubor zavaděče</translation>
550 </message>
551 <message>
552 <location filename="../base/bootloaderinstallimx.cpp" line="110"/>
553 <source>Patching file...</source>
554 <translation>Patchuji soubor...</translation>
555 </message>
556 <message>
557 <location filename="../base/bootloaderinstallimx.cpp" line="137"/>
558 <source>Patching the original firmware failed</source>
559 <translation>Patchování původního firmware selhalo</translation>
560 </message>
561 <message>
562 <location filename="../base/bootloaderinstallimx.cpp" line="143"/>
563 <source>Succesfully patched firmware file</source>
564 <translation>Soubor firmware úspěšně opatchován</translation>
565 </message>
566 <message>
567 <location filename="../base/bootloaderinstallimx.cpp" line="158"/>
568 <source>Bootloader successful installed</source>
569 <translation>Zavaděč úspěšně nainstalován</translation>
570 </message>
571 <message>
572 <location filename="../base/bootloaderinstallimx.cpp" line="164"/>
573 <source>Patched bootloader could not be installed</source>
574 <translation>Opatchovaný zavaděč nemohl být nainstalován</translation>
575 </message>
576 <message>
577 <location filename="../base/bootloaderinstallimx.cpp" line="175"/>
578 <source>To uninstall, perform a normal upgrade with an unmodified original firmware.</source>
579 <translation>Pro odinstalaci proveďte běžnou aktualizaci s neupravovaným původním firmware.</translation>
580 </message>
581</context>
582<context>
583 <name>BootloaderInstallIpod</name>
584 <message>
585 <location filename="../base/bootloaderinstallipod.cpp" line="49"/>
586 <source>Error: can&apos;t allocate buffer memory!</source>
587 <translation>Chyba: Nemohu alokovat vyrovnávací paměť!</translation>
588 </message>
589 <message>
590 <location filename="../base/bootloaderinstallipod.cpp" line="80"/>
591 <source>Downloading bootloader file</source>
592 <translation>Stahuji soubor zavaděče</translation>
593 </message>
594 <message>
595 <location filename="../base/bootloaderinstallipod.cpp" line="90"/>
596 <source>Installing Rockbox bootloader</source>
597 <translation>Instaluji zavaděč Rockboxu</translation>
598 </message>
599 <message>
600 <location filename="../base/bootloaderinstallipod.cpp" line="64"/>
601 <location filename="../base/bootloaderinstallipod.cpp" line="151"/>
602 <source>Failed to read firmware directory</source>
603 <translation>Chyba čtení adresáře firmwaru</translation>
604 </message>
605 <message>
606 <location filename="../base/bootloaderinstallipod.cpp" line="69"/>
607 <location filename="../base/bootloaderinstallipod.cpp" line="156"/>
608 <source>Unknown version number in firmware (%1)</source>
609 <translation>Neznámá verze firmwaru (%1)</translation>
610 </message>
611 <message>
612 <location filename="../base/bootloaderinstallipod.cpp" line="75"/>
613 <source>Warning: This is a MacPod, Rockbox only runs on WinPods.
614See http://www.rockbox.org/wiki/IpodConversionToFAT32</source>
615 <translation>Pozor: Tohle je MacPod, Rockbox funguje pouzena WinPodu.
616Viz http://www.rockbox.org/wiki/IpodConversionToFAT32</translation>
617 </message>
618 <message>
619 <location filename="../base/bootloaderinstallipod.cpp" line="94"/>
620 <location filename="../base/bootloaderinstallipod.cpp" line="163"/>
621 <source>Could not open Ipod in R/W mode</source>
622 <translation>Nelze otevřít Ipod pro čtení a zápis</translation>
623 </message>
624 <message>
625 <location filename="../base/bootloaderinstallipod.cpp" line="104"/>
626 <source>Successfull added bootloader</source>
627 <translation>Zavaděč úspěšně přidán</translation>
628 </message>
629 <message>
630 <location filename="../base/bootloaderinstallipod.cpp" line="115"/>
631 <source>Failed to add bootloader</source>
632 <translation>Přidání zavaděče selhalo</translation>
633 </message>
634 <message>
635 <location filename="../base/bootloaderinstallipod.cpp" line="127"/>
636 <source>Bootloader Installation complete.</source>
637 <translation>Zavaděč úspěšně nainstalován.</translation>
638 </message>
639 <message>
640 <location filename="../base/bootloaderinstallipod.cpp" line="132"/>
641 <source>Writing log aborted</source>
642 <translation>Zápis výpisu přerušen</translation>
643 </message>
644 <message>
645 <location filename="../base/bootloaderinstallipod.cpp" line="142"/>
646 <source>Uninstalling bootloader</source>
647 <translation>Odinstalace zavaděče</translation>
648 </message>
649 <message>
650 <location filename="../base/bootloaderinstallipod.cpp" line="169"/>
651 <source>No bootloader detected.</source>
652 <translation>Zavaděč nenalezen.</translation>
653 </message>
654 <message>
655 <location filename="../base/bootloaderinstallipod.cpp" line="175"/>
656 <source>Successfully removed bootloader</source>
657 <translation>Zavaděč úspěšně odstraněn</translation>
658 </message>
659 <message>
660 <location filename="../base/bootloaderinstallipod.cpp" line="183"/>
661 <source>Removing bootloader failed.</source>
662 <translation>Odstranění zavaděče selhalo.</translation>
663 </message>
664 <message>
665 <location filename="../base/bootloaderinstallipod.cpp" line="229"/>
666 <source>Error: could not retrieve device name</source>
667 <translation>Chyba: nepodařilo se zjistit jméno zařízení</translation>
668 </message>
669 <message>
670 <location filename="../base/bootloaderinstallipod.cpp" line="245"/>
671 <source>Error: no mountpoint specified!</source>
672 <translation>Chyba: Není zvolen přípojný bod!</translation>
673 </message>
674 <message>
675 <location filename="../base/bootloaderinstallipod.cpp" line="250"/>
676 <source>Could not open Ipod: permission denied</source>
677 <translation>Nelze otevřít Ipod: nepovolený přístup</translation>
678 </message>
679 <message>
680 <location filename="../base/bootloaderinstallipod.cpp" line="254"/>
681 <source>Could not open Ipod</source>
682 <translation>Nelze otevřít Ipod</translation>
683 </message>
684 <message>
685 <location filename="../base/bootloaderinstallipod.cpp" line="259"/>
686 <source>Error reading partition table - possibly not an Ipod</source>
687 <translation>Chyba při čtení tabulky oddílů - možná to není Ipod</translation>
688 </message>
689 <message>
690 <location filename="../base/bootloaderinstallipod.cpp" line="265"/>
691 <source>No firmware partition on disk</source>
692 <translation>Na disku není oddíl s firmwarem</translation>
693 </message>
694</context>
695<context>
696 <name>BootloaderInstallMi4</name>
697 <message>
698 <location filename="../base/bootloaderinstallmi4.cpp" line="34"/>
699 <source>Downloading bootloader</source>
700 <translation>Stahuji soubor zavaděče</translation>
701 </message>
702 <message>
703 <location filename="../base/bootloaderinstallmi4.cpp" line="43"/>
704 <source>Installing Rockbox bootloader</source>
705 <translation>Instaluji zavaděč Rockboxu</translation>
706 </message>
707 <message>
708 <location filename="../base/bootloaderinstallmi4.cpp" line="66"/>
709 <source>A firmware file is already present on player</source>
710 <translation>Soubor s firmwarem už v přehrávači existuje</translation>
711 </message>
712 <message>
713 <location filename="../base/bootloaderinstallmi4.cpp" line="71"/>
714 <location filename="../base/bootloaderinstallmi4.cpp" line="79"/>
715 <source>Bootloader successful installed</source>
716 <translation>Zavaděč úspěšně instalován</translation>
717 </message>
718 <message>
719 <location filename="../base/bootloaderinstallmi4.cpp" line="74"/>
720 <source>Copying modified firmware file failed</source>
721 <translation>Kopírování upraveného firmwaru selhalo</translation>
722 </message>
723 <message>
724 <location filename="../base/bootloaderinstallmi4.cpp" line="91"/>
725 <source>Checking for Rockbox bootloader</source>
726 <translation>Zjišťuje se přítomnost zavaděče Rockboxu</translation>
727 </message>
728 <message>
729 <location filename="../base/bootloaderinstallmi4.cpp" line="93"/>
730 <source>No Rockbox bootloader found</source>
731 <translation>Zavaděč Rockboxu nenalezen</translation>
732 </message>
733 <message>
734 <location filename="../base/bootloaderinstallmi4.cpp" line="99"/>
735 <source>Checking for original firmware file</source>
736 <translation>Zjišťuje se přítomnost původního souboru firmware</translation>
737 </message>
738 <message>
739 <location filename="../base/bootloaderinstallmi4.cpp" line="104"/>
740 <source>Error finding original firmware file</source>
741 <translation>Nenalazen originální soubor firmwaru</translation>
742 </message>
743 <message>
744 <location filename="../base/bootloaderinstallmi4.cpp" line="115"/>
745 <source>Rockbox bootloader successful removed</source>
746 <translation>Zavaděč Rockboxu úspěšně odstraněn</translation>
747 </message>
748</context>
749<context>
750 <name>BootloaderInstallMpio</name>
751 <message>
752 <location filename="../base/bootloaderinstallmpio.cpp" line="34"/>
753 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
754 <translation>Instalace zavaděče vyžaduje kopii původního firmware (soubor bin). Z právních důvodů si tento soubor musíte stáhnou sami. Podívejte se prosím do &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;příručky&lt;/a&gt; a na &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wiki stránku jak ho získat. &lt;br/&gt;Vyberte OK pro pokračování a vyberte umístění souboru ve vašem počítači.</translation>
755 </message>
756 <message>
757 <location filename="../base/bootloaderinstallmpio.cpp" line="53"/>
758 <source>Downloading bootloader file</source>
759 <translation>Stahuji soubor zavaděče</translation>
760 </message>
761 <message>
762 <location filename="../base/bootloaderinstallmpio.cpp" line="80"/>
763 <source>Could not open the original firmware.</source>
764 <translation>Nepodařilo se otevřít původní firmware.</translation>
765 </message>
766 <message>
767 <location filename="../base/bootloaderinstallmpio.cpp" line="83"/>
768 <source>Could not read the original firmware.</source>
769 <translation>Nelze přečíst původní firmware.</translation>
770 </message>
771 <message>
772 <location filename="../base/bootloaderinstallmpio.cpp" line="86"/>
773 <source>Loaded firmware file does not look like MPIO original firmware file.</source>
774 <translation>Načtený firmware nevypadá jako původní MPIO firmware.</translation>
775 </message>
776 <message>
777 <location filename="../base/bootloaderinstallmpio.cpp" line="101"/>
778 <source>Could not open output file.</source>
779 <translation>Nelze otevřít výstupní soubor.</translation>
780 </message>
781 <message>
782 <location filename="../base/bootloaderinstallmpio.cpp" line="104"/>
783 <source>Could not write output file.</source>
784 <translation>Nelze zapsat výstupní soubor.</translation>
785 </message>
786 <message>
787 <location filename="../base/bootloaderinstallmpio.cpp" line="107"/>
788 <source>Unknown error number: %1</source>
789 <translation>Neznámá chyba číslo: %1</translation>
790 </message>
791 <message>
792 <location filename="../base/bootloaderinstallmpio.cpp" line="89"/>
793 <source>Could not open downloaded bootloader.</source>
794 <translation>Nelze otevřít stažený zavaděč.</translation>
795 </message>
796 <message>
797 <location filename="../base/bootloaderinstallmpio.cpp" line="92"/>
798 <source>Place for bootloader in OF file not empty.</source>
799 <translation>Místo pro zavaděč v OF souboru není prázdné.</translation>
800 </message>
801 <message>
802 <location filename="../base/bootloaderinstallmpio.cpp" line="95"/>
803 <source>Could not read the downloaded bootloader.</source>
804 <translation>Nelze přečíst stažený zavaděč.</translation>
805 </message>
806 <message>
807 <location filename="../base/bootloaderinstallmpio.cpp" line="98"/>
808 <source>Bootloader checksum error.</source>
809 <translation>Chybný kontrolní součet zavaděče.</translation>
810 </message>
811 <message>
812 <location filename="../base/bootloaderinstallmpio.cpp" line="112"/>
813 <source>Patching original firmware failed: %1</source>
814 <translation>Patchování původního firmware se nezdařilo: %1</translation>
815 </message>
816 <message>
817 <location filename="../base/bootloaderinstallmpio.cpp" line="119"/>
818 <source>Success: modified firmware file created</source>
819 <translation>Úspěch: Vytvořen modifikovaný firmware</translation>
820 </message>
821 <message>
822 <location filename="../base/bootloaderinstallmpio.cpp" line="127"/>
823 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
824 <translation>Pro odinstalaci proveďte běžnou aktualizaci s neupravovaným původním firmware</translation>
825 </message>
826</context>
827<context>
828 <name>BootloaderInstallS5l</name>
829 <message>
830 <location filename="../base/bootloaderinstalls5l.cpp" line="61"/>
831 <source>Could not find mounted iPod.</source>
832 <translation>Nepodařilo se nalézt připojený iPod.</translation>
833 </message>
834 <message>
835 <location filename="../base/bootloaderinstalls5l.cpp" line="68"/>
836 <source>Downloading bootloader file...</source>
837 <translation>Stahuji soubor zavaděče...</translation>
838 </message>
839 <message>
840 <location filename="../base/bootloaderinstalls5l.cpp" line="110"/>
841 <source>Could not make DFU image.</source>
842 <translation>Nepodařilo se vytvořit obraz DFU.</translation>
843 </message>
844 <message>
845 <location filename="../base/bootloaderinstalls5l.cpp" line="116"/>
846 <source>Ejecting iPod...</source>
847 <translation>Odpojuji iPod...</translation>
848 </message>
849 <message>
850 <location filename="../base/bootloaderinstalls5l.cpp" line="138"/>
851 <source>Action required:
852 Please make sure no programs are accessing
853 files on the device. If ejecting still fails
854 please use your computers eject funtionality.</source>
855 <translation>Je nutný zásah:
856 Přesvědčte se prosím, že žádné programy nepracují
857 se soubory na zařízení. Jestliže odpojení přesto selže
858 využijte prosím funkci odpojení vašeho počítače.</translation>
859 </message>
860 <message>
861 <location filename="../base/bootloaderinstalls5l.cpp" line="148"/>
862 <source>Device successfully ejected.</source>
863 <translation>Zařízení úspěšně odpojeno.</translation>
864 </message>
865 <message>
866 <location filename="../base/bootloaderinstalls5l.cpp" line="168"/>
867 <source>Action required:
868 Quit iTunes application.</source>
869 <translation>Je nutný zásah:
870 Ukončete aplikaci iTunes.</translation>
871 </message>
872 <message>
873 <location filename="../base/bootloaderinstalls5l.cpp" line="176"/>
874 <source>iTunes closed.</source>
875 <translation>iTunes ukončeny.</translation>
876 </message>
877 <message>
878 <location filename="../base/bootloaderinstalls5l.cpp" line="189"/>
879 <source>Could not suspend iTunesHelper. Stop it
880using the Task Manager, and try again.</source>
881 <translation>Nepodařilo se zavřít iTunesHelper. Ukončete ho
882prostřednictvím Správce úloh a zkuste to znovu.</translation>
883 </message>
884 <message>
885 <location filename="../base/bootloaderinstalls5l.cpp" line="198"/>
886 <source>Waiting for HDD spin-down...</source>
887 <translation>Čekám na zastavení HDD...</translation>
888 </message>
889 <message>
890 <location filename="../base/bootloaderinstalls5l.cpp" line="214"/>
891 <source>Waiting for DFU mode...</source>
892 <translation>Čekám na DFU režim...</translation>
893 </message>
894 <message>
895 <location filename="../base/bootloaderinstalls5l.cpp" line="215"/>
896 <source>Action required:
897 Press and hold SELECT+MENU buttons, after
898 about 12 seconds a new action will require
899 you to release the buttons, DO IT QUICKLY,
900 otherwise the process could fail.</source>
901 <translation>Je nutný zásah:
902 Zmáčkněte a držte tlačítka SELECT+MENU, po
903 zhruba 12 sekundách bude nutné tlačítka pustit
904 UDĚLEJTE TO RYCHLE, jinak může proces selhat.</translation>
905 </message>
906 <message>
907 <location filename="../base/bootloaderinstalls5l.cpp" line="238"/>
908 <source>DFU mode detected.</source>
909 <translation>Zjištěn DFU režim.</translation>
910 </message>
911 <message>
912 <location filename="../base/bootloaderinstalls5l.cpp" line="240"/>
913 <source>Action required:
914 Release SELECT+MENU buttons and wait...</source>
915 <translation>Je nutný zásah:
916 Pusťte tlačítka SELECT+MENU a čekejte...</translation>
917 </message>
918 <message>
919 <location filename="../base/bootloaderinstalls5l.cpp" line="265"/>
920 <source>Device is not in DFU mode. It seems that
921the previous required action failed, please
922try again.</source>
923 <translation>Zařízení není v DFU režimu. Zdá se,
924že předchozí potřebný zásah selhal. Prosím,
925zkuste to znovu.</translation>
926 </message>
927 <message>
928 <location filename="../base/bootloaderinstalls5l.cpp" line="272"/>
929 <source>Transfering DFU image...</source>
930 <translation>Přenáším DFU obraz...</translation>
931 </message>
932 <message>
933 <location filename="../base/bootloaderinstalls5l.cpp" line="282"/>
934 <source>No valid DFU USB driver found.
935Install iTunes (or the Apple Device Driver)
936and try again.</source>
937 <translation>Nebyl nalezen platný DFU USB ovladač.
938Instalujte iTunes (nebo Apple Device Driver)
939a zkuste to znovu.</translation>
940 </message>
941 <message>
942 <location filename="../base/bootloaderinstalls5l.cpp" line="291"/>
943 <source>Could not transfer DFU image.</source>
944 <translation>Nebylo možné přenést DFU obraz.</translation>
945 </message>
946 <message>
947 <location filename="../base/bootloaderinstalls5l.cpp" line="296"/>
948 <source>DFU transfer completed.</source>
949 <translation>Přenos DFU kompletní.</translation>
950 </message>
951 <message>
952 <location filename="../base/bootloaderinstalls5l.cpp" line="299"/>
953 <source>Restarting iPod, waiting for remount...</source>
954 <translation>Restartuji iPod, čekám na znovupřipojení...</translation>
955 </message>
956 <message>
957 <location filename="../base/bootloaderinstalls5l.cpp" line="318"/>
958 <source>Action required:
959 Could not remount the device, try to do it
960 manually. If the iPod didn&apos;t restart, force
961 a reset by pressing SELECT+MENU buttons
962 for about 5 seconds. If the problem could
963 not be solved then click &apos;Abort&apos; to cancel.</source>
964 <translation>Je nutný zásah:
965 Zařízení se nepodařilo znovu připojit,
966 zkuste to prosím ručně. Jestliže se iPod
967 nerestartoval, vynuťte restart stisknutím
968 tlačítek SELECT+MENU na 5 sekund.
969 Jestliže se problém nepodařilo vyřešit, klikněte
970 na &apos;Zrušit&apos; pro přerušení.</translation>
971 </message>
972 <message>
973 <location filename="../base/bootloaderinstalls5l.cpp" line="330"/>
974 <source>Device remounted.</source>
975 <translation>Zařízení znovupřipojeno.</translation>
976 </message>
977 <message>
978 <location filename="../base/bootloaderinstalls5l.cpp" line="332"/>
979 <source>Bootloader successfully %1.</source>
980 <translation>Zavaděč úspěšně %1.</translation>
981 </message>
982 <message>
983 <location filename="../base/bootloaderinstalls5l.cpp" line="345"/>
984 <source>Could not resume iTunesHelper.</source>
985 <translation>Nelze obnovit iTunesHelper.</translation>
986 </message>
987 <message>
988 <location filename="../base/bootloaderinstalls5l.cpp" line="361"/>
989 <source>%1 aborted by user.</source>
990 <translation>%1 zrušeno uživatelem.</translation>
991 </message>
992</context>
993<context>
994 <name>BootloaderInstallSansa</name>
995 <message>
996 <location filename="../base/bootloaderinstallsansa.cpp" line="50"/>
997 <source>Error: can&apos;t allocate buffer memory!</source>
998 <translation>Chyba: Nemohu alokovat vyrovnávací paměť!</translation>
999 </message>
1000 <message>
1001 <location filename="../base/bootloaderinstallsansa.cpp" line="55"/>
1002 <source>Searching for Sansa</source>
1003 <translation>Hledám Sansu</translation>
1004 </message>
1005 <message>
1006 <location filename="../base/bootloaderinstallsansa.cpp" line="59"/>
1007 <source>Permission for disc access denied!
1008This is required to install the bootloader</source>
1009 <translation>Nepovolen přístup k disku!
1010Což je požadováno pro instalaci zavaděče</translation>
1011 </message>
1012 <message>
1013 <location filename="../base/bootloaderinstallsansa.cpp" line="66"/>
1014 <source>No Sansa detected!</source>
1015 <translation>Sansa nenalezena!</translation>
1016 </message>
1017 <message>
1018 <location filename="../base/bootloaderinstallsansa.cpp" line="79"/>
1019 <source>Downloading bootloader file</source>
1020 <translation>Stahuji soubor zavaděče</translation>
1021 </message>
1022 <message>
1023 <location filename="../base/bootloaderinstallsansa.cpp" line="94"/>
1024 <source>Installing Rockbox bootloader</source>
1025 <translation>Instaluji zavaděč Rockboxu</translation>
1026 </message>
1027 <message>
1028 <location filename="../base/bootloaderinstallsansa.cpp" line="71"/>
1029 <location filename="../base/bootloaderinstallsansa.cpp" line="179"/>
1030 <source>OLD ROCKBOX INSTALLATION DETECTED, ABORTING.
1031You must reinstall the original Sansa firmware before running
1032sansapatcher for the first time.
1033See http://www.rockbox.org/wiki/SansaE200Install
1034</source>
1035 <translation>Nalezena stará instalace Rockboxu, přerušuji.
1036Než poprvé spustíte sansapatcher,
1037musíte přeinstalovat původní Sansa firmware.
1038Viz http://www.rockbox.org/wiki/SansaE200Install
1039</translation>
1040 </message>
1041 <message>
1042 <location filename="../base/bootloaderinstallsansa.cpp" line="102"/>
1043 <location filename="../base/bootloaderinstallsansa.cpp" line="189"/>
1044 <source>Could not open Sansa in R/W mode</source>
1045 <translation>Nelze otevřít Sansu pro čtení a zápis</translation>
1046 </message>
1047 <message>
1048 <location filename="../base/bootloaderinstallsansa.cpp" line="111"/>
1049 <source>Checking downloaded bootloader</source>
1050 <translation>Kontroluji stažený zavaděč</translation>
1051 </message>
1052 <message>
1053 <location filename="../base/bootloaderinstallsansa.cpp" line="119"/>
1054 <source>Bootloader mismatch! Aborting.</source>
1055 <translation>Nesloulad zavaděče! Přerušuji.</translation>
1056 </message>
1057 <message>
1058 <location filename="../base/bootloaderinstallsansa.cpp" line="129"/>
1059 <source>Successfully installed bootloader</source>
1060 <translation>Zavaděč úspěšně nainstalován</translation>
1061 </message>
1062 <message>
1063 <location filename="../base/bootloaderinstallsansa.cpp" line="140"/>
1064 <source>Failed to install bootloader</source>
1065 <translation>Instalace zavaděče selhala</translation>
1066 </message>
1067 <message>
1068 <location filename="../base/bootloaderinstallsansa.cpp" line="153"/>
1069 <source>Bootloader Installation complete.</source>
1070 <translation>Zavaděč úspěšně nainstalován.</translation>
1071 </message>
1072 <message>
1073 <location filename="../base/bootloaderinstallsansa.cpp" line="158"/>
1074 <source>Writing log aborted</source>
1075 <translation>Zápis výpisu přerušen</translation>
1076 </message>
1077 <message>
1078 <location filename="../base/bootloaderinstallsansa.cpp" line="170"/>
1079 <source>Uninstalling bootloader</source>
1080 <translation>Odinstalovávám zavaděč</translation>
1081 </message>
1082 <message>
1083 <location filename="../base/bootloaderinstallsansa.cpp" line="195"/>
1084 <source>Successfully removed bootloader</source>
1085 <translation>Zavaděč úspěšně odstraněn</translation>
1086 </message>
1087 <message>
1088 <location filename="../base/bootloaderinstallsansa.cpp" line="203"/>
1089 <source>Removing bootloader failed.</source>
1090 <translation>Odstranění zavaděče selhalo.</translation>
1091 </message>
1092 <message>
1093 <location filename="../base/bootloaderinstallsansa.cpp" line="239"/>
1094 <source>Error: could not retrieve device name</source>
1095 <translation>Chyba: nepodařilo se zjistit jméno zařízení</translation>
1096 </message>
1097 <message>
1098 <location filename="../base/bootloaderinstallsansa.cpp" line="255"/>
1099 <source>Can&apos;t find Sansa</source>
1100 <translation>Nelze najít Sansu</translation>
1101 </message>
1102 <message>
1103 <location filename="../base/bootloaderinstallsansa.cpp" line="260"/>
1104 <source>Could not open Sansa</source>
1105 <translation>Sansu nelze otevřít</translation>
1106 </message>
1107 <message>
1108 <location filename="../base/bootloaderinstallsansa.cpp" line="265"/>
1109 <source>Could not read partition table</source>
1110 <translation>Nelze přečíst tabulku oddílů</translation>
1111 </message>
1112 <message>
1113 <location filename="../base/bootloaderinstallsansa.cpp" line="272"/>
1114 <source>Disk is not a Sansa (Error %1), aborting.</source>
1115 <translation>Disk není Sansa (chyba %1), přerušuji.</translation>
1116 </message>
1117</context>
1118<context>
1119 <name>BootloaderInstallTcc</name>
1120 <message>
1121 <location filename="../base/bootloaderinstalltcc.cpp" line="33"/>
1122 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wiki page on how to obtain the file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
1123 <translation>Instalace zavaděče vyžaduje kopii původního firmware (soubor bin). Z právních důvodů si tento soubor musíte stáhnout sami. Podívejte se prosím do &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;příručkyl&lt;/a&gt; a na &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wiki stránku jak ho získat. &lt;br/&gt;Vyberte OK pro pokračování a vyberte umístění souboru ve vašem počítači.</translation>
1124 </message>
1125 <message>
1126 <location filename="../base/bootloaderinstalltcc.cpp" line="50"/>
1127 <source>Downloading bootloader file</source>
1128 <translation>Stahuji soubor zavaděče</translation>
1129 </message>
1130 <message>
1131 <location filename="../base/bootloaderinstalltcc.cpp" line="82"/>
1132 <location filename="../base/bootloaderinstalltcc.cpp" line="99"/>
1133 <source>Could not load %1</source>
1134 <translation>Nelze načíst %1</translation>
1135 </message>
1136 <message>
1137 <location filename="../base/bootloaderinstalltcc.cpp" line="90"/>
1138 <source>Unknown OF file used: %1</source>
1139 <translation>Použit neznámý OF soubor: %1</translation>
1140 </message>
1141 <message>
1142 <location filename="../base/bootloaderinstalltcc.cpp" line="104"/>
1143 <source>Patching Firmware...</source>
1144 <translation>Patchuji firmware...</translation>
1145 </message>
1146 <message>
1147 <location filename="../base/bootloaderinstalltcc.cpp" line="111"/>
1148 <source>Could not patch firmware</source>
1149 <translation>Firmware nelze opatchovat</translation>
1150 </message>
1151 <message>
1152 <location filename="../base/bootloaderinstalltcc.cpp" line="117"/>
1153 <source>Could not open %1 for writing</source>
1154 <translation>Nelze otevřít %1 pro zápis</translation>
1155 </message>
1156 <message>
1157 <location filename="../base/bootloaderinstalltcc.cpp" line="126"/>
1158 <source>Could not write firmware file</source>
1159 <translation>Nelze zapsat soubor firmwaru</translation>
1160 </message>
1161 <message>
1162 <location filename="../base/bootloaderinstalltcc.cpp" line="131"/>
1163 <source>Success: modified firmware file created</source>
1164 <translation>Úspěch: Vytvořen modifikovaný firmware</translation>
1165 </message>
1166 <message>
1167 <location filename="../base/bootloaderinstalltcc.cpp" line="151"/>
1168 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
1169 <translation>Pro odinstalaci proveďte běžnou aktualizaci s neupravovaným původním firmware</translation>
1170 </message>
1171</context>
1172<context>
1173 <name>Changelog</name>
1174 <message>
1175 <location filename="../gui/changelogfrm.ui" line="17"/>
1176 <source>Changelog</source>
1177 <translation>Přehled změn</translation>
1178 </message>
1179 <message>
1180 <location filename="../gui/changelogfrm.ui" line="39"/>
1181 <source>Show on startup</source>
1182 <translation>Ukázat při spuštění</translation>
1183 </message>
1184 <message>
1185 <location filename="../gui/changelogfrm.ui" line="46"/>
1186 <source>&amp;Ok</source>
1187 <translation>&amp;OK</translation>
1188 </message>
1189</context>
1190<context>
1191 <name>Config</name>
1192 <message>
1193 <location filename="../configure.cpp" line="130"/>
1194 <source>The following errors occurred:</source>
1195 <translation>Nastaly následující problémy:</translation>
1196 </message>
1197 <message>
1198 <location filename="../configure.cpp" line="175"/>
1199 <source>No mountpoint given</source>
1200 <translation>Neposkytnut žádný přípojný bod</translation>
1201 </message>
1202 <message>
1203 <location filename="../configure.cpp" line="179"/>
1204 <source>Mountpoint does not exist</source>
1205 <translation>Přípojný bod neexistuje</translation>
1206 </message>
1207 <message>
1208 <location filename="../configure.cpp" line="183"/>
1209 <source>Mountpoint is not a directory.</source>
1210 <translation>Přípojný bod není adresář.</translation>
1211 </message>
1212 <message>
1213 <location filename="../configure.cpp" line="187"/>
1214 <source>Mountpoint is not writeable</source>
1215 <translation>Do přípojného bodu nelze zapisovat</translation>
1216 </message>
1217 <message>
1218 <location filename="../configure.cpp" line="202"/>
1219 <source>No player selected</source>
1220 <translation>Nevybrán žádný přehrávač</translation>
1221 </message>
1222 <message>
1223 <location filename="../configure.cpp" line="209"/>
1224 <source>Cache path not writeable. Leave path empty to default to systems temporary path.</source>
1225 <translation>Do zadané vyrovnávací paměti nelze zapisovat. Ponechejte prázdné pro nasměrování do dočasné složky systému.</translation>
1226 </message>
1227 <message>
1228 <location filename="../configure.cpp" line="228"/>
1229 <source>You need to fix the above errors before you can continue.</source>
1230 <translation>Budete muset opravit výše uvedené chyby, než budete moci pokračovat.</translation>
1231 </message>
1232 <message>
1233 <location filename="../configure.cpp" line="231"/>
1234 <source>Configuration error</source>
1235 <translation>Chyba nastavení</translation>
1236 </message>
1237 <message>
1238 <location filename="../configure.cpp" line="322"/>
1239 <source>Current cache size is %L1 kiB.</source>
1240 <translation>Aktuální velikost vyrovnávací paměti je %L1 kiB.</translation>
1241 </message>
1242 <message>
1243 <location filename="../configure.cpp" line="340"/>
1244 <source>Showing disabled targets</source>
1245 <translation>Zobrazit skrytá zařízení</translation>
1246 </message>
1247 <message>
1248 <location filename="../configure.cpp" line="341"/>
1249 <source>You just enabled showing targets that are marked disabled. Disabled targets are not recommended to end users. Please use this option only if you know what you are doing.</source>
1250 <translation>Vybrali jste zobrazení zařízení, která jsou skrytá. Ta nejsou doporučena pro běžné uživatele. Pokračujte jen pokud víte, co děláte.</translation>
1251 </message>
1252 <message>
1253 <location filename="../configure.cpp" line="448"/>
1254 <location filename="../configure.cpp" line="914"/>
1255 <source>TTS error</source>
1256 <translation>Chyba syntézy řeči</translation>
1257 </message>
1258 <message>
1259 <location filename="../configure.cpp" line="449"/>
1260 <location filename="../configure.cpp" line="915"/>
1261 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1262 <translation>Spuštění vybrané syntézy řeči selhalo a nelze ji použít.</translation>
1263 </message>
1264 <message>
1265 <location filename="../configure.cpp" line="455"/>
1266 <location filename="../configure.cpp" line="485"/>
1267 <source>Configuration OK</source>
1268 <translation>Nastavení je v pořádku</translation>
1269 </message>
1270 <message>
1271 <location filename="../configure.cpp" line="461"/>
1272 <location filename="../configure.cpp" line="490"/>
1273 <source>Configuration INVALID</source>
1274 <translation>Nastavení není platné</translation>
1275 </message>
1276 <message>
1277 <location filename="../configure.cpp" line="529"/>
1278 <source>Proxy Detection</source>
1279 <translation>Zjištění proxy</translation>
1280 </message>
1281 <message>
1282 <location filename="../configure.cpp" line="530"/>
1283 <source>The System Proxy settings are invalid!
1284Rockbox Utility can&apos;t work with this proxy settings. Make sure the system proxy is set correctly. Note that &quot;proxy auto-config (PAC)&quot; scripts are not supported by Rockbox Utility. If your system uses this you need to use manual proxy settings.</source>
1285 <translation>Chybné nastavení proxy v systému!
1286S tímto nastavením proxy nebude Rockbox Utilita fungovat. Ověřte, zda je v systému správně nastavena proxy. Skripty automatické konfigurace proxy (PAC) nejsou podporovány. Jestliže je váš systém používá, musíte proxy nastavit ručně.</translation>
1287 </message>
1288 <message>
1289 <location filename="../configure.cpp" line="643"/>
1290 <source>Set Cache Path</source>
1291 <translation>Umístění vyrovnávací paměti</translation>
1292 </message>
1293 <message>
1294 <location filename="../configure.cpp" line="665"/>
1295 <source>%1 (%2 GiB of %3 GiB free)</source>
1296 <translation>%1 (%2 GiB of %3 GiB volné)</translation>
1297 </message>
1298 <message>
1299 <location filename="../configure.cpp" line="739"/>
1300 <source>Multiple devices have been detected. Please disconnect all players but one and try again.</source>
1301 <translation>Bylo zjištěno více zařízení. Odpojte prosím všechny nepotřebné a zkuste to znovu.</translation>
1302 </message>
1303 <message>
1304 <location filename="../configure.cpp" line="742"/>
1305 <source>Detected devices:</source>
1306 <translation>Zjištěná zařízení:</translation>
1307 </message>
1308 <message>
1309 <location filename="../configure.cpp" line="747"/>
1310 <source>(unknown)</source>
1311 <translation>(neznámé)</translation>
1312 </message>
1313 <message>
1314 <location filename="../configure.cpp" line="749"/>
1315 <source>%1 at %2</source>
1316 <translation>%1 na %2</translation>
1317 </message>
1318 <message>
1319 <location filename="../configure.cpp" line="755"/>
1320 <source>Note: detecting connected devices might be ambiguous. You might have less devices connected than listed. In this case it might not be possible to detect your player unambiguously.</source>
1321 <translation>Poznámka: Nezjištění připojených zařízení může být z více důvodů. Můžete mít méně připojených zařízení, než je v seznamu. V tomto případě nemusí být možné jednoznačně zjistit váš přehrávač.</translation>
1322 </message>
1323 <message>
1324 <location filename="../configure.cpp" line="759"/>
1325 <location filename="../configure.cpp" line="763"/>
1326 <location filename="../configure.cpp" line="805"/>
1327 <source>Device Detection</source>
1328 <translation>Zjištění zařízení</translation>
1329 </message>
1330 <message>
1331 <location filename="../configure.cpp" line="780"/>
1332 <source>%1 in MTP mode found!
1333You need to change your player to MSC mode for installation. </source>
1334 <translation>Nalezen %1 v MTP režimu!
1335Musíte přepnout váš přehrávač do MSC módu, aby instalace proběhla. </translation>
1336 </message>
1337 <message>
1338 <location filename="../configure.cpp" line="788"/>
1339 <source>%1 &quot;MacPod&quot; found!
1340Rockbox needs a FAT formatted Ipod (so-called &quot;WinPod&quot;) to run. </source>
1341 <translation>Nalezen %1 &quot;MacPod&quot;!
1342Rockbox potřebuje k běhu Ipod naformátovaný jako FAT (tzv. &quot;WinPod&quot;). </translation>
1343 </message>
1344 <message>
1345 <source>Fatal error</source>
1346 <translation type="obsolete">Fatální chyba</translation>
1347 </message>
1348 <message>
1349 <location filename="../configure.cpp" line="774"/>
1350 <source>Detected an unsupported player:
1351%1
1352Sorry, Rockbox doesn&apos;t run on your player.</source>
1353 <translation>Detekován nepodporovaný přehrávač:
1354%1
1355Je nám líto, Rockbox neběží na vašem přehrávači.</translation>
1356 </message>
1357 <message>
1358 <source>Fatal: player incompatible</source>
1359 <translation type="obsolete">Fatální chyba: přehrávač neslučitelný</translation>
1360 </message>
1361 <message>
1362 <location filename="../configure.cpp" line="858"/>
1363 <source>Autodetection</source>
1364 <translation>Automatická detekce</translation>
1365 </message>
1366 <message>
1367 <location filename="../configure.cpp" line="859"/>
1368 <source>Could not detect a Mountpoint.
1369Select your Mountpoint manually.</source>
1370 <translation>Nelze zjistit přípojný bod.
1371Vyberte svůj přípojný bod ručně.</translation>
1372 </message>
1373 <message>
1374 <location filename="../configure.cpp" line="764"/>
1375 <source>Could not detect a device.
1376Select your device and Mountpoint manually.</source>
1377 <translation>Nelze zjistit zařízení.
1378Vyberte své zařízení a přípojný bod ručně.</translation>
1379 </message>
1380 <message>
1381 <location filename="../configure.cpp" line="794"/>
1382 <source>The player contains an incompatible filesystem.
1383Make sure you selected the correct mountpoint and the player is set up to use a filesystem compatible with Rockbox.</source>
1384 <translation>Přehrávač má nekompatibilní souborový systém.
1385Ujistěte se, že přehrávač je ve správném přípojném bodu a má souborový systém slučitelný s Rockboxem.</translation>
1386 </message>
1387 <message>
1388 <location filename="../configure.cpp" line="802"/>
1389 <source>An unknown error occured during player detection.</source>
1390 <translation>Při detekci přehrávače nastala neznámá chyba.</translation>
1391 </message>
1392 <message>
1393 <location filename="../configure.cpp" line="869"/>
1394 <source>Really delete cache?</source>
1395 <translation>Opravdu vymazat vyrovnávací paměť?</translation>
1396 </message>
1397 <message>
1398 <location filename="../configure.cpp" line="870"/>
1399 <source>Do you really want to delete the cache? Make absolutely sure this setting is correct as it will remove &lt;b&gt;all&lt;/b&gt; files in this folder!</source>
1400 <translation>Chcete opravdu vymazat vyrovnávací paměť? Ujistěte se, že ano, protože se odstraní &lt;b&gt;veškeré&lt;/b&gt; soubory v tomto adresáři!</translation>
1401 </message>
1402 <message>
1403 <location filename="../configure.cpp" line="878"/>
1404 <source>Path wrong!</source>
1405 <translation>Chybná cesta!</translation>
1406 </message>
1407 <message>
1408 <location filename="../configure.cpp" line="879"/>
1409 <source>The cache path is invalid. Aborting.</source>
1410 <translation>Umístění vyrovnávací paměti je chybné. Přerušuji.</translation>
1411 </message>
1412 <message>
1413 <location filename="../configure.cpp" line="921"/>
1414 <source>TTS configuration invalid</source>
1415 <translation>Nastavení syntézy řeči je chybné</translation>
1416 </message>
1417 <message>
1418 <location filename="../configure.cpp" line="922"/>
1419 <source>TTS configuration invalid.
1420 Please configure TTS engine.</source>
1421 <translation>Nastavení syntézy řeči je chybné.
1422Prosím nastavte engine snytézy řeči.</translation>
1423 </message>
1424 <message>
1425 <location filename="../configure.cpp" line="927"/>
1426 <source>Could not start TTS engine.</source>
1427 <translation>Nelze spustit engine syntézy řeči.</translation>
1428 </message>
1429 <message>
1430 <location filename="../configure.cpp" line="928"/>
1431 <source>Could not start TTS engine.
1432</source>
1433 <translation>Nelze spustit engine syntézy řeči.
1434</translation>
1435 </message>
1436 <message>
1437 <location filename="../configure.cpp" line="929"/>
1438 <location filename="../configure.cpp" line="948"/>
1439 <source>
1440Please configure TTS engine.</source>
1441 <translation>
1442Prosím nastavte engine syntézy řeči.</translation>
1443 </message>
1444 <message>
1445 <location filename="../configure.cpp" line="943"/>
1446 <source>Rockbox Utility Voice Test</source>
1447 <translation>Hlasový test Rockbox Utility</translation>
1448 </message>
1449 <message>
1450 <location filename="../configure.cpp" line="946"/>
1451 <source>Could not voice test string.</source>
1452 <translation>Nepodařil se hlasový test řetězce.</translation>
1453 </message>
1454 <message>
1455 <location filename="../configure.cpp" line="947"/>
1456 <source>Could not voice test string.
1457</source>
1458 <translation>Nepodařil se hlasový test řetězce.
1459</translation>
1460 </message>
1461</context>
1462<context>
1463 <name>ConfigForm</name>
1464 <message>
1465 <location filename="../configurefrm.ui" line="14"/>
1466 <source>Configuration</source>
1467 <translation>Nastavení</translation>
1468 </message>
1469 <message>
1470 <location filename="../configurefrm.ui" line="20"/>
1471 <source>Configure Rockbox Utility</source>
1472 <translation>Nastavení Rockbox Utility</translation>
1473 </message>
1474 <message>
1475 <location filename="../configurefrm.ui" line="35"/>
1476 <source>&amp;Device</source>
1477 <translation>&amp;Zařízení</translation>
1478 </message>
1479 <message>
1480 <location filename="../configurefrm.ui" line="41"/>
1481 <source>Select your device in the &amp;filesystem</source>
1482 <translation>Vyberte své zařízení v &amp;systému</translation>
1483 </message>
1484 <message>
1485 <location filename="../configurefrm.ui" line="319"/>
1486 <source>&amp;Browse</source>
1487 <translation>&amp;Procházet</translation>
1488 </message>
1489 <message>
1490 <location filename="../configurefrm.ui" line="72"/>
1491 <source>&amp;Select your audio player</source>
1492 <translation>&amp;Vyberte váš audio přehrávač</translation>
1493 </message>
1494 <message>
1495 <location filename="../configurefrm.ui" line="58"/>
1496 <source>&amp;Refresh</source>
1497 <translation>O&amp;bnovit</translation>
1498 </message>
1499 <message>
1500 <location filename="../configurefrm.ui" line="95"/>
1501 <source>Show disabled targets</source>
1502 <translation>Zobrazit skrytá zařízení</translation>
1503 </message>
1504 <message>
1505 <location filename="../configurefrm.ui" line="114"/>
1506 <source>&amp;Autodetect</source>
1507 <translation>&amp;Zjistit automaticky</translation>
1508 </message>
1509 <message>
1510 <location filename="../configurefrm.ui" line="136"/>
1511 <source>&amp;Proxy</source>
1512 <translation>&amp;Proxy</translation>
1513 </message>
1514 <message>
1515 <location filename="../configurefrm.ui" line="142"/>
1516 <source>&amp;No Proxy</source>
1517 <translation>&amp;Žádné proxy</translation>
1518 </message>
1519 <message>
1520 <location filename="../configurefrm.ui" line="152"/>
1521 <source>Use S&amp;ystem values</source>
1522 <translation>Použít s&amp;ystémové hodnoty</translation>
1523 </message>
1524 <message>
1525 <location filename="../configurefrm.ui" line="159"/>
1526 <source>&amp;Manual Proxy settings</source>
1527 <translation>&amp;Ruční nastavení proxy</translation>
1528 </message>
1529 <message>
1530 <location filename="../configurefrm.ui" line="166"/>
1531 <source>Proxy Values</source>
1532 <translation>Nastavení proxy</translation>
1533 </message>
1534 <message>
1535 <location filename="../configurefrm.ui" line="172"/>
1536 <source>&amp;Host:</source>
1537 <translation>&amp;Host:</translation>
1538 </message>
1539 <message>
1540 <location filename="../configurefrm.ui" line="182"/>
1541 <source>&amp;Port:</source>
1542 <translation>&amp;Port:</translation>
1543 </message>
1544 <message>
1545 <location filename="../configurefrm.ui" line="199"/>
1546 <source>&amp;Username</source>
1547 <translation>&amp;Uživatelské jméno</translation>
1548 </message>
1549 <message>
1550 <location filename="../configurefrm.ui" line="209"/>
1551 <source>Pass&amp;word</source>
1552 <translation>He&amp;slo</translation>
1553 </message>
1554 <message>
1555 <location filename="../configurefrm.ui" line="219"/>
1556 <source>Show</source>
1557 <translation>Zobrazit</translation>
1558 </message>
1559 <message>
1560 <location filename="../configurefrm.ui" line="260"/>
1561 <source>&amp;Language</source>
1562 <translation>&amp;Jazyk</translation>
1563 </message>
1564 <message>
1565 <location filename="../configurefrm.ui" line="274"/>
1566 <source>Cac&amp;he</source>
1567 <translation>Vy&amp;rovnávací paměť</translation>
1568 </message>
1569 <message>
1570 <location filename="../configurefrm.ui" line="277"/>
1571 <source>Download cache settings</source>
1572 <translation>Nastavení vyrovnávací paměti stahování</translation>
1573 </message>
1574 <message>
1575 <location filename="../configurefrm.ui" line="283"/>
1576 <source>Rockbox Utility uses a local download cache to save network traffic. You can change the path to the cache and use it as local repository by enabling Offline mode.</source>
1577 <translation>Rockbox Utilita používá lokální vyrovnávací paměť, aby šetřila síťový přenos. Můžete změnit cestu do vyrovnávací paměti a použít ji jako lokální úložiště zvolením Offline módu.</translation>
1578 </message>
1579 <message>
1580 <location filename="../configurefrm.ui" line="293"/>
1581 <source>Current cache size is %1</source>
1582 <translation>Aktuální velikost vyrovnávací paměti je %1</translation>
1583 </message>
1584 <message>
1585 <location filename="../configurefrm.ui" line="302"/>
1586 <source>P&amp;ath</source>
1587 <translation>C&amp;esta</translation>
1588 </message>
1589 <message>
1590 <location filename="../configurefrm.ui" line="312"/>
1591 <source>Entering an invalid folder will reset the path to the systems temporary path.</source>
1592 <translation>Zadáním neplatného adresáře se resetuje cesta do dočasného adresáře systému.</translation>
1593 </message>
1594 <message>
1595 <location filename="../configurefrm.ui" line="334"/>
1596 <source>Disable local &amp;download cache</source>
1597 <translation>Zakázat lokální vyrovnávací paměť &amp;stahování</translation>
1598 </message>
1599 <message>
1600 <source>&lt;p&gt;This will try to use all information from the cache, even information about updates. Only use this option if you want to install without network connection. Note: you need to do the same install you want to perform later with network access first to download all required files to the cache.&lt;/p&gt;</source>
1601 <translation type="obsolete">&lt;p&gt;Pokud toto zvolíte, všechny informace se utilita pokusí získat z vyrovnávací paměti, i o aktualizacích. Použijte tuto možnost pouze pokud chcete instalovat Rockbox bez připojení k internetu. Poznámka:nyní musíte provést stejnou instalaci (s připojením k internetu), jakou budete chtít provést později, aby se stáhnuly všechny potřebné soubory do vyrovnávací paměti.&lt;/p&gt;</translation>
1602 </message>
1603 <message>
1604 <source>O&amp;ffline mode</source>
1605 <translation type="obsolete">O&amp;ffline mód</translation>
1606 </message>
1607 <message>
1608 <location filename="../configurefrm.ui" line="369"/>
1609 <source>Clean cache &amp;now</source>
1610 <translation>Vyčistit vyrovnávací &amp;paměť</translation>
1611 </message>
1612 <message>
1613 <location filename="../configurefrm.ui" line="385"/>
1614 <source>&amp;TTS &amp;&amp; Encoder</source>
1615 <translation>&amp;Syntéza řeči a enkodér</translation>
1616 </message>
1617 <message>
1618 <location filename="../configurefrm.ui" line="391"/>
1619 <source>TTS Engine</source>
1620 <translation>Engine syntézy řeči</translation>
1621 </message>
1622 <message>
1623 <location filename="../configurefrm.ui" line="397"/>
1624 <source>&amp;Select TTS Engine</source>
1625 <translation>&amp;Vyberte engine syntézy řeči</translation>
1626 </message>
1627 <message>
1628 <location filename="../configurefrm.ui" line="410"/>
1629 <source>Configure TTS Engine</source>
1630 <translation>Nastavení enginu syntézy řeči</translation>
1631 </message>
1632 <message>
1633 <location filename="../configurefrm.ui" line="417"/>
1634 <location filename="../configurefrm.ui" line="468"/>
1635 <source>Configuration invalid!</source>
1636 <translation>Chybně nastaven!</translation>
1637 </message>
1638 <message>
1639 <location filename="../configurefrm.ui" line="434"/>
1640 <source>Configure &amp;TTS</source>
1641 <translation>Nastavení &amp;syntézy řeči</translation>
1642 </message>
1643 <message>
1644 <location filename="../configurefrm.ui" line="445"/>
1645 <source>Test TTS</source>
1646 <translation>Testovat syntézu řeči</translation>
1647 </message>
1648 <message>
1649 <location filename="../configurefrm.ui" line="452"/>
1650 <source>&amp;Use string corrections for TTS</source>
1651 <translation>&amp;Použít opravy vláken pro syntézu řeči</translation>
1652 </message>
1653 <message>
1654 <location filename="../configurefrm.ui" line="462"/>
1655 <source>Encoder Engine</source>
1656 <translation>Engine enkodéru</translation>
1657 </message>
1658 <message>
1659 <location filename="../configurefrm.ui" line="485"/>
1660 <source>Configure &amp;Enc</source>
1661 <translation>Nastavení &amp;enkodéru</translation>
1662 </message>
1663 <message>
1664 <location filename="../configurefrm.ui" line="496"/>
1665 <source>encoder name</source>
1666 <translation>jméno enkodéru</translation>
1667 </message>
1668 <message>
1669 <location filename="../configurefrm.ui" line="536"/>
1670 <source>&amp;Ok</source>
1671 <translation>&amp;OK</translation>
1672 </message>
1673 <message>
1674 <location filename="../configurefrm.ui" line="547"/>
1675 <source>&amp;Cancel</source>
1676 <translation>&amp;Zrušit</translation>
1677 </message>
1678</context>
1679<context>
1680 <name>Configure</name>
1681 <message>
1682 <location filename="../configure.cpp" line="589"/>
1683 <source>English</source>
1684 <comment>This is the localized language name, i.e. your language.</comment>
1685 <translation>Čeština</translation>
1686 </message>
1687</context>
1688<context>
1689 <name>CreateVoiceFrm</name>
1690 <message>
1691 <location filename="../createvoicefrm.ui" line="17"/>
1692 <source>Create Voice File</source>
1693 <translation>Vytvořit soubor hlasu</translation>
1694 </message>
1695 <message>
1696 <location filename="../createvoicefrm.ui" line="42"/>
1697 <source>Select the Language you want to generate a voicefile for:</source>
1698 <translation>Vyberte jazyk, pro který chcete vytvořit soubor s hlasem:</translation>
1699 </message>
1700 <message>
1701 <location filename="../createvoicefrm.ui" line="55"/>
1702 <source>TTS:</source>
1703 <translation>Syntéza řeči:</translation>
1704 </message>
1705 <message>
1706 <location filename="../createvoicefrm.ui" line="101"/>
1707 <source>Silence threshold</source>
1708 <translation>Práh ticha</translation>
1709 </message>
1710 <message>
1711 <location filename="../createvoicefrm.ui" line="163"/>
1712 <source>Language</source>
1713 <translation>Jazyk</translation>
1714 </message>
1715 <message>
1716 <location filename="../createvoicefrm.ui" line="49"/>
1717 <source>Generation settings</source>
1718 <translation>Nastavení generování</translation>
1719 </message>
1720 <message>
1721 <location filename="../createvoicefrm.ui" line="68"/>
1722 <source>Change</source>
1723 <translation>Změnit</translation>
1724 </message>
1725 <message>
1726 <location filename="../createvoicefrm.ui" line="139"/>
1727 <source>&amp;Install</source>
1728 <translation>&amp;Instalovat</translation>
1729 </message>
1730 <message>
1731 <location filename="../createvoicefrm.ui" line="150"/>
1732 <source>&amp;Cancel</source>
1733 <translation>&amp;Zrušit</translation>
1734 </message>
1735 <message>
1736 <location filename="../createvoicefrm.ui" line="88"/>
1737 <source>Wavtrim Threshold</source>
1738 <translation>Práh Wavtrimu</translation>
1739 </message>
1740</context>
1741<context>
1742 <name>CreateVoiceWindow</name>
1743 <message>
1744 <location filename="../createvoicewindow.cpp" line="100"/>
1745 <source>TTS error</source>
1746 <translation>Chyba syntézy řeči</translation>
1747 </message>
1748 <message>
1749 <location filename="../createvoicewindow.cpp" line="101"/>
1750 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1751 <translation>Spuštění vybrané syntézy řeči selhalo a nelze ji použít.</translation>
1752 </message>
1753 <message>
1754 <location filename="../createvoicewindow.cpp" line="105"/>
1755 <location filename="../createvoicewindow.cpp" line="108"/>
1756 <source>Engine: &lt;b&gt;%1&lt;/b&gt;</source>
1757 <translation>Engine: &lt;b&gt;%1&lt;/b&gt;</translation>
1758 </message>
1759</context>
1760<context>
1761 <name>EncTtsCfgGui</name>
1762 <message>
1763 <location filename="../encttscfggui.cpp" line="45"/>
1764 <source>Waiting for engine...</source>
1765 <translation>Čekání na engine...</translation>
1766 </message>
1767 <message>
1768 <location filename="../encttscfggui.cpp" line="95"/>
1769 <source>Ok</source>
1770 <translation>OK</translation>
1771 </message>
1772 <message>
1773 <location filename="../encttscfggui.cpp" line="98"/>
1774 <source>Cancel</source>
1775 <translation>Zrušit</translation>
1776 </message>
1777 <message>
1778 <location filename="../encttscfggui.cpp" line="197"/>
1779 <source>Browse</source>
1780 <translation>Procházet</translation>
1781 </message>
1782 <message>
1783 <location filename="../encttscfggui.cpp" line="205"/>
1784 <source>Refresh</source>
1785 <translation>Obnovit</translation>
1786 </message>
1787 <message>
1788 <location filename="../encttscfggui.cpp" line="377"/>
1789 <source>Select executable</source>
1790 <translation>Vyberte spustitelný soubor</translation>
1791 </message>
1792</context>
1793<context>
1794 <name>EncoderExe</name>
1795 <message>
1796 <location filename="../base/encoderexe.cpp" line="41"/>
1797 <source>Path to Encoder:</source>
1798 <translation>Cesta k enkodéru:</translation>
1799 </message>
1800 <message>
1801 <location filename="../base/encoderexe.cpp" line="43"/>
1802 <source>Encoder options:</source>
1803 <translation>Možnosti enkodéru:</translation>
1804 </message>
1805</context>
1806<context>
1807 <name>EncoderLame</name>
1808 <message>
1809 <location filename="../base/encoderlame.cpp" line="73"/>
1810 <location filename="../base/encoderlame.cpp" line="83"/>
1811 <source>LAME</source>
1812 <translation>LAME</translation>
1813 </message>
1814 <message>
1815 <location filename="../base/encoderlame.cpp" line="75"/>
1816 <source>Volume</source>
1817 <translation>Hlasitost</translation>
1818 </message>
1819 <message>
1820 <location filename="../base/encoderlame.cpp" line="79"/>
1821 <source>Quality</source>
1822 <translation>Kvalita</translation>
1823 </message>
1824 <message>
1825 <location filename="../base/encoderlame.cpp" line="83"/>
1826 <source>Could not find libmp3lame!</source>
1827 <translation>Nenalezena knihovna libmp3lame!</translation>
1828 </message>
1829</context>
1830<context>
1831 <name>EncoderRbSpeex</name>
1832 <message>
1833 <location filename="../base/encoderrbspeex.cpp" line="34"/>
1834 <source>Volume:</source>
1835 <translation>Hlasitost:</translation>
1836 </message>
1837 <message>
1838 <location filename="../base/encoderrbspeex.cpp" line="36"/>
1839 <source>Quality:</source>
1840 <translation>Kvalita:</translation>
1841 </message>
1842 <message>
1843 <location filename="../base/encoderrbspeex.cpp" line="38"/>
1844 <source>Complexity:</source>
1845 <translation>Složitost:</translation>
1846 </message>
1847 <message>
1848 <location filename="../base/encoderrbspeex.cpp" line="40"/>
1849 <source>Use Narrowband:</source>
1850 <translation>Použít úzké pásmo:</translation>
1851 </message>
1852</context>
1853<context>
1854 <name>InfoWidget</name>
1855 <message>
1856 <location filename="../gui/infowidget.cpp" line="30"/>
1857 <location filename="../gui/infowidget.cpp" line="107"/>
1858 <source>File</source>
1859 <translation>Soubor</translation>
1860 </message>
1861 <message>
1862 <location filename="../gui/infowidget.cpp" line="30"/>
1863 <location filename="../gui/infowidget.cpp" line="107"/>
1864 <source>Version</source>
1865 <translation>Verze</translation>
1866 </message>
1867</context>
1868<context>
1869 <name>InfoWidgetFrm</name>
1870 <message>
1871 <location filename="../gui/infowidgetfrm.ui" line="14"/>
1872 <source>Info</source>
1873 <translation>Informace</translation>
1874 </message>
1875 <message>
1876 <location filename="../gui/infowidgetfrm.ui" line="20"/>
1877 <source>Currently installed packages.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; if you manually installed packages this might not be correct!</source>
1878 <translation>Aktuálně nainstalované balíčky.&lt;br/&gt;&lt;b&gt;Poznámka:&lt;/b&gt; pokud jste instalovali balíčky ručně, informace nemusí být správné!</translation>
1879 </message>
1880 <message>
1881 <location filename="../gui/infowidgetfrm.ui" line="34"/>
1882 <source>Package</source>
1883 <translation>Balíčky</translation>
1884 </message>
1885</context>
1886<context>
1887 <name>InstallTalkFrm</name>
1888 <message>
1889 <location filename="../installtalkfrm.ui" line="17"/>
1890 <source>Install Talk Files</source>
1891 <translation>Instalovat soubory řeči</translation>
1892 </message>
1893 <message>
1894 <location filename="../installtalkfrm.ui" line="52"/>
1895 <source>Generate for files</source>
1896 <translation>Vytvořit pro soubory</translation>
1897 </message>
1898 <message>
1899 <location filename="../installtalkfrm.ui" line="78"/>
1900 <source>TTS profile:</source>
1901 <translation>Profil syntézy řeči:</translation>
1902 </message>
1903 <message>
1904 <location filename="../installtalkfrm.ui" line="85"/>
1905 <source>Generate for folders</source>
1906 <translation>Vytvořit pro adresáře</translation>
1907 </message>
1908 <message>
1909 <location filename="../installtalkfrm.ui" line="95"/>
1910 <source>Recurse into folders</source>
1911 <translation>Rekurzivně pro adresáře</translation>
1912 </message>
1913 <message>
1914 <location filename="../installtalkfrm.ui" line="111"/>
1915 <source>Change</source>
1916 <translation>Změnit</translation>
1917 </message>
1918 <message>
1919 <location filename="../installtalkfrm.ui" line="118"/>
1920 <source>Ignore files</source>
1921 <translation>Přeskočit soubory</translation>
1922 </message>
1923 <message>
1924 <location filename="../installtalkfrm.ui" line="128"/>
1925 <source>Skip existing</source>
1926 <translation>Přeskočit existující</translation>
1927 </message>
1928 <message>
1929 <location filename="../installtalkfrm.ui" line="143"/>
1930 <source>&amp;Install</source>
1931 <translation>&amp;Instalovat</translation>
1932 </message>
1933 <message>
1934 <location filename="../installtalkfrm.ui" line="154"/>
1935 <source>&amp;Cancel</source>
1936 <translation>&amp;Zrušit</translation>
1937 </message>
1938 <message>
1939 <location filename="../installtalkfrm.ui" line="170"/>
1940 <source>Select folders for Talkfile generation (Ctrl for multiselect)</source>
1941 <translation>Vyberte složky pro vytvoření souborů s hlasem (Pro více složek použijte Ctrl)</translation>
1942 </message>
1943 <message>
1944 <location filename="../installtalkfrm.ui" line="36"/>
1945 <source>Generation options</source>
1946 <translation>Možnosti generování</translation>
1947 </message>
1948 <message>
1949 <location filename="../installtalkfrm.ui" line="42"/>
1950 <source>Strip Extensions</source>
1951 <translation>Odebrat rozšíření</translation>
1952 </message>
1953</context>
1954<context>
1955 <name>InstallTalkWindow</name>
1956 <message>
1957 <location filename="../installtalkwindow.cpp" line="96"/>
1958 <source>Empty selection</source>
1959 <translation>Prázdný výběr</translation>
1960 </message>
1961 <message>
1962 <location filename="../installtalkwindow.cpp" line="97"/>
1963 <source>No files or folders selected. Please select files or folders first.</source>
1964 <translation>Nebyly vybrány soubory či složky. Nejprve prosím vyberte soubory či složky.</translation>
1965 </message>
1966 <message>
1967 <location filename="../installtalkwindow.cpp" line="137"/>
1968 <source>TTS error</source>
1969 <translation>Chyba syntézy řeči</translation>
1970 </message>
1971 <message>
1972 <location filename="../installtalkwindow.cpp" line="138"/>
1973 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1974 <translation>Spuštění vybrané syntézy řeči selhalo a nelze ji použít.</translation>
1975 </message>
1976</context>
1977<context>
1978 <name>ManualWidget</name>
1979 <message>
1980 <location filename="../gui/manualwidget.cpp" line="44"/>
1981 <source>&lt;a href=&apos;%1&apos;&gt;PDF Manual&lt;/a&gt;</source>
1982 <translation>&lt;a href=&apos;%1&apos;&gt;PDF příručka&lt;/a&gt;</translation>
1983 </message>
1984 <message>
1985 <location filename="../gui/manualwidget.cpp" line="46"/>
1986 <source>&lt;a href=&apos;%1&apos;&gt;HTML Manual (opens in browser)&lt;/a&gt;</source>
1987 <translation>&lt;a href=&apos;%1&apos;&gt;HTML příručka (otevře se v prohlížeči)&lt;/a&gt;</translation>
1988 </message>
1989 <message>
1990 <location filename="../gui/manualwidget.cpp" line="50"/>
1991 <source>Select a device for a link to the correct manual</source>
1992 <translation>Vyberte zařízení pro odkaz na správnou příručku</translation>
1993 </message>
1994 <message>
1995 <location filename="../gui/manualwidget.cpp" line="51"/>
1996 <source>&lt;a href=&apos;%1&apos;&gt;Manual Overview&lt;/a&gt;</source>
1997 <translation>&lt;a href=&apos;%1&apos;&gt;Obsah příručky&lt;/a&gt;</translation>
1998 </message>
1999 <message>
2000 <location filename="../gui/manualwidget.cpp" line="62"/>
2001 <source>Confirm download</source>
2002 <translation>Potvrdit stažení</translation>
2003 </message>
2004 <message>
2005 <location filename="../gui/manualwidget.cpp" line="63"/>
2006 <source>Do you really want to download the manual? The manual will be saved to the root folder of your player.</source>
2007 <translation>Opravdu chcete stáhnout příručku? Bude uložena do kořenového adresáře vašeho přehrávače.</translation>
2008 </message>
2009</context>
2010<context>
2011 <name>ManualWidgetFrm</name>
2012 <message>
2013 <location filename="../gui/manualwidgetfrm.ui" line="14"/>
2014 <source>Manual</source>
2015 <translation>Příručka</translation>
2016 </message>
2017 <message>
2018 <location filename="../gui/manualwidgetfrm.ui" line="20"/>
2019 <source>Read the manual</source>
2020 <translation>Přečíst příručku</translation>
2021 </message>
2022 <message>
2023 <location filename="../gui/manualwidgetfrm.ui" line="26"/>
2024 <source>PDF manual</source>
2025 <translation>PDF příručka</translation>
2026 </message>
2027 <message>
2028 <location filename="../gui/manualwidgetfrm.ui" line="39"/>
2029 <source>HTML manual</source>
2030 <translation>HTML příručka</translation>
2031 </message>
2032 <message>
2033 <location filename="../gui/manualwidgetfrm.ui" line="55"/>
2034 <source>Download the manual</source>
2035 <translation>Stáhnout příručku</translation>
2036 </message>
2037 <message>
2038 <location filename="../gui/manualwidgetfrm.ui" line="63"/>
2039 <source>&amp;PDF version</source>
2040 <translation>&amp;PDF verze</translation>
2041 </message>
2042 <message>
2043 <location filename="../gui/manualwidgetfrm.ui" line="70"/>
2044 <source>&amp;HTML version (zip file)</source>
2045 <translation>&amp;HTML verze (zip soubor)</translation>
2046 </message>
2047 <message>
2048 <location filename="../gui/manualwidgetfrm.ui" line="92"/>
2049 <source>Down&amp;load</source>
2050 <translation>&amp;Stáhnout</translation>
2051 </message>
2052</context>
2053<context>
2054 <name>MsPackUtil</name>
2055 <message>
2056 <location filename="../base/mspackutil.cpp" line="101"/>
2057 <source>Creating output path failed</source>
2058 <translation>Vytvoření výstupní cesty selhalo</translation>
2059 </message>
2060 <message>
2061 <location filename="../base/mspackutil.cpp" line="109"/>
2062 <source>Error during CAB operation</source>
2063 <translation>Chyba při práci s CAB souuborem</translation>
2064 </message>
2065</context>
2066<context>
2067 <name>PreviewFrm</name>
2068 <message>
2069 <location filename="../previewfrm.ui" line="16"/>
2070 <source>Preview</source>
2071 <translation>Náhled</translation>
2072 </message>
2073</context>
2074<context>
2075 <name>ProgressLoggerFrm</name>
2076 <message>
2077 <location filename="../progressloggerfrm.ui" line="18"/>
2078 <location filename="../progressloggerfrm.ui" line="24"/>
2079 <source>Progress</source>
2080 <translation>Průběh</translation>
2081 </message>
2082 <message>
2083 <location filename="../progressloggerfrm.ui" line="37"/>
2084 <source>progresswindow</source>
2085 <translation>oknopostupu</translation>
2086 </message>
2087 <message>
2088 <location filename="../progressloggerfrm.ui" line="63"/>
2089 <source>Save Log</source>
2090 <translation>Uložit záznam</translation>
2091 </message>
2092 <message>
2093 <location filename="../progressloggerfrm.ui" line="87"/>
2094 <source>&amp;Abort</source>
2095 <translation>&amp;Přerušit</translation>
2096 </message>
2097</context>
2098<context>
2099 <name>ProgressLoggerGui</name>
2100 <message>
2101 <location filename="../progressloggergui.cpp" line="104"/>
2102 <source>&amp;Abort</source>
2103 <translation>&amp;Přerušit</translation>
2104 </message>
2105 <message>
2106 <location filename="../progressloggergui.cpp" line="122"/>
2107 <source>&amp;Ok</source>
2108 <translation>&amp;OK</translation>
2109 </message>
2110 <message>
2111 <location filename="../progressloggergui.cpp" line="146"/>
2112 <source>Save system trace log</source>
2113 <translation>Uložit záznam systémového sledování</translation>
2114 </message>
2115</context>
2116<context>
2117 <name>QObject</name>
2118 <message>
2119 <location filename="../configure.cpp" line="625"/>
2120 <location filename="../main.cpp" line="91"/>
2121 <source>LTR</source>
2122 <extracomment>This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.</extracomment>
2123 <translation>LTR</translation>
2124 </message>
2125 <message>
2126 <location filename="../base/system.cpp" line="385"/>
2127 <source>(unknown vendor name) </source>
2128 <translation>(neznámý výrobce) </translation>
2129 </message>
2130 <message>
2131 <location filename="../base/system.cpp" line="403"/>
2132 <source>(unknown product name)</source>
2133 <translation>(neznámé zařízení)</translation>
2134 </message>
2135 <message>
2136 <location filename="../base/bootloaderinstallhelper.cpp" line="84"/>
2137 <source>Bootloader installation is almost complete. Installation &lt;b&gt;requires&lt;/b&gt; you to perform the following steps manually:</source>
2138 <translation>Instalace zavaděče je téměř hotova. Instalace od vás &lt;b&gt;vyžaduje&lt;/b&gt; provést následující kroky ručně:</translation>
2139 </message>
2140 <message>
2141 <location filename="../base/bootloaderinstallhelper.cpp" line="90"/>
2142 <source>&lt;li&gt;Safely remove your player.&lt;/li&gt;</source>
2143 <translation>&lt;li&gt;Bezpečně odeberte váš přehrávač.&lt;/li&gt;</translation>
2144 </message>
2145 <message>
2146 <location filename="../base/bootloaderinstallhelper.cpp" line="95"/>
2147 <source>&lt;li&gt;Reboot your player into the original firmware.&lt;/li&gt;&lt;li&gt;Perform a firmware upgrade using the update functionality of the original firmware. Please refer to your player&apos;s manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before starting the firmware update process.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
2148 <translation>&lt;li&gt;Restartujte váš přehrávač do původního firmware.&lt;/li&gt;&lt;li&gt;Aktualizujte firmware pomocí aktualizačního procesu původního firmware. Podobnosti se dočtete v návodu k vašemu přehrávači.&lt;br/&gt;&lt;b&gt;Důležité:&lt;/b&gt; aktualizace firmware je kritický proces, který nesmí být přerušen. &lt;b&gt;Ujistěte se, že je přehrávač nabitý před zahájením aktualizace.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Po aktualizaci firmware restartujte přehrávač.&lt;/li&gt;</translation>
2149 </message>
2150 <message>
2151 <location filename="../base/bootloaderinstallhelper.cpp" line="106"/>
2152 <source>&lt;li&gt;Remove any previously inserted microSD card&lt;/li&gt;</source>
2153 <translation>&lt;li&gt;Vyjměte jakoukoli dříve vloženou microSD kartu&lt;/li&gt;</translation>
2154 </message>
2155 <message>
2156 <location filename="../base/bootloaderinstallhelper.cpp" line="107"/>
2157 <source>&lt;li&gt;Disconnect your player. The player will reboot and perform an update of the original firmware. Please refer to your players manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before disconnecting the player.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
2158 <translation>&lt;li&gt;Odpojte váš přehrávač. Přehrávač bude restartován a provede aktualizaci původního firmware. Podobnosti se dočtete v návodu k vašemu přehrávači.&lt;br/&gt;&lt;b&gt;Důležité:&lt;/b&gt; aktualizace firmware je kritický proces, který nesmí být přerušen. &lt;b&gt;Ujistěte se, že je přehrávač nabitý před odpojením.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Po aktualizaci firmware restartujte přehrávač.&lt;/li&gt;</translation>
2159 </message>
2160 <message>
2161 <location filename="../base/bootloaderinstallhelper.cpp" line="118"/>
2162 <source>&lt;li&gt;Turn the player off&lt;/li&gt;&lt;li&gt;Insert the charger&lt;/li&gt;</source>
2163 <translation>&lt;li&gt;Vypněte přehrávač&lt;/li&gt;&lt;li&gt;Připojte nabíječku&lt;/li&gt;</translation>
2164 </message>
2165 <message>
2166 <location filename="../base/bootloaderinstallhelper.cpp" line="123"/>
2167 <source>&lt;li&gt;Unplug USB and power adaptors&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to turn the player off&lt;/li&gt;&lt;li&gt;Toggle the battery switch on the player&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to boot into Rockbox&lt;/li&gt;</source>
2168 <translation>&lt;li&gt;Odpojte USB a nabíjecí zařízení&lt;/li&gt;&lt;li&gt;Držte tlačítko&lt;i&gt;Napájení&lt;/i&gt; pro vypnutí přehrávače&lt;/li&gt;&lt;li&gt;Přepněte přepínač baterie na přehrávači&lt;/li&gt;&lt;li&gt;Držte tlačítko&lt;i&gt;Napájení&lt;/i&gt; pro spuštění Rockboxu&lt;/li&gt;</translation>
2169 </message>
2170 <message>
2171 <location filename="../base/bootloaderinstallhelper.cpp" line="129"/>
2172 <source>&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You can safely install other parts first, but the above steps are &lt;b&gt;required&lt;/b&gt; to finish the installation!&lt;/p&gt;</source>
2173 <translation>&lt;p&gt;&lt;b&gt;Poznámka:&lt;/b&gt; Můžete nejprve bezpečně instalovat zbývající části, ale výše uvedené kroky jsou &lt;b&gt;nezbytné&lt;/b&gt; pro dokončení instalace!&lt;/p&gt;</translation>
2174 </message>
2175</context>
2176<context>
2177 <name>QuaZipFile</name>
2178 <message>
2179 <location filename="../quazip/quazipfile.cpp" line="218"/>
2180 <source>ZIP/UNZIP API error %1</source>
2181 <translation>Chyba %1 API ZIP/UNZIP</translation>
2182 </message>
2183</context>
2184<context>
2185 <name>RbUtilQt</name>
2186 <message>
2187 <location filename="../rbutilqt.cpp" line="245"/>
2188 <source>Network error</source>
2189 <translation>Chyba sítě</translation>
2190 </message>
2191 <message>
2192 <location filename="../rbutilqt.cpp" line="338"/>
2193 <source>New installation</source>
2194 <translation>Nová instalace</translation>
2195 </message>
2196 <message>
2197 <location filename="../rbutilqt.cpp" line="339"/>
2198 <source>This is a new installation of Rockbox Utility, or a new version. The configuration dialog will now open to allow you to setup the program, or review your settings.</source>
2199 <translation>Toto je nová instalace nebo verze Rockbox Utility. Nyní se otevře nastavení programu.</translation>
2200 </message>
2201 <message>
2202 <location filename="../rbutilqt.cpp" line="346"/>
2203 <location filename="../rbutilqt.cpp" line="656"/>
2204 <source>Configuration error</source>
2205 <translation>Chyba nastavení</translation>
2206 </message>
2207 <message>
2208 <location filename="../rbutilqt.cpp" line="347"/>
2209 <source>Your configuration is invalid. This is most likely due to a changed device path. The configuration dialog will now open to allow you to correct the problem.</source>
2210 <translation>Vaše nastavení je neplatné. Pravděpodobně kvůli změně cesty k zařízení. Nyní se otevře okno nastavení, které vám dovolí opravit problém.</translation>
2211 </message>
2212 <message>
2213 <location filename="../rbutilqt.cpp" line="119"/>
2214 <source>Wine detected!</source>
2215 <translation>Zjištěn běh pod Wine!</translation>
2216 </message>
2217 <message>
2218 <location filename="../rbutilqt.cpp" line="120"/>
2219 <source>It seems you are trying to run this program under Wine. Please don&apos;t do this, running under Wine will fail. Use the native Linux binary instead.</source>
2220 <translation>Zdá se, že se pokoušite tento program spustit skrze Wine. Prosíme nedělejte to, může dojít k chybám. Použijte raději nativní Linuxový port.</translation>
2221 </message>
2222 <message>
2223 <location filename="../rbutilqt.cpp" line="233"/>
2224 <source>Downloading build information, please wait ...</source>
2225 <translation>Čekejte prosím, stahuji informace o sestavení ...</translation>
2226 </message>
2227 <message>
2228 <location filename="../rbutilqt.cpp" line="244"/>
2229 <source>Can&apos;t get version information!</source>
2230 <translation>Nelze stáhnout informace o verzi!</translation>
2231 </message>
2232 <message>
2233 <location filename="../rbutilqt.cpp" line="246"/>
2234 <source>Can&apos;t get version information.
2235Network error: %1. Please check your network and proxy settings.</source>
2236 <translation>Nelze stáhnout informace o verzi!
2237Chyba sítě: %1. Prosím zkontrolujte vaše nastavení sítě a proxy.</translation>
2238 </message>
2239 <message>
2240 <location filename="../rbutilqt.cpp" line="258"/>
2241 <source>Download build information finished.</source>
2242 <translation>Informace o sestavení staženy.</translation>
2243 </message>
2244 <message>
2245 <location filename="../rbutilqt.cpp" line="459"/>
2246 <source>Confirm Installation</source>
2247 <translation>Potvrdit instalaci</translation>
2248 </message>
2249 <message>
2250 <location filename="../rbutilqt.cpp" line="596"/>
2251 <source>Mount point is wrong!</source>
2252 <translation>Připojovací bod je špatně!</translation>
2253 </message>
2254 <message>
2255 <location filename="../rbutilqt.cpp" line="439"/>
2256 <source>No Rockbox installation found</source>
2257 <translation>Nenalezena instalace Rockboxu</translation>
2258 </message>
2259 <message>
2260 <location filename="../rbutilqt.cpp" line="425"/>
2261 <source>Warning</source>
2262 <translation>Varování</translation>
2263 </message>
2264 <message>
2265 <location filename="../rbutilqt.cpp" line="426"/>
2266 <source>The Application is still downloading Information about new Builds. Please try again shortly.</source>
2267 <translation>Aplikace stahuje informace o nových verzích. Prosím zkuste to později.</translation>
2268 </message>
2269 <message>
2270 <location filename="../rbutilqt.cpp" line="440"/>
2271 <source>Could not determine the installed Rockbox version. Please install a Rockbox build before installing voice files.</source>
2272 <translation>Nelze zjsitit instalovanou verzi Rockboxu. Prosíme nainstalujte Rockbox a až pak hlasové soubory.</translation>
2273 </message>
2274 <message>
2275 <location filename="../rbutilqt.cpp" line="460"/>
2276 <source>Do you really want to install the voice file?</source>
2277 <translation>Opravdu chcete instalovat hlasové soubory?</translation>
2278 </message>
2279 <message>
2280 <location filename="../rbutilqt.cpp" line="521"/>
2281 <source>Confirm Uninstallation</source>
2282 <translation>Potvrdit odinstalování</translation>
2283 </message>
2284 <message>
2285 <location filename="../rbutilqt.cpp" line="522"/>
2286 <source>Do you really want to uninstall the Bootloader?</source>
2287 <translation>Opravdu chcete odinstalovat zavaděč?</translation>
2288 </message>
2289 <message>
2290 <location filename="../rbutilqt.cpp" line="536"/>
2291 <source>No uninstall method for this target known.</source>
2292 <translation>Pro toto zařízení není známý způsob odinstalace.</translation>
2293 </message>
2294 <message>
2295 <location filename="../rbutilqt.cpp" line="748"/>
2296 <source>New version of Rockbox Utility available.</source>
2297 <translation>Je k dispozici aktualizace Rockbox Utility.</translation>
2298 </message>
2299 <message>
2300 <location filename="../rbutilqt.cpp" line="751"/>
2301 <source>Rockbox Utility is up to date.</source>
2302 <translation>Rockbox Utilita je aktuální.</translation>
2303 </message>
2304 <message>
2305 <location filename="../rbutilqt.cpp" line="582"/>
2306 <source>Confirm installation</source>
2307 <translation>Potvrdit instalaci</translation>
2308 </message>
2309 <message>
2310 <location filename="../rbutilqt.cpp" line="448"/>
2311 <source>No voice file available</source>
2312 <translation>Soubory hlasů nejsou k dispozici</translation>
2313 </message>
2314 <message>
2315 <location filename="../rbutilqt.cpp" line="449"/>
2316 <source>The installed version of Rockbox is a development version. Pre-built voices are only available for release versions of Rockbox. Please generate a voice yourself using the &quot;Create voice file&quot; functionality.</source>
2317 <translation>Je instalována vývojářská verze Rockboxu. Předpřipravené hlasy jsou k dispozici jen pro stabilní vydání. Prosím vytvořte si hlas pomocí funkce &quot;Vytvoření hlasového souboru&quot;.</translation>
2318 </message>
2319 <message>
2320 <location filename="../rbutilqt.cpp" line="552"/>
2321 <source>Rockbox Utility can not uninstall the bootloader on your player. Please perform a firmware update using your player vendors firmware update process.</source>
2322 <translation>Rockbox Utilita nemůže instalovat zavaděč na váš přehrávač. Proveďte aktualizaci firmware způsobem používaným výrobcem vašeho přehrávače.</translation>
2323 </message>
2324 <message>
2325 <location filename="../rbutilqt.cpp" line="555"/>
2326 <source>Important: make sure to boot your player into the original firmware before using the vendors firmware update process.</source>
2327 <translation>Důležité: Spusťte na vašem přehrávači původní firmware před tím, než použijete aktualizační postup vašeho výrobce.</translation>
2328 </message>
2329 <message>
2330 <location filename="../rbutilqt.cpp" line="563"/>
2331 <source>No Rockbox bootloader found.</source>
2332 <translation>Nenalezen zavaděč Rockboxu.</translation>
2333 </message>
2334 <message>
2335 <location filename="../rbutilqt.cpp" line="583"/>
2336 <source>Do you really want to install Rockbox Utility to your player? After installation you can run it from the players hard drive.</source>
2337 <translation>Opravdu chcete instalovat Rockbox Utilitu na váš přehrávač? Po instalaci ji můžete spustit z disku přehrávače.</translation>
2338 </message>
2339 <message>
2340 <location filename="../rbutilqt.cpp" line="592"/>
2341 <source>Installing Rockbox Utility</source>
2342 <translation>Instaluji Rockbox Utilitu</translation>
2343 </message>
2344 <message>
2345 <location filename="../rbutilqt.cpp" line="610"/>
2346 <source>Error installing Rockbox Utility</source>
2347 <translation>Chyba instalace Rocxbox Utility</translation>
2348 </message>
2349 <message>
2350 <location filename="../rbutilqt.cpp" line="614"/>
2351 <source>Installing user configuration</source>
2352 <translation>Instalace uživatelských nastavení</translation>
2353 </message>
2354 <message>
2355 <location filename="../rbutilqt.cpp" line="618"/>
2356 <source>Error installing user configuration</source>
2357 <translation>Chyba instalace uživatelských nastavení</translation>
2358 </message>
2359 <message>
2360 <location filename="../rbutilqt.cpp" line="622"/>
2361 <source>Successfully installed Rockbox Utility.</source>
2362 <translation>Úspěšná instalace Rockbox Utility.</translation>
2363 </message>
2364 <message>
2365 <location filename="../rbutilqt.cpp" line="657"/>
2366 <source>Your configuration is invalid. Please go to the configuration dialog and make sure the selected values are correct.</source>
2367 <translation>Vaše nastavení je neplatné. Prosím zkontrolujte nastavení, zda jsou všechny vybrané hodnoty správné.</translation>
2368 </message>
2369 <message>
2370 <location filename="../rbutilqt.cpp" line="678"/>
2371 <source>Checking for update ...</source>
2372 <translation>Kontroluji aktualizace ...</translation>
2373 </message>
2374 <message>
2375 <location filename="../rbutilqt.cpp" line="743"/>
2376 <source>Rockbox Utility Update available</source>
2377 <translation>Je k dispozici aktualizace Rockbox Utility</translation>
2378 </message>
2379 <message>
2380 <location filename="../rbutilqt.cpp" line="744"/>
2381 <source>&lt;b&gt;New Rockbox Utility version available.&lt;/b&gt;&lt;br&gt;&lt;br&gt;You are currently using version %1. Get version %2 at &lt;a href=&apos;%3&apos;&gt;%3&lt;/a&gt;</source>
2382 <translation>&lt;b&gt;Je k dispozici nová verze Rockbox Utility&lt;/b&gt;&lt;br&gt;&lt;br&gt;Používáte verzi %1. Stáhněte si verzi %2 at &lt;a href=&apos;%3&apos;&gt;%3&lt;/a&gt;</translation>
2383 </message>
2384 <message>
2385 <source>RockboxUtility Update available</source>
2386 <translation type="vanished">Je k dispozici aktualizace Rockbox Utility</translation>
2387 </message>
2388 <message>
2389 <source>&lt;b&gt;New RockboxUtility Version available.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Download it from here: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</source>
2390 <translation type="vanished">&lt;b&gt;Je k dispozici nová verze Rockbox Utility.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Stáhněte si ji zde: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</translation>
2391 </message>
2392 <message>
2393 <location filename="../rbutilqt.cpp" line="774"/>
2394 <source>Device ejected</source>
2395 <translation>Zařízení odebráno</translation>
2396 </message>
2397 <message>
2398 <location filename="../rbutilqt.cpp" line="775"/>
2399 <source>Device successfully ejected. You may now disconnect the player from the PC.</source>
2400 <translation>Zařízení úspěšně odebráno. Přehrávač můžete odpojit od počítače.</translation>
2401 </message>
2402 <message>
2403 <location filename="../rbutilqt.cpp" line="779"/>
2404 <source>Ejecting failed</source>
2405 <translation>Odebrání selhalo</translation>
2406 </message>
2407 <message>
2408 <location filename="../rbutilqt.cpp" line="780"/>
2409 <source>Ejecting the device failed. Please make sure no programs are accessing files on the device. If ejecting still fails please use your computers eject funtionality.</source>
2410 <translation>Odpojení zařízení selhalo. Ujistěte se, že žádný program nepracuje se zařízením. Pokud odpojení opětovně selže, použijte funkci odpojení vašeho operačního systému,.</translation>
2411 </message>
2412</context>
2413<context>
2414 <name>RbUtilQtFrm</name>
2415 <message>
2416 <location filename="../rbutilqtfrm.ui" line="14"/>
2417 <source>Rockbox Utility</source>
2418 <translation>Rockbox Utilita</translation>
2419 </message>
2420 <message>
2421 <location filename="../rbutilqtfrm.ui" line="31"/>
2422 <source>Device</source>
2423 <translation>Zařízení</translation>
2424 </message>
2425 <message>
2426 <location filename="../rbutilqtfrm.ui" line="92"/>
2427 <source>&amp;Change</source>
2428 <translation>&amp;Změnit</translation>
2429 </message>
2430 <message>
2431 <location filename="../rbutilqtfrm.ui" line="163"/>
2432 <source>Welcome</source>
2433 <translation>Vítejte</translation>
2434 </message>
2435 <message>
2436 <location filename="../rbutilqtfrm.ui" line="160"/>
2437 <location filename="../rbutilqtfrm.ui" line="658"/>
2438 <source>&amp;Installation</source>
2439 <translation>&amp;Instalace</translation>
2440 </message>
2441 <message>
2442 <location filename="../rbutilqtfrm.ui" line="168"/>
2443 <location filename="../rbutilqtfrm.ui" line="450"/>
2444 <source>&amp;Accessibility</source>
2445 <translation>&amp;Přístupnost</translation>
2446 </message>
2447 <message>
2448 <location filename="../rbutilqtfrm.ui" line="171"/>
2449 <source>Install accessibility add-ons</source>
2450 <translation>Instalovat přídavky pro přístupnost</translation>
2451 </message>
2452 <message>
2453 <location filename="../rbutilqtfrm.ui" line="177"/>
2454 <source>Install Voice files</source>
2455 <translation>Instalovat soubory hlasů</translation>
2456 </message>
2457 <message>
2458 <location filename="../rbutilqtfrm.ui" line="194"/>
2459 <source>&lt;b&gt;Install Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so if you installed the voice file Rockbox will speak.</source>
2460 <translation>&lt;b&gt;Instalovat soubory hlasů&lt;/b&gt;&lt;br/&gt;Hlasové soubory jsou potřebné, aby Rockbox četl uživatelské rozhraní. Čtení je defalutně zapnuto, takže jestliže je instalujete, Rockbox bude mluvit.</translation>
2461 </message>
2462 <message>
2463 <location filename="../rbutilqtfrm.ui" line="204"/>
2464 <source>Install Talk files</source>
2465 <translation>Instalovat .talk soubory</translation>
2466 </message>
2467 <message>
2468 <location filename="../rbutilqtfrm.ui" line="221"/>
2469 <source>&lt;b&gt;Create Talk Files&lt;/b&gt;&lt;br/&gt;Talkfiles are needed to let Rockbox speak File and Foldernames</source>
2470 <translation>&lt;b&gt;Instalovat .talk soubory&lt;/b&gt;&lt;br/&gt;Sobory jsou potřebné, aby Rockbox mohl číst názvy souborů a adresářů</translation>
2471 </message>
2472 <message>
2473 <location filename="../rbutilqtfrm.ui" line="254"/>
2474 <source>Create Voice files</source>
2475 <translation>Vytvořit soubory hlasů</translation>
2476 </message>
2477 <message>
2478 <location filename="../rbutilqtfrm.ui" line="271"/>
2479 <source>&lt;b&gt;Create Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so
2480 if you installed the voice file Rockbox will speak.</source>
2481 <translation>&lt;b&gt;Vytvořit soubory hlasů&lt;/b&gt;&lt;br/&gt;Hlasové soubory jsou potřebné, aby Rockbox četl uživatelské rozhraní. Čtení je defalutně zapnuto, takže jestliže je instalujete, Rockbox bude mluvit.</translation>
2482 </message>
2483 <message>
2484 <location filename="../rbutilqtfrm.ui" line="458"/>
2485 <source>&amp;Uninstallation</source>
2486 <translation>&amp;Odinstalace</translation>
2487 </message>
2488 <message>
2489 <location filename="../rbutilqtfrm.ui" line="286"/>
2490 <location filename="../rbutilqtfrm.ui" line="319"/>
2491 <source>Uninstall Rockbox</source>
2492 <translation>Odinstalovat Rockbox</translation>
2493 </message>
2494 <message>
2495 <location filename="../rbutilqtfrm.ui" line="121"/>
2496 <source>mountpoint unknown or invalid</source>
2497 <translation>Bod připojení neznámý nebo nesprávný</translation>
2498 </message>
2499 <message>
2500 <location filename="../rbutilqtfrm.ui" line="114"/>
2501 <source>Mountpoint:</source>
2502 <translation>Přípojný bod:</translation>
2503 </message>
2504 <message>
2505 <location filename="../rbutilqtfrm.ui" line="72"/>
2506 <source>device unknown or invalid</source>
2507 <translation>Neznámé nebo nevalidní zařízení</translation>
2508 </message>
2509 <message>
2510 <location filename="../rbutilqtfrm.ui" line="65"/>
2511 <source>Device:</source>
2512 <translation>Zařízení:</translation>
2513 </message>
2514 <message>
2515 <location filename="../rbutilqtfrm.ui" line="283"/>
2516 <source>Backup &amp;&amp; &amp;Uninstallation</source>
2517 <translation>Zálohování a &amp;odinstalace</translation>
2518 </message>
2519 <message>
2520 <location filename="../rbutilqtfrm.ui" line="292"/>
2521 <source>Uninstall Bootloader</source>
2522 <translation>Odinstalovat zavaděč</translation>
2523 </message>
2524 <message>
2525 <location filename="../rbutilqtfrm.ui" line="309"/>
2526 <source>&lt;b&gt;Remove the bootloader&lt;/b&gt;&lt;br/&gt;After removing the bootloader you won&apos;t be able to start Rockbox.</source>
2527 <translation>&lt;b&gt;Odstranění zavaděče&lt;/b&gt;&lt;br/&gt;Po odstranění zavaděče nebudete schopni spustit Rockbox.</translation>
2528 </message>
2529 <message>
2530 <location filename="../rbutilqtfrm.ui" line="336"/>
2531 <source>&lt;b&gt;Uninstall Rockbox from your audio player.&lt;/b&gt;&lt;br/&gt;This will leave the bootloader in place (you need to remove it manually).</source>
2532 <translation>&lt;b&gt;Odinstalovat Rockbox z vašeho audio přehrávače&lt;/b&gt;&lt;br/&gt;Ponechá zavaděč na místě (musíte ho odstranit ručně).</translation>
2533 </message>
2534 <message>
2535 <location filename="../rbutilqtfrm.ui" line="349"/>
2536 <source>Backup</source>
2537 <translation>Záloha</translation>
2538 </message>
2539 <message>
2540 <location filename="../rbutilqtfrm.ui" line="366"/>
2541 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup current installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Create a backup by archiving the contents of the Rockbox installation folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2542 <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Zálohovat současnou instalaci.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Vytvoření zálohy archivací instalačního adresáře Rockboxu.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
2543 </message>
2544 <message>
2545 <location filename="../rbutilqtfrm.ui" line="393"/>
2546 <source>&amp;Manual</source>
2547 <translation>&amp;Příručka</translation>
2548 </message>
2549 <message>
2550 <location filename="../rbutilqtfrm.ui" line="396"/>
2551 <source>View and download the manual</source>
2552 <translation>Prohlédnout a stáhnout příručku</translation>
2553 </message>
2554 <message>
2555 <location filename="../rbutilqtfrm.ui" line="401"/>
2556 <source>Inf&amp;o</source>
2557 <translation>Inf&amp;o</translation>
2558 </message>
2559 <message>
2560 <location filename="../rbutilqtfrm.ui" line="419"/>
2561 <source>&amp;File</source>
2562 <translation>&amp;Soubor</translation>
2563 </message>
2564 <message>
2565 <location filename="../rbutilqtfrm.ui" line="432"/>
2566 <source>&amp;Troubleshoot</source>
2567 <translation>&amp;Řešení problémů</translation>
2568 </message>
2569 <message>
2570 <location filename="../rbutilqtfrm.ui" line="446"/>
2571 <source>Action&amp;s</source>
2572 <translation>&amp;Akce</translation>
2573 </message>
2574 <message>
2575 <location filename="../rbutilqtfrm.ui" line="474"/>
2576 <source>Empty local download cache</source>
2577 <translation>Vyprázdnit lokální vyrovnávací paměť stahování</translation>
2578 </message>
2579 <message>
2580 <location filename="../rbutilqtfrm.ui" line="479"/>
2581 <source>Install Rockbox Utility on player</source>
2582 <translation>Instalovat Rockbox Utilitu na váš přehrávač</translation>
2583 </message>
2584 <message>
2585 <location filename="../rbutilqtfrm.ui" line="484"/>
2586 <source>&amp;Configure</source>
2587 <translation>&amp;Nastavení</translation>
2588 </message>
2589 <message>
2590 <location filename="../rbutilqtfrm.ui" line="489"/>
2591 <source>E&amp;xit</source>
2592 <translation>U&amp;končit</translation>
2593 </message>
2594 <message>
2595 <location filename="../rbutilqtfrm.ui" line="492"/>
2596 <source>Ctrl+Q</source>
2597 <translation>Ctrl+Q</translation>
2598 </message>
2599 <message>
2600 <location filename="../rbutilqtfrm.ui" line="497"/>
2601 <source>&amp;About</source>
2602 <translation>&amp;O aplikaci</translation>
2603 </message>
2604 <message>
2605 <location filename="../rbutilqtfrm.ui" line="502"/>
2606 <source>About &amp;Qt</source>
2607 <translation>O aplikaci &amp;Qt</translation>
2608 </message>
2609 <message>
2610 <location filename="../rbutilqtfrm.ui" line="428"/>
2611 <location filename="../rbutilqtfrm.ui" line="507"/>
2612 <source>&amp;Help</source>
2613 <translation>&amp;Nápověda</translation>
2614 </message>
2615 <message>
2616 <location filename="../rbutilqtfrm.ui" line="103"/>
2617 <source>&amp;Eject</source>
2618 <translation>&amp;Odpojit</translation>
2619 </message>
2620 <message>
2621 <location filename="../rbutilqtfrm.ui" line="512"/>
2622 <source>Info</source>
2623 <translation>Informace</translation>
2624 </message>
2625 <message>
2626 <location filename="../rbutilqtfrm.ui" line="521"/>
2627 <source>&amp;Complete Installation</source>
2628 <translation>&amp;Kompletní instalace</translation>
2629 </message>
2630 <message>
2631 <location filename="../rbutilqtfrm.ui" line="530"/>
2632 <source>&amp;Minimal Installation</source>
2633 <translation>&amp;Minimální instalace</translation>
2634 </message>
2635 <message>
2636 <location filename="../rbutilqtfrm.ui" line="539"/>
2637 <source>Install &amp;Bootloader</source>
2638 <translation>Instalovat &amp;zavaděč</translation>
2639 </message>
2640 <message>
2641 <location filename="../rbutilqtfrm.ui" line="548"/>
2642 <source>Install &amp;Rockbox</source>
2643 <translation>Instalovat &amp;Rockbox</translation>
2644 </message>
2645 <message>
2646 <location filename="../rbutilqtfrm.ui" line="557"/>
2647 <source>Install &amp;Fonts Package</source>
2648 <translation>Instalovat balík &amp;fontů</translation>
2649 </message>
2650 <message>
2651 <location filename="../rbutilqtfrm.ui" line="566"/>
2652 <source>Install &amp;Themes</source>
2653 <translation>Instalovat &amp;témata</translation>
2654 </message>
2655 <message>
2656 <location filename="../rbutilqtfrm.ui" line="575"/>
2657 <source>Install &amp;Game Files</source>
2658 <translation>Instalovat &amp;herní soubory</translation>
2659 </message>
2660 <message>
2661 <location filename="../rbutilqtfrm.ui" line="584"/>
2662 <source>&amp;Install Voice File</source>
2663 <translation>&amp;Instalovat soubory hlasů</translation>
2664 </message>
2665 <message>
2666 <location filename="../rbutilqtfrm.ui" line="593"/>
2667 <source>Create &amp;Talk Files</source>
2668 <translation>Instalovat .&amp;talk soubory</translation>
2669 </message>
2670 <message>
2671 <location filename="../rbutilqtfrm.ui" line="602"/>
2672 <source>Remove &amp;bootloader</source>
2673 <translation>Odstranit &amp;zavaděč</translation>
2674 </message>
2675 <message>
2676 <location filename="../rbutilqtfrm.ui" line="611"/>
2677 <source>Uninstall &amp;Rockbox</source>
2678 <translation>Odinstalovat &amp;Rockbox</translation>
2679 </message>
2680 <message>
2681 <location filename="../rbutilqtfrm.ui" line="616"/>
2682 <source>Read PDF manual</source>
2683 <translation>Přečíst PDF příručku</translation>
2684 </message>
2685 <message>
2686 <location filename="../rbutilqtfrm.ui" line="621"/>
2687 <source>Read HTML manual</source>
2688 <translation>Přečíst HTML příručku</translation>
2689 </message>
2690 <message>
2691 <location filename="../rbutilqtfrm.ui" line="626"/>
2692 <source>Download PDF manual</source>
2693 <translation>Stáhnout PDF příručku</translation>
2694 </message>
2695 <message>
2696 <location filename="../rbutilqtfrm.ui" line="631"/>
2697 <source>Download HTML manual (zip)</source>
2698 <translation>Stáhnout HTML příručku (zip)</translation>
2699 </message>
2700 <message>
2701 <location filename="../rbutilqtfrm.ui" line="640"/>
2702 <source>Create &amp;Voice File</source>
2703 <translation>Vytvořit &amp;soubor hlasů</translation>
2704 </message>
2705 <message>
2706 <location filename="../rbutilqtfrm.ui" line="643"/>
2707 <source>Create Voice File</source>
2708 <translation>Vytvořit soubor hlasů</translation>
2709 </message>
2710 <message>
2711 <location filename="../rbutilqtfrm.ui" line="648"/>
2712 <source>&amp;System Info</source>
2713 <translation>&amp;Informace o systému</translation>
2714 </message>
2715 <message>
2716 <location filename="../rbutilqtfrm.ui" line="653"/>
2717 <source>System &amp;Trace</source>
2718 <translation>Sledování &amp;sytému</translation>
2719 </message>
2720 <message>
2721 <location filename="../rbutilqtfrm.ui" line="663"/>
2722 <source>Show &amp;Changelog</source>
2723 <translation>Ukázat &amp;přehled změn</translation>
2724 </message>
2725</context>
2726<context>
2727 <name>SelectiveInstallWidget</name>
2728 <message>
2729 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="20"/>
2730 <source>Selective Installation</source>
2731 <translation>Volitelná instalace</translation>
2732 </message>
2733 <message>
2734 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="26"/>
2735 <source>Rockbox version to install</source>
2736 <translation>Kterou verzi Rockboxu instalovat</translation>
2737 </message>
2738 <message>
2739 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="35"/>
2740 <source>Version information not available yet.</source>
2741 <translation>Informace o verzi nejsou zatím k dispozici.</translation>
2742 </message>
2743 <message>
2744 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="54"/>
2745 <source>Rockbox components to install</source>
2746 <translation>Instalovat následující součásti Rockboxu</translation>
2747 </message>
2748 <message>
2749 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="60"/>
2750 <source>&amp;Bootloader</source>
2751 <translation>&amp;Zavaděč</translation>
2752 </message>
2753 <message>
2754 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="80"/>
2755 <source>The main Rockbox firmware.</source>
2756 <translation>Hlavní firmware Rockboxu.</translation>
2757 </message>
2758 <message>
2759 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="90"/>
2760 <source>Fonts</source>
2761 <translation>Fonty</translation>
2762 </message>
2763 <message>
2764 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="104"/>
2765 <source>&amp;Rockbox</source>
2766 <translation>&amp;Rockbox</translation>
2767 </message>
2768 <message>
2769 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="124"/>
2770 <source>Some game plugins require additional files.</source>
2771 <translation>Některé herní moduly vyžadují dodatečné soubory.</translation>
2772 </message>
2773 <message>
2774 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="140"/>
2775 <source>Additional fonts for the User Interface.</source>
2776 <translation>Dodatečné fonty pro uživatelské prostředí.</translation>
2777 </message>
2778 <message>
2779 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="156"/>
2780 <source>The bootloader is required for starting Rockbox. Only necessary for first time install.</source>
2781 <translation>Rockbox potřebuje ke spuštění zavaděč. Je zapotřebí jen při první instalaci.</translation>
2782 </message>
2783 <message>
2784 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="166"/>
2785 <source>Game Files</source>
2786 <translation>Herní soubory</translation>
2787 </message>
2788 <message>
2789 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="177"/>
2790 <source>Customize</source>
2791 <translation>Vybrat</translation>
2792 </message>
2793 <message>
2794 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="188"/>
2795 <source>Themes</source>
2796 <translation>Témata</translation>
2797 </message>
2798 <message>
2799 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="205"/>
2800 <source>Themes allow adjusting the user interface of Rockbox. Use &quot;Customize&quot; to select themes.</source>
2801 <translation>Témata vám umožní změnit podobu Rockboxu. Zvolte si je pomocí &quot;Vybrat&quot;.</translation>
2802 </message>
2803 <message>
2804 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="250"/>
2805 <source>&amp;Install</source>
2806 <translation>&amp;Instalovat</translation>
2807 </message>
2808 <message>
2809 <location filename="../gui/selectiveinstallwidget.cpp" line="67"/>
2810 <source>This is the latest stable release available.</source>
2811 <translation>Tohle je poslední stabilní vydání.</translation>
2812 </message>
2813 <message>
2814 <location filename="../gui/selectiveinstallwidget.cpp" line="70"/>
2815 <source>The development version is updated on every code change. Last update was on %1</source>
2816 <translation>Vývojářská verze je aktualizována při každé změně kódu. Poslední aktualizace proběhla %1</translation>
2817 </message>
2818 <message>
2819 <location filename="../gui/selectiveinstallwidget.cpp" line="74"/>
2820 <source>This will eventually become the next Rockbox version. Install it to help testing.</source>
2821 <translation>Toto bude v budoucnosti další stabilní verze Rockboxu, isntalací pomůžete jejímu testování.</translation>
2822 </message>
2823 <message>
2824 <location filename="../gui/selectiveinstallwidget.cpp" line="100"/>
2825 <source>Stable Release (Version %1)</source>
2826 <translation>Stabilní vydání (Verze %1)</translation>
2827 </message>
2828 <message>
2829 <location filename="../gui/selectiveinstallwidget.cpp" line="104"/>
2830 <source>Development Version (Revison %1)</source>
2831 <translation>Vývojářská verze (Revize %1)</translation>
2832 </message>
2833 <message>
2834 <location filename="../gui/selectiveinstallwidget.cpp" line="108"/>
2835 <source>Release Candidate (Revison %1)</source>
2836 <translation>Kandidát pro vydání (Revize %1)</translation>
2837 </message>
2838 <message>
2839 <location filename="../gui/selectiveinstallwidget.cpp" line="131"/>
2840 <source>The selected player doesn&apos;t need a bootloader.</source>
2841 <translation>Vybraný přehrávač nepotřebuje zavaděč.</translation>
2842 </message>
2843 <message>
2844 <location filename="../gui/selectiveinstallwidget.cpp" line="136"/>
2845 <source>The bootloader is required for starting Rockbox. Installation of the bootloader is only necessary on first time installation.</source>
2846 <translation>Rockbox potřebuje ke spuštění zavaděč. Jeho instalace je zapotřebí jen při první instalaci.</translation>
2847 </message>
2848 <message>
2849 <location filename="../gui/selectiveinstallwidget.cpp" line="183"/>
2850 <source>Mountpoint is wrong</source>
2851 <translation>Špatný připojovací bod</translation>
2852 </message>
2853 <message>
2854 <location filename="../gui/selectiveinstallwidget.cpp" line="239"/>
2855 <source>No install method known.</source>
2856 <translation>Není známý žádný způsob instalace.</translation>
2857 </message>
2858 <message>
2859 <location filename="../gui/selectiveinstallwidget.cpp" line="268"/>
2860 <source>Bootloader detected</source>
2861 <translation>Zavaděč nalezen</translation>
2862 </message>
2863 <message>
2864 <location filename="../gui/selectiveinstallwidget.cpp" line="269"/>
2865 <source>Bootloader already installed. Do you want to reinstall the bootloader?</source>
2866 <translation>Zavaděč je již instalován. Opravdu chcete přeinstalovat zavaděč?</translation>
2867 </message>
2868 <message>
2869 <location filename="../gui/selectiveinstallwidget.cpp" line="273"/>
2870 <source>Bootloader installation skipped</source>
2871 <translation>Instalace zavaděče přeskočena</translation>
2872 </message>
2873 <message>
2874 <location filename="../gui/selectiveinstallwidget.cpp" line="286"/>
2875 <source>Create Bootloader backup</source>
2876 <translation>Vytváří se záloha zavaděče</translation>
2877 </message>
2878 <message>
2879 <location filename="../gui/selectiveinstallwidget.cpp" line="287"/>
2880 <source>You can create a backup of the original bootloader file. Press &quot;Yes&quot; to select an output folder on your computer to save the file to. The file will get placed in a new folder &quot;%1&quot; created below the selected folder.
2881Press &quot;No&quot; to skip this step.</source>
2882 <translation>Můžete vytvořit zálohu původního souboru zavaděče. Stiskněte &quot;Ano&quot; pro výběr adresáře na vašem počítači, kam se má tento soubor uložit. Soubor bude umístěn do nového podadresáře &quot;%1&quot; vytvořeného v tomto adresáři.
2883Stiskněte &quot;Ne&quot; pro přeskočení tohoto kroku.</translation>
2884 </message>
2885 <message>
2886 <location filename="../gui/selectiveinstallwidget.cpp" line="294"/>
2887 <source>Browse backup folder</source>
2888 <translation>Vybrat zálohovací adresář</translation>
2889 </message>
2890 <message>
2891 <location filename="../gui/selectiveinstallwidget.cpp" line="306"/>
2892 <source>Prerequisites</source>
2893 <translation>Předpoklady</translation>
2894 </message>
2895 <message>
2896 <location filename="../gui/selectiveinstallwidget.cpp" line="311"/>
2897 <source>Bootloader installation aborted</source>
2898 <translation>Instalace zavaděče přerušena</translation>
2899 </message>
2900 <message>
2901 <location filename="../gui/selectiveinstallwidget.cpp" line="321"/>
2902 <source>Bootloader files (%1)</source>
2903 <translation>Soubory zavaděče (%1)</translation>
2904 </message>
2905 <message>
2906 <location filename="../gui/selectiveinstallwidget.cpp" line="323"/>
2907 <source>All files (*)</source>
2908 <translation>Všechny soubory (*)</translation>
2909 </message>
2910 <message>
2911 <location filename="../gui/selectiveinstallwidget.cpp" line="325"/>
2912 <source>Select firmware file</source>
2913 <translation>Vyberte soubor firmware</translation>
2914 </message>
2915 <message>
2916 <location filename="../gui/selectiveinstallwidget.cpp" line="327"/>
2917 <source>Error opening firmware file</source>
2918 <translation>Chyba otevírání souboru firmware</translation>
2919 </message>
2920 <message>
2921 <location filename="../gui/selectiveinstallwidget.cpp" line="333"/>
2922 <source>Error reading firmware file</source>
2923 <translation>Chyba čtení souboru firmware</translation>
2924 </message>
2925 <message>
2926 <location filename="../gui/selectiveinstallwidget.cpp" line="343"/>
2927 <source>Backup error</source>
2928 <translation>Chyba zálohování</translation>
2929 </message>
2930 <message>
2931 <location filename="../gui/selectiveinstallwidget.cpp" line="344"/>
2932 <source>Could not create backup file. Continue?</source>
2933 <translation>Nelze vytvořit soubor se zálohou. Pokračovat?</translation>
2934 </message>
2935 <message>
2936 <location filename="../gui/selectiveinstallwidget.cpp" line="368"/>
2937 <source>Manual steps required</source>
2938 <translation>Nutné ruční kroky</translation>
2939 </message>
2940 <message>
2941 <location filename="../gui/selectiveinstallwidget.cpp" line="518"/>
2942 <source>Your installation doesn&apos;t require any game files, skipping.</source>
2943 <translation>Vaše instalace nepotřebuje žádné herní soubory, přeskakuji.</translation>
2944 </message>
2945 <message>
2946 <location filename="../gui/selectiveinstallwidget.cpp" line="171"/>
2947 <source>Continue with installation?</source>
2948 <translation>Pokračovat s instalací?</translation>
2949 </message>
2950 <message>
2951 <location filename="../gui/selectiveinstallwidget.cpp" line="172"/>
2952 <source>Really continue?</source>
2953 <translation>Opravdu pokračovat?</translation>
2954 </message>
2955 <message>
2956 <source>Aborted!</source>
2957 <translation type="obsolete">Přerušeno!</translation>
2958 </message>
2959 <message>
2960 <source>Your installation doesn&apos;t require game files, skipping.</source>
2961 <translation type="vanished">Vaše instalace nepotřebuje herní soubory, přeskakuji.</translation>
2962 </message>
2963</context>
2964<context>
2965 <name>ServerInfo</name>
2966 <message>
2967 <location filename="../base/serverinfo.cpp" line="117"/>
2968 <source>Unknown</source>
2969 <translation>Neznámý</translation>
2970 </message>
2971 <message>
2972 <location filename="../base/serverinfo.cpp" line="121"/>
2973 <source>Unusable</source>
2974 <translation>Nepoužitelný</translation>
2975 </message>
2976 <message>
2977 <location filename="../base/serverinfo.cpp" line="124"/>
2978 <source>Unstable</source>
2979 <translation>Nestabilní</translation>
2980 </message>
2981 <message>
2982 <location filename="../base/serverinfo.cpp" line="127"/>
2983 <source>Stable</source>
2984 <translation>Stabilní</translation>
2985 </message>
2986</context>
2987<context>
2988 <name>SysTrace</name>
2989 <message>
2990 <location filename="../systrace.cpp" line="100"/>
2991 <location filename="../systrace.cpp" line="109"/>
2992 <source>Save system trace log</source>
2993 <translation>Uložit záznam sledování systému</translation>
2994 </message>
2995</context>
2996<context>
2997 <name>SysTraceFrm</name>
2998 <message>
2999 <location filename="../systracefrm.ui" line="14"/>
3000 <source>System Trace</source>
3001 <translation>Sledování systému</translation>
3002 </message>
3003 <message>
3004 <location filename="../systracefrm.ui" line="20"/>
3005 <source>System State trace</source>
3006 <translation>Uložit sledování systému</translation>
3007 </message>
3008 <message>
3009 <location filename="../systracefrm.ui" line="46"/>
3010 <source>&amp;Close</source>
3011 <translation>&amp;Zavřít</translation>
3012 </message>
3013 <message>
3014 <location filename="../systracefrm.ui" line="57"/>
3015 <source>&amp;Save</source>
3016 <translation>&amp;Uložit</translation>
3017 </message>
3018 <message>
3019 <location filename="../systracefrm.ui" line="68"/>
3020 <source>&amp;Refresh</source>
3021 <translation>&amp;Obnovit</translation>
3022 </message>
3023 <message>
3024 <location filename="../systracefrm.ui" line="79"/>
3025 <source>Save &amp;previous</source>
3026 <translation>Uložit &amp;předchozí</translation>
3027 </message>
3028</context>
3029<context>
3030 <name>Sysinfo</name>
3031 <message>
3032 <location filename="../sysinfo.cpp" line="45"/>
3033 <source>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</source>
3034 <translation>&lt;b&gt;Operační systém&lt;/b&gt;&lt;br/&gt;</translation>
3035 </message>
3036 <message>
3037 <location filename="../sysinfo.cpp" line="46"/>
3038 <source>&lt;b&gt;Username&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
3039 <translation>&lt;b&gt;Uživatelské jméno&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
3040 </message>
3041 <message>
3042 <location filename="../sysinfo.cpp" line="48"/>
3043 <source>&lt;b&gt;Permissions&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
3044 <translation>&lt;b&gt;Oprávnění&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
3045 </message>
3046 <message>
3047 <location filename="../sysinfo.cpp" line="50"/>
3048 <source>&lt;b&gt;Attached USB devices&lt;/b&gt;&lt;br/&gt;</source>
3049 <translation>&lt;b&gt;Připojená USB zařízení&lt;/b&gt;&lt;br/&gt;</translation>
3050 </message>
3051 <message>
3052 <location filename="../sysinfo.cpp" line="54"/>
3053 <source>VID: %1 PID: %2, %3</source>
3054 <translation>VID: %1 PID: %2, %3</translation>
3055 </message>
3056 <message>
3057 <location filename="../sysinfo.cpp" line="63"/>
3058 <source>Filesystem</source>
3059 <translation>Souborový systém</translation>
3060 </message>
3061 <message>
3062 <location filename="../sysinfo.cpp" line="66"/>
3063 <source>Mountpoint</source>
3064 <translation>Přípojný bod</translation>
3065 </message>
3066 <message>
3067 <location filename="../sysinfo.cpp" line="66"/>
3068 <source>Label</source>
3069 <translation>Popisek</translation>
3070 </message>
3071 <message>
3072 <location filename="../sysinfo.cpp" line="67"/>
3073 <source>Free</source>
3074 <translation>Volné</translation>
3075 </message>
3076 <message>
3077 <location filename="../sysinfo.cpp" line="67"/>
3078 <source>Total</source>
3079 <translation>Celkem</translation>
3080 </message>
3081 <message>
3082 <location filename="../sysinfo.cpp" line="68"/>
3083 <source>Cluster Size</source>
3084 <translation>Velikost oddílu</translation>
3085 </message>
3086 <message>
3087 <location filename="../sysinfo.cpp" line="70"/>
3088 <source>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</source>
3089 <translation>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</translation>
3090 </message>
3091</context>
3092<context>
3093 <name>SysinfoFrm</name>
3094 <message>
3095 <location filename="../sysinfofrm.ui" line="13"/>
3096 <source>System Info</source>
3097 <translation>Informace o systému</translation>
3098 </message>
3099 <message>
3100 <location filename="../sysinfofrm.ui" line="22"/>
3101 <source>&amp;Refresh</source>
3102 <translation>&amp;Obnovit</translation>
3103 </message>
3104 <message>
3105 <location filename="../sysinfofrm.ui" line="45"/>
3106 <source>&amp;OK</source>
3107 <translation>&amp;OK</translation>
3108 </message>
3109</context>
3110<context>
3111 <name>System</name>
3112 <message>
3113 <location filename="../base/system.cpp" line="121"/>
3114 <source>Guest</source>
3115 <translation>Host</translation>
3116 </message>
3117 <message>
3118 <location filename="../base/system.cpp" line="124"/>
3119 <source>Admin</source>
3120 <translation>Administrátor</translation>
3121 </message>
3122 <message>
3123 <location filename="../base/system.cpp" line="127"/>
3124 <source>User</source>
3125 <translation>Uživatel</translation>
3126 </message>
3127 <message>
3128 <location filename="../base/system.cpp" line="130"/>
3129 <source>Error</source>
3130 <translation>Chyba</translation>
3131 </message>
3132 <message>
3133 <location filename="../base/system.cpp" line="278"/>
3134 <location filename="../base/system.cpp" line="323"/>
3135 <source>(no description available)</source>
3136 <translation>(žádný popis není k dispozici)</translation>
3137 </message>
3138</context>
3139<context>
3140 <name>TTSBase</name>
3141 <message>
3142 <location filename="../base/ttsbase.cpp" line="45"/>
3143 <source>Espeak TTS Engine</source>
3144 <translation>Syntéza řeči Espeak</translation>
3145 </message>
3146 <message>
3147 <location filename="../base/ttsbase.cpp" line="47"/>
3148 <source>Flite TTS Engine</source>
3149 <translation>Syntéza řeči Flite</translation>
3150 </message>
3151 <message>
3152 <location filename="../base/ttsbase.cpp" line="48"/>
3153 <source>Swift TTS Engine</source>
3154 <translation>Syntéza řeči Swift</translation>
3155 </message>
3156 <message>
3157 <location filename="../base/ttsbase.cpp" line="51"/>
3158 <source>SAPI4 TTS Engine</source>
3159 <translation>Syntéza řeči SAPI4</translation>
3160 </message>
3161 <message>
3162 <location filename="../base/ttsbase.cpp" line="53"/>
3163 <source>SAPI5 TTS Engine</source>
3164 <translation>Syntéza řeči SAPI5</translation>
3165 </message>
3166 <message>
3167 <location filename="../base/ttsbase.cpp" line="54"/>
3168 <source>MS Speech Platform</source>
3169 <translation>Systéza řeči MS Speech</translation>
3170 </message>
3171 <message>
3172 <location filename="../base/ttsbase.cpp" line="57"/>
3173 <source>Festival TTS Engine</source>
3174 <translation>Syntéza řeči Festival</translation>
3175 </message>
3176 <message>
3177 <location filename="../base/ttsbase.cpp" line="60"/>
3178 <source>OS X System Engine</source>
3179 <translation>Systémový engine OS X</translation>
3180 </message>
3181</context>
3182<context>
3183 <name>TTSCarbon</name>
3184 <message>
3185 <location filename="../base/ttscarbon.cpp" line="139"/>
3186 <source>Voice:</source>
3187 <translation>Hlas:</translation>
3188 </message>
3189 <message>
3190 <location filename="../base/ttscarbon.cpp" line="145"/>
3191 <source>Speed (words/min):</source>
3192 <translation>Rychlost (slov za minutu):</translation>
3193 </message>
3194 <message>
3195 <location filename="../base/ttscarbon.cpp" line="152"/>
3196 <source>Pitch (0 for default):</source>
3197 <translation>Výška (0 je výchozí):</translation>
3198 </message>
3199 <message>
3200 <location filename="../base/ttscarbon.cpp" line="222"/>
3201 <source>Could not voice string</source>
3202 <translation>Nepodařilo se převést hlasová vlákna</translation>
3203 </message>
3204 <message>
3205 <location filename="../base/ttscarbon.cpp" line="232"/>
3206 <source>Could not convert intermediate file</source>
3207 <translation>Nepodařilo se převést přechodný soubor</translation>
3208 </message>
3209</context>
3210<context>
3211 <name>TTSExes</name>
3212 <message>
3213 <location filename="../base/ttsexes.cpp" line="44"/>
3214 <source>Path to TTS engine:</source>
3215 <translation>Cesta k enginu systézy řeči:</translation>
3216 </message>
3217 <message>
3218 <location filename="../base/ttsexes.cpp" line="46"/>
3219 <source>TTS engine options:</source>
3220 <translation>Možnosti enginu syntézy řeči:</translation>
3221 </message>
3222 <message>
3223 <location filename="../base/ttsexes.cpp" line="78"/>
3224 <source>TTS executable not found</source>
3225 <translation>Spouštěč syntézy řeči nenalezen</translation>
3226 </message>
3227</context>
3228<context>
3229 <name>TTSFestival</name>
3230 <message>
3231 <location filename="../base/ttsfestival.cpp" line="53"/>
3232 <source>Path to Festival client:</source>
3233 <translation>Cesta k Festival klientu:</translation>
3234 </message>
3235 <message>
3236 <location filename="../base/ttsfestival.cpp" line="58"/>
3237 <source>Voice:</source>
3238 <translation>Hlas:</translation>
3239 </message>
3240 <message>
3241 <location filename="../base/ttsfestival.cpp" line="67"/>
3242 <source>Voice description:</source>
3243 <translation>Popis hlasu:</translation>
3244 </message>
3245 <message>
3246 <location filename="../base/ttsfestival.cpp" line="207"/>
3247 <source>engine could not voice string</source>
3248 <translation>engine nemohl namluvit řetězec</translation>
3249 </message>
3250 <message>
3251 <location filename="../base/ttsfestival.cpp" line="290"/>
3252 <source>No description available</source>
3253 <translation>Popis není k dispozici</translation>
3254 </message>
3255</context>
3256<context>
3257 <name>TTSSapi</name>
3258 <message>
3259 <location filename="../base/ttssapi.cpp" line="49"/>
3260 <source>Language:</source>
3261 <translation>Jazyk:</translation>
3262 </message>
3263 <message>
3264 <location filename="../base/ttssapi.cpp" line="56"/>
3265 <source>Voice:</source>
3266 <translation>Hlas:</translation>
3267 </message>
3268 <message>
3269 <location filename="../base/ttssapi.cpp" line="68"/>
3270 <source>Speed:</source>
3271 <translation>Rychlost:</translation>
3272 </message>
3273 <message>
3274 <location filename="../base/ttssapi.cpp" line="71"/>
3275 <source>Options:</source>
3276 <translation>Možnosti:</translation>
3277 </message>
3278 <message>
3279 <location filename="../base/ttssapi.cpp" line="115"/>
3280 <source>Could not copy the SAPI script</source>
3281 <translation>Nepodařilo se zkopírovat SAPI skript</translation>
3282 </message>
3283 <message>
3284 <location filename="../base/ttssapi.cpp" line="133"/>
3285 <source>Could not start SAPI process</source>
3286 <translation>Nepodařilo se spustit proces SAPI</translation>
3287 </message>
3288</context>
3289<context>
3290 <name>TalkFileCreator</name>
3291 <message>
3292 <location filename="../base/talkfile.cpp" line="36"/>
3293 <source>Starting Talk file generation for folder %1</source>
3294 <translation>Spouštím vytváření .talk souboru složky %1</translation>
3295 </message>
3296 <message>
3297 <location filename="../base/talkfile.cpp" line="42"/>
3298 <source>Reading Filelist...</source>
3299 <translation>Čtení seznamu souborů...</translation>
3300 </message>
3301 <message>
3302 <location filename="../base/talkfile.cpp" line="45"/>
3303 <source>Talk file creation aborted</source>
3304 <translation>Vytváření .talk souboru přerušeno</translation>
3305 </message>
3306 <message>
3307 <location filename="../base/talkfile.cpp" line="68"/>
3308 <source>Copying Talkfiles...</source>
3309 <translation>Kopírují se .talk soubory...</translation>
3310 </message>
3311 <message>
3312 <location filename="../base/talkfile.cpp" line="80"/>
3313 <source>Finished creating Talk files</source>
3314 <translation>Vytváření .talk souboru dokončeno</translation>
3315 </message>
3316 <message>
3317 <location filename="../base/talkfile.cpp" line="240"/>
3318 <source>File copy aborted</source>
3319 <translation>Kopírování souboru přerušeno</translation>
3320 </message>
3321 <message>
3322 <location filename="../base/talkfile.cpp" line="259"/>
3323 <source>Copying of %1 to %2 failed</source>
3324 <translation>Kopírování od %1 do %2 selhalo</translation>
3325 </message>
3326 <message>
3327 <location filename="../base/talkfile.cpp" line="280"/>
3328 <source>Cleaning up...</source>
3329 <translation>Čištění...</translation>
3330 </message>
3331 <message>
3332 <location filename="../base/talkfile.cpp" line="291"/>
3333 <source>Finished</source>
3334 <translation>Dokončeno</translation>
3335 </message>
3336</context>
3337<context>
3338 <name>TalkGenerator</name>
3339 <message>
3340 <location filename="../base/talkgenerator.cpp" line="39"/>
3341 <source>Starting TTS Engine</source>
3342 <translation>Spouští se engine syntézy řeči</translation>
3343 </message>
3344 <message>
3345 <location filename="../base/talkgenerator.cpp" line="44"/>
3346 <location filename="../base/talkgenerator.cpp" line="51"/>
3347 <source>Init of TTS engine failed</source>
3348 <translation>Inicializace enginu syntézy řeči selhala</translation>
3349 </message>
3350 <message>
3351 <location filename="../base/talkgenerator.cpp" line="58"/>
3352 <source>Starting Encoder Engine</source>
3353 <translation>Spouští engine enkodéru</translation>
3354 </message>
3355 <message>
3356 <location filename="../base/talkgenerator.cpp" line="62"/>
3357 <source>Init of Encoder engine failed</source>
3358 <translation>Inicializace enginu enkodéru selhala</translation>
3359 </message>
3360 <message>
3361 <location filename="../base/talkgenerator.cpp" line="72"/>
3362 <source>Voicing entries...</source>
3363 <translation>Ozvučují se záznamy...</translation>
3364 </message>
3365 <message>
3366 <location filename="../base/talkgenerator.cpp" line="87"/>
3367 <source>Encoding files...</source>
3368 <translation>Kódování souborů...</translation>
3369 </message>
3370 <message>
3371 <location filename="../base/talkgenerator.cpp" line="126"/>
3372 <source>Voicing aborted</source>
3373 <translation>Ozvučování přerušeno</translation>
3374 </message>
3375 <message>
3376 <location filename="../base/talkgenerator.cpp" line="162"/>
3377 <location filename="../base/talkgenerator.cpp" line="167"/>
3378 <source>Voicing of %1 failed: %2</source>
3379 <translation>Ozvučování %1 selhalo: %2</translation>
3380 </message>
3381 <message>
3382 <location filename="../base/talkgenerator.cpp" line="211"/>
3383 <source>Encoding aborted</source>
3384 <translation>Kódování přerušeno</translation>
3385 </message>
3386 <message>
3387 <location filename="../base/talkgenerator.cpp" line="239"/>
3388 <source>Encoding of %1 failed</source>
3389 <translation>Kódování %1 selhalo</translation>
3390 </message>
3391</context>
3392<context>
3393 <name>ThemeInstallFrm</name>
3394 <message>
3395 <location filename="../themesinstallfrm.ui" line="13"/>
3396 <source>Theme Installation</source>
3397 <translation>Instalace tématu</translation>
3398 </message>
3399 <message>
3400 <location filename="../themesinstallfrm.ui" line="48"/>
3401 <source>Selected Theme</source>
3402 <translation>Vybrané téma</translation>
3403 </message>
3404 <message>
3405 <location filename="../themesinstallfrm.ui" line="73"/>
3406 <source>Description</source>
3407 <translation>Popis</translation>
3408 </message>
3409 <message>
3410 <location filename="../themesinstallfrm.ui" line="83"/>
3411 <source>Download size:</source>
3412 <translation>Velikost stahování:</translation>
3413 </message>
3414 <message>
3415 <location filename="../themesinstallfrm.ui" line="93"/>
3416 <source>Hold Ctrl to select multiple item, Shift for a range</source>
3417 <translation>Podržte Ctrl pro výběr více položek, Shift pro více položek za sebou</translation>
3418 </message>
3419 <message>
3420 <location filename="../themesinstallfrm.ui" line="115"/>
3421 <source>&amp;Install</source>
3422 <translation>&amp;Instalovat</translation>
3423 </message>
3424 <message>
3425 <location filename="../themesinstallfrm.ui" line="125"/>
3426 <source>&amp;Cancel</source>
3427 <translation>&amp;Zrušit</translation>
3428 </message>
3429</context>
3430<context>
3431 <name>ThemesInstallWindow</name>
3432 <message>
3433 <location filename="../themesinstallwindow.cpp" line="40"/>
3434 <source>no theme selected</source>
3435 <translation>není vybráno žádné téma</translation>
3436 </message>
3437 <message>
3438 <location filename="../themesinstallwindow.cpp" line="41"/>
3439 <source>no selection</source>
3440 <translation>žádný výběr</translation>
3441 </message>
3442 <message>
3443 <location filename="../themesinstallwindow.cpp" line="125"/>
3444 <source>Network error: %1.
3445Please check your network and proxy settings.</source>
3446 <translation>Chyba připojení: %1.
3447Prosím zkontrolujte nastavení sítě a proxy.</translation>
3448 </message>
3449 <message>
3450 <location filename="../themesinstallwindow.cpp" line="138"/>
3451 <source>the following error occured:
3452%1</source>
3453 <translation>došlo k následující chybě:
3454%1</translation>
3455 </message>
3456 <message>
3457 <location filename="../themesinstallwindow.cpp" line="144"/>
3458 <source>done.</source>
3459 <translation>hotovo.</translation>
3460 </message>
3461 <message>
3462 <location filename="../themesinstallwindow.cpp" line="181"/>
3463 <source>Information</source>
3464 <translation>Informace</translation>
3465 </message>
3466 <message numerus="yes">
3467 <location filename="../themesinstallwindow.cpp" line="198"/>
3468 <source>Download size %L1 kiB (%n item(s))</source>
3469 <translation>
3470 <numerusform>Stahovaná velikost je %L1 kiB (%n položka)</numerusform>
3471 <numerusform>Stahovaná velikost je %L1 kiB (%n položky)</numerusform>
3472 <numerusform>Stahovaná velikost je %L1 kiB (%n položek)</numerusform>
3473 </translation>
3474 </message>
3475 <message>
3476 <location filename="../themesinstallwindow.cpp" line="211"/>
3477 <source>fetching details for %1</source>
3478 <translation>načítám podrobnosti o %1</translation>
3479 </message>
3480 <message>
3481 <location filename="../themesinstallwindow.cpp" line="214"/>
3482 <source>fetching preview ...</source>
3483 <translation>načítám náhled ...</translation>
3484 </message>
3485 <message>
3486 <location filename="../themesinstallwindow.cpp" line="227"/>
3487 <source>&lt;b&gt;Author:&lt;/b&gt; %1&lt;hr/&gt;</source>
3488 <translation>&lt;b&gt;Autor:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3489 </message>
3490 <message>
3491 <location filename="../themesinstallwindow.cpp" line="228"/>
3492 <location filename="../themesinstallwindow.cpp" line="230"/>
3493 <source>unknown</source>
3494 <translation>neznámý</translation>
3495 </message>
3496 <message>
3497 <location filename="../themesinstallwindow.cpp" line="229"/>
3498 <source>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</source>
3499 <translation>&lt;b&gt;Verze:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3500 </message>
3501 <message>
3502 <location filename="../themesinstallwindow.cpp" line="231"/>
3503 <source>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</source>
3504 <translation>&lt;b&gt;Popis:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3505 </message>
3506 <message>
3507 <location filename="../themesinstallwindow.cpp" line="232"/>
3508 <source>no description</source>
3509 <translation>žádný popis</translation>
3510 </message>
3511 <message>
3512 <location filename="../themesinstallwindow.cpp" line="248"/>
3513 <source>Retrieving theme preview failed.
3514HTTP response code: %1</source>
3515 <translation>Stahování náhledu tématu selhalo.
3516Kód HTTP odpovědi: %1</translation>
3517 </message>
3518 <message>
3519 <location filename="../themesinstallwindow.cpp" line="260"/>
3520 <source>no theme preview</source>
3521 <translation>žádný náhled tématu</translation>
3522 </message>
3523 <message>
3524 <location filename="../themesinstallwindow.cpp" line="289"/>
3525 <source>Select</source>
3526 <translation>Vybrat</translation>
3527 </message>
3528 <message>
3529 <location filename="../themesinstallwindow.cpp" line="296"/>
3530 <source>getting themes information ...</source>
3531 <translation>stahuji informace o tématu ...</translation>
3532 </message>
3533 <message>
3534 <location filename="../themesinstallwindow.cpp" line="326"/>
3535 <source>No themes selected, skipping</source>
3536 <translation>Nevybráno žádné téma, přeskakuji</translation>
3537 </message>
3538 <message>
3539 <location filename="../themesinstallwindow.cpp" line="356"/>
3540 <source>Mount point is wrong!</source>
3541 <translation>Připojovací bod je špatně!</translation>
3542 </message>
3543</context>
3544<context>
3545 <name>UninstallFrm</name>
3546 <message>
3547 <location filename="../uninstallfrm.ui" line="16"/>
3548 <source>Uninstall Rockbox</source>
3549 <translation>Odinstalovat Rockbox</translation>
3550 </message>
3551 <message>
3552 <location filename="../uninstallfrm.ui" line="35"/>
3553 <source>Please select the Uninstallation Method</source>
3554 <translation>Prosím vyberte způsob odinstalace</translation>
3555 </message>
3556 <message>
3557 <location filename="../uninstallfrm.ui" line="45"/>
3558 <source>Uninstallation Method</source>
3559 <translation>Způsob odinstalace</translation>
3560 </message>
3561 <message>
3562 <location filename="../uninstallfrm.ui" line="51"/>
3563 <source>Complete Uninstallation</source>
3564 <translation>Kompletní odinstalace</translation>
3565 </message>
3566 <message>
3567 <location filename="../uninstallfrm.ui" line="58"/>
3568 <source>Smart Uninstallation</source>
3569 <translation>Volitelná odinstalace</translation>
3570 </message>
3571 <message>
3572 <location filename="../uninstallfrm.ui" line="68"/>
3573 <source>Please select what you want to uninstall</source>
3574 <translation>Prosím vyberte co chcete odebrat</translation>
3575 </message>
3576 <message>
3577 <location filename="../uninstallfrm.ui" line="78"/>
3578 <source>Installed Parts</source>
3579 <translation>Instalované součásti</translation>
3580 </message>
3581 <message>
3582 <location filename="../uninstallfrm.ui" line="128"/>
3583 <source>&amp;Uninstall</source>
3584 <translation>&amp;Odinstalovat</translation>
3585 </message>
3586 <message>
3587 <location filename="../uninstallfrm.ui" line="138"/>
3588 <source>&amp;Cancel</source>
3589 <translation>&amp;Zrušit</translation>
3590 </message>
3591</context>
3592<context>
3593 <name>Uninstaller</name>
3594 <message>
3595 <location filename="../base/uninstall.cpp" line="32"/>
3596 <location filename="../base/uninstall.cpp" line="43"/>
3597 <source>Starting Uninstallation</source>
3598 <translation>Spouštím odinstalaci</translation>
3599 </message>
3600 <message>
3601 <location filename="../base/uninstall.cpp" line="36"/>
3602 <source>Finished Uninstallation</source>
3603 <translation>Odinstalace dokončena</translation>
3604 </message>
3605 <message>
3606 <location filename="../base/uninstall.cpp" line="49"/>
3607 <source>Uninstalling %1...</source>
3608 <translation>Odinstalace %1...</translation>
3609 </message>
3610 <message>
3611 <location filename="../base/uninstall.cpp" line="80"/>
3612 <source>Could not delete %1</source>
3613 <translation>%1 nejde smazat</translation>
3614 </message>
3615 <message>
3616 <location filename="../base/uninstall.cpp" line="109"/>
3617 <source>Uninstallation finished</source>
3618 <translation>Odinstalace dokončena</translation>
3619 </message>
3620</context>
3621<context>
3622 <name>Utils</name>
3623 <message>
3624 <location filename="../base/utils.cpp" line="322"/>
3625 <source>&lt;li&gt;Permissions insufficient for bootloader installation.
3626Administrator priviledges are necessary.&lt;/li&gt;</source>
3627 <translation>&lt;li&gt;Nedostatečná oprávnění pro instalaci zavaděče.
3628Jsou nutná administrátorská práva.&lt;/li&gt;</translation>
3629 </message>
3630 <message>
3631 <location filename="../base/utils.cpp" line="334"/>
3632 <source>&lt;li&gt;Target mismatch detected.&lt;br/&gt;Installed target: %1&lt;br/&gt;Selected target: %2.&lt;/li&gt;</source>
3633 <translation>&lt;li&gt;Zjištěn chybný cíl.&lt;br/&gt;Instalováno na: %1&lt;br/&gt;Vybraný cíl: %2.&lt;/li&gt;</translation>
3634 </message>
3635 <message>
3636 <location filename="../base/utils.cpp" line="341"/>
3637 <source>Problem detected:</source>
3638 <translation>Zjištěn problém:</translation>
3639 </message>
3640</context>
3641<context>
3642 <name>VoiceFileCreator</name>
3643 <message>
3644 <location filename="../base/voicefile.cpp" line="43"/>
3645 <source>Starting Voicefile generation</source>
3646 <translation>Začíná generování hlasového souboru</translation>
3647 </message>
3648 <message>
3649 <location filename="../base/voicefile.cpp" line="56"/>
3650 <source>could not find rockbox-info.txt</source>
3651 <translation>nelze nalézt rockbox-info.txt</translation>
3652 </message>
3653 <message>
3654 <location filename="../base/voicefile.cpp" line="90"/>
3655 <source>Extracted voice strings from installation</source>
3656 <translation>Řetězce řeči získané z instalace</translation>
3657 </message>
3658 <message>
3659 <location filename="../base/voicefile.cpp" line="100"/>
3660 <source>Extracted voice strings incompatible</source>
3661 <translation>Získané řetězce řeči nejsou kompatibilní</translation>
3662 </message>
3663 <message>
3664 <location filename="../base/voicefile.cpp" line="145"/>
3665 <source>Could not retrieve strings from installation, downloading</source>
3666 <translation>Nepodařilo se získat řetězce z instalace, stahuji</translation>
3667 </message>
3668 <message>
3669 <location filename="../base/voicefile.cpp" line="171"/>
3670 <source>Downloading voice info...</source>
3671 <translation>Stahuji informace o hlasu...</translation>
3672 </message>
3673 <message>
3674 <location filename="../base/voicefile.cpp" line="184"/>
3675 <source>Download error: received HTTP error %1.</source>
3676 <translation>Chyba stahování: HTTP chyba %1.</translation>
3677 </message>
3678 <message>
3679 <location filename="../base/voicefile.cpp" line="191"/>
3680 <source>Cached file used.</source>
3681 <translation>Použit cachovaný soubor.</translation>
3682 </message>
3683 <message>
3684 <location filename="../base/voicefile.cpp" line="194"/>
3685 <source>Download error: %1</source>
3686 <translation>Chyba stahování: %1</translation>
3687 </message>
3688 <message>
3689 <location filename="../base/voicefile.cpp" line="199"/>
3690 <source>Download finished.</source>
3691 <translation>Stahování dokončena.</translation>
3692 </message>
3693 <message>
3694 <location filename="../base/voicefile.cpp" line="212"/>
3695 <source>failed to open downloaded file</source>
3696 <translation>otevření staženého souboru selhalo</translation>
3697 </message>
3698 <message>
3699 <location filename="../base/voicefile.cpp" line="218"/>
3700 <source>Reading strings...</source>
3701 <translation>Čtení řetězců...</translation>
3702 </message>
3703 <message>
3704 <location filename="../base/voicefile.cpp" line="271"/>
3705 <source>The downloaded file was empty!</source>
3706 <translation>Stažený soubor byl prázdný!</translation>
3707 </message>
3708 <message>
3709 <location filename="../base/voicefile.cpp" line="297"/>
3710 <source>Creating voicefiles...</source>
3711 <translation>Vytváří se hlasový soubor...</translation>
3712 </message>
3713 <message>
3714 <location filename="../base/voicefile.cpp" line="302"/>
3715 <source>Error opening downloaded file</source>
3716 <translation>Chyba otevírání staženého souboru</translation>
3717 </message>
3718 <message>
3719 <location filename="../base/voicefile.cpp" line="313"/>
3720 <source>Error opening output file</source>
3721 <translation>Chyba při otevírání výstupního souboru</translation>
3722 </message>
3723 <message>
3724 <location filename="../base/voicefile.cpp" line="333"/>
3725 <source>successfully created.</source>
3726 <translation>úspěšně vytvořeno.</translation>
3727 </message>
3728 <message>
3729 <location filename="../base/voicefile.cpp" line="342"/>
3730 <source>Cleaning up...</source>
3731 <translation>Čištění...</translation>
3732 </message>
3733 <message>
3734 <location filename="../base/voicefile.cpp" line="353"/>
3735 <source>Finished</source>
3736 <translation>Dokončeno</translation>
3737 </message>
3738</context>
3739<context>
3740 <name>ZipInstaller</name>
3741 <message>
3742 <location filename="../base/zipinstaller.cpp" line="60"/>
3743 <source>done.</source>
3744 <translation>hotovo.</translation>
3745 </message>
3746 <message>
3747 <location filename="../base/zipinstaller.cpp" line="80"/>
3748 <source>Downloading file %1.%2</source>
3749 <translation>Stahuji soubor %1.%2</translation>
3750 </message>
3751 <message>
3752 <location filename="../base/zipinstaller.cpp" line="115"/>
3753 <source>Download error: received HTTP error %1.</source>
3754 <translation>Chyba stahování: HTTP chyba %1.</translation>
3755 </message>
3756 <message>
3757 <location filename="../base/zipinstaller.cpp" line="121"/>
3758 <source>Cached file used.</source>
3759 <translation>Použit cachovaný soubor.</translation>
3760 </message>
3761 <message>
3762 <location filename="../base/zipinstaller.cpp" line="123"/>
3763 <source>Download error: %1</source>
3764 <translation>Chyba stahování: %1</translation>
3765 </message>
3766 <message>
3767 <location filename="../base/zipinstaller.cpp" line="127"/>
3768 <source>Download finished.</source>
3769 <translation>Stahování dokončeno.</translation>
3770 </message>
3771 <message>
3772 <location filename="../base/zipinstaller.cpp" line="133"/>
3773 <source>Extracting file.</source>
3774 <translation>Rozbaluji soubor.</translation>
3775 </message>
3776 <message>
3777 <location filename="../base/zipinstaller.cpp" line="153"/>
3778 <source>Extraction failed!</source>
3779 <translation>Rozbalení selhalo!</translation>
3780 </message>
3781 <message>
3782 <location filename="../base/zipinstaller.cpp" line="146"/>
3783 <source>Not enough disk space! Aborting.</source>
3784 <translation>Není dost místa na disku! Přerušuji.</translation>
3785 </message>
3786 <message>
3787 <location filename="../base/zipinstaller.cpp" line="68"/>
3788 <source>Package installation finished successfully.</source>
3789 <translation>Instalace balíčku úspěšně dokončena.</translation>
3790 </message>
3791 <message>
3792 <location filename="../base/zipinstaller.cpp" line="162"/>
3793 <source>Installing file.</source>
3794 <translation>Instaluji soubor.</translation>
3795 </message>
3796 <message>
3797 <location filename="../base/zipinstaller.cpp" line="173"/>
3798 <source>Installing file failed.</source>
3799 <translation>Instalace souboru selhala.</translation>
3800 </message>
3801 <message>
3802 <location filename="../base/zipinstaller.cpp" line="186"/>
3803 <source>Creating installation log</source>
3804 <translation>Vytváření instalačního výpisu</translation>
3805 </message>
3806</context>
3807<context>
3808 <name>ZipUtil</name>
3809 <message>
3810 <location filename="../base/ziputil.cpp" line="125"/>
3811 <source>Creating output path failed</source>
3812 <translation>Vytvoření výstupní cesty selhalo</translation>
3813 </message>
3814 <message>
3815 <location filename="../base/ziputil.cpp" line="132"/>
3816 <source>Creating output file failed</source>
3817 <translation>Vytvoření výstupního souboru selhalo</translation>
3818 </message>
3819 <message>
3820 <location filename="../base/ziputil.cpp" line="141"/>
3821 <source>Error during Zip operation</source>
3822 <translation>Chyba během operace se zipy</translation>
3823 </message>
3824</context>
3825<context>
3826 <name>aboutBox</name>
3827 <message>
3828 <location filename="../aboutbox.ui" line="14"/>
3829 <source>About Rockbox Utility</source>
3830 <translation>O Rockbox Utilitě</translation>
3831 </message>
3832 <message>
3833 <location filename="../aboutbox.ui" line="32"/>
3834 <source>The Rockbox Utility</source>
3835 <translation>Rockbox Utilita</translation>
3836 </message>
3837 <message>
3838 <location filename="../aboutbox.ui" line="54"/>
3839 <source>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</source>
3840 <translation>Instalační a úklidová utilita pro open source firmware a digitální audio přehrávač Rockbox.&lt;br/&gt;© Rockbox Tým.&lt;br/&gt;Uvolněno pod licencí GNU General Public License v2.&lt;br/&gt;Použity ikony z &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;projektu Tango&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</translation>
3841 </message>
3842 <message>
3843 <location filename="../aboutbox.ui" line="74"/>
3844 <source>&amp;Credits</source>
3845 <translation>&amp;Zásluhy</translation>
3846 </message>
3847 <message>
3848 <location filename="../aboutbox.ui" line="106"/>
3849 <source>&amp;License</source>
3850 <translation>&amp;Licence</translation>
3851 </message>
3852 <message>
3853 <location filename="../aboutbox.ui" line="132"/>
3854 <source>&amp;Speex License</source>
3855 <translation>Licence &amp;Speex</translation>
3856 </message>
3857 <message>
3858 <location filename="../aboutbox.ui" line="158"/>
3859 <source>&amp;Ok</source>
3860 <translation>&amp;OK</translation>
3861 </message>
3862</context>
3863</TS>
diff --git a/utils/rbutilqt/lang/rbutil_de.ts b/utils/rbutilqt/lang/rbutil_de.ts
new file mode 100644
index 0000000000..26ef691d3a
--- /dev/null
+++ b/utils/rbutilqt/lang/rbutil_de.ts
@@ -0,0 +1,3788 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE TS>
3<TS version="2.1" language="de">
4<context>
5 <name>BackupDialog</name>
6 <message>
7 <location filename="../gui/backupdialogfrm.ui" line="17"/>
8 <location filename="../gui/backupdialogfrm.ui" line="43"/>
9 <source>Backup</source>
10 <translation>Sicherung</translation>
11 </message>
12 <message>
13 <location filename="../gui/backupdialogfrm.ui" line="33"/>
14 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This dialog will create a backup by archiving the contents of the Rockbox installation on the player into a zip file. This will include installed themes and settings stored below the .rockbox folder on the player.&lt;/p&gt;&lt;p&gt;The backup filename will be created based on the installed version. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
15 <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Erzeugt eine Sicherungskopie durch Archivieren der Rockbox-Installation in einer Zip-Datei. Dies schließt Themen und Einstellungen ein, die im .rockbox-Ordner gespeichert sind.&lt;/p&gt;&lt;p&gt;Der Dateiname für die Sicherung wird anhand der installierten Version vorgeschlagen.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
16 </message>
17 <message>
18 <location filename="../gui/backupdialogfrm.ui" line="49"/>
19 <source>Size: unknown</source>
20 <translation>Größe: unbekannt</translation>
21 </message>
22 <message>
23 <location filename="../gui/backupdialogfrm.ui" line="56"/>
24 <source>Backup to: unknown</source>
25 <translation>Sichern nach: unbekannt</translation>
26 </message>
27 <message>
28 <location filename="../gui/backupdialogfrm.ui" line="76"/>
29 <source>&amp;Change</source>
30 <translation>Ä&amp;ndern</translation>
31 </message>
32 <message>
33 <location filename="../gui/backupdialogfrm.ui" line="116"/>
34 <source>&amp;Backup</source>
35 <translation>&amp;Sichern</translation>
36 </message>
37 <message>
38 <location filename="../gui/backupdialogfrm.ui" line="127"/>
39 <source>&amp;Cancel</source>
40 <translation>&amp;Abbrechen</translation>
41 </message>
42 <message>
43 <location filename="../gui/backupdialog.cpp" line="70"/>
44 <source>Installation size: calculating ...</source>
45 <translation>Installationsgröße: berechne ...</translation>
46 </message>
47 <message>
48 <location filename="../gui/backupdialog.cpp" line="89"/>
49 <source>Select Backup Filename</source>
50 <translation>Dateiname für Sicherung auswählen</translation>
51 </message>
52 <message>
53 <location filename="../gui/backupdialog.cpp" line="109"/>
54 <source>Installation size: %L1 %2</source>
55 <translation>Installationsgröße: %L1 %2</translation>
56 </message>
57 <message>
58 <location filename="../gui/backupdialog.cpp" line="116"/>
59 <source>File exists</source>
60 <translation>Datei existiert</translation>
61 </message>
62 <message>
63 <location filename="../gui/backupdialog.cpp" line="117"/>
64 <source>The selected backup file already exists. Overwrite?</source>
65 <translation>Ausgewählte Sicherungsdatei bereits vorhanden. Überschreiben?</translation>
66 </message>
67 <message>
68 <location filename="../gui/backupdialog.cpp" line="125"/>
69 <source>Starting backup ...</source>
70 <translation>Starte Sicherung ...</translation>
71 </message>
72 <message>
73 <location filename="../gui/backupdialog.cpp" line="144"/>
74 <source>Backup successful.</source>
75 <translation>Sicherung erfolgreich.</translation>
76 </message>
77 <message>
78 <location filename="../gui/backupdialog.cpp" line="147"/>
79 <source>Backup failed!</source>
80 <translation>Sicherung fehlgeschlagen!</translation>
81 </message>
82</context>
83<context>
84 <name>BootloaderInstallAms</name>
85 <message>
86 <location filename="../base/bootloaderinstallams.cpp" line="33"/>
87 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; This file is not present on your player and will disappear automatically after installing it.&lt;br/&gt;&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
88 <translation>Die Bootloader-Installation erfordert Originalfirmware-Datei (bin-Datei). Die Firmware-Datei wird angepasst und auf dem Gerät mit dem Rockbox-Bootloader installiert. Aus rechtlichen Gründen muss diese Datei separat heruntergeladen werden. Die Datei ist im &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa-Forum&lt;/a&gt; zu finden sowie im &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;Handbuch&lt;/a&gt; und auf der &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; Wiki-Seite beschrieben.&lt;br/&gt;&lt;b&gt;Hinweis:&lt;/b&gt; Diese Datei ist nicht auf dem Gerät vorhanden und wird automatisch nach der Installation entfernt.&lt;br/&gt;&lt;br/&gt;OK, um fortzufahren und die Datei auf dem Computer auszuwählen.</translation>
89 </message>
90 <message>
91 <location filename="../base/bootloaderinstallams.cpp" line="58"/>
92 <source>Downloading bootloader file</source>
93 <translation>Lade Bootloader-Datei herunter</translation>
94 </message>
95 <message>
96 <location filename="../base/bootloaderinstallams.cpp" line="100"/>
97 <location filename="../base/bootloaderinstallams.cpp" line="113"/>
98 <source>Could not load %1</source>
99 <translation>Konnte %1 nicht laden</translation>
100 </message>
101 <message>
102 <location filename="../base/bootloaderinstallams.cpp" line="127"/>
103 <source>No room to insert bootloader, try another firmware version</source>
104 <translation>Kein Platz, um den Bootloader einzufügen. Bitte mit anderer Firmware-Version versuchen</translation>
105 </message>
106 <message>
107 <location filename="../base/bootloaderinstallams.cpp" line="137"/>
108 <source>Patching Firmware...</source>
109 <translation>Modifiziere Firmware ...</translation>
110 </message>
111 <message>
112 <location filename="../base/bootloaderinstallams.cpp" line="148"/>
113 <source>Could not open %1 for writing</source>
114 <translation>Konnte %1 nicht zum schreiben öffnen</translation>
115 </message>
116 <message>
117 <location filename="../base/bootloaderinstallams.cpp" line="161"/>
118 <source>Could not write firmware file</source>
119 <translation>Konnte Firmware-Datei nicht schreiben</translation>
120 </message>
121 <message>
122 <location filename="../base/bootloaderinstallams.cpp" line="177"/>
123 <source>Success: modified firmware file created</source>
124 <translation>Erfolg: modifizierte Firmware-Datei erzeugt</translation>
125 </message>
126 <message>
127 <location filename="../base/bootloaderinstallams.cpp" line="185"/>
128 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
129 <translation>Zum deinstallieren ein Upgrade mit einer unveränderten Originalfirmware-Datei durchführen</translation>
130 </message>
131</context>
132<context>
133 <name>BootloaderInstallBSPatch</name>
134 <message>
135 <location filename="../base/bootloaderinstallbspatch.cpp" line="65"/>
136 <source>Bootloader installation requires you to provide the correct verrsion of the original firmware file. This file will be patched with the Rockbox bootloader and installed to your player. You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/wiki/&apos;&gt;rockbox wiki&lt;/a&gt; pages on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
137 <translation>Die Bootloader-Installation erfordert eine Datei der Originalfirmware. Die Firmware-Datei wird angepasst und auf dem Gerät mit dem Rockbox-Bootloader installiert. Aus rechtlichen Gründen muss diese Datei separat heruntergeladen werden. Wie diese Datei zu beziehen ist, ist im &lt;a href=&apos;http://www.rockbox.org/wiki/&apos;&gt;Rockbox Wiki&lt;/a&gt; beschrieben.&lt;br/&gt;OK, um fortzufahren und die Datei auf dem Computer auszuwählen.</translation>
138 </message>
139 <message>
140 <location filename="../base/bootloaderinstallbspatch.cpp" line="84"/>
141 <source>Could not read original firmware file</source>
142 <translation>Konnte Original-Firmware-Datei nicht lesen</translation>
143 </message>
144 <message>
145 <location filename="../base/bootloaderinstallbspatch.cpp" line="90"/>
146 <source>Downloading bootloader file</source>
147 <translation>Lade Bootloader-Datei herunter</translation>
148 </message>
149 <message>
150 <location filename="../base/bootloaderinstallbspatch.cpp" line="99"/>
151 <source>Patching file...</source>
152 <translation>Patche Firmware ...</translation>
153 </message>
154 <message>
155 <location filename="../base/bootloaderinstallbspatch.cpp" line="124"/>
156 <source>Patching the original firmware failed</source>
157 <translation>Modifizieren der Firmware-Datei fehlgeschlagen</translation>
158 </message>
159 <message>
160 <location filename="../base/bootloaderinstallbspatch.cpp" line="130"/>
161 <source>Succesfully patched firmware file</source>
162 <translation>Firmware-Datei erfolgreich modifiziert</translation>
163 </message>
164 <message>
165 <location filename="../base/bootloaderinstallbspatch.cpp" line="145"/>
166 <source>Bootloader successful installed</source>
167 <translation>Bootloader erfolgreich installiert</translation>
168 </message>
169 <message>
170 <location filename="../base/bootloaderinstallbspatch.cpp" line="151"/>
171 <source>Patched bootloader could not be installed</source>
172 <translation>Modifizierter Bootloader konnte nicht installiert werden</translation>
173 </message>
174 <message>
175 <location filename="../base/bootloaderinstallbspatch.cpp" line="161"/>
176 <source>To uninstall, perform a normal upgrade with an unmodified original firmware.</source>
177 <translation>Zum deinstallieren ein Upgrade mit einer unveränderten Originalfirmware-Datei durchführen.</translation>
178 </message>
179</context>
180<context>
181 <name>BootloaderInstallBase</name>
182 <message>
183 <location filename="../base/bootloaderinstallbase.cpp" line="78"/>
184 <source>Download error: received HTTP error %1.</source>
185 <translation>Fehler beim Herunterladen: HTTP Fehler %1.</translation>
186 </message>
187 <message>
188 <location filename="../base/bootloaderinstallbase.cpp" line="84"/>
189 <source>Download error: %1</source>
190 <translation>Fehler beim Herunterladen: %1</translation>
191 </message>
192 <message>
193 <location filename="../base/bootloaderinstallbase.cpp" line="90"/>
194 <source>Download finished (cache used).</source>
195 <translation>Download abgeschlossen (Cache verwendet).</translation>
196 </message>
197 <message>
198 <location filename="../base/bootloaderinstallbase.cpp" line="92"/>
199 <source>Download finished.</source>
200 <translation>Download abgeschlossen.</translation>
201 </message>
202 <message>
203 <location filename="../base/bootloaderinstallbase.cpp" line="120"/>
204 <source>Creating backup of original firmware file.</source>
205 <translation>Erzeuge Sicherungskopie der Original-Firmware.</translation>
206 </message>
207 <message>
208 <location filename="../base/bootloaderinstallbase.cpp" line="122"/>
209 <source>Creating backup folder failed</source>
210 <translation>Erzeugen des Sicherungskopie-Ordners fehlgeschlagen</translation>
211 </message>
212 <message>
213 <location filename="../base/bootloaderinstallbase.cpp" line="128"/>
214 <source>Creating backup copy failed.</source>
215 <translation>Erzeugen der Sicherungskopie fehlgeschlagen.</translation>
216 </message>
217 <message>
218 <location filename="../base/bootloaderinstallbase.cpp" line="131"/>
219 <source>Backup created.</source>
220 <translation>Sicherungskopie erzeugt.</translation>
221 </message>
222 <message>
223 <location filename="../base/bootloaderinstallbase.cpp" line="144"/>
224 <source>Creating installation log</source>
225 <translation>Erzeuge Installationslog</translation>
226 </message>
227 <message>
228 <location filename="../base/bootloaderinstallbase.cpp" line="242"/>
229 <source>Zip file format detected</source>
230 <translation>Zip-Format erkannt</translation>
231 </message>
232 <message>
233 <location filename="../base/bootloaderinstallbase.cpp" line="254"/>
234 <source>CAB file format detected</source>
235 <translation>CAB-Format erkannt</translation>
236 </message>
237 <message>
238 <location filename="../base/bootloaderinstallbase.cpp" line="275"/>
239 <source>Extracting firmware %1 from archive</source>
240 <translation>Entpacke Firmware %1 aus Archiv</translation>
241 </message>
242 <message>
243 <location filename="../base/bootloaderinstallbase.cpp" line="282"/>
244 <source>Error extracting firmware from archive</source>
245 <translation>Fehler beim Extrahieren der Firmware</translation>
246 </message>
247 <message>
248 <location filename="../base/bootloaderinstallbase.cpp" line="291"/>
249 <source>Could not find firmware in archive</source>
250 <translation>Keine Firmware im Archiv gefunden</translation>
251 </message>
252 <message>
253 <location filename="../base/bootloaderinstallbase.cpp" line="166"/>
254 <source>Waiting for system to remount player</source>
255 <translation>Warte bis das Gerät wieder eingehängt ist</translation>
256 </message>
257 <message>
258 <location filename="../base/bootloaderinstallbase.cpp" line="196"/>
259 <source>Player remounted</source>
260 <translation>Gerät wieder eingehängt</translation>
261 </message>
262 <message>
263 <location filename="../base/bootloaderinstallbase.cpp" line="201"/>
264 <source>Timeout on remount</source>
265 <translation>Zeitüberschreitung beim Warten</translation>
266 </message>
267 <message>
268 <location filename="../base/bootloaderinstallbase.cpp" line="156"/>
269 <source>Installation log created</source>
270 <translation>Installationslog erzeugt</translation>
271 </message>
272</context>
273<context>
274 <name>BootloaderInstallChinaChip</name>
275 <message>
276 <location filename="../base/bootloaderinstallchinachip.cpp" line="33"/>
277 <source>Bootloader installation requires you to provide a firmware file of the original firmware (HXF file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
278 <translation>Die Bootloader-Installation erfordert eine Firmware-Datei der Originalfirmware (HXF-Datei). Diese Datei muss aus rechtlichen Gründen separat heruntergeladen werden. Wie diese Datei zu beziehen ist, ist im &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;Handbuch&lt;/a&gt; und auf der &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; Wiki-Seite beschrieben.&lt;br/&gt;OK, um fortzufahren und die Datei auf dem Computer auszuwählen.</translation>
279 </message>
280 <message>
281 <location filename="../base/bootloaderinstallchinachip.cpp" line="50"/>
282 <source>Downloading bootloader file</source>
283 <translation>Lade Bootloader-Datei herunter</translation>
284 </message>
285 <message>
286 <location filename="../base/bootloaderinstallchinachip.cpp" line="75"/>
287 <source>Could not open firmware file</source>
288 <translation>Konnte Firmware-Datei nicht öffnen</translation>
289 </message>
290 <message>
291 <location filename="../base/bootloaderinstallchinachip.cpp" line="78"/>
292 <source>Could not open bootloader file</source>
293 <translation>Konnte Bootloader-Datei nicht öffnen</translation>
294 </message>
295 <message>
296 <location filename="../base/bootloaderinstallchinachip.cpp" line="81"/>
297 <source>Could not allocate memory</source>
298 <translation>Konnte Speicher nicht allokieren</translation>
299 </message>
300 <message>
301 <location filename="../base/bootloaderinstallchinachip.cpp" line="84"/>
302 <source>Could not load firmware file</source>
303 <translation>Konnte Firmware-Datei nicht laden</translation>
304 </message>
305 <message>
306 <location filename="../base/bootloaderinstallchinachip.cpp" line="87"/>
307 <source>File is not a valid ChinaChip firmware</source>
308 <translation>Datei ist keine gültige ChinaChip-Firmware</translation>
309 </message>
310 <message>
311 <location filename="../base/bootloaderinstallchinachip.cpp" line="90"/>
312 <source>Could not find ccpmp.bin in input file</source>
313 <translation>Konnte ccpmp.bin in Eingabedatei nicht finden</translation>
314 </message>
315 <message>
316 <location filename="../base/bootloaderinstallchinachip.cpp" line="93"/>
317 <source>Could not open backup file for ccpmp.bin</source>
318 <translation>Konnte Backup-Datei für ccpmp.bin nicht öffnen</translation>
319 </message>
320 <message>
321 <location filename="../base/bootloaderinstallchinachip.cpp" line="96"/>
322 <source>Could not write backup file for ccpmp.bin</source>
323 <translation>Konnte Backup-Datei für ccpmp.bin nicht schreiben</translation>
324 </message>
325 <message>
326 <location filename="../base/bootloaderinstallchinachip.cpp" line="99"/>
327 <source>Could not load bootloader file</source>
328 <translation>Konnte Bootloader-Datei nicht laden</translation>
329 </message>
330 <message>
331 <location filename="../base/bootloaderinstallchinachip.cpp" line="102"/>
332 <source>Could not get current time</source>
333 <translation>Konnte aktuelle Zeit nicht lesen</translation>
334 </message>
335 <message>
336 <location filename="../base/bootloaderinstallchinachip.cpp" line="105"/>
337 <source>Could not open output file</source>
338 <translation>Konnte Ausgabedatei nicht öffnen</translation>
339 </message>
340 <message>
341 <location filename="../base/bootloaderinstallchinachip.cpp" line="108"/>
342 <source>Could not write output file</source>
343 <translation>Konnte Ausgabedatei nicht schreiben</translation>
344 </message>
345 <message>
346 <location filename="../base/bootloaderinstallchinachip.cpp" line="111"/>
347 <source>Unexpected error from chinachippatcher</source>
348 <translation>Unerwarteter Fehler von chinachippatcher</translation>
349 </message>
350</context>
351<context>
352 <name>BootloaderInstallFile</name>
353 <message>
354 <location filename="../base/bootloaderinstallfile.cpp" line="34"/>
355 <source>Downloading bootloader</source>
356 <translation>Lade Bootloader herunter</translation>
357 </message>
358 <message>
359 <location filename="../base/bootloaderinstallfile.cpp" line="43"/>
360 <source>Installing Rockbox bootloader</source>
361 <translation>Installiere Rockbox Bootloader</translation>
362 </message>
363 <message>
364 <location filename="../base/bootloaderinstallfile.cpp" line="75"/>
365 <source>Error accessing output folder</source>
366 <translation>Fehler beim Zugriff auf den Ausgabeordner</translation>
367 </message>
368 <message>
369 <location filename="../base/bootloaderinstallfile.cpp" line="89"/>
370 <source>A firmware file is already present on player</source>
371 <translation>Firmware-Datei bereits auf dem Gerät vorhanden</translation>
372 </message>
373 <message>
374 <location filename="../base/bootloaderinstallfile.cpp" line="94"/>
375 <source>Bootloader successful installed</source>
376 <translation>Bootloader erfolgreich installiert</translation>
377 </message>
378 <message>
379 <location filename="../base/bootloaderinstallfile.cpp" line="97"/>
380 <source>Copying modified firmware file failed</source>
381 <translation>Kopieren der geänderten Firmware-Datei fehlgeschlagen</translation>
382 </message>
383 <message>
384 <location filename="../base/bootloaderinstallfile.cpp" line="111"/>
385 <source>Removing Rockbox bootloader</source>
386 <translation>Entferne Rockbox Bootloader</translation>
387 </message>
388 <message>
389 <location filename="../base/bootloaderinstallfile.cpp" line="115"/>
390 <source>No original firmware file found.</source>
391 <translation>Keine Original-Firmware gefunden.</translation>
392 </message>
393 <message>
394 <location filename="../base/bootloaderinstallfile.cpp" line="121"/>
395 <source>Can&apos;t remove Rockbox bootloader file.</source>
396 <translation>Kann Rockbox Bootloader-Datei nicht entfernen.</translation>
397 </message>
398 <message>
399 <location filename="../base/bootloaderinstallfile.cpp" line="126"/>
400 <source>Can&apos;t restore bootloader file.</source>
401 <translation>Kann Bootloader-Datei nicht wiederherstellen.</translation>
402 </message>
403 <message>
404 <location filename="../base/bootloaderinstallfile.cpp" line="130"/>
405 <source>Original bootloader restored successfully.</source>
406 <translation>Original-Bootloader erfolgreich wiederhergestellt.</translation>
407 </message>
408</context>
409<context>
410 <name>BootloaderInstallHex</name>
411 <message>
412 <location filename="../base/bootloaderinstallhex.cpp" line="69"/>
413 <source>checking MD5 hash of input file ...</source>
414 <translation>prüfe MD5-Hash der Eingabedatei ...</translation>
415 </message>
416 <message>
417 <location filename="../base/bootloaderinstallhex.cpp" line="80"/>
418 <source>Could not verify original firmware file</source>
419 <translation>Konnte Originalfirmware-Datei nicht prüfen</translation>
420 </message>
421 <message>
422 <location filename="../base/bootloaderinstallhex.cpp" line="95"/>
423 <source>Firmware file not recognized.</source>
424 <translation>Firmware-Datei nicht erkannt.</translation>
425 </message>
426 <message>
427 <location filename="../base/bootloaderinstallhex.cpp" line="99"/>
428 <source>MD5 hash ok</source>
429 <translation>MD5-Hash ok</translation>
430 </message>
431 <message>
432 <location filename="../base/bootloaderinstallhex.cpp" line="106"/>
433 <source>Firmware file doesn&apos;t match selected player.</source>
434 <translation>Firmware passt nicht zum gewählten Gerät.</translation>
435 </message>
436 <message>
437 <location filename="../base/bootloaderinstallhex.cpp" line="111"/>
438 <source>Descrambling file</source>
439 <translation>Descramble Datei</translation>
440 </message>
441 <message>
442 <location filename="../base/bootloaderinstallhex.cpp" line="119"/>
443 <source>Error in descramble: %1</source>
444 <translation>Fehler bei Descramble: %1</translation>
445 </message>
446 <message>
447 <location filename="../base/bootloaderinstallhex.cpp" line="124"/>
448 <source>Downloading bootloader file</source>
449 <translation>Lade Bootloader-Datei herunter</translation>
450 </message>
451 <message>
452 <location filename="../base/bootloaderinstallhex.cpp" line="134"/>
453 <source>Adding bootloader to firmware file</source>
454 <translation>Füge Bootloader zu Firmware-Datei hinzu</translation>
455 </message>
456 <message>
457 <location filename="../base/bootloaderinstallhex.cpp" line="172"/>
458 <source>could not open input file</source>
459 <translation>Konnte die Eingabedatei nicht öffnen</translation>
460 </message>
461 <message>
462 <location filename="../base/bootloaderinstallhex.cpp" line="173"/>
463 <source>reading header failed</source>
464 <translation>Konnte Header nicht lesen</translation>
465 </message>
466 <message>
467 <location filename="../base/bootloaderinstallhex.cpp" line="174"/>
468 <source>reading firmware failed</source>
469 <translation>Konnte Firmware nicht lesen</translation>
470 </message>
471 <message>
472 <location filename="../base/bootloaderinstallhex.cpp" line="175"/>
473 <source>can&apos;t open bootloader file</source>
474 <translation>Konnte Bootloader nicht öffnen</translation>
475 </message>
476 <message>
477 <location filename="../base/bootloaderinstallhex.cpp" line="176"/>
478 <source>reading bootloader file failed</source>
479 <translation>Konnte Bootloader nicht lesen</translation>
480 </message>
481 <message>
482 <location filename="../base/bootloaderinstallhex.cpp" line="177"/>
483 <source>can&apos;t open output file</source>
484 <translation>Konnte Ausgabedatei nicht öffnen</translation>
485 </message>
486 <message>
487 <location filename="../base/bootloaderinstallhex.cpp" line="178"/>
488 <source>writing output file failed</source>
489 <translation>Konnte Ausgabedatei nicht schreiben</translation>
490 </message>
491 <message>
492 <location filename="../base/bootloaderinstallhex.cpp" line="180"/>
493 <source>Error in patching: %1</source>
494 <translation>Fehler beim Patchen %1</translation>
495 </message>
496 <message>
497 <location filename="../base/bootloaderinstallhex.cpp" line="191"/>
498 <source>Error in scramble: %1</source>
499 <translation>Fehler bei Scramble: %1</translation>
500 </message>
501 <message>
502 <location filename="../base/bootloaderinstallhex.cpp" line="206"/>
503 <source>Checking modified firmware file</source>
504 <translation>Prüfe modifizierte Firmware-Datei</translation>
505 </message>
506 <message>
507 <location filename="../base/bootloaderinstallhex.cpp" line="208"/>
508 <source>Error: modified file checksum wrong</source>
509 <translation>Fehler: Prüfsumme der modifizierten Datei falsch</translation>
510 </message>
511 <message>
512 <location filename="../base/bootloaderinstallhex.cpp" line="215"/>
513 <source>A firmware file is already present on player</source>
514 <translation>Firmware-Datei bereits auf dem Gerät vorhanden</translation>
515 </message>
516 <message>
517 <location filename="../base/bootloaderinstallhex.cpp" line="220"/>
518 <source>Success: modified firmware file created</source>
519 <translation>Erfolg: modifizierte Firmware-Datei erzeugt</translation>
520 </message>
521 <message>
522 <location filename="../base/bootloaderinstallhex.cpp" line="223"/>
523 <source>Copying modified firmware file failed</source>
524 <translation>Kopieren der geänderten Firmware-Datei fehlgeschlagen</translation>
525 </message>
526 <message>
527 <location filename="../base/bootloaderinstallhex.cpp" line="237"/>
528 <source>Uninstallation not possible, only installation info removed</source>
529 <translation>Deinstallation nicht möglich, Installationsinformationen entfernt</translation>
530 </message>
531 <message>
532 <location filename="../base/bootloaderinstallhex.cpp" line="259"/>
533 <source>Can&apos;t open input file</source>
534 <translation>Konnte Eingabedatei nicht öffnen</translation>
535 </message>
536 <message>
537 <location filename="../base/bootloaderinstallhex.cpp" line="260"/>
538 <source>Can&apos;t open output file</source>
539 <translation>Konnte Ausgabedatei nicht öffnen</translation>
540 </message>
541 <message>
542 <location filename="../base/bootloaderinstallhex.cpp" line="261"/>
543 <source>invalid file: header length wrong</source>
544 <translation>ungültige Datei: Länge des Headers ist falsch</translation>
545 </message>
546 <message>
547 <location filename="../base/bootloaderinstallhex.cpp" line="262"/>
548 <source>invalid file: unrecognized header</source>
549 <translation>ungültige Datei: unbekannter Header</translation>
550 </message>
551 <message>
552 <location filename="../base/bootloaderinstallhex.cpp" line="263"/>
553 <source>invalid file: &quot;length&quot; field wrong</source>
554 <translation>ungültige Datei: &quot;length&quot; Eintrag ist falsch</translation>
555 </message>
556 <message>
557 <location filename="../base/bootloaderinstallhex.cpp" line="264"/>
558 <source>invalid file: &quot;length2&quot; field wrong</source>
559 <translation>ungültige Datei: &quot;length2&quot; Eintrag ist falsch</translation>
560 </message>
561 <message>
562 <location filename="../base/bootloaderinstallhex.cpp" line="265"/>
563 <source>invalid file: internal checksum error</source>
564 <translation>ungültige Datei: interne Prüfsumme ist falsch</translation>
565 </message>
566 <message>
567 <location filename="../base/bootloaderinstallhex.cpp" line="266"/>
568 <source>invalid file: &quot;length3&quot; field wrong</source>
569 <translation>ungültige Datei: &quot;length3&quot; Eintrag ist falsch</translation>
570 </message>
571 <message>
572 <location filename="../base/bootloaderinstallhex.cpp" line="267"/>
573 <source>unknown</source>
574 <translation>unbekannt</translation>
575 </message>
576 <message>
577 <location filename="../base/bootloaderinstallhex.cpp" line="50"/>
578 <source>Bootloader installation requires you to provide a firmware file of the original firmware (hex file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
579 <translation>Die Bootloader-Installation benötigt eine Firmware-Datei der originalen Firmware (Hex-Datei). Diese Datei muss aus rechtlichen Gründen separat heruntergeladen werden. Informationen, wie diese Datei heruntergeladen werden kann, sind im &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;Handbuch&lt;/a&gt; und der Wiki-Seite &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; aufgeführt.&lt;br/&gt;OK, um fortzufahren und die Datei auf dem Computer auszuwählen.</translation>
580 </message>
581</context>
582<context>
583 <name>BootloaderInstallImx</name>
584 <message>
585 <location filename="../base/bootloaderinstallimx.cpp" line="72"/>
586 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (firmware.sb file). This file will be patched with the Rockbox bootloader and installed to your player. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
587 <translation>Die Bootloader-Installation erfordert eine Datei der Originalfirmware (firmware.sb-Datei). Die Firmware-Datei wird angepasst und auf dem Gerät mit dem Rockbox-Bootloader installiert. Aus rechtlichen Gründen muss diese Datei separat heruntergeladen werden. Diese Datei ist im &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa-Forum&lt;/a&gt; zu finden und auf der &lt;a href=&apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; Wiki-Seite beschrieben.&lt;br/&gt;OK, um fortzufahren und die Datei auf dem Computer auszuwählen.</translation>
588 </message>
589 <message>
590 <location filename="../base/bootloaderinstallimx.cpp" line="94"/>
591 <source>Could not read original firmware file</source>
592 <translation>Konnte Original-Firmware-Datei nicht lesen</translation>
593 </message>
594 <message>
595 <location filename="../base/bootloaderinstallimx.cpp" line="100"/>
596 <source>Downloading bootloader file</source>
597 <translation>Lade Bootloader-Datei herunter</translation>
598 </message>
599 <message>
600 <location filename="../base/bootloaderinstallimx.cpp" line="110"/>
601 <source>Patching file...</source>
602 <translation>Patche Firmware ...</translation>
603 </message>
604 <message>
605 <location filename="../base/bootloaderinstallimx.cpp" line="137"/>
606 <source>Patching the original firmware failed</source>
607 <translation>Modifizieren der Firmware-Datei fehlgeschlagen</translation>
608 </message>
609 <message>
610 <location filename="../base/bootloaderinstallimx.cpp" line="143"/>
611 <source>Succesfully patched firmware file</source>
612 <translation>Firmware-Datei erfolgreich modifiziert</translation>
613 </message>
614 <message>
615 <location filename="../base/bootloaderinstallimx.cpp" line="158"/>
616 <source>Bootloader successful installed</source>
617 <translation>Bootloader erfolgreich installiert</translation>
618 </message>
619 <message>
620 <location filename="../base/bootloaderinstallimx.cpp" line="164"/>
621 <source>Patched bootloader could not be installed</source>
622 <translation>Modifizierter Bootloader konnte nicht installiert werden</translation>
623 </message>
624 <message>
625 <location filename="../base/bootloaderinstallimx.cpp" line="175"/>
626 <source>To uninstall, perform a normal upgrade with an unmodified original firmware.</source>
627 <translation>Zum deinstallieren ein Upgrade mit einer unveränderten Originalfirmware-Datei durchführen.</translation>
628 </message>
629</context>
630<context>
631 <name>BootloaderInstallIpod</name>
632 <message>
633 <location filename="../base/bootloaderinstallipod.cpp" line="49"/>
634 <source>Error: can&apos;t allocate buffer memory!</source>
635 <translation>Fehler: kann Speicher nicht allokieren!</translation>
636 </message>
637 <message>
638 <location filename="../base/bootloaderinstallipod.cpp" line="80"/>
639 <source>Downloading bootloader file</source>
640 <translation>Lade Bootloader-Datei herunter</translation>
641 </message>
642 <message>
643 <location filename="../base/bootloaderinstallipod.cpp" line="64"/>
644 <location filename="../base/bootloaderinstallipod.cpp" line="151"/>
645 <source>Failed to read firmware directory</source>
646 <translation>Konnte Firmwareverzeichnis nicht lesen</translation>
647 </message>
648 <message>
649 <location filename="../base/bootloaderinstallipod.cpp" line="69"/>
650 <location filename="../base/bootloaderinstallipod.cpp" line="156"/>
651 <source>Unknown version number in firmware (%1)</source>
652 <translation>Unbekannte Versionsnummer in Firmware (%1)</translation>
653 </message>
654 <message>
655 <location filename="../base/bootloaderinstallipod.cpp" line="75"/>
656 <source>Warning: This is a MacPod, Rockbox only runs on WinPods.
657See http://www.rockbox.org/wiki/IpodConversionToFAT32</source>
658 <translation>Warnung: Dies ist ein MacPod, Rockbox läuft nur auf WinPods.
659Siehe http://www.rockbox.org/wiki/IpodConversionToFAT32</translation>
660 </message>
661 <message>
662 <location filename="../base/bootloaderinstallipod.cpp" line="94"/>
663 <location filename="../base/bootloaderinstallipod.cpp" line="163"/>
664 <source>Could not open Ipod in R/W mode</source>
665 <translation>Kann Ipod nicht im R/W-Modus öffnen</translation>
666 </message>
667 <message>
668 <location filename="../base/bootloaderinstallipod.cpp" line="104"/>
669 <source>Successfull added bootloader</source>
670 <translation>Bootloader erfolgreich hinzugefügt</translation>
671 </message>
672 <message>
673 <location filename="../base/bootloaderinstallipod.cpp" line="115"/>
674 <source>Failed to add bootloader</source>
675 <translation>Konnte Bootloader nicht hinzufügen</translation>
676 </message>
677 <message>
678 <location filename="../base/bootloaderinstallipod.cpp" line="127"/>
679 <source>Bootloader Installation complete.</source>
680 <translation>Bootloader-Installation vollständig.</translation>
681 </message>
682 <message>
683 <location filename="../base/bootloaderinstallipod.cpp" line="132"/>
684 <source>Writing log aborted</source>
685 <translation>Schreiben der Log-Datei abgebrochen</translation>
686 </message>
687 <message>
688 <location filename="../base/bootloaderinstallipod.cpp" line="169"/>
689 <source>No bootloader detected.</source>
690 <translation>Kein Bootloader erkannt.</translation>
691 </message>
692 <message>
693 <location filename="../base/bootloaderinstallipod.cpp" line="229"/>
694 <source>Error: could not retrieve device name</source>
695 <translation>Fehler: konnte Gerätenamen nicht ermitteln</translation>
696 </message>
697 <message>
698 <location filename="../base/bootloaderinstallipod.cpp" line="245"/>
699 <source>Error: no mountpoint specified!</source>
700 <translation>Fehler: kein Einhängepunkt angegeben!</translation>
701 </message>
702 <message>
703 <location filename="../base/bootloaderinstallipod.cpp" line="250"/>
704 <source>Could not open Ipod: permission denied</source>
705 <translation>Konnte Ipod nicht öffnen: Zugriff verweigert</translation>
706 </message>
707 <message>
708 <location filename="../base/bootloaderinstallipod.cpp" line="254"/>
709 <source>Could not open Ipod</source>
710 <translation>Konnte Ipod nicht öffnen</translation>
711 </message>
712 <message>
713 <location filename="../base/bootloaderinstallipod.cpp" line="265"/>
714 <source>No firmware partition on disk</source>
715 <translation>Keine Firmware-Partition auf dem Laufwerk</translation>
716 </message>
717 <message>
718 <location filename="../base/bootloaderinstallipod.cpp" line="175"/>
719 <source>Successfully removed bootloader</source>
720 <translation>Bootloader erfolgreich entfernt</translation>
721 </message>
722 <message>
723 <location filename="../base/bootloaderinstallipod.cpp" line="183"/>
724 <source>Removing bootloader failed.</source>
725 <translation>Entfernen des Bootloaders fehlgeschlagen.</translation>
726 </message>
727 <message>
728 <location filename="../base/bootloaderinstallipod.cpp" line="90"/>
729 <source>Installing Rockbox bootloader</source>
730 <translation>Installiere Rockbox Bootloader</translation>
731 </message>
732 <message>
733 <location filename="../base/bootloaderinstallipod.cpp" line="142"/>
734 <source>Uninstalling bootloader</source>
735 <translation>Entferne Bootloader</translation>
736 </message>
737 <message>
738 <location filename="../base/bootloaderinstallipod.cpp" line="259"/>
739 <source>Error reading partition table - possibly not an Ipod</source>
740 <translation>Fehler beim Lesen der Partitionstabelle - möglicherweise kein Ipod</translation>
741 </message>
742</context>
743<context>
744 <name>BootloaderInstallMi4</name>
745 <message>
746 <location filename="../base/bootloaderinstallmi4.cpp" line="34"/>
747 <source>Downloading bootloader</source>
748 <translation>Lade Bootloader herunter</translation>
749 </message>
750 <message>
751 <location filename="../base/bootloaderinstallmi4.cpp" line="43"/>
752 <source>Installing Rockbox bootloader</source>
753 <translation>Installiere Rockbox Bootloader</translation>
754 </message>
755 <message>
756 <location filename="../base/bootloaderinstallmi4.cpp" line="66"/>
757 <source>A firmware file is already present on player</source>
758 <translation>Firmware-Datei bereits auf dem Gerät vorhanden</translation>
759 </message>
760 <message>
761 <location filename="../base/bootloaderinstallmi4.cpp" line="71"/>
762 <location filename="../base/bootloaderinstallmi4.cpp" line="79"/>
763 <source>Bootloader successful installed</source>
764 <translation>Bootloader erfolgreich installiert</translation>
765 </message>
766 <message>
767 <location filename="../base/bootloaderinstallmi4.cpp" line="74"/>
768 <source>Copying modified firmware file failed</source>
769 <translation>Kopieren der geänderten Firmware-Datei fehlgeschlagen</translation>
770 </message>
771 <message>
772 <location filename="../base/bootloaderinstallmi4.cpp" line="91"/>
773 <source>Checking for Rockbox bootloader</source>
774 <translation>Prüfe auf Rockbox-Bootloader</translation>
775 </message>
776 <message>
777 <location filename="../base/bootloaderinstallmi4.cpp" line="93"/>
778 <source>No Rockbox bootloader found</source>
779 <translation>Kein Rockbox-Bootloader gefunden</translation>
780 </message>
781 <message>
782 <location filename="../base/bootloaderinstallmi4.cpp" line="99"/>
783 <source>Checking for original firmware file</source>
784 <translation>Prüfe auf Firmwaredatei der Originalfirmware</translation>
785 </message>
786 <message>
787 <location filename="../base/bootloaderinstallmi4.cpp" line="104"/>
788 <source>Error finding original firmware file</source>
789 <translation>Fehler beim finden der Originalfirmware-Datei</translation>
790 </message>
791 <message>
792 <location filename="../base/bootloaderinstallmi4.cpp" line="115"/>
793 <source>Rockbox bootloader successful removed</source>
794 <translation>Rockbox Bootloader erfolgreich entfernt</translation>
795 </message>
796</context>
797<context>
798 <name>BootloaderInstallMpio</name>
799 <message>
800 <location filename="../base/bootloaderinstallmpio.cpp" line="34"/>
801 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
802 <translation>Die Bootloader-Installation benötigt eine Firmware-Datei der originalen Firmware (bin-Datei). Diese Datei muss aus rechtlichen Gründen separat heruntergeladen werden. Informationen, wie diese Datei heruntergeladen werden kann, ist im &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;Handbuch&lt;/a&gt; und der Wiki-Seite &lt;a href=&apos;http://www.rockbox.org/wiki/MPIO200Port&apos;&gt;MPIO200Port&lt;/a&gt; aufgeführt.&lt;br/&gt;OK, um fortzufahren und die Datei auf dem Computer auszuwählen.</translation>
803 </message>
804 <message>
805 <location filename="../base/bootloaderinstallmpio.cpp" line="53"/>
806 <source>Downloading bootloader file</source>
807 <translation>Lade Bootloader-Datei herunter</translation>
808 </message>
809 <message>
810 <location filename="../base/bootloaderinstallmpio.cpp" line="80"/>
811 <source>Could not open the original firmware.</source>
812 <translation>Konnte Firmware-Datei nicht öffnen.</translation>
813 </message>
814 <message>
815 <location filename="../base/bootloaderinstallmpio.cpp" line="83"/>
816 <source>Could not read the original firmware.</source>
817 <translation>Konnte Firmware-Datei nicht lesen.</translation>
818 </message>
819 <message>
820 <location filename="../base/bootloaderinstallmpio.cpp" line="86"/>
821 <source>Loaded firmware file does not look like MPIO original firmware file.</source>
822 <translation>Geladene Firmware-Datei scheint keine MPIO Firmware-Datei zu sein.</translation>
823 </message>
824 <message>
825 <location filename="../base/bootloaderinstallmpio.cpp" line="101"/>
826 <source>Could not open output file.</source>
827 <translation>Konnte Ausgabedatei nicht öffnen.</translation>
828 </message>
829 <message>
830 <location filename="../base/bootloaderinstallmpio.cpp" line="104"/>
831 <source>Could not write output file.</source>
832 <translation>Kann Ausgabedatei nicht schreiben.</translation>
833 </message>
834 <message>
835 <location filename="../base/bootloaderinstallmpio.cpp" line="107"/>
836 <source>Unknown error number: %1</source>
837 <translation>Unbekannter Fehler Nummer: %1</translation>
838 </message>
839 <message>
840 <location filename="../base/bootloaderinstallmpio.cpp" line="89"/>
841 <source>Could not open downloaded bootloader.</source>
842 <translation>Kann heruntergeladenen Bootloader nicht öffnen.</translation>
843 </message>
844 <message>
845 <location filename="../base/bootloaderinstallmpio.cpp" line="92"/>
846 <source>Place for bootloader in OF file not empty.</source>
847 <translation>Zielbereich für Bootloader in Original-Firmware nicht leer.</translation>
848 </message>
849 <message>
850 <location filename="../base/bootloaderinstallmpio.cpp" line="95"/>
851 <source>Could not read the downloaded bootloader.</source>
852 <translation>Konnte heruntergeladenen Bootloader nicht lesen.</translation>
853 </message>
854 <message>
855 <location filename="../base/bootloaderinstallmpio.cpp" line="98"/>
856 <source>Bootloader checksum error.</source>
857 <translation>Prüfsummenfehler im Bootloader.</translation>
858 </message>
859 <message>
860 <location filename="../base/bootloaderinstallmpio.cpp" line="112"/>
861 <source>Patching original firmware failed: %1</source>
862 <translation>Patchen der Original-Firmware fehlgeschlagen: %1</translation>
863 </message>
864 <message>
865 <location filename="../base/bootloaderinstallmpio.cpp" line="119"/>
866 <source>Success: modified firmware file created</source>
867 <translation>Erfolg: modifizierte Firmware-Datei erzeugt</translation>
868 </message>
869 <message>
870 <location filename="../base/bootloaderinstallmpio.cpp" line="127"/>
871 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
872 <translation>Zum deinstallieren ein Upgrade mit einer unveränderten Originalfirmware-Datei durchführen</translation>
873 </message>
874</context>
875<context>
876 <name>BootloaderInstallS5l</name>
877 <message>
878 <location filename="../base/bootloaderinstalls5l.cpp" line="61"/>
879 <source>Could not find mounted iPod.</source>
880 <translation>Konnte keinen eingehängten iPod erkennen.</translation>
881 </message>
882 <message>
883 <location filename="../base/bootloaderinstalls5l.cpp" line="68"/>
884 <source>Downloading bootloader file...</source>
885 <translation>Lade Bootloader-Datei herunter ...</translation>
886 </message>
887 <message>
888 <location filename="../base/bootloaderinstalls5l.cpp" line="113"/>
889 <source>Could not make DFU image.</source>
890 <translation>Konnte DFU-Abbild nicht erzeugen.</translation>
891 </message>
892 <message>
893 <location filename="../base/bootloaderinstalls5l.cpp" line="119"/>
894 <source>Ejecting iPod...</source>
895 <translation>Werfe iPod aus ...</translation>
896 </message>
897 <message>
898 <location filename="../base/bootloaderinstalls5l.cpp" line="151"/>
899 <source>Device successfully ejected.</source>
900 <translation>Gerät erfolgreich ausgeworfen.</translation>
901 </message>
902 <message>
903 <location filename="../base/bootloaderinstalls5l.cpp" line="179"/>
904 <source>iTunes closed.</source>
905 <translation>iTunes beended.</translation>
906 </message>
907 <message>
908 <location filename="../base/bootloaderinstalls5l.cpp" line="201"/>
909 <source>Waiting for HDD spin-down...</source>
910 <translation>Warte auf Herunterfahren der Festplatte ...</translation>
911 </message>
912 <message>
913 <location filename="../base/bootloaderinstalls5l.cpp" line="217"/>
914 <source>Waiting for DFU mode...</source>
915 <translation>Warte auf DFU-Modus ...</translation>
916 </message>
917 <message>
918 <location filename="../base/bootloaderinstalls5l.cpp" line="218"/>
919 <source>Action required:
920
921Press and hold SELECT+MENU buttons, after about 12 seconds a new action will require you to release the buttons, DO IT QUICKLY, otherwise the process could fail.</source>
922 <translation>Aktion notwendig:
923
924SELECT+MENU drücken und halten. Nach ungefähr 12 Sekunden wird die die nächste Aktion erscheinen und auffordern die Tasten loszulassen, hier SCHNELL SEIN, ansonsten kann der Vorgang fehlschlagen.</translation>
925 </message>
926 <message>
927 <location filename="../base/bootloaderinstalls5l.cpp" line="241"/>
928 <source>DFU mode detected.</source>
929 <translation>DFU-Modus erkannt.</translation>
930 </message>
931 <message>
932 <location filename="../base/bootloaderinstalls5l.cpp" line="171"/>
933 <source>Action required:
934
935Quit iTunes application.</source>
936 <translation>Aktion notwendig:
937
938iTunes beenden.</translation>
939 </message>
940 <message>
941 <location filename="../base/bootloaderinstalls5l.cpp" line="192"/>
942 <source>Could not suspend iTunesHelper. Stop it using the Task Manager, and try again.</source>
943 <translation>Konnte iTunesHelper nicht beenden. Mit dem Task-Manager beenden und erneut versuchen.</translation>
944 </message>
945 <message>
946 <location filename="../base/bootloaderinstalls5l.cpp" line="243"/>
947 <source>Action required:
948
949Release SELECT+MENU buttons and wait...</source>
950 <translation>Aktion notwendig:
951
952SELECT+MENU loslassen und warten ...</translation>
953 </message>
954 <message>
955 <location filename="../base/bootloaderinstalls5l.cpp" line="275"/>
956 <source>Transfering DFU image...</source>
957 <translation>Übertrage DFU-Abbild ...</translation>
958 </message>
959 <message>
960 <location filename="../base/bootloaderinstalls5l.cpp" line="268"/>
961 <source>Device is not in DFU mode. It seems that the previous required action failed, please try again.</source>
962 <translation>Gerät nicht im DFU-Modus. Anscheinend ist die vorgehende Aktion fehlgeschlagen, bitte erneut versuchen.</translation>
963 </message>
964 <message>
965 <location filename="../base/bootloaderinstalls5l.cpp" line="141"/>
966 <source>Action required:
967
968Please make sure no programs are accessing files on the device. If ejecting still fails please use your computers eject functionality.</source>
969 <translation>Aktion notwendig:
970
971Sicherstellen dass keine Programme Dateien auf dem Gerät verwenden. Wenn das Auswerfen weiter fehlschlägt mit dem PC &quot;sicher entfernen&quot;.</translation>
972 </message>
973 <message>
974 <location filename="../base/bootloaderinstalls5l.cpp" line="285"/>
975 <source>No valid DFU USB driver found.
976
977Install iTunes (or the Apple Device Driver) and try again.</source>
978 <translation>Kein DFU USB-Treiber gefunden.
979
980iTunes (oder den Apple Treiber) installieren und erneut versuchen.</translation>
981 </message>
982 <message>
983 <location filename="../base/bootloaderinstalls5l.cpp" line="294"/>
984 <source>Could not transfer DFU image.</source>
985 <translation>Konnte DFU-Abbild nicht übertragen.</translation>
986 </message>
987 <message>
988 <location filename="../base/bootloaderinstalls5l.cpp" line="299"/>
989 <source>DFU transfer completed.</source>
990 <translation>DFU-Übertragung abgeschlossen.</translation>
991 </message>
992 <message>
993 <location filename="../base/bootloaderinstalls5l.cpp" line="302"/>
994 <source>Restarting iPod, waiting for remount...</source>
995 <translation>iPod wird neu gestartet, warte auf wieder einhängen ...</translation>
996 </message>
997 <message>
998 <location filename="../base/bootloaderinstalls5l.cpp" line="321"/>
999 <source>Action required:
1000
1001Could not remount the device, try to do it manually. If the iPod didn&apos;t restart, force a reset by pressing SELECT+MENU buttons for about 5 seconds. If the problem could not be solved then click &apos;Abort&apos; to cancel.</source>
1002 <translation>Aktion notwendig:
1003
1004Konnte Gerät nicht wieder einhängen, bitte manuall vornehmen. Wenn der iPod nicht neu gestartet hat, einen Neustart durch drücken von SELECT+MENU für etwa 5 Sekunden erzwingen. Wenn das Problem nicht gelöst werden kann abbrechen.</translation>
1005 </message>
1006 <message>
1007 <location filename="../base/bootloaderinstalls5l.cpp" line="333"/>
1008 <source>Device remounted.</source>
1009 <translation>Gerät wieder eingehängt.</translation>
1010 </message>
1011 <message>
1012 <location filename="../base/bootloaderinstalls5l.cpp" line="336"/>
1013 <source>Bootloader successfully installed.</source>
1014 <translation>Bootloader erfolgreich installiert.</translation>
1015 </message>
1016 <message>
1017 <location filename="../base/bootloaderinstalls5l.cpp" line="338"/>
1018 <source>Bootloader successfully uninstalled.</source>
1019 <translation>Bootloader erfolgreich deinstalliert.</translation>
1020 </message>
1021 <message>
1022 <location filename="../base/bootloaderinstalls5l.cpp" line="368"/>
1023 <source>Install aborted by user.</source>
1024 <translation>Installation von Benutzer abgebrochen.</translation>
1025 </message>
1026 <message>
1027 <location filename="../base/bootloaderinstalls5l.cpp" line="370"/>
1028 <source>Uninstall aborted by user.</source>
1029 <translation>Deinstallation von Benutzer abgebrochen.</translation>
1030 </message>
1031 <message>
1032 <location filename="../base/bootloaderinstalls5l.cpp" line="350"/>
1033 <source>Could not resume iTunesHelper.</source>
1034 <translation>Konnte iTunesHelper nicht wieder starten.</translation>
1035 </message>
1036</context>
1037<context>
1038 <name>BootloaderInstallSansa</name>
1039 <message>
1040 <location filename="../base/bootloaderinstallsansa.cpp" line="50"/>
1041 <source>Error: can&apos;t allocate buffer memory!</source>
1042 <translation>Fehler: kann Speicher nicht allokieren!</translation>
1043 </message>
1044 <message>
1045 <location filename="../base/bootloaderinstallsansa.cpp" line="55"/>
1046 <source>Searching for Sansa</source>
1047 <translation>Suche nach Sansa</translation>
1048 </message>
1049 <message>
1050 <location filename="../base/bootloaderinstallsansa.cpp" line="59"/>
1051 <source>Permission for disc access denied!
1052This is required to install the bootloader</source>
1053 <translation>Direkter Laufwerkszugriff verweigert!
1054Der Zugriff ist notwendig, um den Bootloader zu installieren</translation>
1055 </message>
1056 <message>
1057 <location filename="../base/bootloaderinstallsansa.cpp" line="66"/>
1058 <source>No Sansa detected!</source>
1059 <translation>Kein Sansa gefunden!</translation>
1060 </message>
1061 <message>
1062 <location filename="../base/bootloaderinstallsansa.cpp" line="79"/>
1063 <source>Downloading bootloader file</source>
1064 <translation>Lade Bootloader-Datei herunter</translation>
1065 </message>
1066 <message>
1067 <location filename="../base/bootloaderinstallsansa.cpp" line="71"/>
1068 <location filename="../base/bootloaderinstallsansa.cpp" line="179"/>
1069 <source>OLD ROCKBOX INSTALLATION DETECTED, ABORTING.
1070You must reinstall the original Sansa firmware before running
1071sansapatcher for the first time.
1072See http://www.rockbox.org/wiki/SansaE200Install
1073</source>
1074 <translation>ALTE ROCKBOX-INSTALLATION ERKANNT, ABBRUCH.
1075Die Original-Sansa-Firmware muss neu installiert werden,
1076bevor sansapatcher zum ersten Mal verwendet werden kann.
1077Siehe http://www.rockbox.org/wiki/SansaE200Install
1078</translation>
1079 </message>
1080 <message>
1081 <location filename="../base/bootloaderinstallsansa.cpp" line="102"/>
1082 <location filename="../base/bootloaderinstallsansa.cpp" line="189"/>
1083 <source>Could not open Sansa in R/W mode</source>
1084 <translation>Konnte Sansa nicht im R/W-Modus öffnen</translation>
1085 </message>
1086 <message>
1087 <location filename="../base/bootloaderinstallsansa.cpp" line="129"/>
1088 <source>Successfully installed bootloader</source>
1089 <translation>Bootloader erfolgreich installiert</translation>
1090 </message>
1091 <message>
1092 <location filename="../base/bootloaderinstallsansa.cpp" line="140"/>
1093 <source>Failed to install bootloader</source>
1094 <translation>Bootloader-Installation fehlgeschlagen</translation>
1095 </message>
1096 <message>
1097 <location filename="../base/bootloaderinstallsansa.cpp" line="153"/>
1098 <source>Bootloader Installation complete.</source>
1099 <translation>Bootloader-Installation vollständig.</translation>
1100 </message>
1101 <message>
1102 <location filename="../base/bootloaderinstallsansa.cpp" line="158"/>
1103 <source>Writing log aborted</source>
1104 <translation>Schreiben der Log-Datei abgebrochen</translation>
1105 </message>
1106 <message>
1107 <location filename="../base/bootloaderinstallsansa.cpp" line="239"/>
1108 <source>Error: could not retrieve device name</source>
1109 <translation>Fehler: konnte Gerätenamen nicht ermitteln</translation>
1110 </message>
1111 <message>
1112 <location filename="../base/bootloaderinstallsansa.cpp" line="255"/>
1113 <source>Can&apos;t find Sansa</source>
1114 <translation>Konnte Sansa nicht finden</translation>
1115 </message>
1116 <message>
1117 <location filename="../base/bootloaderinstallsansa.cpp" line="260"/>
1118 <source>Could not open Sansa</source>
1119 <translation>Konnte Sansa nicht öffnen</translation>
1120 </message>
1121 <message>
1122 <location filename="../base/bootloaderinstallsansa.cpp" line="265"/>
1123 <source>Could not read partition table</source>
1124 <translation>Konnte Partitionstabelle nicht lesen</translation>
1125 </message>
1126 <message>
1127 <location filename="../base/bootloaderinstallsansa.cpp" line="272"/>
1128 <source>Disk is not a Sansa (Error %1), aborting.</source>
1129 <translation>Laufwerk ist kein Sansa (Fehler: %1), breche ab.</translation>
1130 </message>
1131 <message>
1132 <location filename="../base/bootloaderinstallsansa.cpp" line="195"/>
1133 <source>Successfully removed bootloader</source>
1134 <translation>Bootloader erfolgreich entfernt</translation>
1135 </message>
1136 <message>
1137 <location filename="../base/bootloaderinstallsansa.cpp" line="203"/>
1138 <source>Removing bootloader failed.</source>
1139 <translation>Entfernen des Bootloaders fehlgeschlagen.</translation>
1140 </message>
1141 <message>
1142 <location filename="../base/bootloaderinstallsansa.cpp" line="94"/>
1143 <source>Installing Rockbox bootloader</source>
1144 <translation>Installiere Rockbox Bootloader</translation>
1145 </message>
1146 <message>
1147 <location filename="../base/bootloaderinstallsansa.cpp" line="170"/>
1148 <source>Uninstalling bootloader</source>
1149 <translation>Entferne Bootloader</translation>
1150 </message>
1151 <message>
1152 <location filename="../base/bootloaderinstallsansa.cpp" line="111"/>
1153 <source>Checking downloaded bootloader</source>
1154 <translation>Prüfe heruntergeladenen Bootloader</translation>
1155 </message>
1156 <message>
1157 <location filename="../base/bootloaderinstallsansa.cpp" line="119"/>
1158 <source>Bootloader mismatch! Aborting.</source>
1159 <translation>Fehler im Bootloader! Abbruch.</translation>
1160 </message>
1161</context>
1162<context>
1163 <name>BootloaderInstallTcc</name>
1164 <message>
1165 <location filename="../base/bootloaderinstalltcc.cpp" line="33"/>
1166 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wiki page on how to obtain the file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
1167 <translation>Die Bootloader-Installation benötigt eine Firmware-Datei der originalen Firmware (bin-Datei). Diese Datei muss aus rechtlichen Gründen separat heruntergeladen werden. Informationen, wie diese Datei heruntergeladen werden kann, sind im &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;Handbuch&lt;/a&gt; und der Wiki-Seite &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; aufgeführt.&lt;br/&gt;OK, um fortzufahren und die Datei auf dem Computer auszuwählen.</translation>
1168 </message>
1169 <message>
1170 <location filename="../base/bootloaderinstalltcc.cpp" line="50"/>
1171 <source>Downloading bootloader file</source>
1172 <translation>Lade Bootloader-Datei herunter</translation>
1173 </message>
1174 <message>
1175 <location filename="../base/bootloaderinstalltcc.cpp" line="82"/>
1176 <location filename="../base/bootloaderinstalltcc.cpp" line="99"/>
1177 <source>Could not load %1</source>
1178 <translation>Konnte %1 nicht laden</translation>
1179 </message>
1180 <message>
1181 <location filename="../base/bootloaderinstalltcc.cpp" line="90"/>
1182 <source>Unknown OF file used: %1</source>
1183 <translation>Unbekannte Original-Firmware-Datei: %1</translation>
1184 </message>
1185 <message>
1186 <location filename="../base/bootloaderinstalltcc.cpp" line="104"/>
1187 <source>Patching Firmware...</source>
1188 <translation>Patche Firmware ...</translation>
1189 </message>
1190 <message>
1191 <location filename="../base/bootloaderinstalltcc.cpp" line="111"/>
1192 <source>Could not patch firmware</source>
1193 <translation>Konnte Firmware nicht patchen</translation>
1194 </message>
1195 <message>
1196 <location filename="../base/bootloaderinstalltcc.cpp" line="117"/>
1197 <source>Could not open %1 for writing</source>
1198 <translation>Konnte %1 nicht zum schreiben öffnen</translation>
1199 </message>
1200 <message>
1201 <location filename="../base/bootloaderinstalltcc.cpp" line="126"/>
1202 <source>Could not write firmware file</source>
1203 <translation>Konnte Firmware-Datei nicht schreiben</translation>
1204 </message>
1205 <message>
1206 <location filename="../base/bootloaderinstalltcc.cpp" line="131"/>
1207 <source>Success: modified firmware file created</source>
1208 <translation>Erfolg: modifizierte Firmware-Datei erzeugt</translation>
1209 </message>
1210 <message>
1211 <location filename="../base/bootloaderinstalltcc.cpp" line="151"/>
1212 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
1213 <translation>Zum deinstallieren ein Upgrade mit einer unveränderten Originalfirmware-Datei durchführen</translation>
1214 </message>
1215</context>
1216<context>
1217 <name>Changelog</name>
1218 <message>
1219 <location filename="../gui/changelogfrm.ui" line="17"/>
1220 <source>Changelog</source>
1221 <translation>Änderungshistorie</translation>
1222 </message>
1223 <message>
1224 <location filename="../gui/changelogfrm.ui" line="39"/>
1225 <source>Show on startup</source>
1226 <translation>Beim Start zeigen</translation>
1227 </message>
1228 <message>
1229 <location filename="../gui/changelogfrm.ui" line="46"/>
1230 <source>&amp;Ok</source>
1231 <translation>&amp;Ok</translation>
1232 </message>
1233</context>
1234<context>
1235 <name>Config</name>
1236 <message>
1237 <location filename="../configure.cpp" line="853"/>
1238 <source>Autodetection</source>
1239 <translation>Automatische Erkennung</translation>
1240 </message>
1241 <message>
1242 <location filename="../configure.cpp" line="854"/>
1243 <source>Could not detect a Mountpoint.
1244Select your Mountpoint manually.</source>
1245 <translation>Konnte Einhängepunkt nicht erkennen.
1246Bitte manuell auswählen.</translation>
1247 </message>
1248 <message>
1249 <location filename="../configure.cpp" line="756"/>
1250 <source>Could not detect a device.
1251Select your device and Mountpoint manually.</source>
1252 <translation>Konnte kein Gerät erkennen.
1253Bitte Gerät und Einhängepunkt manuell auswählen.</translation>
1254 </message>
1255 <message>
1256 <location filename="../configure.cpp" line="789"/>
1257 <source>The player contains an incompatible filesystem.
1258Make sure you selected the correct mountpoint and the player is set up to use a filesystem compatible with Rockbox.</source>
1259 <translation>Das Dateisystem auf dem Gerät ist inkompatibel.
1260Bitte sicherstellen dass der korrekte Einhängepunkt ausgewählt ist und das Gerät ein Dateisystem benutzt das mit Rockbox kompatibel ist.</translation>
1261 </message>
1262 <message>
1263 <location filename="../configure.cpp" line="797"/>
1264 <source>An unknown error occured during player detection.</source>
1265 <translation>Ein unbekannter Fehler während der Erkennung ist aufgetreten.</translation>
1266 </message>
1267 <message>
1268 <location filename="../configure.cpp" line="864"/>
1269 <source>Really delete cache?</source>
1270 <translation>Cache wirklich löschen?</translation>
1271 </message>
1272 <message>
1273 <location filename="../configure.cpp" line="865"/>
1274 <source>Do you really want to delete the cache? Make absolutely sure this setting is correct as it will remove &lt;b&gt;all&lt;/b&gt; files in this folder!</source>
1275 <translation>Cache wirklich löschen? Unbedingt sicherstellen, dass die Enstellungen korrekt sind, dies löscht &lt;b&gt;alle&lt;/b&gt; Dateien im Cache-Ordner!</translation>
1276 </message>
1277 <message>
1278 <location filename="../configure.cpp" line="873"/>
1279 <source>Path wrong!</source>
1280 <translation>Pfad fehlerhaft!</translation>
1281 </message>
1282 <message>
1283 <location filename="../configure.cpp" line="874"/>
1284 <source>The cache path is invalid. Aborting.</source>
1285 <translation>Cache-Pfad ist ungültig. Abbruch.</translation>
1286 </message>
1287 <message>
1288 <location filename="../configure.cpp" line="310"/>
1289 <source>Current cache size is %L1 kiB.</source>
1290 <translation>Aktuelle Cachegröße ist %L1 kiB.</translation>
1291 </message>
1292 <message>
1293 <location filename="../configure.cpp" line="445"/>
1294 <location filename="../configure.cpp" line="479"/>
1295 <source>Configuration OK</source>
1296 <translation>Konfiguration OK</translation>
1297 </message>
1298 <message>
1299 <location filename="../configure.cpp" line="455"/>
1300 <location filename="../configure.cpp" line="484"/>
1301 <source>Configuration INVALID</source>
1302 <translation>Konfiguration UNGÜLTIG</translation>
1303 </message>
1304 <message>
1305 <location filename="../configure.cpp" line="125"/>
1306 <source>The following errors occurred:</source>
1307 <translation>Die folgenden Fehler sind aufgetreten:</translation>
1308 </message>
1309 <message>
1310 <location filename="../configure.cpp" line="170"/>
1311 <source>No mountpoint given</source>
1312 <translation>Kein Einhängepunkt ausgewählt</translation>
1313 </message>
1314 <message>
1315 <location filename="../configure.cpp" line="174"/>
1316 <source>Mountpoint does not exist</source>
1317 <translation>Einhängepunkt existiert nicht</translation>
1318 </message>
1319 <message>
1320 <location filename="../configure.cpp" line="178"/>
1321 <source>Mountpoint is not a directory.</source>
1322 <translation>Einhängepunkt ist kein Verzeichnis.</translation>
1323 </message>
1324 <message>
1325 <location filename="../configure.cpp" line="182"/>
1326 <source>Mountpoint is not writeable</source>
1327 <translation>Einhängepunkt ist nicht schreibbar</translation>
1328 </message>
1329 <message>
1330 <location filename="../configure.cpp" line="197"/>
1331 <source>No player selected</source>
1332 <translation>Kein Gerät ausgewählt</translation>
1333 </message>
1334 <message>
1335 <location filename="../configure.cpp" line="204"/>
1336 <source>Cache path not writeable. Leave path empty to default to systems temporary path.</source>
1337 <translation>Cache-Pfad ist nicht schreibbar. Um auf den temporären Pfad des Systems zurückzusetzen, den Pfad leer lassen.</translation>
1338 </message>
1339 <message>
1340 <location filename="../configure.cpp" line="223"/>
1341 <source>You need to fix the above errors before you can continue.</source>
1342 <translation>Die Fehler müssen beseitigt werden um fortzufahren.</translation>
1343 </message>
1344 <message>
1345 <location filename="../configure.cpp" line="226"/>
1346 <source>Configuration error</source>
1347 <translation>Konfigurationsfehler</translation>
1348 </message>
1349 <message>
1350 <location filename="../configure.cpp" line="328"/>
1351 <source>Showing disabled targets</source>
1352 <translation>Zeige deaktivierte Geräte</translation>
1353 </message>
1354 <message>
1355 <location filename="../configure.cpp" line="329"/>
1356 <source>You just enabled showing targets that are marked disabled. Disabled targets are not recommended to end users. Please use this option only if you know what you are doing.</source>
1357 <translation>Deaktivierte Geräte werden jetzt angezeigt. Deaktivierte Geräte sind nicht für Anwender gedacht. Bitte diese Option nur benutzen, wenn die Folgen klar sind.</translation>
1358 </message>
1359 <message>
1360 <location filename="../configure.cpp" line="438"/>
1361 <location filename="../configure.cpp" line="904"/>
1362 <source>TTS error</source>
1363 <translation>TTS-Fehler</translation>
1364 </message>
1365 <message>
1366 <location filename="../configure.cpp" line="439"/>
1367 <location filename="../configure.cpp" line="905"/>
1368 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1369 <translation>Ausgewähltes TTS-System konnte nicht initialisiert werden. TTS-System kann nicht verwendet werden.</translation>
1370 </message>
1371 <message>
1372 <location filename="../configure.cpp" line="523"/>
1373 <source>Proxy Detection</source>
1374 <translation>Proxy-Erkennung</translation>
1375 </message>
1376 <message>
1377 <location filename="../configure.cpp" line="524"/>
1378 <source>The System Proxy settings are invalid!
1379Rockbox Utility can&apos;t work with this proxy settings. Make sure the system proxy is set correctly. Note that &quot;proxy auto-config (PAC)&quot; scripts are not supported by Rockbox Utility. If your system uses this you need to use manual proxy settings.</source>
1380 <translation>Die System-Proxy-Werte sind ungültig!
1381Rockbox Utility kann mit diesen Proxy-Einstellungen nicht arbeiten. Bitte sicherstellen, dass die Proxy-Einstellungen im System korrekt sind. Hinweis: &quot;Proxy Auto-Konfiguration (PAC)&quot;-Skripte werden von Rockbox Utility nicht unterstützt. Sofern das System dies benutzt, muss der Proxy manuell angegeben werden.</translation>
1382 </message>
1383 <message>
1384 <location filename="../configure.cpp" line="634"/>
1385 <source>Set Cache Path</source>
1386 <translation>Cache-Pfad einstellen</translation>
1387 </message>
1388 <message>
1389 <location filename="../configure.cpp" line="656"/>
1390 <source>%1 (%2 GiB of %3 GiB free)</source>
1391 <translation>%1 (%2 GiB von %3 GiB frei)</translation>
1392 </message>
1393 <message>
1394 <location filename="../configure.cpp" line="730"/>
1395 <source>Multiple devices have been detected. Please disconnect all players but one and try again.</source>
1396 <translation>Mehrere Geräte gefunden. Bitte alle bis auf eins entfernen und erneut versuchen.</translation>
1397 </message>
1398 <message>
1399 <location filename="../configure.cpp" line="733"/>
1400 <source>Detected devices:</source>
1401 <translation>Erkannte Geräte:</translation>
1402 </message>
1403 <message>
1404 <location filename="../configure.cpp" line="738"/>
1405 <source>(unknown)</source>
1406 <translation>(unbekannt)</translation>
1407 </message>
1408 <message>
1409 <location filename="../configure.cpp" line="740"/>
1410 <source>%1 at %2</source>
1411 <translation>%1 an %2</translation>
1412 </message>
1413 <message>
1414 <location filename="../configure.cpp" line="747"/>
1415 <source>Note: detecting connected devices might be ambiguous. You might have less devices connected than listed. In this case it might not be possible to detect your player unambiguously.</source>
1416 <translation>Hinweis: die Erkennung ist möglicherweise nicht eindeutig. Möglicherweise sind weniger Geräte verbunden sein wie angezeigt. Sollte nur ein Gerät angeschlossen sein ist es nicht möglich das Gerät eindeutig zu identifizieren.</translation>
1417 </message>
1418 <message>
1419 <location filename="../configure.cpp" line="751"/>
1420 <location filename="../configure.cpp" line="755"/>
1421 <location filename="../configure.cpp" line="800"/>
1422 <source>Device Detection</source>
1423 <translation>Geräteerkennung</translation>
1424 </message>
1425 <message>
1426 <location filename="../configure.cpp" line="782"/>
1427 <source>%1 &quot;MacPod&quot; found!
1428Rockbox needs a FAT formatted Ipod (so-called &quot;WinPod&quot;) to run. </source>
1429 <translation>%1 &quot;MacPod&quot; gefunden!
1430Rockbox benötigt einen mit dem Dateisystem FAT formatierten Ipod (sogenannter &quot;WinPod&quot;).</translation>
1431 </message>
1432 <message>
1433 <location filename="../configure.cpp" line="773"/>
1434 <source>%1 in MTP mode found!
1435You need to change your player to MSC mode for installation. </source>
1436 <translation>%1 im MTP-Modus gefunden!
1437Das Gerät muss für die Installation im MSC-Modus sein.</translation>
1438 </message>
1439 <message>
1440 <location filename="../configure.cpp" line="766"/>
1441 <source>Detected an unsupported player:
1442%1
1443Sorry, Rockbox doesn&apos;t run on your player.</source>
1444 <translation>Nicht unterstütztes Gerät gefunden:
1445%1
1446Rockbox funktioniert auf diesem Gerät leider nicht.</translation>
1447 </message>
1448 <message>
1449 <location filename="../configure.cpp" line="911"/>
1450 <source>TTS configuration invalid</source>
1451 <translation>TTS-Konfiguration ungültig</translation>
1452 </message>
1453 <message>
1454 <location filename="../configure.cpp" line="912"/>
1455 <source>TTS configuration invalid.
1456 Please configure TTS engine.</source>
1457 <translation>TTS-Konfiguration ungültig. Bitte TTS-System konfigurieren.</translation>
1458 </message>
1459 <message>
1460 <location filename="../configure.cpp" line="917"/>
1461 <source>Could not start TTS engine.</source>
1462 <translation>Konnte TTS-System nicht starten.</translation>
1463 </message>
1464 <message>
1465 <location filename="../configure.cpp" line="918"/>
1466 <source>Could not start TTS engine.
1467</source>
1468 <translation>Konnte TTS-System nicht starten.
1469</translation>
1470 </message>
1471 <message>
1472 <location filename="../configure.cpp" line="919"/>
1473 <location filename="../configure.cpp" line="938"/>
1474 <source>
1475Please configure TTS engine.</source>
1476 <translation>
1477Bitte TTS-System konfigurieren.</translation>
1478 </message>
1479 <message>
1480 <location filename="../configure.cpp" line="933"/>
1481 <source>Rockbox Utility Voice Test</source>
1482 <translation>Rockbox Utility Sprachtest</translation>
1483 </message>
1484 <message>
1485 <location filename="../configure.cpp" line="936"/>
1486 <source>Could not voice test string.</source>
1487 <translation>Konnte Teststring nicht sprechen.</translation>
1488 </message>
1489 <message>
1490 <location filename="../configure.cpp" line="937"/>
1491 <source>Could not voice test string.
1492</source>
1493 <translation>Konnte Teststring nicht sprechen.
1494</translation>
1495 </message>
1496</context>
1497<context>
1498 <name>ConfigForm</name>
1499 <message>
1500 <location filename="../configurefrm.ui" line="14"/>
1501 <source>Configuration</source>
1502 <translation>Konfiguration</translation>
1503 </message>
1504 <message>
1505 <location filename="../configurefrm.ui" line="20"/>
1506 <source>Configure Rockbox Utility</source>
1507 <translation>Rockbox Utility konfigurieren</translation>
1508 </message>
1509 <message>
1510 <location filename="../configurefrm.ui" line="547"/>
1511 <source>&amp;Ok</source>
1512 <translation>&amp;Ok</translation>
1513 </message>
1514 <message>
1515 <location filename="../configurefrm.ui" line="558"/>
1516 <source>&amp;Cancel</source>
1517 <translation>&amp;Abbrechen</translation>
1518 </message>
1519 <message>
1520 <location filename="../configurefrm.ui" line="136"/>
1521 <source>&amp;Proxy</source>
1522 <translation>&amp;Proxy</translation>
1523 </message>
1524 <message>
1525 <location filename="../configurefrm.ui" line="95"/>
1526 <source>Show disabled targets</source>
1527 <translation>Deaktivierte Geräte anzeigen</translation>
1528 </message>
1529 <message>
1530 <location filename="../configurefrm.ui" line="142"/>
1531 <source>&amp;No Proxy</source>
1532 <translation>&amp;kein Proxy</translation>
1533 </message>
1534 <message>
1535 <location filename="../configurefrm.ui" line="159"/>
1536 <source>&amp;Manual Proxy settings</source>
1537 <translation>&amp;Manuelle Proxyeinstellungen</translation>
1538 </message>
1539 <message>
1540 <location filename="../configurefrm.ui" line="166"/>
1541 <source>Proxy Values</source>
1542 <translation>Proxy-Einstellungen</translation>
1543 </message>
1544 <message>
1545 <location filename="../configurefrm.ui" line="172"/>
1546 <source>&amp;Host:</source>
1547 <translation>&amp;Host:</translation>
1548 </message>
1549 <message>
1550 <location filename="../configurefrm.ui" line="182"/>
1551 <source>&amp;Port:</source>
1552 <translation>&amp;Port:</translation>
1553 </message>
1554 <message>
1555 <location filename="../configurefrm.ui" line="199"/>
1556 <source>&amp;Username</source>
1557 <translation>&amp;Benutzername</translation>
1558 </message>
1559 <message>
1560 <location filename="../configurefrm.ui" line="267"/>
1561 <source>&amp;Language</source>
1562 <translation>&amp;Sprache</translation>
1563 </message>
1564 <message>
1565 <location filename="../configurefrm.ui" line="35"/>
1566 <source>&amp;Device</source>
1567 <translation>&amp;Gerät</translation>
1568 </message>
1569 <message>
1570 <location filename="../configurefrm.ui" line="41"/>
1571 <source>Select your device in the &amp;filesystem</source>
1572 <translation>Gerät im &amp;Dateisystem auswählen</translation>
1573 </message>
1574 <message>
1575 <location filename="../configurefrm.ui" line="326"/>
1576 <source>&amp;Browse</source>
1577 <translation>D&amp;urchsuchen</translation>
1578 </message>
1579 <message>
1580 <location filename="../configurefrm.ui" line="72"/>
1581 <source>&amp;Select your audio player</source>
1582 <translation>Gerät au&amp;swählen</translation>
1583 </message>
1584 <message>
1585 <location filename="../configurefrm.ui" line="58"/>
1586 <source>&amp;Refresh</source>
1587 <translation>&amp;Aktualisieren</translation>
1588 </message>
1589 <message>
1590 <location filename="../configurefrm.ui" line="114"/>
1591 <source>&amp;Autodetect</source>
1592 <translation>&amp;automatische Erkennung</translation>
1593 </message>
1594 <message>
1595 <location filename="../configurefrm.ui" line="152"/>
1596 <source>Use S&amp;ystem values</source>
1597 <translation>S&amp;ystemwerte verwenden</translation>
1598 </message>
1599 <message>
1600 <location filename="../configurefrm.ui" line="209"/>
1601 <source>Pass&amp;word</source>
1602 <translation>Pass&amp;wort</translation>
1603 </message>
1604 <message>
1605 <location filename="../configurefrm.ui" line="219"/>
1606 <source>Show</source>
1607 <translation>Anzeigen</translation>
1608 </message>
1609 <message>
1610 <location filename="../configurefrm.ui" line="281"/>
1611 <source>Cac&amp;he</source>
1612 <translation>Cac&amp;he</translation>
1613 </message>
1614 <message>
1615 <location filename="../configurefrm.ui" line="284"/>
1616 <source>Download cache settings</source>
1617 <translation>Downloadcache-Einstellungen</translation>
1618 </message>
1619 <message>
1620 <location filename="../configurefrm.ui" line="290"/>
1621 <source>Rockbox Utility uses a local download cache to save network traffic. You can change the path to the cache and use it as local repository by enabling Offline mode.</source>
1622 <translation>Rockbox Utility verwendet einen lokalen Download-Cache, um die übertragene Datenmenge zu begrenzen. Der Pfad zum Cache kann geändert sowie im Offline-Modus als lokales Repository verwenden werden.</translation>
1623 </message>
1624 <message>
1625 <location filename="../configurefrm.ui" line="300"/>
1626 <source>Current cache size is %1</source>
1627 <translation>Aktuelle Cache-Größe ist %1</translation>
1628 </message>
1629 <message>
1630 <location filename="../configurefrm.ui" line="309"/>
1631 <source>P&amp;ath</source>
1632 <translation>P&amp;fad</translation>
1633 </message>
1634 <message>
1635 <location filename="../configurefrm.ui" line="341"/>
1636 <source>Disable local &amp;download cache</source>
1637 <translation>lokalen &amp;Download-Cache ausschalten</translation>
1638 </message>
1639 <message>
1640 <location filename="../configurefrm.ui" line="376"/>
1641 <source>Clean cache &amp;now</source>
1642 <translation>C&amp;ache löschen</translation>
1643 </message>
1644 <message>
1645 <location filename="../configurefrm.ui" line="319"/>
1646 <source>Entering an invalid folder will reset the path to the systems temporary path.</source>
1647 <translation>Ein ungültiger Ordner setzt den Pfad auf den temporären Pfad des Systems zurück.</translation>
1648 </message>
1649 <message>
1650 <location filename="../configurefrm.ui" line="392"/>
1651 <source>&amp;TTS &amp;&amp; Encoder</source>
1652 <translation>&amp;TTS &amp;&amp; Encoder</translation>
1653 </message>
1654 <message>
1655 <location filename="../configurefrm.ui" line="398"/>
1656 <source>TTS Engine</source>
1657 <translation>TTS-System</translation>
1658 </message>
1659 <message>
1660 <location filename="../configurefrm.ui" line="473"/>
1661 <source>Encoder Engine</source>
1662 <translation>Encoder-System</translation>
1663 </message>
1664 <message>
1665 <location filename="../configurefrm.ui" line="404"/>
1666 <source>&amp;Select TTS Engine</source>
1667 <translation>TT&amp;S-System auswählen</translation>
1668 </message>
1669 <message>
1670 <location filename="../configurefrm.ui" line="417"/>
1671 <source>Configure TTS Engine</source>
1672 <translation>TTS-System konfigurieren</translation>
1673 </message>
1674 <message>
1675 <location filename="../configurefrm.ui" line="424"/>
1676 <location filename="../configurefrm.ui" line="479"/>
1677 <source>Configuration invalid!</source>
1678 <translation>Konfiguration ungültig!</translation>
1679 </message>
1680 <message>
1681 <location filename="../configurefrm.ui" line="441"/>
1682 <source>Configure &amp;TTS</source>
1683 <translation>&amp;TTS konfigurieren</translation>
1684 </message>
1685 <message>
1686 <location filename="../configurefrm.ui" line="463"/>
1687 <source>&amp;Use string corrections for TTS</source>
1688 <translation>Verwende &amp;Wortkorrektur für TTS</translation>
1689 </message>
1690 <message>
1691 <location filename="../configurefrm.ui" line="496"/>
1692 <source>Configure &amp;Enc</source>
1693 <translation>&amp;Encoder konfigurieren</translation>
1694 </message>
1695 <message>
1696 <location filename="../configurefrm.ui" line="507"/>
1697 <source>encoder name</source>
1698 <translation>Encoder-Name</translation>
1699 </message>
1700 <message>
1701 <location filename="../configurefrm.ui" line="452"/>
1702 <source>Test TTS</source>
1703 <translation>TTS testen</translation>
1704 </message>
1705</context>
1706<context>
1707 <name>Configure</name>
1708 <message>
1709 <location filename="../configure.cpp" line="581"/>
1710 <source>English</source>
1711 <comment>This is the localized language name, i.e. your language.</comment>
1712 <translation>Deutsch</translation>
1713 </message>
1714</context>
1715<context>
1716 <name>CreateVoiceFrm</name>
1717 <message>
1718 <location filename="../createvoicefrm.ui" line="17"/>
1719 <source>Create Voice File</source>
1720 <translation>Sprachdatei erstellen</translation>
1721 </message>
1722 <message>
1723 <location filename="../createvoicefrm.ui" line="42"/>
1724 <source>Select the Language you want to generate a voicefile for:</source>
1725 <translation>Sprache auswählen, für die die Sprachdatei generiert werden soll:</translation>
1726 </message>
1727 <message>
1728 <location filename="../createvoicefrm.ui" line="49"/>
1729 <source>Generation settings</source>
1730 <translation>Allgemeine Einstellungen</translation>
1731 </message>
1732 <message>
1733 <location filename="../createvoicefrm.ui" line="72"/>
1734 <source>Change</source>
1735 <translation>Ändern</translation>
1736 </message>
1737 <message>
1738 <location filename="../createvoicefrm.ui" line="105"/>
1739 <source>Silence threshold</source>
1740 <translation>Schwellwert für Ruhe</translation>
1741 </message>
1742 <message>
1743 <location filename="../createvoicefrm.ui" line="143"/>
1744 <source>&amp;Install</source>
1745 <translation>&amp;Installieren</translation>
1746 </message>
1747 <message>
1748 <location filename="../createvoicefrm.ui" line="154"/>
1749 <source>&amp;Cancel</source>
1750 <translation>&amp;Abbrechen</translation>
1751 </message>
1752 <message>
1753 <location filename="../createvoicefrm.ui" line="92"/>
1754 <source>Wavtrim Threshold</source>
1755 <translation>Wavtrim Schwellenwert</translation>
1756 </message>
1757 <message>
1758 <location filename="../createvoicefrm.ui" line="55"/>
1759 <source>TTS:</source>
1760 <translation>TTS:</translation>
1761 </message>
1762 <message>
1763 <location filename="../createvoicefrm.ui" line="167"/>
1764 <source>Language</source>
1765 <translation>Sprache</translation>
1766 </message>
1767</context>
1768<context>
1769 <name>CreateVoiceWindow</name>
1770 <message>
1771 <location filename="../createvoicewindow.cpp" line="106"/>
1772 <source>TTS error</source>
1773 <translation>TTS-Fehler</translation>
1774 </message>
1775 <message>
1776 <location filename="../createvoicewindow.cpp" line="107"/>
1777 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1778 <translation>Ausgewähltes TTS-System konnte nicht initialisiert werden. TTS-System kann nicht verwendet werden.</translation>
1779 </message>
1780 <message>
1781 <location filename="../createvoicewindow.cpp" line="111"/>
1782 <location filename="../createvoicewindow.cpp" line="114"/>
1783 <source>Engine: &lt;b&gt;%1&lt;/b&gt;</source>
1784 <translation>TTS-System: &lt;b&gt;%1&lt;/b&gt;</translation>
1785 </message>
1786</context>
1787<context>
1788 <name>EncTtsCfgGui</name>
1789 <message>
1790 <location filename="../encttscfggui.cpp" line="45"/>
1791 <source>Waiting for engine...</source>
1792 <translation>Warte auf Engine ...</translation>
1793 </message>
1794 <message>
1795 <location filename="../encttscfggui.cpp" line="95"/>
1796 <source>Ok</source>
1797 <translation>Ok</translation>
1798 </message>
1799 <message>
1800 <location filename="../encttscfggui.cpp" line="98"/>
1801 <source>Cancel</source>
1802 <translation>Abbrechen</translation>
1803 </message>
1804 <message>
1805 <location filename="../encttscfggui.cpp" line="197"/>
1806 <source>Browse</source>
1807 <translation>Durchsuchen</translation>
1808 </message>
1809 <message>
1810 <location filename="../encttscfggui.cpp" line="205"/>
1811 <source>Refresh</source>
1812 <translation>Aktualisieren</translation>
1813 </message>
1814 <message>
1815 <location filename="../encttscfggui.cpp" line="378"/>
1816 <source>Select executable</source>
1817 <translation>Ausführbare Datei auswählen</translation>
1818 </message>
1819</context>
1820<context>
1821 <name>EncoderExe</name>
1822 <message>
1823 <location filename="../base/encoderexe.cpp" line="37"/>
1824 <source>Path to Encoder:</source>
1825 <translation>Pfad zum Encoder:</translation>
1826 </message>
1827 <message>
1828 <location filename="../base/encoderexe.cpp" line="39"/>
1829 <source>Encoder options:</source>
1830 <translation>Encoder-Optionen:</translation>
1831 </message>
1832</context>
1833<context>
1834 <name>EncoderLame</name>
1835 <message>
1836 <location filename="../base/encoderlame.cpp" line="75"/>
1837 <location filename="../base/encoderlame.cpp" line="85"/>
1838 <source>LAME</source>
1839 <translation>LAME</translation>
1840 </message>
1841 <message>
1842 <location filename="../base/encoderlame.cpp" line="77"/>
1843 <source>Volume</source>
1844 <translation>Lautstärke</translation>
1845 </message>
1846 <message>
1847 <location filename="../base/encoderlame.cpp" line="81"/>
1848 <source>Quality</source>
1849 <translation>Qualität</translation>
1850 </message>
1851 <message>
1852 <location filename="../base/encoderlame.cpp" line="85"/>
1853 <source>Could not find libmp3lame!</source>
1854 <translation>Konnte libmp3lame nicht finden!</translation>
1855 </message>
1856</context>
1857<context>
1858 <name>EncoderRbSpeex</name>
1859 <message>
1860 <location filename="../base/encoderrbspeex.cpp" line="34"/>
1861 <source>Volume:</source>
1862 <translation>Lautstärke:</translation>
1863 </message>
1864 <message>
1865 <location filename="../base/encoderrbspeex.cpp" line="36"/>
1866 <source>Quality:</source>
1867 <translation>Qualität:</translation>
1868 </message>
1869 <message>
1870 <location filename="../base/encoderrbspeex.cpp" line="38"/>
1871 <source>Complexity:</source>
1872 <translation>Komplexität:</translation>
1873 </message>
1874 <message>
1875 <location filename="../base/encoderrbspeex.cpp" line="40"/>
1876 <source>Use Narrowband:</source>
1877 <translation>Benutze Schmalband:</translation>
1878 </message>
1879</context>
1880<context>
1881 <name>InfoWidget</name>
1882 <message>
1883 <location filename="../gui/infowidget.cpp" line="30"/>
1884 <location filename="../gui/infowidget.cpp" line="107"/>
1885 <source>File</source>
1886 <translation>Datei</translation>
1887 </message>
1888 <message>
1889 <location filename="../gui/infowidget.cpp" line="30"/>
1890 <location filename="../gui/infowidget.cpp" line="107"/>
1891 <source>Version</source>
1892 <translation>Version</translation>
1893 </message>
1894</context>
1895<context>
1896 <name>InfoWidgetFrm</name>
1897 <message>
1898 <location filename="../gui/infowidgetfrm.ui" line="14"/>
1899 <source>Info</source>
1900 <translation>Info</translation>
1901 </message>
1902 <message>
1903 <location filename="../gui/infowidgetfrm.ui" line="20"/>
1904 <source>Currently installed packages.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; if you manually installed packages this might not be correct!</source>
1905 <translation>Aktuell installierte Pakete.&lt;br/&gt;&lt;b&gt;Hinweis:&lt;/b&gt; wenn Pakete manuell installiert wurden, kann die Anzeige fehlerhaft sein!</translation>
1906 </message>
1907 <message>
1908 <location filename="../gui/infowidgetfrm.ui" line="34"/>
1909 <source>Package</source>
1910 <translation>Paket</translation>
1911 </message>
1912</context>
1913<context>
1914 <name>InstallTalkFrm</name>
1915 <message>
1916 <location filename="../installtalkfrm.ui" line="17"/>
1917 <source>Install Talk Files</source>
1918 <translation>Talk-Dateien installieren</translation>
1919 </message>
1920 <message>
1921 <location filename="../installtalkfrm.ui" line="42"/>
1922 <source>Strip Extensions</source>
1923 <translation>Dateiendungen entfernen</translation>
1924 </message>
1925 <message>
1926 <location filename="../installtalkfrm.ui" line="52"/>
1927 <source>Generate for files</source>
1928 <translation>Für Dateien generieren</translation>
1929 </message>
1930 <message>
1931 <location filename="../installtalkfrm.ui" line="85"/>
1932 <source>Generate for folders</source>
1933 <translation>Für Ordner generieren</translation>
1934 </message>
1935 <message>
1936 <location filename="../installtalkfrm.ui" line="95"/>
1937 <source>Recurse into folders</source>
1938 <translation>Ordner rekursiv durchsuchen</translation>
1939 </message>
1940 <message>
1941 <location filename="../installtalkfrm.ui" line="122"/>
1942 <source>Ignore files</source>
1943 <translation>Dateien ignorieren</translation>
1944 </message>
1945 <message>
1946 <location filename="../installtalkfrm.ui" line="132"/>
1947 <source>Skip existing</source>
1948 <translation>Existierende überspringen</translation>
1949 </message>
1950 <message>
1951 <location filename="../installtalkfrm.ui" line="158"/>
1952 <source>&amp;Cancel</source>
1953 <translation>&amp;Abbrechen</translation>
1954 </message>
1955 <message>
1956 <location filename="../installtalkfrm.ui" line="174"/>
1957 <source>Select folders for Talkfile generation (Ctrl for multiselect)</source>
1958 <translation>Ordner für Generieren von Talk-Dateien auswählen (Strg für Mehrfachauswahl)</translation>
1959 </message>
1960 <message>
1961 <location filename="../installtalkfrm.ui" line="78"/>
1962 <source>TTS profile:</source>
1963 <translation>TTS-Profil:</translation>
1964 </message>
1965 <message>
1966 <location filename="../installtalkfrm.ui" line="36"/>
1967 <source>Generation options</source>
1968 <translation>Generierungsoptionen</translation>
1969 </message>
1970 <message>
1971 <location filename="../installtalkfrm.ui" line="115"/>
1972 <source>Change</source>
1973 <translation>Ändern</translation>
1974 </message>
1975 <message>
1976 <location filename="../installtalkfrm.ui" line="147"/>
1977 <source>&amp;Install</source>
1978 <translation>&amp;Installieren</translation>
1979 </message>
1980</context>
1981<context>
1982 <name>InstallTalkWindow</name>
1983 <message>
1984 <location filename="../installtalkwindow.cpp" line="95"/>
1985 <source>Empty selection</source>
1986 <translation>Leere Auswahl</translation>
1987 </message>
1988 <message>
1989 <location filename="../installtalkwindow.cpp" line="96"/>
1990 <source>No files or folders selected. Please select files or folders first.</source>
1991 <translation>Keine Dateien oder Ordner ausgewählt. Bitte zuerst Dateien oder Ordner auswählen.</translation>
1992 </message>
1993 <message>
1994 <location filename="../installtalkwindow.cpp" line="140"/>
1995 <source>TTS error</source>
1996 <translation>TTS-Fehler</translation>
1997 </message>
1998 <message>
1999 <location filename="../installtalkwindow.cpp" line="141"/>
2000 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
2001 <translation>Ausgewähltes TTS-System konnte nicht initialisiert werden. TTS-System kann nicht verwendet werden.</translation>
2002 </message>
2003</context>
2004<context>
2005 <name>MsPackUtil</name>
2006 <message>
2007 <location filename="../base/mspackutil.cpp" line="101"/>
2008 <source>Creating output path failed</source>
2009 <translation>Ausgabepfad konnte nicht erzeugt werden</translation>
2010 </message>
2011 <message>
2012 <location filename="../base/mspackutil.cpp" line="109"/>
2013 <source>Error during CAB operation</source>
2014 <translation>Fehler während CAB-Vorgang</translation>
2015 </message>
2016</context>
2017<context>
2018 <name>PlayerBuildInfo</name>
2019 <message>
2020 <location filename="../base/playerbuildinfo.cpp" line="327"/>
2021 <source>Stable (Retired)</source>
2022 <translation>Stabil (Final)</translation>
2023 </message>
2024 <message>
2025 <location filename="../base/playerbuildinfo.cpp" line="330"/>
2026 <source>Unusable</source>
2027 <translation>Unbenutzbar</translation>
2028 </message>
2029 <message>
2030 <location filename="../base/playerbuildinfo.cpp" line="333"/>
2031 <source>Unstable</source>
2032 <translation>Instabil</translation>
2033 </message>
2034 <message>
2035 <location filename="../base/playerbuildinfo.cpp" line="336"/>
2036 <source>Stable</source>
2037 <translation>Stabil</translation>
2038 </message>
2039 <message>
2040 <location filename="../base/playerbuildinfo.cpp" line="339"/>
2041 <source>Unknown</source>
2042 <translation>Unbekannt</translation>
2043 </message>
2044</context>
2045<context>
2046 <name>PreviewFrm</name>
2047 <message>
2048 <location filename="../previewfrm.ui" line="16"/>
2049 <source>Preview</source>
2050 <translation>Vorschau</translation>
2051 </message>
2052</context>
2053<context>
2054 <name>ProgressLoggerFrm</name>
2055 <message>
2056 <location filename="../progressloggerfrm.ui" line="18"/>
2057 <location filename="../progressloggerfrm.ui" line="24"/>
2058 <source>Progress</source>
2059 <translation>Fortschritt</translation>
2060 </message>
2061 <message>
2062 <location filename="../progressloggerfrm.ui" line="87"/>
2063 <source>&amp;Abort</source>
2064 <translation>&amp;Abbrechen</translation>
2065 </message>
2066 <message>
2067 <location filename="../progressloggerfrm.ui" line="37"/>
2068 <source>progresswindow</source>
2069 <translation>Fortschrittsfenster</translation>
2070 </message>
2071 <message>
2072 <location filename="../progressloggerfrm.ui" line="63"/>
2073 <source>Save Log</source>
2074 <translation>Log speichern</translation>
2075 </message>
2076</context>
2077<context>
2078 <name>ProgressLoggerGui</name>
2079 <message>
2080 <location filename="../progressloggergui.cpp" line="120"/>
2081 <source>&amp;Ok</source>
2082 <translation>&amp;Ok</translation>
2083 </message>
2084 <message>
2085 <location filename="../progressloggergui.cpp" line="100"/>
2086 <source>&amp;Abort</source>
2087 <translation>&amp;Abbrechen</translation>
2088 </message>
2089 <message>
2090 <location filename="../progressloggergui.cpp" line="146"/>
2091 <source>Save system trace log</source>
2092 <translation>System-Trace Log speichern</translation>
2093 </message>
2094</context>
2095<context>
2096 <name>QObject</name>
2097 <message>
2098 <location filename="../configure.cpp" line="616"/>
2099 <location filename="../main.cpp" line="97"/>
2100 <source>LTR</source>
2101 <extracomment>This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.</extracomment>
2102 <translation>LTR</translation>
2103 </message>
2104 <message>
2105 <location filename="../base/system.cpp" line="333"/>
2106 <source>(unknown vendor name) </source>
2107 <translation>(unbekannter Hersteller) </translation>
2108 </message>
2109 <message>
2110 <location filename="../base/system.cpp" line="351"/>
2111 <source>(unknown product name)</source>
2112 <translation>(Unbekannter Produktname)</translation>
2113 </message>
2114 <message>
2115 <location filename="../base/bootloaderinstallhelper.cpp" line="87"/>
2116 <source>Bootloader installation is almost complete. Installation &lt;b&gt;requires&lt;/b&gt; you to perform the following steps manually:</source>
2117 <translation>Installation des Bootloader ist fast abgeschlossen. Zum Abschluss der Installation ist es &lt;b&gt;notwendig&lt;/b&gt;, die folgenden Schritte manuell auszuführen:</translation>
2118 </message>
2119 <message>
2120 <location filename="../base/bootloaderinstallhelper.cpp" line="93"/>
2121 <source>&lt;li&gt;Safely remove your player.&lt;/li&gt;</source>
2122 <translation>&lt;li&gt;Gerät sicher entfernen.&lt;/li&gt;</translation>
2123 </message>
2124 <message>
2125 <location filename="../base/bootloaderinstallhelper.cpp" line="99"/>
2126 <source>&lt;li&gt;Reboot your player into the original firmware.&lt;/li&gt;&lt;li&gt;Perform a firmware upgrade using the update functionality of the original firmware. Please refer to your player&apos;s manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before starting the firmware update process.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
2127 <translation>&lt;li&gt;Gerät mit der Original-Firmware starten.&lt;/li&gt;&lt;li&gt;Ein Firmware-Update mit der Update-Funktion der Original-Firmware entsprechend der Anleitung des Geräts durchführen.&lt;/li&gt;&lt;b&gt;Wichtig:&lt;/b&gt;Das Firmware-Update ist ein kritischer Prozess, der nicht unterbrochen werden darf. &lt;b&gt;Bitte darauf achten, dass der Akku vor dem Starten des Updates geladen ist.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Nach Abschluß des Updates das Gerät neu starten.&lt;/li&gt;</translation>
2128 </message>
2129 <message>
2130 <location filename="../base/bootloaderinstallhelper.cpp" line="110"/>
2131 <source>&lt;li&gt;Remove any previously inserted microSD card&lt;/li&gt;</source>
2132 <translation>&lt;li&gt;Eine eventuell eingelegte microSD-Karte entfernen&lt;/li&gt;</translation>
2133 </message>
2134 <message>
2135 <location filename="../base/bootloaderinstallhelper.cpp" line="111"/>
2136 <source>&lt;li&gt;Disconnect your player. The player will reboot and perform an update of the original firmware. Please refer to your players manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before disconnecting the player.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
2137 <translation>&lt;li&gt;Das Gerät entfernen. Es wird einen Neustart und ein Update der Original-Firmware durchführen. Für Details bitte das Handbuch des Gerätes beachten.&lt;br/&gt;&lt;b&gt;Wichtig:&lt;/b&gt;Das Firmware-Update ist ein kritischer Prozess, der nicht unterbrochen werden darf. &lt;b&gt;Unbedingt vor dem Trennen darauf achten dass das Gerät aufgeladen ist.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Nach Abschluß des Updates das Gerät neu starten.&lt;/li&gt;</translation>
2138 </message>
2139 <message>
2140 <location filename="../base/bootloaderinstallhelper.cpp" line="122"/>
2141 <source>&lt;li&gt;Turn the player off&lt;/li&gt;&lt;li&gt;Insert the charger&lt;/li&gt;</source>
2142 <translation>&lt;li&gt;Gerät ausschalten&lt;/li&gt;&lt;li&gt;Ladegerät anstecken&lt;/li&gt;</translation>
2143 </message>
2144 <message>
2145 <location filename="../base/bootloaderinstallhelper.cpp" line="127"/>
2146 <source>&lt;li&gt;Unplug USB and power adaptors&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to turn the player off&lt;/li&gt;&lt;li&gt;Toggle the battery switch on the player&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to boot into Rockbox&lt;/li&gt;</source>
2147 <translation>&lt;li&gt;USB und Stromkabel abziehen&lt;/li&gt;&lt;li&gt;&lt;i&gt;Power&lt;/i&gt; gedrückt halten, um das Gerät auszuschalten&lt;/li&gt;&lt;li&gt;Batterieschalter am Gerät umlegen&lt;/li&gt;&lt;li&gt;&lt;i&gt;Power&lt;/i&gt; halten, um Rockbox zu booten&lt;/li&gt;</translation>
2148 </message>
2149 <message>
2150 <location filename="../base/bootloaderinstallhelper.cpp" line="133"/>
2151 <source>&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You can safely install other parts first, but the above steps are &lt;b&gt;required&lt;/b&gt; to finish the installation!&lt;/p&gt;</source>
2152 <translation>&lt;p&gt;&lt;b&gt;Hinweis:&lt;/b&gt; andere Teile von Rockbox können problemlos vorher installiert werden, aber die genannten Schritte sind &lt;b&gt;notwendig&lt;/b&gt;, um die Installation abzuschließen!&lt;/p&gt;</translation>
2153 </message>
2154</context>
2155<context>
2156 <name>QuaZipFile</name>
2157 <message>
2158 <location filename="../quazip/quazipfile.cpp" line="251"/>
2159 <source>ZIP/UNZIP API error %1</source>
2160 <translation>ZIP / Unzip API Fehler %1</translation>
2161 </message>
2162</context>
2163<context>
2164 <name>RbUtilQt</name>
2165 <message>
2166 <location filename="../rbutilqt.cpp" line="457"/>
2167 <source>Confirm Uninstallation</source>
2168 <translation>Entfernen bestätigen</translation>
2169 </message>
2170 <message>
2171 <location filename="../rbutilqt.cpp" line="458"/>
2172 <source>Do you really want to uninstall the Bootloader?</source>
2173 <translation>Bootloader wirklich entfernen?</translation>
2174 </message>
2175 <message>
2176 <location filename="../rbutilqt.cpp" line="472"/>
2177 <source>No uninstall method for this target known.</source>
2178 <translation>Keine Deinstallationsmethode für dieses Gerät verfügbar.</translation>
2179 </message>
2180 <message>
2181 <location filename="../rbutilqt.cpp" line="499"/>
2182 <source>No Rockbox bootloader found.</source>
2183 <translation>Kein Rockbox-Bootloader gefunden.</translation>
2184 </message>
2185 <message>
2186 <location filename="../rbutilqt.cpp" line="518"/>
2187 <source>Confirm installation</source>
2188 <translation>Installation bestätigen</translation>
2189 </message>
2190 <message>
2191 <location filename="../rbutilqt.cpp" line="519"/>
2192 <source>Do you really want to install Rockbox Utility to your player? After installation you can run it from the players hard drive.</source>
2193 <translation>Rockbox Utility wirklich auf dem Gerät installieren? Nach der Installation kann es von dem Laufwerk des Geräts ausgeführt werden.</translation>
2194 </message>
2195 <message>
2196 <location filename="../rbutilqt.cpp" line="528"/>
2197 <source>Installing Rockbox Utility</source>
2198 <translation>Installiere Rockbox Utility</translation>
2199 </message>
2200 <message>
2201 <location filename="../rbutilqt.cpp" line="679"/>
2202 <source>Rockbox Utility Update available</source>
2203 <translation>Update von Rockbox Utility verfügbar</translation>
2204 </message>
2205 <message>
2206 <location filename="../rbutilqt.cpp" line="680"/>
2207 <source>&lt;b&gt;New Rockbox Utility version available.&lt;/b&gt;&lt;br&gt;&lt;br&gt;You are currently using version %1. Get version %2 at &lt;a href=&apos;%3&apos;&gt;%3&lt;/a&gt;</source>
2208 <translation>&lt;b&gt;Neue Version von Rockbox Utility verfügbar.&lt;/b&gt;&lt;br&gt;&lt;br&gt;Aktuell verwendete Version ist %1. Version %2 ist verfügbar unter &lt;a href=&apos;%3&apos;&gt;%3&lt;/a&gt;</translation>
2209 </message>
2210 <message>
2211 <location filename="../rbutilqt.cpp" line="684"/>
2212 <source>New version of Rockbox Utility available.</source>
2213 <translation>Neue Version von Rockbox Utility verfügbar.</translation>
2214 </message>
2215 <message>
2216 <location filename="../rbutilqt.cpp" line="687"/>
2217 <source>Rockbox Utility is up to date.</source>
2218 <translation>Rockbox Utility ist aktuell.</translation>
2219 </message>
2220 <message>
2221 <location filename="../rbutilqt.cpp" line="710"/>
2222 <source>Device ejected</source>
2223 <translation>Gerät ausgeworfen</translation>
2224 </message>
2225 <message>
2226 <location filename="../rbutilqt.cpp" line="711"/>
2227 <source>Device successfully ejected. You may now disconnect the player from the PC.</source>
2228 <translation>Gerät erfolgreich ausgeworfen. Es kann jetzt vom PC getrennt werden.</translation>
2229 </message>
2230 <message>
2231 <location filename="../rbutilqt.cpp" line="715"/>
2232 <source>Ejecting failed</source>
2233 <translation>Auswerfen fehlgeschlagen</translation>
2234 </message>
2235 <message>
2236 <location filename="../rbutilqt.cpp" line="716"/>
2237 <source>Ejecting the device failed. Please make sure no programs are accessing files on the device. If ejecting still fails please use your computers eject funtionality.</source>
2238 <translation>Auswerfen fehlgeschlagen. Bitte sicherstellen dass keine anderen Programme auf Dateien auf dem Gerät zugreifen. Falls das Auswerfen dann immer noch fehltschlägt bitte die Auswerf-Funktion des Computers benutzen.</translation>
2239 </message>
2240 <message>
2241 <location filename="../rbutilqt.cpp" line="532"/>
2242 <source>Mount point is wrong!</source>
2243 <translation>Falscher Einhängepunkt!</translation>
2244 </message>
2245 <message>
2246 <location filename="../rbutilqt.cpp" line="488"/>
2247 <source>Rockbox Utility can not uninstall the bootloader on your player. Please perform a firmware update using your player vendors firmware update process.</source>
2248 <translation>Rockbox Utility kann den Bootloader auf dem Gerät nicht deinstallieren. Bitte ein Firmware-Update mit Hilfe des Update-Verfahrens des Herstellers durchführen.</translation>
2249 </message>
2250 <message>
2251 <location filename="../rbutilqt.cpp" line="491"/>
2252 <source>Important: make sure to boot your player into the original firmware before using the vendors firmware update process.</source>
2253 <translation>Wichtig: bitte darauf achten das Gerät vor dem Update in die Herstellerfirmware zu booten.</translation>
2254 </message>
2255 <message>
2256 <location filename="../rbutilqt.cpp" line="546"/>
2257 <source>Error installing Rockbox Utility</source>
2258 <translation>Fehler beim installieren von Rockbox Utility</translation>
2259 </message>
2260 <message>
2261 <location filename="../rbutilqt.cpp" line="550"/>
2262 <source>Installing user configuration</source>
2263 <translation>Installiere Benutzerkonfiguration</translation>
2264 </message>
2265 <message>
2266 <location filename="../rbutilqt.cpp" line="554"/>
2267 <source>Error installing user configuration</source>
2268 <translation>Fehler beim installieren der Benutzerkonfiguration</translation>
2269 </message>
2270 <message>
2271 <location filename="../rbutilqt.cpp" line="558"/>
2272 <source>Successfully installed Rockbox Utility.</source>
2273 <translation>Rockbox Utility erfolgreich installiert.</translation>
2274 </message>
2275 <message>
2276 <location filename="../rbutilqt.cpp" line="353"/>
2277 <location filename="../rbutilqt.cpp" line="592"/>
2278 <source>Configuration error</source>
2279 <translation>Konfigurationsfehler</translation>
2280 </message>
2281 <message>
2282 <location filename="../rbutilqt.cpp" line="593"/>
2283 <source>Your configuration is invalid. Please go to the configuration dialog and make sure the selected values are correct.</source>
2284 <translation>Die Konfiguration ist ungültig. Bitte im Konfigurationsdialog sicherstellen, dass die Einstellungen korrekt sind.</translation>
2285 </message>
2286 <message>
2287 <location filename="../rbutilqt.cpp" line="346"/>
2288 <source>This is a new installation of Rockbox Utility, or a new version. The configuration dialog will now open to allow you to setup the program, or review your settings.</source>
2289 <translation>Dies ist eine neue Installation oder eine neue Version von Rockbox Utility. Der Konfigurationsdialog wird nun automatisch geöffnet, um das Programm zu konfigurieren oder die Einstellungen zu prüfen.</translation>
2290 </message>
2291 <message>
2292 <location filename="../rbutilqt.cpp" line="105"/>
2293 <source>Wine detected!</source>
2294 <translation>Wine entdeckt!</translation>
2295 </message>
2296 <message>
2297 <location filename="../rbutilqt.cpp" line="106"/>
2298 <source>It seems you are trying to run this program under Wine. Please don&apos;t do this, running under Wine will fail. Use the native Linux binary instead.</source>
2299 <translation>Es scheint so, als ob dieses Programm mit Wine ausgeführt wird. Dies wird fehlschlagen. Unter Linux bitte die native Linux-Version verwenden.</translation>
2300 </message>
2301 <message>
2302 <location filename="../rbutilqt.cpp" line="224"/>
2303 <source>Can&apos;t get version information.
2304Network error: %1. Please check your network and proxy settings.</source>
2305 <translation>Kann Versions-Informationen nicht laden.
2306Netzwerkfehler: %1. Bitte Netzwerk- und Proxy-Einstellungen überprüfen.</translation>
2307 </message>
2308 <message>
2309 <location filename="../rbutilqt.cpp" line="345"/>
2310 <source>New installation</source>
2311 <translation>Neue Installation</translation>
2312 </message>
2313 <message>
2314 <location filename="../rbutilqt.cpp" line="354"/>
2315 <source>Your configuration is invalid. This is most likely due to a changed device path. The configuration dialog will now open to allow you to correct the problem.</source>
2316 <translation>Die Konfiguration ist ungültig. Dies kommt wahrscheinlich von einem geänderten Gerätepfad. Der Konfigurationsdialog wird geöffnet, damit das Problem korrigiert werden kann.</translation>
2317 </message>
2318 <message>
2319 <location filename="../rbutilqt.cpp" line="223"/>
2320 <source>Network error</source>
2321 <translation>Netzwerkfehler</translation>
2322 </message>
2323 <message>
2324 <location filename="../rbutilqt.cpp" line="211"/>
2325 <source>Downloading build information, please wait ...</source>
2326 <translation>Lade Informationen über Builds, bitte warten ...</translation>
2327 </message>
2328 <message>
2329 <location filename="../rbutilqt.cpp" line="222"/>
2330 <source>Can&apos;t get version information!</source>
2331 <translation>Konnte Versionsinformationen nicht ermitteln!</translation>
2332 </message>
2333 <message>
2334 <location filename="../rbutilqt.cpp" line="236"/>
2335 <source>Download build information finished.</source>
2336 <translation>Informationen über Builds heruntergeladen.</translation>
2337 </message>
2338 <message>
2339 <location filename="../rbutilqt.cpp" line="265"/>
2340 <source>Libraries used</source>
2341 <translation>Verwendete Bibliotheken</translation>
2342 </message>
2343 <message>
2344 <location filename="../rbutilqt.cpp" line="614"/>
2345 <source>Checking for update ...</source>
2346 <translation>Prüfe auf Update ...</translation>
2347 </message>
2348</context>
2349<context>
2350 <name>RbUtilQtFrm</name>
2351 <message>
2352 <location filename="../rbutilqtfrm.ui" line="14"/>
2353 <source>Rockbox Utility</source>
2354 <translation>Rockbox Utility</translation>
2355 </message>
2356 <message>
2357 <location filename="../rbutilqtfrm.ui" line="169"/>
2358 <location filename="../rbutilqtfrm.ui" line="626"/>
2359 <source>&amp;Installation</source>
2360 <translation>&amp;Installation</translation>
2361 </message>
2362 <message>
2363 <location filename="../rbutilqtfrm.ui" line="426"/>
2364 <source>&amp;Uninstallation</source>
2365 <translation>Ent&amp;fernen</translation>
2366 </message>
2367 <message>
2368 <location filename="../rbutilqtfrm.ui" line="393"/>
2369 <source>&amp;File</source>
2370 <translation>&amp;Datei</translation>
2371 </message>
2372 <message>
2373 <location filename="../rbutilqtfrm.ui" line="465"/>
2374 <source>&amp;About</source>
2375 <translation>Ü&amp;ber</translation>
2376 </message>
2377 <message>
2378 <location filename="../rbutilqtfrm.ui" line="442"/>
2379 <source>Empty local download cache</source>
2380 <translation>Download-Cache löschen</translation>
2381 </message>
2382 <message>
2383 <location filename="../rbutilqtfrm.ui" line="155"/>
2384 <source>mountpoint unknown or invalid</source>
2385 <translation>unbekannt oder ungültig</translation>
2386 </message>
2387 <message>
2388 <location filename="../rbutilqtfrm.ui" line="148"/>
2389 <source>Mountpoint:</source>
2390 <translation>Einhängepunkt:</translation>
2391 </message>
2392 <message>
2393 <location filename="../rbutilqtfrm.ui" line="106"/>
2394 <source>device unknown or invalid</source>
2395 <translation>unbekannt oder ungültig</translation>
2396 </message>
2397 <message>
2398 <location filename="../rbutilqtfrm.ui" line="99"/>
2399 <source>Device:</source>
2400 <translation>Gerät:</translation>
2401 </message>
2402 <message>
2403 <location filename="../rbutilqtfrm.ui" line="447"/>
2404 <source>Install Rockbox Utility on player</source>
2405 <translation>Rockbox Utility auf dem Gerät installieren</translation>
2406 </message>
2407 <message>
2408 <location filename="../rbutilqtfrm.ui" line="452"/>
2409 <source>&amp;Configure</source>
2410 <translation>&amp;Konfigurieren</translation>
2411 </message>
2412 <message>
2413 <location filename="../rbutilqtfrm.ui" line="457"/>
2414 <source>E&amp;xit</source>
2415 <translation>&amp;Beenden</translation>
2416 </message>
2417 <message>
2418 <location filename="../rbutilqtfrm.ui" line="460"/>
2419 <source>Ctrl+Q</source>
2420 <translation>Ctrl+Q</translation>
2421 </message>
2422 <message>
2423 <location filename="../rbutilqtfrm.ui" line="470"/>
2424 <source>About &amp;Qt</source>
2425 <translation>Über &amp;Qt</translation>
2426 </message>
2427 <message>
2428 <location filename="../rbutilqtfrm.ui" line="274"/>
2429 <source>Uninstall Bootloader</source>
2430 <translation>Bootloader entfernen</translation>
2431 </message>
2432 <message>
2433 <location filename="../rbutilqtfrm.ui" line="268"/>
2434 <location filename="../rbutilqtfrm.ui" line="301"/>
2435 <source>Uninstall Rockbox</source>
2436 <translation>Rockbox entfernen</translation>
2437 </message>
2438 <message>
2439 <location filename="../rbutilqtfrm.ui" line="65"/>
2440 <source>Device</source>
2441 <translation>Gerät</translation>
2442 </message>
2443 <message>
2444 <location filename="../rbutilqtfrm.ui" line="126"/>
2445 <source>&amp;Change</source>
2446 <translation>Ä&amp;ndern</translation>
2447 </message>
2448 <message>
2449 <location filename="../rbutilqtfrm.ui" line="172"/>
2450 <source>Welcome</source>
2451 <translation>Willkommen</translation>
2452 </message>
2453 <message>
2454 <location filename="../rbutilqtfrm.ui" line="177"/>
2455 <location filename="../rbutilqtfrm.ui" line="419"/>
2456 <source>&amp;Accessibility</source>
2457 <translation>&amp;Zugänglichkeit</translation>
2458 </message>
2459 <message>
2460 <location filename="../rbutilqtfrm.ui" line="180"/>
2461 <source>Install accessibility add-ons</source>
2462 <translation>Installiere Zugänglichkeits-Erweiterungen</translation>
2463 </message>
2464 <message>
2465 <location filename="../rbutilqtfrm.ui" line="186"/>
2466 <source>Install Talk files</source>
2467 <translation>Talk-Dateien installieren</translation>
2468 </message>
2469 <message>
2470 <location filename="../rbutilqtfrm.ui" line="375"/>
2471 <source>Inf&amp;o</source>
2472 <translation>Inf&amp;o</translation>
2473 </message>
2474 <message>
2475 <location filename="../rbutilqtfrm.ui" line="402"/>
2476 <location filename="../rbutilqtfrm.ui" line="475"/>
2477 <source>&amp;Help</source>
2478 <translation>&amp;Hilfe</translation>
2479 </message>
2480 <message>
2481 <location filename="../rbutilqtfrm.ui" line="415"/>
2482 <source>Action&amp;s</source>
2483 <translation>A&amp;ktionen</translation>
2484 </message>
2485 <message>
2486 <location filename="../rbutilqtfrm.ui" line="480"/>
2487 <source>Info</source>
2488 <translation>Info</translation>
2489 </message>
2490 <message>
2491 <location filename="../rbutilqtfrm.ui" line="584"/>
2492 <source>Read PDF manual</source>
2493 <translation>Lese Anleitung im PDF-Format</translation>
2494 </message>
2495 <message>
2496 <location filename="../rbutilqtfrm.ui" line="589"/>
2497 <source>Read HTML manual</source>
2498 <translation>Lese Anleitung im HTML-Format</translation>
2499 </message>
2500 <message>
2501 <location filename="../rbutilqtfrm.ui" line="594"/>
2502 <source>Download PDF manual</source>
2503 <translation>Lade Anleitung im PDF-Format herunter</translation>
2504 </message>
2505 <message>
2506 <location filename="../rbutilqtfrm.ui" line="599"/>
2507 <source>Download HTML manual (zip)</source>
2508 <translation>Lade Anleitung im HTML-Format herunter</translation>
2509 </message>
2510 <message>
2511 <location filename="../rbutilqtfrm.ui" line="236"/>
2512 <source>Create Voice files</source>
2513 <translation>Erstelle Sprachdateien</translation>
2514 </message>
2515 <message>
2516 <location filename="../rbutilqtfrm.ui" line="611"/>
2517 <source>Create Voice File</source>
2518 <translation>Erstelle Sprachdatei</translation>
2519 </message>
2520 <message>
2521 <location filename="../rbutilqtfrm.ui" line="137"/>
2522 <source>&amp;Eject</source>
2523 <translation>Ausw&amp;erfen</translation>
2524 </message>
2525 <message>
2526 <location filename="../rbutilqtfrm.ui" line="203"/>
2527 <source>&lt;b&gt;Create Talk Files&lt;/b&gt;&lt;br/&gt;Talkfiles are needed to let Rockbox speak File and Foldernames</source>
2528 <translation>&lt;b&gt;Erstelle Talk Dateien&lt;/b&gt;&lt;br/&gt;Talkdateien werden benötigt, damit Rockbox Dateien und Ordner vorlesen kann</translation>
2529 </message>
2530 <message>
2531 <location filename="../rbutilqtfrm.ui" line="253"/>
2532 <source>&lt;b&gt;Create Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so
2533 if you installed the voice file Rockbox will speak.</source>
2534 <translation>&lt;b&gt;Erzeuge Sprachdatei&lt;/b&gt;&lt;br&gt; Sprachdateien werden benötigt, damit Rockbox seine Benutzeroberfläche vorlesen kann. Sprachausgabe ist Standardmäßig angeschaltet. Sobald Sie eine Sprachdatei installieren, wird Rockbox sprechen.</translation>
2535 </message>
2536 <message>
2537 <location filename="../rbutilqtfrm.ui" line="265"/>
2538 <source>Backup &amp;&amp; &amp;Uninstallation</source>
2539 <translation>Sicherung &amp;&amp; &amp;Deinstallation</translation>
2540 </message>
2541 <message>
2542 <location filename="../rbutilqtfrm.ui" line="291"/>
2543 <source>&lt;b&gt;Remove the bootloader&lt;/b&gt;&lt;br/&gt;After removing the bootloader you won&apos;t be able to start Rockbox.</source>
2544 <translation>&lt;b&gt;Entferne Bootloader&lt;/b&gt;&lt;br/&gt;Nach dem Entfernen des Bootloaders kann Rockbox nicht mehr gestartet werden.</translation>
2545 </message>
2546 <message>
2547 <location filename="../rbutilqtfrm.ui" line="318"/>
2548 <source>&lt;b&gt;Uninstall Rockbox from your audio player.&lt;/b&gt;&lt;br/&gt;This will leave the bootloader in place (you need to remove it manually).</source>
2549 <translation>&lt;b&gt;Entferne Rockbox vom Gerät&lt;/b&gt;&lt;br/&gt;Dies wird den Bootloader intakt lassen (er muss manuell entfernt werden).</translation>
2550 </message>
2551 <message>
2552 <location filename="../rbutilqtfrm.ui" line="331"/>
2553 <source>Backup</source>
2554 <translation>Sicherung</translation>
2555 </message>
2556 <message>
2557 <location filename="../rbutilqtfrm.ui" line="348"/>
2558 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup current installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Create a backup by archiving the contents of the Rockbox installation folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2559 <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Sicherung erstellen.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Sicherungskopie der aktuellen Installation durch Archivieren des Inhaltes des Rockbox-Ordners erstellen.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
2560 </message>
2561 <message>
2562 <location filename="../rbutilqtfrm.ui" line="507"/>
2563 <source>Install &amp;Bootloader</source>
2564 <translation>Installiere &amp;Bootloader</translation>
2565 </message>
2566 <message>
2567 <location filename="../rbutilqtfrm.ui" line="516"/>
2568 <source>Install &amp;Rockbox</source>
2569 <translation>Installiere &amp;Rockbox</translation>
2570 </message>
2571 <message>
2572 <location filename="../rbutilqtfrm.ui" line="525"/>
2573 <source>Install &amp;Fonts Package</source>
2574 <translation>Installiere &amp;Schriften-Paket</translation>
2575 </message>
2576 <message>
2577 <location filename="../rbutilqtfrm.ui" line="534"/>
2578 <source>Install &amp;Themes</source>
2579 <translation>Installiere &amp;Themen</translation>
2580 </message>
2581 <message>
2582 <location filename="../rbutilqtfrm.ui" line="543"/>
2583 <source>Install &amp;Game Files</source>
2584 <translation>Installiere &amp;Spiele-Dateien</translation>
2585 </message>
2586 <message>
2587 <location filename="../rbutilqtfrm.ui" line="552"/>
2588 <source>&amp;Install Voice File</source>
2589 <translation>&amp;Installiere Sprachdateien</translation>
2590 </message>
2591 <message>
2592 <location filename="../rbutilqtfrm.ui" line="561"/>
2593 <source>Create &amp;Talk Files</source>
2594 <translation>Erstelle &amp;Talk-Dateien</translation>
2595 </message>
2596 <message>
2597 <location filename="../rbutilqtfrm.ui" line="570"/>
2598 <source>Remove &amp;bootloader</source>
2599 <translation>&amp;Bootloader entfernen</translation>
2600 </message>
2601 <message>
2602 <location filename="../rbutilqtfrm.ui" line="579"/>
2603 <source>Uninstall &amp;Rockbox</source>
2604 <translation>&amp;Rockbox entfernen</translation>
2605 </message>
2606 <message>
2607 <location filename="../rbutilqtfrm.ui" line="608"/>
2608 <source>Create &amp;Voice File</source>
2609 <translation>&amp;Sprachdateien erzeugen</translation>
2610 </message>
2611 <message>
2612 <location filename="../rbutilqtfrm.ui" line="616"/>
2613 <source>&amp;System Info</source>
2614 <translation>&amp;Systeminfo</translation>
2615 </message>
2616 <message>
2617 <location filename="../rbutilqtfrm.ui" line="631"/>
2618 <source>Show &amp;Changelog</source>
2619 <translation>Änderungshistorie an&amp;zeigen</translation>
2620 </message>
2621 <message>
2622 <location filename="../rbutilqtfrm.ui" line="489"/>
2623 <source>&amp;Complete Installation</source>
2624 <translation>&amp;Vollständige Installation</translation>
2625 </message>
2626 <message>
2627 <location filename="../rbutilqtfrm.ui" line="498"/>
2628 <source>&amp;Minimal Installation</source>
2629 <translation>&amp;Minimale Installation</translation>
2630 </message>
2631 <message>
2632 <location filename="../rbutilqtfrm.ui" line="621"/>
2633 <source>System &amp;Trace</source>
2634 <translation>System &amp;Trace</translation>
2635 </message>
2636</context>
2637<context>
2638 <name>SelectiveInstallWidget</name>
2639 <message>
2640 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="20"/>
2641 <source>Selective Installation</source>
2642 <translation>Selektive Installation</translation>
2643 </message>
2644 <message>
2645 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="26"/>
2646 <source>Rockbox version to install</source>
2647 <translation>Zu installierende Rockbox-Version</translation>
2648 </message>
2649 <message>
2650 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="35"/>
2651 <source>Version information not available yet.</source>
2652 <translation>Versionsinformation noch nicht verfügbar.</translation>
2653 </message>
2654 <message>
2655 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="54"/>
2656 <source>Rockbox components to install</source>
2657 <translation>Zu installierende Komponenten</translation>
2658 </message>
2659 <message>
2660 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="60"/>
2661 <source>&amp;Bootloader</source>
2662 <translation>&amp;Bootloader</translation>
2663 </message>
2664 <message>
2665 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="151"/>
2666 <source>Some plugins require additional data files.</source>
2667 <translation>Einige Plugins benötigen zusätzliche Dateien.</translation>
2668 </message>
2669 <message>
2670 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="188"/>
2671 <source>Install prerendered voice file.</source>
2672 <translation>Vorgefertigte Sprachdatei installieren.</translation>
2673 </message>
2674 <message>
2675 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="195"/>
2676 <source>Plugin Data</source>
2677 <translation>Plugin-Daten</translation>
2678 </message>
2679 <message>
2680 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="222"/>
2681 <source>&amp;Manual</source>
2682 <translation>&amp;Handbuch</translation>
2683 </message>
2684 <message>
2685 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="233"/>
2686 <source>&amp;Voice File</source>
2687 <translation>&amp;Sprachdatei</translation>
2688 </message>
2689 <message>
2690 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="253"/>
2691 <source>The main Rockbox firmware.</source>
2692 <translation>Die eigentliche Rockbox-Firmware.</translation>
2693 </message>
2694 <message>
2695 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="115"/>
2696 <source>Fonts</source>
2697 <translation>Schriften</translation>
2698 </message>
2699 <message>
2700 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="74"/>
2701 <source>&amp;Rockbox</source>
2702 <translation>&amp;Rockbox</translation>
2703 </message>
2704 <message>
2705 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="178"/>
2706 <source>Additional fonts for the User Interface.</source>
2707 <translation>Zusätzliche Schriften für die Benutzeroberfläche.</translation>
2708 </message>
2709 <message>
2710 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="135"/>
2711 <source>The bootloader is required for starting Rockbox. Only necessary for first time install.</source>
2712 <translation>Der Bootloader ist notwendig, um Rockbox zu starten. Die Installation ist nur beim ersten Mal notwendig.</translation>
2713 </message>
2714 <message>
2715 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="161"/>
2716 <source>Customize</source>
2717 <translation>Anpassen</translation>
2718 </message>
2719 <message>
2720 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="104"/>
2721 <source>Themes</source>
2722 <translation>Themen</translation>
2723 </message>
2724 <message>
2725 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="94"/>
2726 <source>Themes allow adjusting the user interface of Rockbox. Use &quot;Customize&quot; to select themes.</source>
2727 <translation>Themen erlauben das Benutzer-Interface von Rockbox zu verändern. Themen können mit &quot;Anpassen&quot; ausgewählt werden.</translation>
2728 </message>
2729 <message>
2730 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="263"/>
2731 <source>Save a copy of the manual on the player.</source>
2732 <translation>Das Handbuch auf dem Player speichern.</translation>
2733 </message>
2734 <message>
2735 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="292"/>
2736 <source>&amp;Install</source>
2737 <translation>&amp;Installieren</translation>
2738 </message>
2739 <message>
2740 <location filename="../gui/selectiveinstallwidget.cpp" line="77"/>
2741 <source>This is the latest stable release available.</source>
2742 <translation>Dies ist die letzte stabile Version.</translation>
2743 </message>
2744 <message>
2745 <location filename="../gui/selectiveinstallwidget.cpp" line="87"/>
2746 <source>This will eventually become the next Rockbox version. Install it to help testing.</source>
2747 <translation>Dies wird die Basis der nächsten Rockbox-Version. Um testen zu helfen, diese Version installieren.</translation>
2748 </message>
2749 <message>
2750 <location filename="../gui/selectiveinstallwidget.cpp" line="120"/>
2751 <source>Stable Release (Version %1)</source>
2752 <translation>Stabiles Release (Version %1)</translation>
2753 </message>
2754 <message>
2755 <location filename="../gui/selectiveinstallwidget.cpp" line="124"/>
2756 <source>Development Version (Revison %1)</source>
2757 <translation>Entwicklungsversion (Revision %1)</translation>
2758 </message>
2759 <message>
2760 <location filename="../gui/selectiveinstallwidget.cpp" line="122"/>
2761 <source>Release Candidate (Revison %1)</source>
2762 <translation>Release-Kandidat (Revision %1)</translation>
2763 </message>
2764 <message>
2765 <location filename="../gui/selectiveinstallwidget.cpp" line="82"/>
2766 <source>The development version is updated on every code change.</source>
2767 <translation>Die Entwicklungsversion wird bei jeder Code-Änderung aktualisiert.</translation>
2768 </message>
2769 <message>
2770 <location filename="../gui/selectiveinstallwidget.cpp" line="92"/>
2771 <source>Daily updated development version.</source>
2772 <translation>Täglich aktuelisierte Entwicklungsversion.</translation>
2773 </message>
2774 <message>
2775 <location filename="../gui/selectiveinstallwidget.cpp" line="99"/>
2776 <source>Not available for the selected version</source>
2777 <translation>Für ausgewählte Version nicht verfügbar</translation>
2778 </message>
2779 <message>
2780 <location filename="../gui/selectiveinstallwidget.cpp" line="123"/>
2781 <source>Daily Build (%1)</source>
2782 <translation>Tägliche Version (%1)</translation>
2783 </message>
2784 <message>
2785 <location filename="../gui/selectiveinstallwidget.cpp" line="151"/>
2786 <source>The selected player doesn&apos;t need a bootloader.</source>
2787 <translation>Das ausgewählte Gerät benötigt keinen Bootloader.</translation>
2788 </message>
2789 <message>
2790 <location filename="../gui/selectiveinstallwidget.cpp" line="156"/>
2791 <source>The bootloader is required for starting Rockbox. Installation of the bootloader is only necessary on first time installation.</source>
2792 <translation>Der Bootloader ist notwendig, um Rockbox zu starten. Die Installation ist nur einmalig notwendig.</translation>
2793 </message>
2794 <message>
2795 <location filename="../gui/selectiveinstallwidget.cpp" line="231"/>
2796 <source>Mountpoint is wrong</source>
2797 <translation>Einhängepunkt ist falsch</translation>
2798 </message>
2799 <message>
2800 <location filename="../gui/selectiveinstallwidget.cpp" line="290"/>
2801 <source>No install method known.</source>
2802 <translation>Keine Installationsmethode bekannt.</translation>
2803 </message>
2804 <message>
2805 <location filename="../gui/selectiveinstallwidget.cpp" line="323"/>
2806 <source>Bootloader detected</source>
2807 <translation>Bootloader erkannt</translation>
2808 </message>
2809 <message>
2810 <location filename="../gui/selectiveinstallwidget.cpp" line="324"/>
2811 <source>Bootloader already installed. Do you want to reinstall the bootloader?</source>
2812 <translation>Bootloader ist bereits installiert. Soll der Bootloader neu installiert werden?</translation>
2813 </message>
2814 <message>
2815 <location filename="../gui/selectiveinstallwidget.cpp" line="328"/>
2816 <source>Bootloader installation skipped</source>
2817 <translation>Bootloader-Installation übersprungen</translation>
2818 </message>
2819 <message>
2820 <location filename="../gui/selectiveinstallwidget.cpp" line="342"/>
2821 <source>Create Bootloader backup</source>
2822 <translation>Erzeuge Sicherungskopie vom Bootloader</translation>
2823 </message>
2824 <message>
2825 <location filename="../gui/selectiveinstallwidget.cpp" line="343"/>
2826 <source>You can create a backup of the original bootloader file. Press &quot;Yes&quot; to select an output folder on your computer to save the file to. The file will get placed in a new folder &quot;%1&quot; created below the selected folder.
2827Press &quot;No&quot; to skip this step.</source>
2828 <translation>Es kann eine Sicherungskopie der originalen Bootloader-Datei erstellt werden. &quot;Ja&quot;, um einen Zielordner auf dem Computer auszuwählen. Die Datei wird in einem neuen Unterordner &quot;%1&quot; im gewählten Ordner abgelegt.
2829&quot;Nein&quot;, um diesen Schritt zu überspringen.</translation>
2830 </message>
2831 <message>
2832 <location filename="../gui/selectiveinstallwidget.cpp" line="350"/>
2833 <source>Browse backup folder</source>
2834 <translation>Ordner für Sicherungskopie suchen</translation>
2835 </message>
2836 <message>
2837 <location filename="../gui/selectiveinstallwidget.cpp" line="362"/>
2838 <source>Prerequisites</source>
2839 <translation>Voraussetzungen</translation>
2840 </message>
2841 <message>
2842 <location filename="../gui/selectiveinstallwidget.cpp" line="367"/>
2843 <source>Bootloader installation aborted</source>
2844 <translation>Bootloader-Installation abgebrochen</translation>
2845 </message>
2846 <message>
2847 <location filename="../gui/selectiveinstallwidget.cpp" line="377"/>
2848 <source>Bootloader files (%1)</source>
2849 <translation>Bootloader-Dateien (%1)</translation>
2850 </message>
2851 <message>
2852 <location filename="../gui/selectiveinstallwidget.cpp" line="379"/>
2853 <source>All files (*)</source>
2854 <translation>Alle Dateien (*)</translation>
2855 </message>
2856 <message>
2857 <location filename="../gui/selectiveinstallwidget.cpp" line="381"/>
2858 <source>Select firmware file</source>
2859 <translation>Firmware-Datei auswählen</translation>
2860 </message>
2861 <message>
2862 <location filename="../gui/selectiveinstallwidget.cpp" line="383"/>
2863 <source>Error opening firmware file</source>
2864 <translation>Fehler beim Öffnen der Firmware-Datei</translation>
2865 </message>
2866 <message>
2867 <location filename="../gui/selectiveinstallwidget.cpp" line="389"/>
2868 <source>Error reading firmware file</source>
2869 <translation>Fehler beim Lesen der Firmware-Datei</translation>
2870 </message>
2871 <message>
2872 <location filename="../gui/selectiveinstallwidget.cpp" line="399"/>
2873 <source>Backup error</source>
2874 <translation>Sicherungskopie-Fehler</translation>
2875 </message>
2876 <message>
2877 <location filename="../gui/selectiveinstallwidget.cpp" line="400"/>
2878 <source>Could not create backup file. Continue?</source>
2879 <translation>Konnte Sicherungskopie-Datei nicht erzeugen. Fortfahren?</translation>
2880 </message>
2881 <message>
2882 <location filename="../gui/selectiveinstallwidget.cpp" line="424"/>
2883 <source>Manual steps required</source>
2884 <translation>Manuelle Schritte erforderlich</translation>
2885 </message>
2886 <message>
2887 <location filename="../gui/selectiveinstallwidget.cpp" line="671"/>
2888 <source>Your installation doesn&apos;t require any plugin data files, skipping.</source>
2889 <translation>Installation benötigt keine zusätzlichen Dateien, überspringe.</translation>
2890 </message>
2891 <message>
2892 <location filename="../gui/selectiveinstallwidget.cpp" line="219"/>
2893 <source>Continue with installation?</source>
2894 <translation>Mit Installation fortfahren?</translation>
2895 </message>
2896 <message>
2897 <location filename="../gui/selectiveinstallwidget.cpp" line="220"/>
2898 <source>Really continue?</source>
2899 <translation>Wirklich fortfahren?</translation>
2900 </message>
2901</context>
2902<context>
2903 <name>SysTrace</name>
2904 <message>
2905 <location filename="../systrace.cpp" line="100"/>
2906 <location filename="../systrace.cpp" line="109"/>
2907 <source>Save system trace log</source>
2908 <translation>System-Trace Log speichern</translation>
2909 </message>
2910</context>
2911<context>
2912 <name>SysTraceFrm</name>
2913 <message>
2914 <location filename="../systracefrm.ui" line="14"/>
2915 <source>System Trace</source>
2916 <translation>System-Trace</translation>
2917 </message>
2918 <message>
2919 <location filename="../systracefrm.ui" line="20"/>
2920 <source>System State trace</source>
2921 <translation>System-Status Trace</translation>
2922 </message>
2923 <message>
2924 <location filename="../systracefrm.ui" line="46"/>
2925 <source>&amp;Close</source>
2926 <translation>S&amp;chließen</translation>
2927 </message>
2928 <message>
2929 <location filename="../systracefrm.ui" line="57"/>
2930 <source>&amp;Save</source>
2931 <translation>&amp;Speichern</translation>
2932 </message>
2933 <message>
2934 <location filename="../systracefrm.ui" line="68"/>
2935 <source>&amp;Refresh</source>
2936 <translation>&amp;Aktualisieren</translation>
2937 </message>
2938 <message>
2939 <location filename="../systracefrm.ui" line="79"/>
2940 <source>Save &amp;previous</source>
2941 <translation>&amp;vorhergehenden Speichern</translation>
2942 </message>
2943</context>
2944<context>
2945 <name>Sysinfo</name>
2946 <message>
2947 <location filename="../sysinfo.cpp" line="45"/>
2948 <source>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</source>
2949 <translation>&lt;b&gt;Betriebssystem&lt;/b&gt;&lt;br/&gt;</translation>
2950 </message>
2951 <message>
2952 <location filename="../sysinfo.cpp" line="46"/>
2953 <source>&lt;b&gt;Username&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2954 <translation>&lt;b&gt;Benutzername&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2955 </message>
2956 <message>
2957 <location filename="../sysinfo.cpp" line="48"/>
2958 <source>&lt;b&gt;Permissions&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2959 <translation>&lt;b&gt;Berechtigungen&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2960 </message>
2961 <message>
2962 <location filename="../sysinfo.cpp" line="50"/>
2963 <source>&lt;b&gt;Attached USB devices&lt;/b&gt;&lt;br/&gt;</source>
2964 <translation>&lt;b&gt;Angeschlossene USB-Geräte&lt;/b&gt;&lt;br/&gt;</translation>
2965 </message>
2966 <message>
2967 <location filename="../sysinfo.cpp" line="54"/>
2968 <source>VID: %1 PID: %2, %3</source>
2969 <translation>VID: %1 PID: %2, %3</translation>
2970 </message>
2971 <message>
2972 <location filename="../sysinfo.cpp" line="63"/>
2973 <source>Filesystem</source>
2974 <translation>Dateisystem</translation>
2975 </message>
2976 <message>
2977 <location filename="../sysinfo.cpp" line="66"/>
2978 <source>Mountpoint</source>
2979 <translation>Einhängepunkt</translation>
2980 </message>
2981 <message>
2982 <location filename="../sysinfo.cpp" line="66"/>
2983 <source>Label</source>
2984 <translation>Bezeichnung</translation>
2985 </message>
2986 <message>
2987 <location filename="../sysinfo.cpp" line="67"/>
2988 <source>Free</source>
2989 <translation>Frei</translation>
2990 </message>
2991 <message>
2992 <location filename="../sysinfo.cpp" line="67"/>
2993 <source>Total</source>
2994 <translation>Gesamt</translation>
2995 </message>
2996 <message>
2997 <location filename="../sysinfo.cpp" line="68"/>
2998 <source>Type</source>
2999 <translation>Typ</translation>
3000 </message>
3001 <message>
3002 <location filename="../sysinfo.cpp" line="70"/>
3003 <source>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</source>
3004 <translation>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</translation>
3005 </message>
3006</context>
3007<context>
3008 <name>SysinfoFrm</name>
3009 <message>
3010 <location filename="../sysinfofrm.ui" line="13"/>
3011 <source>System Info</source>
3012 <translation>Systeminfo</translation>
3013 </message>
3014 <message>
3015 <location filename="../sysinfofrm.ui" line="22"/>
3016 <source>&amp;Refresh</source>
3017 <translation>&amp;Aktualisieren</translation>
3018 </message>
3019 <message>
3020 <location filename="../sysinfofrm.ui" line="46"/>
3021 <source>&amp;OK</source>
3022 <translation>&amp;Ok</translation>
3023 </message>
3024</context>
3025<context>
3026 <name>System</name>
3027 <message>
3028 <location filename="../base/system.cpp" line="117"/>
3029 <source>Guest</source>
3030 <translation>Gast</translation>
3031 </message>
3032 <message>
3033 <location filename="../base/system.cpp" line="120"/>
3034 <source>Admin</source>
3035 <translation>Administrator</translation>
3036 </message>
3037 <message>
3038 <location filename="../base/system.cpp" line="123"/>
3039 <source>User</source>
3040 <translation>Benutzer</translation>
3041 </message>
3042 <message>
3043 <location filename="../base/system.cpp" line="126"/>
3044 <source>Error</source>
3045 <translation>Fehler</translation>
3046 </message>
3047 <message>
3048 <location filename="../base/system.cpp" line="273"/>
3049 <source>(no description available)</source>
3050 <translation>(keine Beschreibung verfügbar)</translation>
3051 </message>
3052</context>
3053<context>
3054 <name>TTSBase</name>
3055 <message>
3056 <location filename="../base/ttsbase.cpp" line="47"/>
3057 <source>Espeak TTS Engine</source>
3058 <translation>Espeak TTS-System</translation>
3059 </message>
3060 <message>
3061 <location filename="../base/ttsbase.cpp" line="48"/>
3062 <source>Espeak-ng TTS Engine</source>
3063 <translation>Espeak-ng TTS-System</translation>
3064 </message>
3065 <message>
3066 <location filename="../base/ttsbase.cpp" line="49"/>
3067 <source>Mimic TTS Engine</source>
3068 <translation>Mimic TTS-System</translation>
3069 </message>
3070 <message>
3071 <location filename="../base/ttsbase.cpp" line="51"/>
3072 <source>Flite TTS Engine</source>
3073 <translation>Flite TTS-System</translation>
3074 </message>
3075 <message>
3076 <location filename="../base/ttsbase.cpp" line="52"/>
3077 <source>Swift TTS Engine</source>
3078 <translation>Swift TTS-System</translation>
3079 </message>
3080 <message>
3081 <location filename="../base/ttsbase.cpp" line="55"/>
3082 <source>SAPI4 TTS Engine</source>
3083 <translation>SAPI4 TTS-System</translation>
3084 </message>
3085 <message>
3086 <location filename="../base/ttsbase.cpp" line="57"/>
3087 <source>SAPI5 TTS Engine</source>
3088 <translation>SAPI5 TTS-System</translation>
3089 </message>
3090 <message>
3091 <location filename="../base/ttsbase.cpp" line="58"/>
3092 <source>MS Speech Platform</source>
3093 <translation>MS Speech Platform System</translation>
3094 </message>
3095 <message>
3096 <location filename="../base/ttsbase.cpp" line="61"/>
3097 <source>Festival TTS Engine</source>
3098 <translation>Festival TTS-System</translation>
3099 </message>
3100 <message>
3101 <location filename="../base/ttsbase.cpp" line="64"/>
3102 <source>OS X System Engine</source>
3103 <translation>Mac OS X TTS-System</translation>
3104 </message>
3105</context>
3106<context>
3107 <name>TTSCarbon</name>
3108 <message>
3109 <location filename="../base/ttscarbon.cpp" line="139"/>
3110 <source>Voice:</source>
3111 <translation>Stimme:</translation>
3112 </message>
3113 <message>
3114 <location filename="../base/ttscarbon.cpp" line="145"/>
3115 <source>Speed (words/min):</source>
3116 <translation>Geschwindigkeit (Wörter / Minute):</translation>
3117 </message>
3118 <message>
3119 <location filename="../base/ttscarbon.cpp" line="152"/>
3120 <source>Pitch (0 for default):</source>
3121 <translation>Tonhöhe (0 für Vorgabewert):</translation>
3122 </message>
3123 <message>
3124 <location filename="../base/ttscarbon.cpp" line="222"/>
3125 <source>Could not voice string</source>
3126 <translation>Konnte Text nicht sprechen</translation>
3127 </message>
3128 <message>
3129 <location filename="../base/ttscarbon.cpp" line="232"/>
3130 <source>Could not convert intermediate file</source>
3131 <translation>Konnte Zwischendatei nicht umwandeln</translation>
3132 </message>
3133</context>
3134<context>
3135 <name>TTSExes</name>
3136 <message>
3137 <location filename="../base/ttsexes.cpp" line="78"/>
3138 <source>TTS executable not found</source>
3139 <translation>TTS-System nicht gefunden</translation>
3140 </message>
3141 <message>
3142 <location filename="../base/ttsexes.cpp" line="44"/>
3143 <source>Path to TTS engine:</source>
3144 <translation>Pfad zum TTS-System:</translation>
3145 </message>
3146 <message>
3147 <location filename="../base/ttsexes.cpp" line="46"/>
3148 <source>TTS engine options:</source>
3149 <translation>TTS-System Optionen:</translation>
3150 </message>
3151</context>
3152<context>
3153 <name>TTSFestival</name>
3154 <message>
3155 <location filename="../base/ttsfestival.cpp" line="210"/>
3156 <source>engine could not voice string</source>
3157 <translation>Konnte String nicht sprechen</translation>
3158 </message>
3159 <message>
3160 <location filename="../base/ttsfestival.cpp" line="293"/>
3161 <source>No description available</source>
3162 <translation>keine Beschreibung verfügbar</translation>
3163 </message>
3164 <message>
3165 <location filename="../base/ttsfestival.cpp" line="53"/>
3166 <source>Path to Festival client:</source>
3167 <translation>Pfad zu Festival-Client:</translation>
3168 </message>
3169 <message>
3170 <location filename="../base/ttsfestival.cpp" line="58"/>
3171 <source>Voice:</source>
3172 <translation>Stimme:</translation>
3173 </message>
3174 <message>
3175 <location filename="../base/ttsfestival.cpp" line="69"/>
3176 <source>Voice description:</source>
3177 <translation>Stimmenbeschreibung:</translation>
3178 </message>
3179</context>
3180<context>
3181 <name>TTSSapi</name>
3182 <message>
3183 <location filename="../base/ttssapi.cpp" line="46"/>
3184 <source>Language:</source>
3185 <translation>Sprache:</translation>
3186 </message>
3187 <message>
3188 <location filename="../base/ttssapi.cpp" line="53"/>
3189 <source>Voice:</source>
3190 <translation>Stimme:</translation>
3191 </message>
3192 <message>
3193 <location filename="../base/ttssapi.cpp" line="65"/>
3194 <source>Speed:</source>
3195 <translation>Geschwindigkeit:</translation>
3196 </message>
3197 <message>
3198 <location filename="../base/ttssapi.cpp" line="68"/>
3199 <source>Options:</source>
3200 <translation>Optionen:</translation>
3201 </message>
3202 <message>
3203 <location filename="../base/ttssapi.cpp" line="112"/>
3204 <source>Could not copy the SAPI script</source>
3205 <translation>Konnte SAPI-Skript nicht kopieren</translation>
3206 </message>
3207 <message>
3208 <location filename="../base/ttssapi.cpp" line="130"/>
3209 <source>Could not start SAPI process</source>
3210 <translation>Konnte SAPI-Prozess nicht starten</translation>
3211 </message>
3212</context>
3213<context>
3214 <name>TalkFileCreator</name>
3215 <message>
3216 <location filename="../base/talkfile.cpp" line="45"/>
3217 <source>Talk file creation aborted</source>
3218 <translation>Erzeugen der Sprachdatei abgebrochen</translation>
3219 </message>
3220 <message>
3221 <location filename="../base/talkfile.cpp" line="78"/>
3222 <source>Finished creating Talk files</source>
3223 <translation>Erstellen der Sprachdateien beendet</translation>
3224 </message>
3225 <message>
3226 <location filename="../base/talkfile.cpp" line="42"/>
3227 <source>Reading Filelist...</source>
3228 <translation>Lese Dateiliste...</translation>
3229 </message>
3230 <message>
3231 <location filename="../base/talkfile.cpp" line="257"/>
3232 <source>Copying of %1 to %2 failed</source>
3233 <translation>Kopieren von %1 nach %2 fehlgeschlagen</translation>
3234 </message>
3235 <message>
3236 <location filename="../base/talkfile.cpp" line="66"/>
3237 <source>Copying Talkfiles...</source>
3238 <translation>Kopiere Sprachdateien ...</translation>
3239 </message>
3240 <message>
3241 <location filename="../base/talkfile.cpp" line="36"/>
3242 <source>Starting Talk file generation for folder %1</source>
3243 <translation>Starte Erzeugung von Sprachdateien für Ordner %1</translation>
3244 </message>
3245 <message>
3246 <location filename="../base/talkfile.cpp" line="238"/>
3247 <source>File copy aborted</source>
3248 <translation>Kopieren abgebrochen</translation>
3249 </message>
3250 <message>
3251 <location filename="../base/talkfile.cpp" line="278"/>
3252 <source>Cleaning up...</source>
3253 <translation>Räume auf ...</translation>
3254 </message>
3255 <message>
3256 <location filename="../base/talkfile.cpp" line="289"/>
3257 <source>Finished</source>
3258 <translation>Fertig</translation>
3259 </message>
3260</context>
3261<context>
3262 <name>TalkGenerator</name>
3263 <message>
3264 <location filename="../base/talkgenerator.cpp" line="39"/>
3265 <source>Starting TTS Engine</source>
3266 <translation>Starte TTS-System</translation>
3267 </message>
3268 <message>
3269 <location filename="../base/talkgenerator.cpp" line="44"/>
3270 <location filename="../base/talkgenerator.cpp" line="51"/>
3271 <source>Init of TTS engine failed</source>
3272 <translation>Initalisierung des TTS-Systems fehlgeschlagen</translation>
3273 </message>
3274 <message>
3275 <location filename="../base/talkgenerator.cpp" line="58"/>
3276 <source>Starting Encoder Engine</source>
3277 <translation>Starte Encoder</translation>
3278 </message>
3279 <message>
3280 <location filename="../base/talkgenerator.cpp" line="63"/>
3281 <source>Init of Encoder engine failed</source>
3282 <translation>Starten des Encoders fehlgeschlagen</translation>
3283 </message>
3284 <message>
3285 <location filename="../base/talkgenerator.cpp" line="73"/>
3286 <source>Voicing entries...</source>
3287 <translation>Spreche Einträge ...</translation>
3288 </message>
3289 <message>
3290 <location filename="../base/talkgenerator.cpp" line="88"/>
3291 <source>Encoding files...</source>
3292 <translation>Kodiere Dateien ...</translation>
3293 </message>
3294 <message>
3295 <location filename="../base/talkgenerator.cpp" line="127"/>
3296 <source>Voicing aborted</source>
3297 <translation>Sprechen abgebrochen</translation>
3298 </message>
3299 <message>
3300 <location filename="../base/talkgenerator.cpp" line="164"/>
3301 <location filename="../base/talkgenerator.cpp" line="169"/>
3302 <source>Voicing of %1 failed: %2</source>
3303 <translation>Sprechen von %1 fehlgeschlagen: %2</translation>
3304 </message>
3305 <message>
3306 <location filename="../base/talkgenerator.cpp" line="213"/>
3307 <source>Encoding aborted</source>
3308 <translation>Kodieren abgebrochen</translation>
3309 </message>
3310 <message>
3311 <location filename="../base/talkgenerator.cpp" line="241"/>
3312 <source>Encoding of %1 failed</source>
3313 <translation>Kodieren of %1 ist fehlgeschlagen</translation>
3314 </message>
3315</context>
3316<context>
3317 <name>ThemeInstallFrm</name>
3318 <message>
3319 <location filename="../themesinstallfrm.ui" line="13"/>
3320 <source>Theme Installation</source>
3321 <translation>Theme-Installation</translation>
3322 </message>
3323 <message>
3324 <location filename="../themesinstallfrm.ui" line="48"/>
3325 <source>Selected Theme</source>
3326 <translation>Ausgewähltes Theme</translation>
3327 </message>
3328 <message>
3329 <location filename="../themesinstallfrm.ui" line="73"/>
3330 <source>Description</source>
3331 <translation>Beschreibung</translation>
3332 </message>
3333 <message>
3334 <location filename="../themesinstallfrm.ui" line="83"/>
3335 <source>Download size:</source>
3336 <translation>Downloadgröße:</translation>
3337 </message>
3338 <message>
3339 <location filename="../themesinstallfrm.ui" line="126"/>
3340 <source>&amp;Cancel</source>
3341 <translation>&amp;Abbrechen</translation>
3342 </message>
3343 <message>
3344 <location filename="../themesinstallfrm.ui" line="115"/>
3345 <source>&amp;Install</source>
3346 <translation>&amp;Installieren</translation>
3347 </message>
3348 <message>
3349 <location filename="../themesinstallfrm.ui" line="93"/>
3350 <source>Hold Ctrl to select multiple item, Shift for a range</source>
3351 <translation>Strg halten, um mehrere Einträge, Umschalt, um einen Bereich auszuwählen</translation>
3352 </message>
3353</context>
3354<context>
3355 <name>ThemesInstallWindow</name>
3356 <message>
3357 <location filename="../themesinstallwindow.cpp" line="41"/>
3358 <source>no theme selected</source>
3359 <translation>Kein Theme ausgewählt</translation>
3360 </message>
3361 <message>
3362 <location filename="../themesinstallwindow.cpp" line="128"/>
3363 <source>Network error: %1.
3364Please check your network and proxy settings.</source>
3365 <translation>Netzwerkfehler: %1
3366Bitte Netzwerk- und Proxyeinstellungen überprüfen.</translation>
3367 </message>
3368 <message>
3369 <location filename="../themesinstallwindow.cpp" line="141"/>
3370 <source>the following error occured:
3371%1</source>
3372 <translation>Der folgende Fehler ist aufgetreten:
3373%1</translation>
3374 </message>
3375 <message>
3376 <location filename="../themesinstallwindow.cpp" line="147"/>
3377 <source>done.</source>
3378 <translation>Abgeschlossen.</translation>
3379 </message>
3380 <message>
3381 <location filename="../themesinstallwindow.cpp" line="216"/>
3382 <source>fetching details for %1</source>
3383 <translation>lade Details für %1</translation>
3384 </message>
3385 <message>
3386 <location filename="../themesinstallwindow.cpp" line="219"/>
3387 <source>fetching preview ...</source>
3388 <translation>lade Vorschau ...</translation>
3389 </message>
3390 <message>
3391 <location filename="../themesinstallwindow.cpp" line="232"/>
3392 <source>&lt;b&gt;Author:&lt;/b&gt; %1&lt;hr/&gt;</source>
3393 <translation>&lt;b&gt;Autor:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3394 </message>
3395 <message>
3396 <location filename="../themesinstallwindow.cpp" line="233"/>
3397 <location filename="../themesinstallwindow.cpp" line="235"/>
3398 <source>unknown</source>
3399 <translation>unbekannt</translation>
3400 </message>
3401 <message>
3402 <location filename="../themesinstallwindow.cpp" line="234"/>
3403 <source>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</source>
3404 <translation>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3405 </message>
3406 <message>
3407 <location filename="../themesinstallwindow.cpp" line="237"/>
3408 <source>no description</source>
3409 <translation>Keine Beschreibung vorhanden</translation>
3410 </message>
3411 <message>
3412 <location filename="../themesinstallwindow.cpp" line="265"/>
3413 <source>no theme preview</source>
3414 <translation>Keine Themevorschau vorhanden</translation>
3415 </message>
3416 <message>
3417 <location filename="../themesinstallwindow.cpp" line="294"/>
3418 <source>Select</source>
3419 <translation>Auswählen</translation>
3420 </message>
3421 <message>
3422 <location filename="../themesinstallwindow.cpp" line="301"/>
3423 <source>getting themes information ...</source>
3424 <translation>lade Theme-Informationen ...</translation>
3425 </message>
3426 <message>
3427 <location filename="../themesinstallwindow.cpp" line="331"/>
3428 <source>No themes selected, skipping</source>
3429 <translation>Keine Themen ausgewählt, überspringe</translation>
3430 </message>
3431 <message>
3432 <location filename="../themesinstallwindow.cpp" line="360"/>
3433 <source>Mount point is wrong!</source>
3434 <translation>Einhängepunkt ungültig!</translation>
3435 </message>
3436 <message>
3437 <location filename="../themesinstallwindow.cpp" line="236"/>
3438 <source>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</source>
3439 <translation>&lt;b&gt;Beschreibung:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3440 </message>
3441 <message>
3442 <location filename="../themesinstallwindow.cpp" line="42"/>
3443 <source>no selection</source>
3444 <translation>keine Auswahl</translation>
3445 </message>
3446 <message>
3447 <location filename="../themesinstallwindow.cpp" line="184"/>
3448 <source>Information</source>
3449 <translation>Information</translation>
3450 </message>
3451 <message numerus="yes">
3452 <location filename="../themesinstallwindow.cpp" line="202"/>
3453 <source>Download size %L1 kiB (%n item(s))</source>
3454 <translation>
3455 <numerusform>Download-Größe %L1 kiB (%n Element)</numerusform>
3456 <numerusform>Download-Größe %L1 kiB (%n Elemente)</numerusform>
3457 </translation>
3458 </message>
3459 <message>
3460 <location filename="../themesinstallwindow.cpp" line="253"/>
3461 <source>Retrieving theme preview failed.
3462HTTP response code: %1</source>
3463 <translation>Laden der Vorschau fehlgeschlagen.
3464HTTP Antwortcode: %1</translation>
3465 </message>
3466</context>
3467<context>
3468 <name>UninstallFrm</name>
3469 <message>
3470 <location filename="../uninstallfrm.ui" line="16"/>
3471 <source>Uninstall Rockbox</source>
3472 <translation>Rockbox entfernen</translation>
3473 </message>
3474 <message>
3475 <location filename="../uninstallfrm.ui" line="35"/>
3476 <source>Please select the Uninstallation Method</source>
3477 <translation>Bitte Methode zum Entfernen auswählen</translation>
3478 </message>
3479 <message>
3480 <location filename="../uninstallfrm.ui" line="45"/>
3481 <source>Uninstallation Method</source>
3482 <translation>Methode zum Entfernen</translation>
3483 </message>
3484 <message>
3485 <location filename="../uninstallfrm.ui" line="51"/>
3486 <source>Complete Uninstallation</source>
3487 <translation>Vollständiges Entfernen</translation>
3488 </message>
3489 <message>
3490 <location filename="../uninstallfrm.ui" line="58"/>
3491 <source>Smart Uninstallation</source>
3492 <translation>Intelligentes Entfernen</translation>
3493 </message>
3494 <message>
3495 <location filename="../uninstallfrm.ui" line="68"/>
3496 <source>Please select what you want to uninstall</source>
3497 <translation>Bitte die zu entfernenden Teile auswählen</translation>
3498 </message>
3499 <message>
3500 <location filename="../uninstallfrm.ui" line="78"/>
3501 <source>Installed Parts</source>
3502 <translation>Installierte Teile</translation>
3503 </message>
3504 <message>
3505 <location filename="../uninstallfrm.ui" line="139"/>
3506 <source>&amp;Cancel</source>
3507 <translation>&amp;Abbrechen</translation>
3508 </message>
3509 <message>
3510 <location filename="../uninstallfrm.ui" line="128"/>
3511 <source>&amp;Uninstall</source>
3512 <translation>&amp;Entfernen</translation>
3513 </message>
3514</context>
3515<context>
3516 <name>Uninstaller</name>
3517 <message>
3518 <location filename="../base/uninstall.cpp" line="32"/>
3519 <location filename="../base/uninstall.cpp" line="43"/>
3520 <source>Starting Uninstallation</source>
3521 <translation>Beginne Entfernen</translation>
3522 </message>
3523 <message>
3524 <location filename="../base/uninstall.cpp" line="36"/>
3525 <source>Finished Uninstallation</source>
3526 <translation>Entfernen erfolgreich</translation>
3527 </message>
3528 <message>
3529 <location filename="../base/uninstall.cpp" line="49"/>
3530 <source>Uninstalling %1...</source>
3531 <translation>Entferne %1 ...</translation>
3532 </message>
3533 <message>
3534 <location filename="../base/uninstall.cpp" line="80"/>
3535 <source>Could not delete %1</source>
3536 <translation>Konnte %1 nicht löschen</translation>
3537 </message>
3538 <message>
3539 <location filename="../base/uninstall.cpp" line="109"/>
3540 <source>Uninstallation finished</source>
3541 <translation>Entfernen erfolgreich</translation>
3542 </message>
3543</context>
3544<context>
3545 <name>Utils</name>
3546 <message>
3547 <location filename="../base/utils.cpp" line="374"/>
3548 <source>&lt;li&gt;Permissions insufficient for bootloader installation.
3549Administrator priviledges are necessary.&lt;/li&gt;</source>
3550 <translation>&lt;li&gt;Bereichtigung für Bootloader-Installation nicht ausreichend.
3551Administratorrechte sind notwendig.&lt;/li&gt;</translation>
3552 </message>
3553 <message>
3554 <location filename="../base/utils.cpp" line="386"/>
3555 <source>&lt;li&gt;Target mismatch detected.&lt;br/&gt;Installed target: %1&lt;br/&gt;Selected target: %2.&lt;/li&gt;</source>
3556 <translation>&lt;li&gt;Abweichendes Gerät entdeckt.&lt;br/&gt;Installiertes Gerät: %1&lt;br/&gt;Ausgewähltes Gerät: %2&lt;/li&gt;</translation>
3557 </message>
3558 <message>
3559 <location filename="../base/utils.cpp" line="395"/>
3560 <source>Problem detected:</source>
3561 <translation>Problem gefunden:</translation>
3562 </message>
3563</context>
3564<context>
3565 <name>VoiceFileCreator</name>
3566 <message>
3567 <location filename="../base/voicefile.cpp" line="43"/>
3568 <source>Starting Voicefile generation</source>
3569 <translation>Erzeugen der Sprachdatei beginnt</translation>
3570 </message>
3571 <message>
3572 <location filename="../base/voicefile.cpp" line="90"/>
3573 <source>Extracted voice strings from installation</source>
3574 <translation>Sprachinformationen aus Installation extrahiert</translation>
3575 </message>
3576 <message>
3577 <location filename="../base/voicefile.cpp" line="100"/>
3578 <source>Extracted voice strings incompatible</source>
3579 <translation>Extrahierte Sprachinformationen sind inkompatibel</translation>
3580 </message>
3581 <message>
3582 <location filename="../base/voicefile.cpp" line="145"/>
3583 <source>Could not retrieve strings from installation, downloading</source>
3584 <translation>Konnte Sprachinformationen nicht aus Installation extrahieren, lade herunter</translation>
3585 </message>
3586 <message>
3587 <location filename="../base/voicefile.cpp" line="185"/>
3588 <source>Download error: received HTTP error %1.</source>
3589 <translation>Fehler beim Herunterladen: HTTP Fehler %1.</translation>
3590 </message>
3591 <message>
3592 <location filename="../base/voicefile.cpp" line="192"/>
3593 <source>Cached file used.</source>
3594 <translation>Datei aus Cache verwendet.</translation>
3595 </message>
3596 <message>
3597 <location filename="../base/voicefile.cpp" line="195"/>
3598 <source>Download error: %1</source>
3599 <translation>Downloadfehler: %1</translation>
3600 </message>
3601 <message>
3602 <location filename="../base/voicefile.cpp" line="200"/>
3603 <source>Download finished.</source>
3604 <translation>Download abgeschlossen.</translation>
3605 </message>
3606 <message>
3607 <location filename="../base/voicefile.cpp" line="213"/>
3608 <source>failed to open downloaded file</source>
3609 <translation>Konnte heruntergeladene Datei nicht öffnen</translation>
3610 </message>
3611 <message>
3612 <location filename="../base/voicefile.cpp" line="276"/>
3613 <source>The downloaded file was empty!</source>
3614 <translation>Die heruntergeladene Datei war leer!</translation>
3615 </message>
3616 <message>
3617 <location filename="../base/voicefile.cpp" line="307"/>
3618 <source>Error opening downloaded file</source>
3619 <translation>Konnte heruntergeladene Datei nicht öffnen</translation>
3620 </message>
3621 <message>
3622 <location filename="../base/voicefile.cpp" line="318"/>
3623 <source>Error opening output file</source>
3624 <translation>Konnte Ausgabedatei nicht öffnen</translation>
3625 </message>
3626 <message>
3627 <location filename="../base/voicefile.cpp" line="338"/>
3628 <source>successfully created.</source>
3629 <translation>erfolgreich erzeugt.</translation>
3630 </message>
3631 <message>
3632 <location filename="../base/voicefile.cpp" line="56"/>
3633 <source>could not find rockbox-info.txt</source>
3634 <translation>Konnte rockbox-info.txt nicht finden</translation>
3635 </message>
3636 <message>
3637 <location filename="../base/voicefile.cpp" line="172"/>
3638 <source>Downloading voice info...</source>
3639 <translation>Lade Sprachinformationen herunter ...</translation>
3640 </message>
3641 <message>
3642 <location filename="../base/voicefile.cpp" line="219"/>
3643 <source>Reading strings...</source>
3644 <translation>Lese Strings ...</translation>
3645 </message>
3646 <message>
3647 <location filename="../base/voicefile.cpp" line="302"/>
3648 <source>Creating voicefiles...</source>
3649 <translation>Erzeuge Sprachdateien ...</translation>
3650 </message>
3651 <message>
3652 <location filename="../base/voicefile.cpp" line="347"/>
3653 <source>Cleaning up...</source>
3654 <translation>Räume auf ...</translation>
3655 </message>
3656 <message>
3657 <location filename="../base/voicefile.cpp" line="358"/>
3658 <source>Finished</source>
3659 <translation>Fertig</translation>
3660 </message>
3661</context>
3662<context>
3663 <name>ZipInstaller</name>
3664 <message>
3665 <location filename="../base/zipinstaller.cpp" line="59"/>
3666 <source>done.</source>
3667 <translation>Abgeschlossen.</translation>
3668 </message>
3669 <message>
3670 <location filename="../base/zipinstaller.cpp" line="78"/>
3671 <source>Downloading file %1.%2</source>
3672 <translation>Herunterladen von Datei %1.%2</translation>
3673 </message>
3674 <message>
3675 <location filename="../base/zipinstaller.cpp" line="122"/>
3676 <source>Download error: %1</source>
3677 <translation>Downloadfehler: %1</translation>
3678 </message>
3679 <message>
3680 <location filename="../base/zipinstaller.cpp" line="126"/>
3681 <source>Download finished.</source>
3682 <translation>Download abgeschlossen.</translation>
3683 </message>
3684 <message>
3685 <location filename="../base/zipinstaller.cpp" line="132"/>
3686 <source>Extracting file.</source>
3687 <translation>Extrahiere Datei.</translation>
3688 </message>
3689 <message>
3690 <location filename="../base/zipinstaller.cpp" line="153"/>
3691 <source>Extraction failed!</source>
3692 <translation>Extrahieren fehlgeschlagen!</translation>
3693 </message>
3694 <message>
3695 <location filename="../base/zipinstaller.cpp" line="165"/>
3696 <source>Installing file.</source>
3697 <translation>Installiere Datei.</translation>
3698 </message>
3699 <message>
3700 <location filename="../base/zipinstaller.cpp" line="177"/>
3701 <source>Installing file failed.</source>
3702 <translation>Dateiinstallation fehlgeschlagen.</translation>
3703 </message>
3704 <message>
3705 <location filename="../base/zipinstaller.cpp" line="190"/>
3706 <source>Creating installation log</source>
3707 <translation>Erstelle Installationslog</translation>
3708 </message>
3709 <message>
3710 <location filename="../base/zipinstaller.cpp" line="120"/>
3711 <source>Cached file used.</source>
3712 <translation>Datei aus Cache verwendet.</translation>
3713 </message>
3714 <message>
3715 <location filename="../base/zipinstaller.cpp" line="67"/>
3716 <source>Package installation finished successfully.</source>
3717 <translation>Paket-Installation erfolgreich abgeschlossen.</translation>
3718 </message>
3719 <message>
3720 <location filename="../base/zipinstaller.cpp" line="113"/>
3721 <source>Download error: received HTTP error %1
3722%2</source>
3723 <translation>Fehler beim Herunterladen: HTTP Fehler %1
3724%2</translation>
3725 </message>
3726 <message>
3727 <location filename="../base/zipinstaller.cpp" line="146"/>
3728 <source>Not enough disk space! Aborting.</source>
3729 <translation>Nicht genügend Speicherplatz verfügbar! Abbruch.</translation>
3730 </message>
3731</context>
3732<context>
3733 <name>ZipUtil</name>
3734 <message>
3735 <location filename="../base/ziputil.cpp" line="125"/>
3736 <source>Creating output path failed</source>
3737 <translation>Ausgabepfad konnte nicht erzeugt werden</translation>
3738 </message>
3739 <message>
3740 <location filename="../base/ziputil.cpp" line="132"/>
3741 <source>Creating output file failed</source>
3742 <translation>Ausgabedatei konnte nicht geschrieben werden</translation>
3743 </message>
3744 <message>
3745 <location filename="../base/ziputil.cpp" line="141"/>
3746 <source>Error during Zip operation</source>
3747 <translation>Fehler bei Zip-Vorgang</translation>
3748 </message>
3749</context>
3750<context>
3751 <name>aboutBox</name>
3752 <message>
3753 <location filename="../aboutbox.ui" line="14"/>
3754 <source>About Rockbox Utility</source>
3755 <translation>Über Rockbox Utility</translation>
3756 </message>
3757 <message>
3758 <location filename="../aboutbox.ui" line="74"/>
3759 <source>&amp;Credits</source>
3760 <translation>&amp;Credits</translation>
3761 </message>
3762 <message>
3763 <location filename="../aboutbox.ui" line="106"/>
3764 <source>&amp;License</source>
3765 <translation>&amp;Lizenz</translation>
3766 </message>
3767 <message>
3768 <location filename="../aboutbox.ui" line="132"/>
3769 <source>L&amp;ibraries</source>
3770 <translation>B&amp;ibliotheken</translation>
3771 </message>
3772 <message>
3773 <location filename="../aboutbox.ui" line="158"/>
3774 <source>&amp;Ok</source>
3775 <translation>&amp;Ok</translation>
3776 </message>
3777 <message>
3778 <location filename="../aboutbox.ui" line="32"/>
3779 <source>The Rockbox Utility</source>
3780 <translation>Rockbox Utility</translation>
3781 </message>
3782 <message>
3783 <location filename="../aboutbox.ui" line="54"/>
3784 <source>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</source>
3785 <translation>Installations- und Wartungstool für die Open-Source-Firmware für digitale Audioabspieler Rockbox.&lt;br/&gt;© Das Rockbox Team.&lt;br/&gt;Veröffentlicht unter der GNU General Public License v2.&lt;br/&gt;Verwendet Icons des &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango-Projekts&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</translation>
3786 </message>
3787</context>
3788</TS>
diff --git a/utils/rbutilqt/lang/rbutil_fi.ts b/utils/rbutilqt/lang/rbutil_fi.ts
new file mode 100644
index 0000000000..50a799ac4d
--- /dev/null
+++ b/utils/rbutilqt/lang/rbutil_fi.ts
@@ -0,0 +1,3652 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE TS>
3<TS version="2.0">
4<context>
5 <name>BackupDialog</name>
6 <message>
7 <location filename="../gui/backupdialogfrm.ui" line="17"/>
8 <location filename="../gui/backupdialogfrm.ui" line="43"/>
9 <source>Backup</source>
10 <translation type="unfinished">Varmuuskopioi</translation>
11 </message>
12 <message>
13 <location filename="../gui/backupdialogfrm.ui" line="33"/>
14 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This dialog will create a backup by archiving the contents of the Rockbox installation on the player into a zip file. This will include installed themes and settings stored below the .rockbox folder on the player.&lt;/p&gt;&lt;p&gt;The backup filename will be created based on the installed version. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
15 <translation type="unfinished"></translation>
16 </message>
17 <message>
18 <location filename="../gui/backupdialogfrm.ui" line="49"/>
19 <source>Size: unknown</source>
20 <translation type="unfinished"></translation>
21 </message>
22 <message>
23 <location filename="../gui/backupdialogfrm.ui" line="56"/>
24 <source>Backup to: unknown</source>
25 <translation type="unfinished"></translation>
26 </message>
27 <message>
28 <location filename="../gui/backupdialogfrm.ui" line="76"/>
29 <source>&amp;Change</source>
30 <translation type="unfinished">&amp;Vaihda</translation>
31 </message>
32 <message>
33 <location filename="../gui/backupdialogfrm.ui" line="116"/>
34 <source>&amp;Backup</source>
35 <translation type="unfinished"></translation>
36 </message>
37 <message>
38 <location filename="../gui/backupdialogfrm.ui" line="127"/>
39 <source>&amp;Cancel</source>
40 <translation type="unfinished">&amp;Peruuta</translation>
41 </message>
42 <message>
43 <location filename="../gui/backupdialog.cpp" line="70"/>
44 <source>Installation size: calculating ...</source>
45 <translation type="unfinished"></translation>
46 </message>
47 <message>
48 <location filename="../gui/backupdialog.cpp" line="89"/>
49 <source>Select Backup Filename</source>
50 <translation type="unfinished"></translation>
51 </message>
52 <message>
53 <location filename="../gui/backupdialog.cpp" line="109"/>
54 <source>Installation size: %L1 %2</source>
55 <translation type="unfinished"></translation>
56 </message>
57 <message>
58 <location filename="../gui/backupdialog.cpp" line="116"/>
59 <source>File exists</source>
60 <translation type="unfinished"></translation>
61 </message>
62 <message>
63 <location filename="../gui/backupdialog.cpp" line="117"/>
64 <source>The selected backup file already exists. Overwrite?</source>
65 <translation type="unfinished"></translation>
66 </message>
67 <message>
68 <location filename="../gui/backupdialog.cpp" line="125"/>
69 <source>Starting backup ...</source>
70 <translation type="unfinished"></translation>
71 </message>
72 <message>
73 <location filename="../gui/backupdialog.cpp" line="144"/>
74 <source>Backup successful.</source>
75 <translation type="unfinished"></translation>
76 </message>
77 <message>
78 <location filename="../gui/backupdialog.cpp" line="147"/>
79 <source>Backup failed!</source>
80 <translation type="unfinished">Varmuuskopiointi epäonnistui!</translation>
81 </message>
82</context>
83<context>
84 <name>BootloaderInstallAms</name>
85 <message>
86 <location filename="../base/bootloaderinstallams.cpp" line="33"/>
87 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; This file is not present on your player and will disappear automatically after installing it.&lt;br/&gt;&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
88 <translation type="unfinished"></translation>
89 </message>
90 <message>
91 <location filename="../base/bootloaderinstallams.cpp" line="58"/>
92 <source>Downloading bootloader file</source>
93 <translation type="unfinished"></translation>
94 </message>
95 <message>
96 <location filename="../base/bootloaderinstallams.cpp" line="100"/>
97 <location filename="../base/bootloaderinstallams.cpp" line="113"/>
98 <source>Could not load %1</source>
99 <translation type="unfinished"></translation>
100 </message>
101 <message>
102 <location filename="../base/bootloaderinstallams.cpp" line="127"/>
103 <source>No room to insert bootloader, try another firmware version</source>
104 <translation type="unfinished"></translation>
105 </message>
106 <message>
107 <location filename="../base/bootloaderinstallams.cpp" line="137"/>
108 <source>Patching Firmware...</source>
109 <translation type="unfinished"></translation>
110 </message>
111 <message>
112 <location filename="../base/bootloaderinstallams.cpp" line="148"/>
113 <source>Could not open %1 for writing</source>
114 <translation type="unfinished"></translation>
115 </message>
116 <message>
117 <location filename="../base/bootloaderinstallams.cpp" line="161"/>
118 <source>Could not write firmware file</source>
119 <translation type="unfinished"></translation>
120 </message>
121 <message>
122 <location filename="../base/bootloaderinstallams.cpp" line="177"/>
123 <source>Success: modified firmware file created</source>
124 <translation type="unfinished"></translation>
125 </message>
126 <message>
127 <location filename="../base/bootloaderinstallams.cpp" line="185"/>
128 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
129 <translation type="unfinished"></translation>
130 </message>
131</context>
132<context>
133 <name>BootloaderInstallBase</name>
134 <message>
135 <location filename="../base/bootloaderinstallbase.cpp" line="78"/>
136 <source>Download error: received HTTP error %1.</source>
137 <translation type="unfinished">Latausvirhe: HTTP-virhe %1.</translation>
138 </message>
139 <message>
140 <location filename="../base/bootloaderinstallbase.cpp" line="84"/>
141 <source>Download error: %1</source>
142 <translation type="unfinished">Latausvirhe: %1</translation>
143 </message>
144 <message>
145 <location filename="../base/bootloaderinstallbase.cpp" line="90"/>
146 <source>Download finished (cache used).</source>
147 <translation type="unfinished"></translation>
148 </message>
149 <message>
150 <location filename="../base/bootloaderinstallbase.cpp" line="92"/>
151 <source>Download finished.</source>
152 <translation type="unfinished">Lataus valmis.</translation>
153 </message>
154 <message>
155 <location filename="../base/bootloaderinstallbase.cpp" line="113"/>
156 <source>Creating backup of original firmware file.</source>
157 <translation type="unfinished"></translation>
158 </message>
159 <message>
160 <location filename="../base/bootloaderinstallbase.cpp" line="115"/>
161 <source>Creating backup folder failed</source>
162 <translation type="unfinished"></translation>
163 </message>
164 <message>
165 <location filename="../base/bootloaderinstallbase.cpp" line="121"/>
166 <source>Creating backup copy failed.</source>
167 <translation type="unfinished"></translation>
168 </message>
169 <message>
170 <location filename="../base/bootloaderinstallbase.cpp" line="124"/>
171 <source>Backup created.</source>
172 <translation type="unfinished"></translation>
173 </message>
174 <message>
175 <location filename="../base/bootloaderinstallbase.cpp" line="137"/>
176 <source>Creating installation log</source>
177 <translation type="unfinished">Luodaan lokitiedostoa asennuksesta</translation>
178 </message>
179 <message>
180 <location filename="../base/bootloaderinstallbase.cpp" line="226"/>
181 <source>Zip file format detected</source>
182 <translation type="unfinished"></translation>
183 </message>
184 <message>
185 <location filename="../base/bootloaderinstallbase.cpp" line="238"/>
186 <source>CAB file format detected</source>
187 <translation type="unfinished"></translation>
188 </message>
189 <message>
190 <location filename="../base/bootloaderinstallbase.cpp" line="259"/>
191 <source>Extracting firmware %1 from archive</source>
192 <translation type="unfinished"></translation>
193 </message>
194 <message>
195 <location filename="../base/bootloaderinstallbase.cpp" line="266"/>
196 <source>Error extracting firmware from archive</source>
197 <translation type="unfinished"></translation>
198 </message>
199 <message>
200 <location filename="../base/bootloaderinstallbase.cpp" line="275"/>
201 <source>Could not find firmware in archive</source>
202 <translation type="unfinished"></translation>
203 </message>
204 <message>
205 <location filename="../base/bootloaderinstallbase.cpp" line="159"/>
206 <source>Waiting for system to remount player</source>
207 <translation type="unfinished"></translation>
208 </message>
209 <message>
210 <location filename="../base/bootloaderinstallbase.cpp" line="189"/>
211 <source>Player remounted</source>
212 <translation type="unfinished"></translation>
213 </message>
214 <message>
215 <location filename="../base/bootloaderinstallbase.cpp" line="194"/>
216 <source>Timeout on remount</source>
217 <translation type="unfinished"></translation>
218 </message>
219 <message>
220 <location filename="../base/bootloaderinstallbase.cpp" line="149"/>
221 <source>Installation log created</source>
222 <translation type="unfinished"></translation>
223 </message>
224</context>
225<context>
226 <name>BootloaderInstallChinaChip</name>
227 <message>
228 <location filename="../base/bootloaderinstallchinachip.cpp" line="33"/>
229 <source>Bootloader installation requires you to provide a firmware file of the original firmware (HXF file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
230 <translation type="unfinished"></translation>
231 </message>
232 <message>
233 <location filename="../base/bootloaderinstallchinachip.cpp" line="50"/>
234 <source>Downloading bootloader file</source>
235 <translation type="unfinished"></translation>
236 </message>
237 <message>
238 <location filename="../base/bootloaderinstallchinachip.cpp" line="75"/>
239 <source>Could not open firmware file</source>
240 <translation type="unfinished"></translation>
241 </message>
242 <message>
243 <location filename="../base/bootloaderinstallchinachip.cpp" line="78"/>
244 <source>Could not open bootloader file</source>
245 <translation type="unfinished"></translation>
246 </message>
247 <message>
248 <location filename="../base/bootloaderinstallchinachip.cpp" line="81"/>
249 <source>Could not allocate memory</source>
250 <translation type="unfinished"></translation>
251 </message>
252 <message>
253 <location filename="../base/bootloaderinstallchinachip.cpp" line="84"/>
254 <source>Could not load firmware file</source>
255 <translation type="unfinished"></translation>
256 </message>
257 <message>
258 <location filename="../base/bootloaderinstallchinachip.cpp" line="87"/>
259 <source>File is not a valid ChinaChip firmware</source>
260 <translation type="unfinished"></translation>
261 </message>
262 <message>
263 <location filename="../base/bootloaderinstallchinachip.cpp" line="90"/>
264 <source>Could not find ccpmp.bin in input file</source>
265 <translation type="unfinished"></translation>
266 </message>
267 <message>
268 <location filename="../base/bootloaderinstallchinachip.cpp" line="93"/>
269 <source>Could not open backup file for ccpmp.bin</source>
270 <translation type="unfinished"></translation>
271 </message>
272 <message>
273 <location filename="../base/bootloaderinstallchinachip.cpp" line="96"/>
274 <source>Could not write backup file for ccpmp.bin</source>
275 <translation type="unfinished"></translation>
276 </message>
277 <message>
278 <location filename="../base/bootloaderinstallchinachip.cpp" line="99"/>
279 <source>Could not load bootloader file</source>
280 <translation type="unfinished"></translation>
281 </message>
282 <message>
283 <location filename="../base/bootloaderinstallchinachip.cpp" line="102"/>
284 <source>Could not get current time</source>
285 <translation type="unfinished"></translation>
286 </message>
287 <message>
288 <location filename="../base/bootloaderinstallchinachip.cpp" line="105"/>
289 <source>Could not open output file</source>
290 <translation type="unfinished"></translation>
291 </message>
292 <message>
293 <location filename="../base/bootloaderinstallchinachip.cpp" line="108"/>
294 <source>Could not write output file</source>
295 <translation type="unfinished"></translation>
296 </message>
297 <message>
298 <location filename="../base/bootloaderinstallchinachip.cpp" line="111"/>
299 <source>Unexpected error from chinachippatcher</source>
300 <translation type="unfinished"></translation>
301 </message>
302</context>
303<context>
304 <name>BootloaderInstallFile</name>
305 <message>
306 <location filename="../base/bootloaderinstallfile.cpp" line="34"/>
307 <source>Downloading bootloader</source>
308 <translation type="unfinished"></translation>
309 </message>
310 <message>
311 <location filename="../base/bootloaderinstallfile.cpp" line="43"/>
312 <source>Installing Rockbox bootloader</source>
313 <translation type="unfinished"></translation>
314 </message>
315 <message>
316 <location filename="../base/bootloaderinstallfile.cpp" line="75"/>
317 <source>Error accessing output folder</source>
318 <translation type="unfinished"></translation>
319 </message>
320 <message>
321 <location filename="../base/bootloaderinstallfile.cpp" line="89"/>
322 <source>A firmware file is already present on player</source>
323 <translation type="unfinished"></translation>
324 </message>
325 <message>
326 <location filename="../base/bootloaderinstallfile.cpp" line="94"/>
327 <source>Bootloader successful installed</source>
328 <translation type="unfinished"></translation>
329 </message>
330 <message>
331 <location filename="../base/bootloaderinstallfile.cpp" line="97"/>
332 <source>Copying modified firmware file failed</source>
333 <translation type="unfinished"></translation>
334 </message>
335 <message>
336 <location filename="../base/bootloaderinstallfile.cpp" line="111"/>
337 <source>Removing Rockbox bootloader</source>
338 <translation type="unfinished"></translation>
339 </message>
340 <message>
341 <location filename="../base/bootloaderinstallfile.cpp" line="115"/>
342 <source>No original firmware file found.</source>
343 <translation type="unfinished"></translation>
344 </message>
345 <message>
346 <location filename="../base/bootloaderinstallfile.cpp" line="121"/>
347 <source>Can&apos;t remove Rockbox bootloader file.</source>
348 <translation type="unfinished"></translation>
349 </message>
350 <message>
351 <location filename="../base/bootloaderinstallfile.cpp" line="126"/>
352 <source>Can&apos;t restore bootloader file.</source>
353 <translation type="unfinished"></translation>
354 </message>
355 <message>
356 <location filename="../base/bootloaderinstallfile.cpp" line="130"/>
357 <source>Original bootloader restored successfully.</source>
358 <translation type="unfinished"></translation>
359 </message>
360</context>
361<context>
362 <name>BootloaderInstallHex</name>
363 <message>
364 <location filename="../base/bootloaderinstallhex.cpp" line="69"/>
365 <source>checking MD5 hash of input file ...</source>
366 <translation type="unfinished"></translation>
367 </message>
368 <message>
369 <location filename="../base/bootloaderinstallhex.cpp" line="80"/>
370 <source>Could not verify original firmware file</source>
371 <translation type="unfinished"></translation>
372 </message>
373 <message>
374 <location filename="../base/bootloaderinstallhex.cpp" line="95"/>
375 <source>Firmware file not recognized.</source>
376 <translation type="unfinished"></translation>
377 </message>
378 <message>
379 <location filename="../base/bootloaderinstallhex.cpp" line="99"/>
380 <source>MD5 hash ok</source>
381 <translation type="unfinished"></translation>
382 </message>
383 <message>
384 <location filename="../base/bootloaderinstallhex.cpp" line="106"/>
385 <source>Firmware file doesn&apos;t match selected player.</source>
386 <translation type="unfinished"></translation>
387 </message>
388 <message>
389 <location filename="../base/bootloaderinstallhex.cpp" line="111"/>
390 <source>Descrambling file</source>
391 <translation type="unfinished"></translation>
392 </message>
393 <message>
394 <location filename="../base/bootloaderinstallhex.cpp" line="119"/>
395 <source>Error in descramble: %1</source>
396 <translation type="unfinished"></translation>
397 </message>
398 <message>
399 <location filename="../base/bootloaderinstallhex.cpp" line="124"/>
400 <source>Downloading bootloader file</source>
401 <translation type="unfinished"></translation>
402 </message>
403 <message>
404 <location filename="../base/bootloaderinstallhex.cpp" line="134"/>
405 <source>Adding bootloader to firmware file</source>
406 <translation type="unfinished"></translation>
407 </message>
408 <message>
409 <location filename="../base/bootloaderinstallhex.cpp" line="172"/>
410 <source>could not open input file</source>
411 <translation type="unfinished"></translation>
412 </message>
413 <message>
414 <location filename="../base/bootloaderinstallhex.cpp" line="173"/>
415 <source>reading header failed</source>
416 <translation type="unfinished"></translation>
417 </message>
418 <message>
419 <location filename="../base/bootloaderinstallhex.cpp" line="174"/>
420 <source>reading firmware failed</source>
421 <translation type="unfinished">ohjelmiston lukeminen epäonnistui</translation>
422 </message>
423 <message>
424 <location filename="../base/bootloaderinstallhex.cpp" line="175"/>
425 <source>can&apos;t open bootloader file</source>
426 <translation type="unfinished"></translation>
427 </message>
428 <message>
429 <location filename="../base/bootloaderinstallhex.cpp" line="176"/>
430 <source>reading bootloader file failed</source>
431 <translation type="unfinished"></translation>
432 </message>
433 <message>
434 <location filename="../base/bootloaderinstallhex.cpp" line="177"/>
435 <source>can&apos;t open output file</source>
436 <translation type="unfinished"></translation>
437 </message>
438 <message>
439 <location filename="../base/bootloaderinstallhex.cpp" line="178"/>
440 <source>writing output file failed</source>
441 <translation type="unfinished"></translation>
442 </message>
443 <message>
444 <location filename="../base/bootloaderinstallhex.cpp" line="180"/>
445 <source>Error in patching: %1</source>
446 <translation type="unfinished"></translation>
447 </message>
448 <message>
449 <location filename="../base/bootloaderinstallhex.cpp" line="191"/>
450 <source>Error in scramble: %1</source>
451 <translation type="unfinished"></translation>
452 </message>
453 <message>
454 <location filename="../base/bootloaderinstallhex.cpp" line="206"/>
455 <source>Checking modified firmware file</source>
456 <translation type="unfinished"></translation>
457 </message>
458 <message>
459 <location filename="../base/bootloaderinstallhex.cpp" line="208"/>
460 <source>Error: modified file checksum wrong</source>
461 <translation type="unfinished"></translation>
462 </message>
463 <message>
464 <location filename="../base/bootloaderinstallhex.cpp" line="215"/>
465 <source>A firmware file is already present on player</source>
466 <translation type="unfinished"></translation>
467 </message>
468 <message>
469 <location filename="../base/bootloaderinstallhex.cpp" line="220"/>
470 <source>Success: modified firmware file created</source>
471 <translation type="unfinished"></translation>
472 </message>
473 <message>
474 <location filename="../base/bootloaderinstallhex.cpp" line="223"/>
475 <source>Copying modified firmware file failed</source>
476 <translation type="unfinished"></translation>
477 </message>
478 <message>
479 <location filename="../base/bootloaderinstallhex.cpp" line="237"/>
480 <source>Uninstallation not possible, only installation info removed</source>
481 <translation type="unfinished"></translation>
482 </message>
483 <message>
484 <location filename="../base/bootloaderinstallhex.cpp" line="258"/>
485 <source>Can&apos;t open input file</source>
486 <translation type="unfinished"></translation>
487 </message>
488 <message>
489 <location filename="../base/bootloaderinstallhex.cpp" line="259"/>
490 <source>Can&apos;t open output file</source>
491 <translation type="unfinished">Virhe avattaessa kohdetiedostoa</translation>
492 </message>
493 <message>
494 <location filename="../base/bootloaderinstallhex.cpp" line="260"/>
495 <source>invalid file: header length wrong</source>
496 <translation type="unfinished"></translation>
497 </message>
498 <message>
499 <location filename="../base/bootloaderinstallhex.cpp" line="261"/>
500 <source>invalid file: unrecognized header</source>
501 <translation type="unfinished"></translation>
502 </message>
503 <message>
504 <location filename="../base/bootloaderinstallhex.cpp" line="262"/>
505 <source>invalid file: &quot;length&quot; field wrong</source>
506 <translation type="unfinished"></translation>
507 </message>
508 <message>
509 <location filename="../base/bootloaderinstallhex.cpp" line="263"/>
510 <source>invalid file: &quot;length2&quot; field wrong</source>
511 <translation type="unfinished"></translation>
512 </message>
513 <message>
514 <location filename="../base/bootloaderinstallhex.cpp" line="264"/>
515 <source>invalid file: internal checksum error</source>
516 <translation type="unfinished"></translation>
517 </message>
518 <message>
519 <location filename="../base/bootloaderinstallhex.cpp" line="265"/>
520 <source>invalid file: &quot;length3&quot; field wrong</source>
521 <translation type="unfinished"></translation>
522 </message>
523 <message>
524 <location filename="../base/bootloaderinstallhex.cpp" line="266"/>
525 <source>unknown</source>
526 <translation type="unfinished">tuntematon</translation>
527 </message>
528 <message>
529 <location filename="../base/bootloaderinstallhex.cpp" line="50"/>
530 <source>Bootloader installation requires you to provide a firmware file of the original firmware (hex file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
531 <translation type="unfinished"></translation>
532 </message>
533</context>
534<context>
535 <name>BootloaderInstallImx</name>
536 <message>
537 <location filename="../base/bootloaderinstallimx.cpp" line="72"/>
538 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (firmware.sb file). This file will be patched with the Rockbox bootloader and installed to your player. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
539 <translation type="unfinished"></translation>
540 </message>
541 <message>
542 <location filename="../base/bootloaderinstallimx.cpp" line="94"/>
543 <source>Could not read original firmware file</source>
544 <translation type="unfinished"></translation>
545 </message>
546 <message>
547 <location filename="../base/bootloaderinstallimx.cpp" line="100"/>
548 <source>Downloading bootloader file</source>
549 <translation type="unfinished"></translation>
550 </message>
551 <message>
552 <location filename="../base/bootloaderinstallimx.cpp" line="110"/>
553 <source>Patching file...</source>
554 <translation type="unfinished"></translation>
555 </message>
556 <message>
557 <location filename="../base/bootloaderinstallimx.cpp" line="137"/>
558 <source>Patching the original firmware failed</source>
559 <translation type="unfinished"></translation>
560 </message>
561 <message>
562 <location filename="../base/bootloaderinstallimx.cpp" line="143"/>
563 <source>Succesfully patched firmware file</source>
564 <translation type="unfinished"></translation>
565 </message>
566 <message>
567 <location filename="../base/bootloaderinstallimx.cpp" line="158"/>
568 <source>Bootloader successful installed</source>
569 <translation type="unfinished"></translation>
570 </message>
571 <message>
572 <location filename="../base/bootloaderinstallimx.cpp" line="164"/>
573 <source>Patched bootloader could not be installed</source>
574 <translation type="unfinished"></translation>
575 </message>
576 <message>
577 <location filename="../base/bootloaderinstallimx.cpp" line="175"/>
578 <source>To uninstall, perform a normal upgrade with an unmodified original firmware.</source>
579 <translation type="unfinished"></translation>
580 </message>
581</context>
582<context>
583 <name>BootloaderInstallIpod</name>
584 <message>
585 <location filename="../base/bootloaderinstallipod.cpp" line="49"/>
586 <source>Error: can&apos;t allocate buffer memory!</source>
587 <translation type="unfinished"></translation>
588 </message>
589 <message>
590 <location filename="../base/bootloaderinstallipod.cpp" line="80"/>
591 <source>Downloading bootloader file</source>
592 <translation type="unfinished"></translation>
593 </message>
594 <message>
595 <location filename="../base/bootloaderinstallipod.cpp" line="64"/>
596 <location filename="../base/bootloaderinstallipod.cpp" line="151"/>
597 <source>Failed to read firmware directory</source>
598 <translation type="unfinished">Ohjelmistohakemistoa ei voitu lukea</translation>
599 </message>
600 <message>
601 <location filename="../base/bootloaderinstallipod.cpp" line="69"/>
602 <location filename="../base/bootloaderinstallipod.cpp" line="156"/>
603 <source>Unknown version number in firmware (%1)</source>
604 <translation type="unfinished">Tuntematon ohjelmiston versio (%1)</translation>
605 </message>
606 <message>
607 <location filename="../base/bootloaderinstallipod.cpp" line="75"/>
608 <source>Warning: This is a MacPod, Rockbox only runs on WinPods.
609See http://www.rockbox.org/wiki/IpodConversionToFAT32</source>
610 <translation type="unfinished"></translation>
611 </message>
612 <message>
613 <location filename="../base/bootloaderinstallipod.cpp" line="94"/>
614 <location filename="../base/bootloaderinstallipod.cpp" line="163"/>
615 <source>Could not open Ipod in R/W mode</source>
616 <translation type="unfinished"></translation>
617 </message>
618 <message>
619 <location filename="../base/bootloaderinstallipod.cpp" line="104"/>
620 <source>Successfull added bootloader</source>
621 <translation type="unfinished"></translation>
622 </message>
623 <message>
624 <location filename="../base/bootloaderinstallipod.cpp" line="115"/>
625 <source>Failed to add bootloader</source>
626 <translation type="unfinished"></translation>
627 </message>
628 <message>
629 <location filename="../base/bootloaderinstallipod.cpp" line="127"/>
630 <source>Bootloader Installation complete.</source>
631 <translation type="unfinished"></translation>
632 </message>
633 <message>
634 <location filename="../base/bootloaderinstallipod.cpp" line="132"/>
635 <source>Writing log aborted</source>
636 <translation type="unfinished"></translation>
637 </message>
638 <message>
639 <location filename="../base/bootloaderinstallipod.cpp" line="169"/>
640 <source>No bootloader detected.</source>
641 <translation type="unfinished">Käynnistyslatainta ei havaittu.</translation>
642 </message>
643 <message>
644 <location filename="../base/bootloaderinstallipod.cpp" line="175"/>
645 <source>Successfully removed bootloader</source>
646 <translation type="unfinished"></translation>
647 </message>
648 <message>
649 <location filename="../base/bootloaderinstallipod.cpp" line="182"/>
650 <source>Removing bootloader failed.</source>
651 <translation type="unfinished"></translation>
652 </message>
653 <message>
654 <location filename="../base/bootloaderinstallipod.cpp" line="228"/>
655 <source>Error: could not retrieve device name</source>
656 <translation type="unfinished"></translation>
657 </message>
658 <message>
659 <location filename="../base/bootloaderinstallipod.cpp" line="244"/>
660 <source>Error: no mountpoint specified!</source>
661 <translation type="unfinished"></translation>
662 </message>
663 <message>
664 <location filename="../base/bootloaderinstallipod.cpp" line="249"/>
665 <source>Could not open Ipod: permission denied</source>
666 <translation type="unfinished"></translation>
667 </message>
668 <message>
669 <location filename="../base/bootloaderinstallipod.cpp" line="253"/>
670 <source>Could not open Ipod</source>
671 <translation type="unfinished"></translation>
672 </message>
673 <message>
674 <location filename="../base/bootloaderinstallipod.cpp" line="264"/>
675 <source>No firmware partition on disk</source>
676 <translation type="unfinished"></translation>
677 </message>
678 <message>
679 <location filename="../base/bootloaderinstallipod.cpp" line="90"/>
680 <source>Installing Rockbox bootloader</source>
681 <translation type="unfinished"></translation>
682 </message>
683 <message>
684 <location filename="../base/bootloaderinstallipod.cpp" line="142"/>
685 <source>Uninstalling bootloader</source>
686 <translation type="unfinished"></translation>
687 </message>
688 <message>
689 <location filename="../base/bootloaderinstallipod.cpp" line="258"/>
690 <source>Error reading partition table - possibly not an Ipod</source>
691 <translation type="unfinished"></translation>
692 </message>
693</context>
694<context>
695 <name>BootloaderInstallMi4</name>
696 <message>
697 <location filename="../base/bootloaderinstallmi4.cpp" line="34"/>
698 <source>Downloading bootloader</source>
699 <translation type="unfinished"></translation>
700 </message>
701 <message>
702 <location filename="../base/bootloaderinstallmi4.cpp" line="43"/>
703 <source>Installing Rockbox bootloader</source>
704 <translation type="unfinished"></translation>
705 </message>
706 <message>
707 <location filename="../base/bootloaderinstallmi4.cpp" line="66"/>
708 <source>A firmware file is already present on player</source>
709 <translation type="unfinished"></translation>
710 </message>
711 <message>
712 <location filename="../base/bootloaderinstallmi4.cpp" line="71"/>
713 <location filename="../base/bootloaderinstallmi4.cpp" line="79"/>
714 <source>Bootloader successful installed</source>
715 <translation type="unfinished"></translation>
716 </message>
717 <message>
718 <location filename="../base/bootloaderinstallmi4.cpp" line="74"/>
719 <source>Copying modified firmware file failed</source>
720 <translation type="unfinished"></translation>
721 </message>
722 <message>
723 <location filename="../base/bootloaderinstallmi4.cpp" line="91"/>
724 <source>Checking for Rockbox bootloader</source>
725 <translation type="unfinished"></translation>
726 </message>
727 <message>
728 <location filename="../base/bootloaderinstallmi4.cpp" line="93"/>
729 <source>No Rockbox bootloader found</source>
730 <translation type="unfinished"></translation>
731 </message>
732 <message>
733 <location filename="../base/bootloaderinstallmi4.cpp" line="98"/>
734 <source>Checking for original firmware file</source>
735 <translation type="unfinished"></translation>
736 </message>
737 <message>
738 <location filename="../base/bootloaderinstallmi4.cpp" line="103"/>
739 <source>Error finding original firmware file</source>
740 <translation type="unfinished"></translation>
741 </message>
742 <message>
743 <location filename="../base/bootloaderinstallmi4.cpp" line="113"/>
744 <source>Rockbox bootloader successful removed</source>
745 <translation type="unfinished"></translation>
746 </message>
747</context>
748<context>
749 <name>BootloaderInstallMpio</name>
750 <message>
751 <location filename="../base/bootloaderinstallmpio.cpp" line="34"/>
752 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
753 <translation type="unfinished"></translation>
754 </message>
755 <message>
756 <location filename="../base/bootloaderinstallmpio.cpp" line="53"/>
757 <source>Downloading bootloader file</source>
758 <translation type="unfinished"></translation>
759 </message>
760 <message>
761 <location filename="../base/bootloaderinstallmpio.cpp" line="80"/>
762 <source>Could not open the original firmware.</source>
763 <translation type="unfinished"></translation>
764 </message>
765 <message>
766 <location filename="../base/bootloaderinstallmpio.cpp" line="83"/>
767 <source>Could not read the original firmware.</source>
768 <translation type="unfinished"></translation>
769 </message>
770 <message>
771 <location filename="../base/bootloaderinstallmpio.cpp" line="86"/>
772 <source>Loaded firmware file does not look like MPIO original firmware file.</source>
773 <translation type="unfinished"></translation>
774 </message>
775 <message>
776 <location filename="../base/bootloaderinstallmpio.cpp" line="101"/>
777 <source>Could not open output file.</source>
778 <translation type="unfinished"></translation>
779 </message>
780 <message>
781 <location filename="../base/bootloaderinstallmpio.cpp" line="104"/>
782 <source>Could not write output file.</source>
783 <translation type="unfinished"></translation>
784 </message>
785 <message>
786 <location filename="../base/bootloaderinstallmpio.cpp" line="107"/>
787 <source>Unknown error number: %1</source>
788 <translation type="unfinished"></translation>
789 </message>
790 <message>
791 <location filename="../base/bootloaderinstallmpio.cpp" line="89"/>
792 <source>Could not open downloaded bootloader.</source>
793 <translation type="unfinished"></translation>
794 </message>
795 <message>
796 <location filename="../base/bootloaderinstallmpio.cpp" line="92"/>
797 <source>Place for bootloader in OF file not empty.</source>
798 <translation type="unfinished"></translation>
799 </message>
800 <message>
801 <location filename="../base/bootloaderinstallmpio.cpp" line="95"/>
802 <source>Could not read the downloaded bootloader.</source>
803 <translation type="unfinished"></translation>
804 </message>
805 <message>
806 <location filename="../base/bootloaderinstallmpio.cpp" line="98"/>
807 <source>Bootloader checksum error.</source>
808 <translation type="unfinished"></translation>
809 </message>
810 <message>
811 <location filename="../base/bootloaderinstallmpio.cpp" line="112"/>
812 <source>Patching original firmware failed: %1</source>
813 <translation type="unfinished"></translation>
814 </message>
815 <message>
816 <location filename="../base/bootloaderinstallmpio.cpp" line="119"/>
817 <source>Success: modified firmware file created</source>
818 <translation type="unfinished"></translation>
819 </message>
820 <message>
821 <location filename="../base/bootloaderinstallmpio.cpp" line="127"/>
822 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
823 <translation type="unfinished"></translation>
824 </message>
825</context>
826<context>
827 <name>BootloaderInstallSansa</name>
828 <message>
829 <location filename="../base/bootloaderinstallsansa.cpp" line="50"/>
830 <source>Error: can&apos;t allocate buffer memory!</source>
831 <translation type="unfinished"></translation>
832 </message>
833 <message>
834 <location filename="../base/bootloaderinstallsansa.cpp" line="55"/>
835 <source>Searching for Sansa</source>
836 <translation type="unfinished"></translation>
837 </message>
838 <message>
839 <location filename="../base/bootloaderinstallsansa.cpp" line="59"/>
840 <source>Permission for disc access denied!
841This is required to install the bootloader</source>
842 <translation type="unfinished"></translation>
843 </message>
844 <message>
845 <location filename="../base/bootloaderinstallsansa.cpp" line="66"/>
846 <source>No Sansa detected!</source>
847 <translation type="unfinished"></translation>
848 </message>
849 <message>
850 <location filename="../base/bootloaderinstallsansa.cpp" line="79"/>
851 <source>Downloading bootloader file</source>
852 <translation type="unfinished"></translation>
853 </message>
854 <message>
855 <location filename="../base/bootloaderinstallsansa.cpp" line="71"/>
856 <location filename="../base/bootloaderinstallsansa.cpp" line="179"/>
857 <source>OLD ROCKBOX INSTALLATION DETECTED, ABORTING.
858You must reinstall the original Sansa firmware before running
859sansapatcher for the first time.
860See http://www.rockbox.org/wiki/SansaE200Install
861</source>
862 <translation type="unfinished"></translation>
863 </message>
864 <message>
865 <location filename="../base/bootloaderinstallsansa.cpp" line="102"/>
866 <location filename="../base/bootloaderinstallsansa.cpp" line="189"/>
867 <source>Could not open Sansa in R/W mode</source>
868 <translation type="unfinished"></translation>
869 </message>
870 <message>
871 <location filename="../base/bootloaderinstallsansa.cpp" line="129"/>
872 <source>Successfully installed bootloader</source>
873 <translation type="unfinished"></translation>
874 </message>
875 <message>
876 <location filename="../base/bootloaderinstallsansa.cpp" line="140"/>
877 <source>Failed to install bootloader</source>
878 <translation type="unfinished"></translation>
879 </message>
880 <message>
881 <location filename="../base/bootloaderinstallsansa.cpp" line="153"/>
882 <source>Bootloader Installation complete.</source>
883 <translation type="unfinished"></translation>
884 </message>
885 <message>
886 <location filename="../base/bootloaderinstallsansa.cpp" line="158"/>
887 <source>Writing log aborted</source>
888 <translation type="unfinished"></translation>
889 </message>
890 <message>
891 <location filename="../base/bootloaderinstallsansa.cpp" line="238"/>
892 <source>Error: could not retrieve device name</source>
893 <translation type="unfinished"></translation>
894 </message>
895 <message>
896 <location filename="../base/bootloaderinstallsansa.cpp" line="254"/>
897 <source>Can&apos;t find Sansa</source>
898 <translation type="unfinished"></translation>
899 </message>
900 <message>
901 <location filename="../base/bootloaderinstallsansa.cpp" line="259"/>
902 <source>Could not open Sansa</source>
903 <translation type="unfinished"></translation>
904 </message>
905 <message>
906 <location filename="../base/bootloaderinstallsansa.cpp" line="264"/>
907 <source>Could not read partition table</source>
908 <translation type="unfinished"></translation>
909 </message>
910 <message>
911 <location filename="../base/bootloaderinstallsansa.cpp" line="271"/>
912 <source>Disk is not a Sansa (Error %1), aborting.</source>
913 <translation type="unfinished"></translation>
914 </message>
915 <message>
916 <location filename="../base/bootloaderinstallsansa.cpp" line="195"/>
917 <source>Successfully removed bootloader</source>
918 <translation type="unfinished"></translation>
919 </message>
920 <message>
921 <location filename="../base/bootloaderinstallsansa.cpp" line="202"/>
922 <source>Removing bootloader failed.</source>
923 <translation type="unfinished"></translation>
924 </message>
925 <message>
926 <location filename="../base/bootloaderinstallsansa.cpp" line="94"/>
927 <source>Installing Rockbox bootloader</source>
928 <translation type="unfinished"></translation>
929 </message>
930 <message>
931 <location filename="../base/bootloaderinstallsansa.cpp" line="111"/>
932 <source>Checking downloaded bootloader</source>
933 <translation type="unfinished"></translation>
934 </message>
935 <message>
936 <location filename="../base/bootloaderinstallsansa.cpp" line="119"/>
937 <source>Bootloader mismatch! Aborting.</source>
938 <translation type="unfinished"></translation>
939 </message>
940 <message>
941 <location filename="../base/bootloaderinstallsansa.cpp" line="170"/>
942 <source>Uninstalling bootloader</source>
943 <translation type="unfinished"></translation>
944 </message>
945</context>
946<context>
947 <name>BootloaderInstallTcc</name>
948 <message>
949 <location filename="../base/bootloaderinstalltcc.cpp" line="33"/>
950 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wiki page on how to obtain the file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
951 <translation type="unfinished"></translation>
952 </message>
953 <message>
954 <location filename="../base/bootloaderinstalltcc.cpp" line="50"/>
955 <source>Downloading bootloader file</source>
956 <translation type="unfinished"></translation>
957 </message>
958 <message>
959 <location filename="../base/bootloaderinstalltcc.cpp" line="82"/>
960 <location filename="../base/bootloaderinstalltcc.cpp" line="99"/>
961 <source>Could not load %1</source>
962 <translation type="unfinished"></translation>
963 </message>
964 <message>
965 <location filename="../base/bootloaderinstalltcc.cpp" line="90"/>
966 <source>Unknown OF file used: %1</source>
967 <translation type="unfinished"></translation>
968 </message>
969 <message>
970 <location filename="../base/bootloaderinstalltcc.cpp" line="104"/>
971 <source>Patching Firmware...</source>
972 <translation type="unfinished"></translation>
973 </message>
974 <message>
975 <location filename="../base/bootloaderinstalltcc.cpp" line="111"/>
976 <source>Could not patch firmware</source>
977 <translation type="unfinished"></translation>
978 </message>
979 <message>
980 <location filename="../base/bootloaderinstalltcc.cpp" line="117"/>
981 <source>Could not open %1 for writing</source>
982 <translation type="unfinished"></translation>
983 </message>
984 <message>
985 <location filename="../base/bootloaderinstalltcc.cpp" line="126"/>
986 <source>Could not write firmware file</source>
987 <translation type="unfinished"></translation>
988 </message>
989 <message>
990 <location filename="../base/bootloaderinstalltcc.cpp" line="131"/>
991 <source>Success: modified firmware file created</source>
992 <translation type="unfinished"></translation>
993 </message>
994 <message>
995 <location filename="../base/bootloaderinstalltcc.cpp" line="151"/>
996 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
997 <translation type="unfinished"></translation>
998 </message>
999</context>
1000<context>
1001 <name>Changelog</name>
1002 <message>
1003 <location filename="../gui/changelogfrm.ui" line="17"/>
1004 <source>Changelog</source>
1005 <translation type="unfinished"></translation>
1006 </message>
1007 <message>
1008 <location filename="../gui/changelogfrm.ui" line="39"/>
1009 <source>Show on startup</source>
1010 <translation type="unfinished"></translation>
1011 </message>
1012 <message>
1013 <location filename="../gui/changelogfrm.ui" line="46"/>
1014 <source>&amp;Ok</source>
1015 <translation type="unfinished">&amp;Ok</translation>
1016 </message>
1017</context>
1018<context>
1019 <name>Config</name>
1020 <message>
1021 <location filename="../configure.cpp" line="322"/>
1022 <source>Current cache size is %L1 kiB.</source>
1023 <translation>Nykyinen välimuistin koko on %L1 kt.</translation>
1024 </message>
1025 <message>
1026 <location filename="../configure.cpp" line="340"/>
1027 <source>Showing disabled targets</source>
1028 <translation type="unfinished"></translation>
1029 </message>
1030 <message>
1031 <location filename="../configure.cpp" line="341"/>
1032 <source>You just enabled showing targets that are marked disabled. Disabled targets are not recommended to end users. Please use this option only if you know what you are doing.</source>
1033 <translation type="unfinished"></translation>
1034 </message>
1035 <message>
1036 <location filename="../configure.cpp" line="448"/>
1037 <location filename="../configure.cpp" line="914"/>
1038 <source>TTS error</source>
1039 <translation type="unfinished"></translation>
1040 </message>
1041 <message>
1042 <location filename="../configure.cpp" line="449"/>
1043 <location filename="../configure.cpp" line="915"/>
1044 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1045 <translation type="unfinished"></translation>
1046 </message>
1047 <message>
1048 <location filename="../configure.cpp" line="455"/>
1049 <location filename="../configure.cpp" line="485"/>
1050 <source>Configuration OK</source>
1051 <translation>Asetukset kunnossa</translation>
1052 </message>
1053 <message>
1054 <location filename="../configure.cpp" line="461"/>
1055 <location filename="../configure.cpp" line="490"/>
1056 <source>Configuration INVALID</source>
1057 <translation>Vialliset asetukset</translation>
1058 </message>
1059 <message>
1060 <location filename="../configure.cpp" line="529"/>
1061 <source>Proxy Detection</source>
1062 <translation type="unfinished"></translation>
1063 </message>
1064 <message>
1065 <location filename="../configure.cpp" line="530"/>
1066 <source>The System Proxy settings are invalid!
1067Rockbox Utility can&apos;t work with this proxy settings. Make sure the system proxy is set correctly. Note that &quot;proxy auto-config (PAC)&quot; scripts are not supported by Rockbox Utility. If your system uses this you need to use manual proxy settings.</source>
1068 <translation type="unfinished"></translation>
1069 </message>
1070 <message>
1071 <location filename="../configure.cpp" line="643"/>
1072 <source>Set Cache Path</source>
1073 <translation type="unfinished"></translation>
1074 </message>
1075 <message>
1076 <location filename="../configure.cpp" line="665"/>
1077 <source>%1 (%2 GiB of %3 GiB free)</source>
1078 <translation type="unfinished"></translation>
1079 </message>
1080 <message>
1081 <location filename="../configure.cpp" line="739"/>
1082 <source>Multiple devices have been detected. Please disconnect all players but one and try again.</source>
1083 <translation type="unfinished"></translation>
1084 </message>
1085 <message>
1086 <location filename="../configure.cpp" line="742"/>
1087 <source>Detected devices:</source>
1088 <translation type="unfinished"></translation>
1089 </message>
1090 <message>
1091 <location filename="../configure.cpp" line="747"/>
1092 <source>(unknown)</source>
1093 <translation type="unfinished"></translation>
1094 </message>
1095 <message>
1096 <location filename="../configure.cpp" line="749"/>
1097 <source>%1 at %2</source>
1098 <translation type="unfinished"></translation>
1099 </message>
1100 <message>
1101 <location filename="../configure.cpp" line="755"/>
1102 <source>Note: detecting connected devices might be ambiguous. You might have less devices connected than listed. In this case it might not be possible to detect your player unambiguously.</source>
1103 <translation type="unfinished"></translation>
1104 </message>
1105 <message>
1106 <location filename="../configure.cpp" line="759"/>
1107 <location filename="../configure.cpp" line="763"/>
1108 <location filename="../configure.cpp" line="805"/>
1109 <source>Device Detection</source>
1110 <translation type="unfinished"></translation>
1111 </message>
1112 <message>
1113 <location filename="../configure.cpp" line="788"/>
1114 <source>%1 &quot;MacPod&quot; found!
1115Rockbox needs a FAT formatted Ipod (so-called &quot;WinPod&quot;) to run. </source>
1116 <translation type="unfinished"></translation>
1117 </message>
1118 <message>
1119 <source>Fatal error</source>
1120 <translation type="obsolete">Vakava virhe</translation>
1121 </message>
1122 <message>
1123 <location filename="../configure.cpp" line="774"/>
1124 <source>Detected an unsupported player:
1125%1
1126Sorry, Rockbox doesn&apos;t run on your player.</source>
1127 <translation type="unfinished"></translation>
1128 </message>
1129 <message>
1130 <location filename="../configure.cpp" line="921"/>
1131 <source>TTS configuration invalid</source>
1132 <translation type="unfinished"></translation>
1133 </message>
1134 <message>
1135 <location filename="../configure.cpp" line="922"/>
1136 <source>TTS configuration invalid.
1137 Please configure TTS engine.</source>
1138 <translation type="unfinished"></translation>
1139 </message>
1140 <message>
1141 <location filename="../configure.cpp" line="927"/>
1142 <source>Could not start TTS engine.</source>
1143 <translation type="unfinished"></translation>
1144 </message>
1145 <message>
1146 <location filename="../configure.cpp" line="928"/>
1147 <source>Could not start TTS engine.
1148</source>
1149 <translation type="unfinished"></translation>
1150 </message>
1151 <message>
1152 <location filename="../configure.cpp" line="929"/>
1153 <location filename="../configure.cpp" line="948"/>
1154 <source>
1155Please configure TTS engine.</source>
1156 <translation type="unfinished"></translation>
1157 </message>
1158 <message>
1159 <location filename="../configure.cpp" line="943"/>
1160 <source>Rockbox Utility Voice Test</source>
1161 <translation type="unfinished"></translation>
1162 </message>
1163 <message>
1164 <location filename="../configure.cpp" line="946"/>
1165 <source>Could not voice test string.</source>
1166 <translation type="unfinished"></translation>
1167 </message>
1168 <message>
1169 <location filename="../configure.cpp" line="947"/>
1170 <source>Could not voice test string.
1171</source>
1172 <translation type="unfinished"></translation>
1173 </message>
1174 <message>
1175 <location filename="../configure.cpp" line="858"/>
1176 <source>Autodetection</source>
1177 <translation>Automaattinen tunnistus</translation>
1178 </message>
1179 <message>
1180 <location filename="../configure.cpp" line="780"/>
1181 <source>%1 in MTP mode found!
1182You need to change your player to MSC mode for installation. </source>
1183 <translation type="unfinished"></translation>
1184 </message>
1185 <message>
1186 <location filename="../configure.cpp" line="859"/>
1187 <source>Could not detect a Mountpoint.
1188Select your Mountpoint manually.</source>
1189 <translation>Liitospistettä ei voitu tunnistaa
1190Valitse liitospiste käsin.</translation>
1191 </message>
1192 <message>
1193 <location filename="../configure.cpp" line="764"/>
1194 <source>Could not detect a device.
1195Select your device and Mountpoint manually.</source>
1196 <translation>Laitetta ei voitu tunnistaa
1197Valitse laite ja liitospiste käsin.</translation>
1198 </message>
1199 <message>
1200 <location filename="../configure.cpp" line="794"/>
1201 <source>The player contains an incompatible filesystem.
1202Make sure you selected the correct mountpoint and the player is set up to use a filesystem compatible with Rockbox.</source>
1203 <translation type="unfinished"></translation>
1204 </message>
1205 <message>
1206 <location filename="../configure.cpp" line="802"/>
1207 <source>An unknown error occured during player detection.</source>
1208 <translation type="unfinished"></translation>
1209 </message>
1210 <message>
1211 <location filename="../configure.cpp" line="869"/>
1212 <source>Really delete cache?</source>
1213 <translation>Oletko varma että haluat tyhjentää välimuistin?</translation>
1214 </message>
1215 <message>
1216 <location filename="../configure.cpp" line="870"/>
1217 <source>Do you really want to delete the cache? Make absolutely sure this setting is correct as it will remove &lt;b&gt;all&lt;/b&gt; files in this folder!</source>
1218 <translation>Haluatko varmasti tyhjentää välimuistin? Varmista kaksi kertaa, sillä tämä poistaa &lt;b&gt;kaikki&lt;/b&gt; tiedostot tästä hakemistosta!</translation>
1219 </message>
1220 <message>
1221 <location filename="../configure.cpp" line="878"/>
1222 <source>Path wrong!</source>
1223 <translation>Polku väärin!</translation>
1224 </message>
1225 <message>
1226 <location filename="../configure.cpp" line="879"/>
1227 <source>The cache path is invalid. Aborting.</source>
1228 <translation>Välimuistin polku on epäkelpo. Keskeytetään.</translation>
1229 </message>
1230 <message>
1231 <location filename="../configure.cpp" line="130"/>
1232 <source>The following errors occurred:</source>
1233 <translation type="unfinished"></translation>
1234 </message>
1235 <message>
1236 <location filename="../configure.cpp" line="175"/>
1237 <source>No mountpoint given</source>
1238 <translation type="unfinished"></translation>
1239 </message>
1240 <message>
1241 <location filename="../configure.cpp" line="179"/>
1242 <source>Mountpoint does not exist</source>
1243 <translation type="unfinished"></translation>
1244 </message>
1245 <message>
1246 <location filename="../configure.cpp" line="183"/>
1247 <source>Mountpoint is not a directory.</source>
1248 <translation type="unfinished"></translation>
1249 </message>
1250 <message>
1251 <location filename="../configure.cpp" line="187"/>
1252 <source>Mountpoint is not writeable</source>
1253 <translation type="unfinished"></translation>
1254 </message>
1255 <message>
1256 <location filename="../configure.cpp" line="202"/>
1257 <source>No player selected</source>
1258 <translation type="unfinished"></translation>
1259 </message>
1260 <message>
1261 <location filename="../configure.cpp" line="209"/>
1262 <source>Cache path not writeable. Leave path empty to default to systems temporary path.</source>
1263 <translation type="unfinished"></translation>
1264 </message>
1265 <message>
1266 <location filename="../configure.cpp" line="228"/>
1267 <source>You need to fix the above errors before you can continue.</source>
1268 <translation type="unfinished"></translation>
1269 </message>
1270 <message>
1271 <location filename="../configure.cpp" line="231"/>
1272 <source>Configuration error</source>
1273 <translation type="unfinished">Asetusvirhe</translation>
1274 </message>
1275</context>
1276<context>
1277 <name>ConfigForm</name>
1278 <message>
1279 <location filename="../configurefrm.ui" line="14"/>
1280 <source>Configuration</source>
1281 <translation>Asetukset</translation>
1282 </message>
1283 <message>
1284 <location filename="../configurefrm.ui" line="20"/>
1285 <source>Configure Rockbox Utility</source>
1286 <translation>Määritä Rockbox Utilityn asetukset</translation>
1287 </message>
1288 <message>
1289 <location filename="../configurefrm.ui" line="35"/>
1290 <source>&amp;Device</source>
1291 <translation>&amp;Laite</translation>
1292 </message>
1293 <message>
1294 <location filename="../configurefrm.ui" line="41"/>
1295 <source>Select your device in the &amp;filesystem</source>
1296 <translation>Valitse laitteesi &amp;tiedostojärjestelmästä</translation>
1297 </message>
1298 <message>
1299 <location filename="../configurefrm.ui" line="319"/>
1300 <source>&amp;Browse</source>
1301 <translation>&amp;Selaa</translation>
1302 </message>
1303 <message>
1304 <location filename="../configurefrm.ui" line="72"/>
1305 <source>&amp;Select your audio player</source>
1306 <translation>&amp;Valitse soittimesi</translation>
1307 </message>
1308 <message>
1309 <location filename="../configurefrm.ui" line="58"/>
1310 <source>&amp;Refresh</source>
1311 <translation type="unfinished">&amp;Päivitä</translation>
1312 </message>
1313 <message>
1314 <location filename="../configurefrm.ui" line="95"/>
1315 <source>Show disabled targets</source>
1316 <translation type="unfinished"></translation>
1317 </message>
1318 <message>
1319 <location filename="../configurefrm.ui" line="114"/>
1320 <source>&amp;Autodetect</source>
1321 <translation>&amp;Automaattinen tunnistus</translation>
1322 </message>
1323 <message>
1324 <location filename="../configurefrm.ui" line="136"/>
1325 <source>&amp;Proxy</source>
1326 <translation>Välityspalvelin</translation>
1327 </message>
1328 <message>
1329 <location filename="../configurefrm.ui" line="142"/>
1330 <source>&amp;No Proxy</source>
1331 <translation>Ei välityspalvelinta</translation>
1332 </message>
1333 <message>
1334 <location filename="../configurefrm.ui" line="152"/>
1335 <source>Use S&amp;ystem values</source>
1336 <translation>Käytä järjestelmän asetuksia</translation>
1337 </message>
1338 <message>
1339 <location filename="../configurefrm.ui" line="159"/>
1340 <source>&amp;Manual Proxy settings</source>
1341 <translation>&amp;Säädä asetukset käsin</translation>
1342 </message>
1343 <message>
1344 <location filename="../configurefrm.ui" line="166"/>
1345 <source>Proxy Values</source>
1346 <translation>Välityspalvelimen asetukset</translation>
1347 </message>
1348 <message>
1349 <location filename="../configurefrm.ui" line="172"/>
1350 <source>&amp;Host:</source>
1351 <translation>&amp;Osoite:</translation>
1352 </message>
1353 <message>
1354 <location filename="../configurefrm.ui" line="182"/>
1355 <source>&amp;Port:</source>
1356 <translation>&amp;Portti:</translation>
1357 </message>
1358 <message>
1359 <location filename="../configurefrm.ui" line="199"/>
1360 <source>&amp;Username</source>
1361 <translation>&amp;Käyttäjänimi</translation>
1362 </message>
1363 <message>
1364 <location filename="../configurefrm.ui" line="209"/>
1365 <source>Pass&amp;word</source>
1366 <translation>S&amp;alasana</translation>
1367 </message>
1368 <message>
1369 <location filename="../configurefrm.ui" line="219"/>
1370 <source>Show</source>
1371 <translation type="unfinished"></translation>
1372 </message>
1373 <message>
1374 <location filename="../configurefrm.ui" line="260"/>
1375 <source>&amp;Language</source>
1376 <translation>&amp;Kieli</translation>
1377 </message>
1378 <message>
1379 <location filename="../configurefrm.ui" line="274"/>
1380 <source>Cac&amp;he</source>
1381 <translation>V&amp;älimuisti</translation>
1382 </message>
1383 <message>
1384 <location filename="../configurefrm.ui" line="277"/>
1385 <source>Download cache settings</source>
1386 <translation>Välimuistin asetukset</translation>
1387 </message>
1388 <message>
1389 <location filename="../configurefrm.ui" line="283"/>
1390 <source>Rockbox Utility uses a local download cache to save network traffic. You can change the path to the cache and use it as local repository by enabling Offline mode.</source>
1391 <translation>Rockbox Utility käyttää paikallista välimuistia säästääkseen verkon käyttöä. Voit vaihtaa välimuistin polkua ja käyttää sitä varastona ottamalla yhteydettömän tilan käyttöön.</translation>
1392 </message>
1393 <message>
1394 <location filename="../configurefrm.ui" line="293"/>
1395 <source>Current cache size is %1</source>
1396 <translation>Nykyinen välimuistin koko on %1 kt</translation>
1397 </message>
1398 <message>
1399 <location filename="../configurefrm.ui" line="302"/>
1400 <source>P&amp;ath</source>
1401 <translation>Polku:</translation>
1402 </message>
1403 <message>
1404 <location filename="../configurefrm.ui" line="312"/>
1405 <source>Entering an invalid folder will reset the path to the systems temporary path.</source>
1406 <translation type="unfinished"></translation>
1407 </message>
1408 <message>
1409 <location filename="../configurefrm.ui" line="334"/>
1410 <source>Disable local &amp;download cache</source>
1411 <translation>Älä käytä välimuistia</translation>
1412 </message>
1413 <message>
1414 <source>O&amp;ffline mode</source>
1415 <translation type="obsolete">Yhteydetön tila</translation>
1416 </message>
1417 <message>
1418 <location filename="../configurefrm.ui" line="369"/>
1419 <source>Clean cache &amp;now</source>
1420 <translation>Tyhjennä välimuisti n&amp;yt</translation>
1421 </message>
1422 <message>
1423 <location filename="../configurefrm.ui" line="385"/>
1424 <source>&amp;TTS &amp;&amp; Encoder</source>
1425 <translation>Puhesyntetisaattori ja pakkaus</translation>
1426 </message>
1427 <message>
1428 <location filename="../configurefrm.ui" line="391"/>
1429 <source>TTS Engine</source>
1430 <translation>Puhesyntetisaattori</translation>
1431 </message>
1432 <message>
1433 <location filename="../configurefrm.ui" line="397"/>
1434 <source>&amp;Select TTS Engine</source>
1435 <translation>&amp;Valitse puhesyntetisaattori</translation>
1436 </message>
1437 <message>
1438 <location filename="../configurefrm.ui" line="410"/>
1439 <source>Configure TTS Engine</source>
1440 <translation>Määritä puhesyntetisaattorin asetukset</translation>
1441 </message>
1442 <message>
1443 <location filename="../configurefrm.ui" line="417"/>
1444 <location filename="../configurefrm.ui" line="468"/>
1445 <source>Configuration invalid!</source>
1446 <translation>Vialliset asetukset</translation>
1447 </message>
1448 <message>
1449 <location filename="../configurefrm.ui" line="434"/>
1450 <source>Configure &amp;TTS</source>
1451 <translation>Määritä puhesyntetisaattorin asetukset</translation>
1452 </message>
1453 <message>
1454 <location filename="../configurefrm.ui" line="445"/>
1455 <source>Test TTS</source>
1456 <translation type="unfinished"></translation>
1457 </message>
1458 <message>
1459 <location filename="../configurefrm.ui" line="452"/>
1460 <source>&amp;Use string corrections for TTS</source>
1461 <translation type="unfinished"></translation>
1462 </message>
1463 <message>
1464 <location filename="../configurefrm.ui" line="462"/>
1465 <source>Encoder Engine</source>
1466 <translation>Pakkausohjelma</translation>
1467 </message>
1468 <message>
1469 <location filename="../configurefrm.ui" line="485"/>
1470 <source>Configure &amp;Enc</source>
1471 <translation>Määritä pakkauksen asetukset</translation>
1472 </message>
1473 <message>
1474 <location filename="../configurefrm.ui" line="496"/>
1475 <source>encoder name</source>
1476 <translation>pakkausohjelman nimi</translation>
1477 </message>
1478 <message>
1479 <location filename="../configurefrm.ui" line="536"/>
1480 <source>&amp;Ok</source>
1481 <translation>&amp;Ok</translation>
1482 </message>
1483 <message>
1484 <location filename="../configurefrm.ui" line="547"/>
1485 <source>&amp;Cancel</source>
1486 <translation>&amp;Peruuta</translation>
1487 </message>
1488</context>
1489<context>
1490 <name>Configure</name>
1491 <message>
1492 <location filename="../configure.cpp" line="589"/>
1493 <source>English</source>
1494 <comment>This is the localized language name, i.e. your language.</comment>
1495 <translation>Suomi</translation>
1496 </message>
1497</context>
1498<context>
1499 <name>CreateVoiceFrm</name>
1500 <message>
1501 <location filename="../createvoicefrm.ui" line="17"/>
1502 <source>Create Voice File</source>
1503 <translation>Luo äänitiedosto</translation>
1504 </message>
1505 <message>
1506 <location filename="../createvoicefrm.ui" line="42"/>
1507 <source>Select the Language you want to generate a voicefile for:</source>
1508 <translation>Valitse kieli, jolle haluat tehdä äänitiedoston:</translation>
1509 </message>
1510 <message>
1511 <location filename="../createvoicefrm.ui" line="55"/>
1512 <source>TTS:</source>
1513 <translation type="unfinished"></translation>
1514 </message>
1515 <message>
1516 <location filename="../createvoicefrm.ui" line="101"/>
1517 <source>Silence threshold</source>
1518 <translation type="unfinished"></translation>
1519 </message>
1520 <message>
1521 <location filename="../createvoicefrm.ui" line="163"/>
1522 <source>Language</source>
1523 <translation type="unfinished"></translation>
1524 </message>
1525 <message>
1526 <location filename="../createvoicefrm.ui" line="49"/>
1527 <source>Generation settings</source>
1528 <translation>Luontiasetukset</translation>
1529 </message>
1530 <message>
1531 <location filename="../createvoicefrm.ui" line="68"/>
1532 <source>Change</source>
1533 <translation>Vaihda</translation>
1534 </message>
1535 <message>
1536 <location filename="../createvoicefrm.ui" line="139"/>
1537 <source>&amp;Install</source>
1538 <translation>&amp;Asenna</translation>
1539 </message>
1540 <message>
1541 <location filename="../createvoicefrm.ui" line="150"/>
1542 <source>&amp;Cancel</source>
1543 <translation>&amp;Peruuta</translation>
1544 </message>
1545 <message>
1546 <location filename="../createvoicefrm.ui" line="88"/>
1547 <source>Wavtrim Threshold</source>
1548 <translation type="unfinished"></translation>
1549 </message>
1550</context>
1551<context>
1552 <name>CreateVoiceWindow</name>
1553 <message>
1554 <location filename="../createvoicewindow.cpp" line="100"/>
1555 <source>TTS error</source>
1556 <translation type="unfinished"></translation>
1557 </message>
1558 <message>
1559 <location filename="../createvoicewindow.cpp" line="101"/>
1560 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1561 <translation type="unfinished"></translation>
1562 </message>
1563 <message>
1564 <location filename="../createvoicewindow.cpp" line="105"/>
1565 <location filename="../createvoicewindow.cpp" line="108"/>
1566 <source>Engine: &lt;b&gt;%1&lt;/b&gt;</source>
1567 <translation type="unfinished"></translation>
1568 </message>
1569</context>
1570<context>
1571 <name>EncTtsCfgGui</name>
1572 <message>
1573 <location filename="../encttscfggui.cpp" line="45"/>
1574 <source>Waiting for engine...</source>
1575 <translation type="unfinished"></translation>
1576 </message>
1577 <message>
1578 <location filename="../encttscfggui.cpp" line="95"/>
1579 <source>Ok</source>
1580 <translation type="unfinished"></translation>
1581 </message>
1582 <message>
1583 <location filename="../encttscfggui.cpp" line="98"/>
1584 <source>Cancel</source>
1585 <translation type="unfinished"></translation>
1586 </message>
1587 <message>
1588 <location filename="../encttscfggui.cpp" line="197"/>
1589 <source>Browse</source>
1590 <translation type="unfinished"></translation>
1591 </message>
1592 <message>
1593 <location filename="../encttscfggui.cpp" line="205"/>
1594 <source>Refresh</source>
1595 <translation type="unfinished"></translation>
1596 </message>
1597 <message>
1598 <location filename="../encttscfggui.cpp" line="377"/>
1599 <source>Select executable</source>
1600 <translation type="unfinished"></translation>
1601 </message>
1602</context>
1603<context>
1604 <name>EncoderExe</name>
1605 <message>
1606 <location filename="../base/encoderexe.cpp" line="41"/>
1607 <source>Path to Encoder:</source>
1608 <translation type="unfinished"></translation>
1609 </message>
1610 <message>
1611 <location filename="../base/encoderexe.cpp" line="43"/>
1612 <source>Encoder options:</source>
1613 <translation type="unfinished"></translation>
1614 </message>
1615</context>
1616<context>
1617 <name>EncoderLame</name>
1618 <message>
1619 <location filename="../base/encoderlame.cpp" line="73"/>
1620 <location filename="../base/encoderlame.cpp" line="83"/>
1621 <source>LAME</source>
1622 <translation type="unfinished"></translation>
1623 </message>
1624 <message>
1625 <location filename="../base/encoderlame.cpp" line="75"/>
1626 <source>Volume</source>
1627 <translation type="unfinished"></translation>
1628 </message>
1629 <message>
1630 <location filename="../base/encoderlame.cpp" line="79"/>
1631 <source>Quality</source>
1632 <translation type="unfinished"></translation>
1633 </message>
1634 <message>
1635 <location filename="../base/encoderlame.cpp" line="83"/>
1636 <source>Could not find libmp3lame!</source>
1637 <translation type="unfinished"></translation>
1638 </message>
1639</context>
1640<context>
1641 <name>EncoderRbSpeex</name>
1642 <message>
1643 <location filename="../base/encoderrbspeex.cpp" line="34"/>
1644 <source>Volume:</source>
1645 <translation type="unfinished"></translation>
1646 </message>
1647 <message>
1648 <location filename="../base/encoderrbspeex.cpp" line="36"/>
1649 <source>Quality:</source>
1650 <translation type="unfinished"></translation>
1651 </message>
1652 <message>
1653 <location filename="../base/encoderrbspeex.cpp" line="38"/>
1654 <source>Complexity:</source>
1655 <translation type="unfinished"></translation>
1656 </message>
1657 <message>
1658 <location filename="../base/encoderrbspeex.cpp" line="40"/>
1659 <source>Use Narrowband:</source>
1660 <translation type="unfinished"></translation>
1661 </message>
1662</context>
1663<context>
1664 <name>InfoWidget</name>
1665 <message>
1666 <location filename="../gui/infowidget.cpp" line="30"/>
1667 <location filename="../gui/infowidget.cpp" line="107"/>
1668 <source>File</source>
1669 <translation type="unfinished">Tiedosto</translation>
1670 </message>
1671 <message>
1672 <location filename="../gui/infowidget.cpp" line="30"/>
1673 <location filename="../gui/infowidget.cpp" line="107"/>
1674 <source>Version</source>
1675 <translation type="unfinished">Versio</translation>
1676 </message>
1677</context>
1678<context>
1679 <name>InfoWidgetFrm</name>
1680 <message>
1681 <location filename="../gui/infowidgetfrm.ui" line="14"/>
1682 <source>Info</source>
1683 <translation type="unfinished">Tietoja</translation>
1684 </message>
1685 <message>
1686 <location filename="../gui/infowidgetfrm.ui" line="20"/>
1687 <source>Currently installed packages.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; if you manually installed packages this might not be correct!</source>
1688 <translation type="unfinished">Asennetut paketit.&lt;br/&gt;&lt;b&gt;Huomaa:&lt;/b&gt; Jos olet asentanut paketteja käsin, tämä voi olla väärin!</translation>
1689 </message>
1690 <message>
1691 <location filename="../gui/infowidgetfrm.ui" line="34"/>
1692 <source>Package</source>
1693 <translation type="unfinished"></translation>
1694 </message>
1695</context>
1696<context>
1697 <name>InstallTalkFrm</name>
1698 <message>
1699 <location filename="../installtalkfrm.ui" line="17"/>
1700 <source>Install Talk Files</source>
1701 <translation>Asenna puhetiedostot</translation>
1702 </message>
1703 <message>
1704 <location filename="../installtalkfrm.ui" line="52"/>
1705 <source>Generate for files</source>
1706 <translation type="unfinished"></translation>
1707 </message>
1708 <message>
1709 <location filename="../installtalkfrm.ui" line="78"/>
1710 <source>TTS profile:</source>
1711 <translation>Puhesyntetisaattorin profiili:</translation>
1712 </message>
1713 <message>
1714 <location filename="../installtalkfrm.ui" line="85"/>
1715 <source>Generate for folders</source>
1716 <translation type="unfinished"></translation>
1717 </message>
1718 <message>
1719 <location filename="../installtalkfrm.ui" line="95"/>
1720 <source>Recurse into folders</source>
1721 <translation type="unfinished"></translation>
1722 </message>
1723 <message>
1724 <location filename="../installtalkfrm.ui" line="111"/>
1725 <source>Change</source>
1726 <translation>Vaihda</translation>
1727 </message>
1728 <message>
1729 <location filename="../installtalkfrm.ui" line="118"/>
1730 <source>Ignore files</source>
1731 <translation type="unfinished"></translation>
1732 </message>
1733 <message>
1734 <location filename="../installtalkfrm.ui" line="128"/>
1735 <source>Skip existing</source>
1736 <translation type="unfinished"></translation>
1737 </message>
1738 <message>
1739 <location filename="../installtalkfrm.ui" line="170"/>
1740 <source>Select folders for Talkfile generation (Ctrl for multiselect)</source>
1741 <translation type="unfinished"></translation>
1742 </message>
1743 <message>
1744 <location filename="../installtalkfrm.ui" line="36"/>
1745 <source>Generation options</source>
1746 <translation>Luontivalinnat</translation>
1747 </message>
1748 <message>
1749 <location filename="../installtalkfrm.ui" line="42"/>
1750 <source>Strip Extensions</source>
1751 <translation>Poista tiedostopäätteet</translation>
1752 </message>
1753 <message>
1754 <location filename="../installtalkfrm.ui" line="143"/>
1755 <source>&amp;Install</source>
1756 <translation>&amp;Asenna</translation>
1757 </message>
1758 <message>
1759 <location filename="../installtalkfrm.ui" line="154"/>
1760 <source>&amp;Cancel</source>
1761 <translation>&amp;Peruuta</translation>
1762 </message>
1763</context>
1764<context>
1765 <name>InstallTalkWindow</name>
1766 <message>
1767 <location filename="../installtalkwindow.cpp" line="96"/>
1768 <source>Empty selection</source>
1769 <translation type="unfinished"></translation>
1770 </message>
1771 <message>
1772 <location filename="../installtalkwindow.cpp" line="97"/>
1773 <source>No files or folders selected. Please select files or folders first.</source>
1774 <translation type="unfinished"></translation>
1775 </message>
1776 <message>
1777 <location filename="../installtalkwindow.cpp" line="137"/>
1778 <source>TTS error</source>
1779 <translation type="unfinished"></translation>
1780 </message>
1781 <message>
1782 <location filename="../installtalkwindow.cpp" line="138"/>
1783 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1784 <translation type="unfinished"></translation>
1785 </message>
1786</context>
1787<context>
1788 <name>ManualWidget</name>
1789 <message>
1790 <location filename="../gui/manualwidget.cpp" line="44"/>
1791 <source>&lt;a href=&apos;%1&apos;&gt;PDF Manual&lt;/a&gt;</source>
1792 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;PDF-ohjekirja (englanniksi)&lt;/a&gt;</translation>
1793 </message>
1794 <message>
1795 <location filename="../gui/manualwidget.cpp" line="46"/>
1796 <source>&lt;a href=&apos;%1&apos;&gt;HTML Manual (opens in browser)&lt;/a&gt;</source>
1797 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;HTML-ohjekirja (aukeaa selaimessa)&lt;/a&gt;</translation>
1798 </message>
1799 <message>
1800 <location filename="../gui/manualwidget.cpp" line="50"/>
1801 <source>Select a device for a link to the correct manual</source>
1802 <translation type="unfinished">Valitse laitteesi oikean laitteen ohjetta varten</translation>
1803 </message>
1804 <message>
1805 <location filename="../gui/manualwidget.cpp" line="51"/>
1806 <source>&lt;a href=&apos;%1&apos;&gt;Manual Overview&lt;/a&gt;</source>
1807 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Ohjekirjan yleiskuva&lt;/a&gt;</translation>
1808 </message>
1809 <message>
1810 <location filename="../gui/manualwidget.cpp" line="62"/>
1811 <source>Confirm download</source>
1812 <translation type="unfinished">Vahvista lataus</translation>
1813 </message>
1814 <message>
1815 <location filename="../gui/manualwidget.cpp" line="63"/>
1816 <source>Do you really want to download the manual? The manual will be saved to the root folder of your player.</source>
1817 <translation type="unfinished">Haluatko varmasti ladata ohjekirjan? Ohjekirja tallennetaan soittimeesi.</translation>
1818 </message>
1819</context>
1820<context>
1821 <name>ManualWidgetFrm</name>
1822 <message>
1823 <location filename="../gui/manualwidgetfrm.ui" line="14"/>
1824 <source>Manual</source>
1825 <translation type="unfinished"></translation>
1826 </message>
1827 <message>
1828 <location filename="../gui/manualwidgetfrm.ui" line="20"/>
1829 <source>Read the manual</source>
1830 <translation type="unfinished">Lue ohjekirjaa</translation>
1831 </message>
1832 <message>
1833 <location filename="../gui/manualwidgetfrm.ui" line="26"/>
1834 <source>PDF manual</source>
1835 <translation type="unfinished">PDF-ohjekirja</translation>
1836 </message>
1837 <message>
1838 <location filename="../gui/manualwidgetfrm.ui" line="39"/>
1839 <source>HTML manual</source>
1840 <translation type="unfinished">HTML-ohjekirja</translation>
1841 </message>
1842 <message>
1843 <location filename="../gui/manualwidgetfrm.ui" line="55"/>
1844 <source>Download the manual</source>
1845 <translation type="unfinished">Lataa ohjekirja</translation>
1846 </message>
1847 <message>
1848 <location filename="../gui/manualwidgetfrm.ui" line="63"/>
1849 <source>&amp;PDF version</source>
1850 <translation type="unfinished">&amp;PDF-versio</translation>
1851 </message>
1852 <message>
1853 <location filename="../gui/manualwidgetfrm.ui" line="70"/>
1854 <source>&amp;HTML version (zip file)</source>
1855 <translation type="unfinished">&amp;HTML-versio (zip-pakattu)</translation>
1856 </message>
1857 <message>
1858 <location filename="../gui/manualwidgetfrm.ui" line="92"/>
1859 <source>Down&amp;load</source>
1860 <translation type="unfinished">&amp;Lataa</translation>
1861 </message>
1862</context>
1863<context>
1864 <name>MsPackUtil</name>
1865 <message>
1866 <location filename="../base/mspackutil.cpp" line="101"/>
1867 <source>Creating output path failed</source>
1868 <translation type="unfinished"></translation>
1869 </message>
1870 <message>
1871 <location filename="../base/mspackutil.cpp" line="109"/>
1872 <source>Error during CAB operation</source>
1873 <translation type="unfinished"></translation>
1874 </message>
1875</context>
1876<context>
1877 <name>PreviewFrm</name>
1878 <message>
1879 <location filename="../previewfrm.ui" line="16"/>
1880 <source>Preview</source>
1881 <translation>Esikatselu</translation>
1882 </message>
1883</context>
1884<context>
1885 <name>ProgressLoggerFrm</name>
1886 <message>
1887 <location filename="../progressloggerfrm.ui" line="13"/>
1888 <location filename="../progressloggerfrm.ui" line="19"/>
1889 <source>Progress</source>
1890 <translation>Eteneminen</translation>
1891 </message>
1892 <message>
1893 <location filename="../progressloggerfrm.ui" line="58"/>
1894 <source>Save Log</source>
1895 <translation type="unfinished"></translation>
1896 </message>
1897 <message>
1898 <location filename="../progressloggerfrm.ui" line="82"/>
1899 <source>&amp;Abort</source>
1900 <translation>&amp;Keskeytä</translation>
1901 </message>
1902 <message>
1903 <location filename="../progressloggerfrm.ui" line="32"/>
1904 <source>progresswindow</source>
1905 <translation type="unfinished"></translation>
1906 </message>
1907</context>
1908<context>
1909 <name>ProgressLoggerGui</name>
1910 <message>
1911 <location filename="../progressloggergui.cpp" line="122"/>
1912 <source>&amp;Ok</source>
1913 <translation></translation>
1914 </message>
1915 <message>
1916 <location filename="../progressloggergui.cpp" line="146"/>
1917 <source>Save system trace log</source>
1918 <translation type="unfinished"></translation>
1919 </message>
1920 <message>
1921 <location filename="../progressloggergui.cpp" line="104"/>
1922 <source>&amp;Abort</source>
1923 <translation>&amp;Keskeytä</translation>
1924 </message>
1925</context>
1926<context>
1927 <name>QObject</name>
1928 <message>
1929 <location filename="../configure.cpp" line="625"/>
1930 <location filename="../main.cpp" line="83"/>
1931 <source>LTR</source>
1932 <extracomment>This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.
1933----------
1934This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.</extracomment>
1935 <translation type="unfinished"></translation>
1936 </message>
1937 <message>
1938 <location filename="../base/system.cpp" line="385"/>
1939 <source>(unknown vendor name) </source>
1940 <translation type="unfinished"></translation>
1941 </message>
1942 <message>
1943 <location filename="../base/system.cpp" line="403"/>
1944 <source>(unknown product name)</source>
1945 <translation type="unfinished"></translation>
1946 </message>
1947 <message>
1948 <location filename="../base/bootloaderinstallhelper.cpp" line="80"/>
1949 <source>Bootloader installation is almost complete. Installation &lt;b&gt;requires&lt;/b&gt; you to perform the following steps manually:</source>
1950 <translation type="unfinished"></translation>
1951 </message>
1952 <message>
1953 <location filename="../base/bootloaderinstallhelper.cpp" line="86"/>
1954 <source>&lt;li&gt;Safely remove your player.&lt;/li&gt;</source>
1955 <translation type="unfinished"></translation>
1956 </message>
1957 <message>
1958 <location filename="../base/bootloaderinstallhelper.cpp" line="91"/>
1959 <source>&lt;li&gt;Reboot your player into the original firmware.&lt;/li&gt;&lt;li&gt;Perform a firmware upgrade using the update functionality of the original firmware. Please refer to your player&apos;s manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before starting the firmware update process.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1960 <translation type="unfinished"></translation>
1961 </message>
1962 <message>
1963 <location filename="../base/bootloaderinstallhelper.cpp" line="102"/>
1964 <source>&lt;li&gt;Remove any previously inserted microSD card&lt;/li&gt;</source>
1965 <translation type="unfinished"></translation>
1966 </message>
1967 <message>
1968 <location filename="../base/bootloaderinstallhelper.cpp" line="103"/>
1969 <source>&lt;li&gt;Disconnect your player. The player will reboot and perform an update of the original firmware. Please refer to your players manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before disconnecting the player.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1970 <translation type="unfinished"></translation>
1971 </message>
1972 <message>
1973 <location filename="../base/bootloaderinstallhelper.cpp" line="114"/>
1974 <source>&lt;li&gt;Turn the player off&lt;/li&gt;&lt;li&gt;Insert the charger&lt;/li&gt;</source>
1975 <translation type="unfinished"></translation>
1976 </message>
1977 <message>
1978 <location filename="../base/bootloaderinstallhelper.cpp" line="119"/>
1979 <source>&lt;li&gt;Unplug USB and power adaptors&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to turn the player off&lt;/li&gt;&lt;li&gt;Toggle the battery switch on the player&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to boot into Rockbox&lt;/li&gt;</source>
1980 <translation type="unfinished"></translation>
1981 </message>
1982 <message>
1983 <location filename="../base/bootloaderinstallhelper.cpp" line="125"/>
1984 <source>&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You can safely install other parts first, but the above steps are &lt;b&gt;required&lt;/b&gt; to finish the installation!&lt;/p&gt;</source>
1985 <translation type="unfinished"></translation>
1986 </message>
1987</context>
1988<context>
1989 <name>QuaZipFile</name>
1990 <message>
1991 <location filename="../quazip/quazipfile.cpp" line="141"/>
1992 <source>ZIP/UNZIP API error %1</source>
1993 <translation type="unfinished"></translation>
1994 </message>
1995</context>
1996<context>
1997 <name>RbUtilQt</name>
1998 <message>
1999 <location filename="../rbutilqt.cpp" line="329"/>
2000 <source>New installation</source>
2001 <translation>Uusi asennus</translation>
2002 </message>
2003 <message>
2004 <location filename="../rbutilqt.cpp" line="330"/>
2005 <source>This is a new installation of Rockbox Utility, or a new version. The configuration dialog will now open to allow you to setup the program, or review your settings.</source>
2006 <translation>Tämä on uusi asennus tai uusi versio. Asetusikkuna aukeaa ja voit tehdä ja tarkistaa asetukset.</translation>
2007 </message>
2008 <message>
2009 <location filename="../rbutilqt.cpp" line="337"/>
2010 <location filename="../rbutilqt.cpp" line="642"/>
2011 <source>Configuration error</source>
2012 <translation>Asetusvirhe</translation>
2013 </message>
2014 <message>
2015 <location filename="../rbutilqt.cpp" line="338"/>
2016 <source>Your configuration is invalid. This is most likely due to a changed device path. The configuration dialog will now open to allow you to correct the problem.</source>
2017 <translation>Asetuksesi eivät ole kunnossa. Yleensä tämä johtuu vaihtuneesta laitteen osoitteesta. Asetusikkuna aukeaa, voit korjata asetukset siitä.</translation>
2018 </message>
2019 <message>
2020 <location filename="../rbutilqt.cpp" line="224"/>
2021 <source>Downloading build information, please wait ...</source>
2022 <translation type="unfinished"></translation>
2023 </message>
2024 <message>
2025 <location filename="../rbutilqt.cpp" line="235"/>
2026 <source>Can&apos;t get version information!</source>
2027 <translation type="unfinished"></translation>
2028 </message>
2029 <message>
2030 <location filename="../rbutilqt.cpp" line="237"/>
2031 <source>Can&apos;t get version information.
2032Network error: %1. Please check your network and proxy settings.</source>
2033 <translation type="unfinished"></translation>
2034 </message>
2035 <message>
2036 <location filename="../rbutilqt.cpp" line="249"/>
2037 <source>Download build information finished.</source>
2038 <translation type="unfinished"></translation>
2039 </message>
2040 <message>
2041 <location filename="../rbutilqt.cpp" line="450"/>
2042 <source>Confirm Installation</source>
2043 <translation>Vahvista asennus</translation>
2044 </message>
2045 <message>
2046 <location filename="../rbutilqt.cpp" line="582"/>
2047 <source>Mount point is wrong!</source>
2048 <translation>Liitospiste on väärin!</translation>
2049 </message>
2050 <message>
2051 <location filename="../rbutilqt.cpp" line="430"/>
2052 <source>No Rockbox installation found</source>
2053 <translation type="unfinished"></translation>
2054 </message>
2055 <message>
2056 <location filename="../rbutilqt.cpp" line="416"/>
2057 <source>Warning</source>
2058 <translation>Varoitus</translation>
2059 </message>
2060 <message>
2061 <location filename="../rbutilqt.cpp" line="417"/>
2062 <source>The Application is still downloading Information about new Builds. Please try again shortly.</source>
2063 <translation>Ohjelma lataa tietoja uusista versioista. Yritä uudelleen hetken päästä.</translation>
2064 </message>
2065 <message>
2066 <location filename="../rbutilqt.cpp" line="431"/>
2067 <source>Could not determine the installed Rockbox version. Please install a Rockbox build before installing voice files.</source>
2068 <translation type="unfinished"></translation>
2069 </message>
2070 <message>
2071 <location filename="../rbutilqt.cpp" line="451"/>
2072 <source>Do you really want to install the voice file?</source>
2073 <translation>Haluatko varmasti asentaa äänitiedoston?</translation>
2074 </message>
2075 <message>
2076 <location filename="../rbutilqt.cpp" line="439"/>
2077 <source>No voice file available</source>
2078 <translation type="unfinished"></translation>
2079 </message>
2080 <message>
2081 <location filename="../rbutilqt.cpp" line="440"/>
2082 <source>The installed version of Rockbox is a development version. Pre-built voices are only available for release versions of Rockbox. Please generate a voice yourself using the &quot;Create voice file&quot; functionality.</source>
2083 <translation type="unfinished"></translation>
2084 </message>
2085 <message>
2086 <location filename="../rbutilqt.cpp" line="512"/>
2087 <source>Confirm Uninstallation</source>
2088 <translation>Vahvista asennuksen poisto</translation>
2089 </message>
2090 <message>
2091 <location filename="../rbutilqt.cpp" line="513"/>
2092 <source>Do you really want to uninstall the Bootloader?</source>
2093 <translation>Haluatko varmasti poistaa käynnistyslataimen?</translation>
2094 </message>
2095 <message>
2096 <location filename="../rbutilqt.cpp" line="528"/>
2097 <source>No uninstall method for this target known.</source>
2098 <translation type="unfinished"></translation>
2099 </message>
2100 <message>
2101 <location filename="../rbutilqt.cpp" line="542"/>
2102 <source>Rockbox Utility can not uninstall the bootloader on this target. Try a normal firmware update to remove the booloader.</source>
2103 <translation type="unfinished"></translation>
2104 </message>
2105 <message>
2106 <location filename="../rbutilqt.cpp" line="550"/>
2107 <source>No Rockbox bootloader found.</source>
2108 <translation type="unfinished"></translation>
2109 </message>
2110 <message>
2111 <location filename="../rbutilqt.cpp" line="568"/>
2112 <source>Confirm installation</source>
2113 <translation>Vahvista asennus</translation>
2114 </message>
2115 <message>
2116 <location filename="../rbutilqt.cpp" line="569"/>
2117 <source>Do you really want to install Rockbox Utility to your player? After installation you can run it from the players hard drive.</source>
2118 <translation>Haluatko varmasti asentaa Rockbox Utilityn soittimeesi? Asennuksen jälkeen voit ajaa sen soittimeltasi.</translation>
2119 </message>
2120 <message>
2121 <location filename="../rbutilqt.cpp" line="578"/>
2122 <source>Installing Rockbox Utility</source>
2123 <translation>Asennetaan Rockbox Utilityä</translation>
2124 </message>
2125 <message>
2126 <location filename="../rbutilqt.cpp" line="596"/>
2127 <source>Error installing Rockbox Utility</source>
2128 <translation>Virhe asennettaessa Rockbox Utilityä</translation>
2129 </message>
2130 <message>
2131 <location filename="../rbutilqt.cpp" line="600"/>
2132 <source>Installing user configuration</source>
2133 <translation>Asennetaan käyttäjän asetuksia</translation>
2134 </message>
2135 <message>
2136 <location filename="../rbutilqt.cpp" line="604"/>
2137 <source>Error installing user configuration</source>
2138 <translation>Virhe asennettaessa käyttäjän asetuksia</translation>
2139 </message>
2140 <message>
2141 <location filename="../rbutilqt.cpp" line="608"/>
2142 <source>Successfully installed Rockbox Utility.</source>
2143 <translation>Rockbox Utility asennettu.</translation>
2144 </message>
2145 <message>
2146 <location filename="../rbutilqt.cpp" line="643"/>
2147 <source>Your configuration is invalid. Please go to the configuration dialog and make sure the selected values are correct.</source>
2148 <translation type="unfinished"></translation>
2149 </message>
2150 <message>
2151 <location filename="../rbutilqt.cpp" line="664"/>
2152 <source>Checking for update ...</source>
2153 <translation type="unfinished"></translation>
2154 </message>
2155 <message>
2156 <location filename="../rbutilqt.cpp" line="729"/>
2157 <source>RockboxUtility Update available</source>
2158 <translation type="unfinished"></translation>
2159 </message>
2160 <message>
2161 <location filename="../rbutilqt.cpp" line="730"/>
2162 <source>&lt;b&gt;New RockboxUtility Version available.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Download it from here: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</source>
2163 <translation type="unfinished"></translation>
2164 </message>
2165 <message>
2166 <location filename="../rbutilqt.cpp" line="733"/>
2167 <source>New version of Rockbox Utility available.</source>
2168 <translation type="unfinished"></translation>
2169 </message>
2170 <message>
2171 <location filename="../rbutilqt.cpp" line="736"/>
2172 <source>Rockbox Utility is up to date.</source>
2173 <translation type="unfinished"></translation>
2174 </message>
2175 <message>
2176 <location filename="../rbutilqt.cpp" line="759"/>
2177 <source>Device ejected</source>
2178 <translation type="unfinished"></translation>
2179 </message>
2180 <message>
2181 <location filename="../rbutilqt.cpp" line="760"/>
2182 <source>Device successfully ejected. You may now disconnect the player from the PC.</source>
2183 <translation type="unfinished"></translation>
2184 </message>
2185 <message>
2186 <location filename="../rbutilqt.cpp" line="764"/>
2187 <source>Ejecting failed</source>
2188 <translation type="unfinished"></translation>
2189 </message>
2190 <message>
2191 <location filename="../rbutilqt.cpp" line="765"/>
2192 <source>Ejecting the device failed. Please make sure no programs are accessing files on the device. If ejecting still fails please use your computers eject funtionality.</source>
2193 <translation type="unfinished"></translation>
2194 </message>
2195 <message>
2196 <location filename="../rbutilqt.cpp" line="110"/>
2197 <source>Wine detected!</source>
2198 <translation type="unfinished"></translation>
2199 </message>
2200 <message>
2201 <location filename="../rbutilqt.cpp" line="111"/>
2202 <source>It seems you are trying to run this program under Wine. Please don&apos;t do this, running under Wine will fail. Use the native Linux binary instead.</source>
2203 <translation type="unfinished"></translation>
2204 </message>
2205 <message>
2206 <location filename="../rbutilqt.cpp" line="236"/>
2207 <source>Network error</source>
2208 <translation type="unfinished"></translation>
2209 </message>
2210</context>
2211<context>
2212 <name>RbUtilQtFrm</name>
2213 <message>
2214 <location filename="../rbutilqtfrm.ui" line="14"/>
2215 <source>Rockbox Utility</source>
2216 <translation>Rockbox Utility</translation>
2217 </message>
2218 <message>
2219 <location filename="../rbutilqtfrm.ui" line="31"/>
2220 <source>Device</source>
2221 <translation>Laite</translation>
2222 </message>
2223 <message>
2224 <location filename="../rbutilqtfrm.ui" line="92"/>
2225 <source>&amp;Change</source>
2226 <translation>&amp;Vaihda</translation>
2227 </message>
2228 <message>
2229 <location filename="../rbutilqtfrm.ui" line="163"/>
2230 <source>Welcome</source>
2231 <translation>Tervetuloa</translation>
2232 </message>
2233 <message>
2234 <location filename="../rbutilqtfrm.ui" line="160"/>
2235 <location filename="../rbutilqtfrm.ui" line="658"/>
2236 <source>&amp;Installation</source>
2237 <translation>&amp;Asennus</translation>
2238 </message>
2239 <message>
2240 <location filename="../rbutilqtfrm.ui" line="168"/>
2241 <location filename="../rbutilqtfrm.ui" line="450"/>
2242 <source>&amp;Accessibility</source>
2243 <translation>Helppokäytt&amp;ötoiminnot</translation>
2244 </message>
2245 <message>
2246 <location filename="../rbutilqtfrm.ui" line="171"/>
2247 <source>Install accessibility add-ons</source>
2248 <translation>Asenna helppokäyttötoiminnot</translation>
2249 </message>
2250 <message>
2251 <location filename="../rbutilqtfrm.ui" line="177"/>
2252 <source>Install Voice files</source>
2253 <translation>Asenna äänitiedostot</translation>
2254 </message>
2255 <message>
2256 <location filename="../rbutilqtfrm.ui" line="194"/>
2257 <source>&lt;b&gt;Install Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so if you installed the voice file Rockbox will speak.</source>
2258 <translation>&lt;b&gt;Asenna äänitiedosto&lt;/b&gt;&lt;br/&gt;Äänitiedostoja tarvitaan, jos haluat Rockboxin puhuvan käyttöliittymän kohdat ääneen. Puhe on päällä oletuksena, joten pelkkien tiedostojen lataaminen riittää.</translation>
2259 </message>
2260 <message>
2261 <location filename="../rbutilqtfrm.ui" line="204"/>
2262 <source>Install Talk files</source>
2263 <translation>Asenna puhetiedostoja</translation>
2264 </message>
2265 <message>
2266 <location filename="../rbutilqtfrm.ui" line="221"/>
2267 <source>&lt;b&gt;Create Talk Files&lt;/b&gt;&lt;br/&gt;Talkfiles are needed to let Rockbox speak File and Foldernames</source>
2268 <translation>&lt;b&gt;Luo puhetiedostoja&lt;/b&gt;&lt;br/&gt;Puhetiedostoja tarvitaan, jos haluat Rockboxin puhuvan tiedosto- ja hakemistonimet</translation>
2269 </message>
2270 <message>
2271 <location filename="../rbutilqtfrm.ui" line="254"/>
2272 <source>Create Voice files</source>
2273 <translation>Luo äänitiedostot</translation>
2274 </message>
2275 <message>
2276 <location filename="../rbutilqtfrm.ui" line="271"/>
2277 <source>&lt;b&gt;Create Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so
2278 if you installed the voice file Rockbox will speak.</source>
2279 <translation>&lt;b&gt;Luo äänitiedosto&lt;/b&gt;&lt;br/&gt;Äänitiedostoja tarvitaan, jos haluat Rockboxin puhuvan käyttöliittymän kohdat ääneen. Puhe on päällä oletuksena, joten pelkkien tiedostojen lataaminen riittää.</translation>
2280 </message>
2281 <message>
2282 <location filename="../rbutilqtfrm.ui" line="458"/>
2283 <source>&amp;Uninstallation</source>
2284 <translation>Po&amp;isto</translation>
2285 </message>
2286 <message>
2287 <location filename="../rbutilqtfrm.ui" line="286"/>
2288 <location filename="../rbutilqtfrm.ui" line="319"/>
2289 <source>Uninstall Rockbox</source>
2290 <translation>Poista Rockbox</translation>
2291 </message>
2292 <message>
2293 <location filename="../rbutilqtfrm.ui" line="121"/>
2294 <source>mountpoint unknown or invalid</source>
2295 <translation type="unfinished"></translation>
2296 </message>
2297 <message>
2298 <location filename="../rbutilqtfrm.ui" line="114"/>
2299 <source>Mountpoint:</source>
2300 <translation type="unfinished"></translation>
2301 </message>
2302 <message>
2303 <location filename="../rbutilqtfrm.ui" line="72"/>
2304 <source>device unknown or invalid</source>
2305 <translation type="unfinished"></translation>
2306 </message>
2307 <message>
2308 <location filename="../rbutilqtfrm.ui" line="65"/>
2309 <source>Device:</source>
2310 <translation type="unfinished"></translation>
2311 </message>
2312 <message>
2313 <location filename="../rbutilqtfrm.ui" line="283"/>
2314 <source>Backup &amp;&amp; &amp;Uninstallation</source>
2315 <translation type="unfinished"></translation>
2316 </message>
2317 <message>
2318 <location filename="../rbutilqtfrm.ui" line="292"/>
2319 <source>Uninstall Bootloader</source>
2320 <translation>Poista käynnistyslatain</translation>
2321 </message>
2322 <message>
2323 <location filename="../rbutilqtfrm.ui" line="309"/>
2324 <source>&lt;b&gt;Remove the bootloader&lt;/b&gt;&lt;br/&gt;After removing the bootloader you won&apos;t be able to start Rockbox.</source>
2325 <translation>&lt;b&gt;Poista käynnistyslatain&lt;/b&gt;&lt;br/&gt;Poistamisen jälkeen et enää voi käynnistää Rockboxia.</translation>
2326 </message>
2327 <message>
2328 <location filename="../rbutilqtfrm.ui" line="336"/>
2329 <source>&lt;b&gt;Uninstall Rockbox from your audio player.&lt;/b&gt;&lt;br/&gt;This will leave the bootloader in place (you need to remove it manually).</source>
2330 <translation>&lt;b&gt;Poista Rockbox soittimestasi.&lt;/b&gt;&lt;br/&gt;Tämä jättää käynnistyslataimen (voit poistaa sen käsin).</translation>
2331 </message>
2332 <message>
2333 <location filename="../rbutilqtfrm.ui" line="349"/>
2334 <source>Backup</source>
2335 <translation type="unfinished">Varmuuskopioi</translation>
2336 </message>
2337 <message>
2338 <location filename="../rbutilqtfrm.ui" line="366"/>
2339 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup current installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Create a backup by archiving the contents of the Rockbox installation folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2340 <translation type="unfinished"></translation>
2341 </message>
2342 <message>
2343 <location filename="../rbutilqtfrm.ui" line="393"/>
2344 <source>&amp;Manual</source>
2345 <translation>O&amp;hjekirja</translation>
2346 </message>
2347 <message>
2348 <location filename="../rbutilqtfrm.ui" line="396"/>
2349 <source>View and download the manual</source>
2350 <translation>Näytä ja lataa ohjekirja</translation>
2351 </message>
2352 <message>
2353 <location filename="../rbutilqtfrm.ui" line="401"/>
2354 <source>Inf&amp;o</source>
2355 <translation>Tieto&amp;ja</translation>
2356 </message>
2357 <message>
2358 <location filename="../rbutilqtfrm.ui" line="419"/>
2359 <source>&amp;File</source>
2360 <translation>&amp;Tiedosto</translation>
2361 </message>
2362 <message>
2363 <location filename="../rbutilqtfrm.ui" line="653"/>
2364 <source>System &amp;Trace</source>
2365 <translation type="unfinished"></translation>
2366 </message>
2367 <message>
2368 <location filename="../rbutilqtfrm.ui" line="446"/>
2369 <source>Action&amp;s</source>
2370 <translation>Toiminnot</translation>
2371 </message>
2372 <message>
2373 <location filename="../rbutilqtfrm.ui" line="474"/>
2374 <source>Empty local download cache</source>
2375 <translation>Tyhjennä välimuisti</translation>
2376 </message>
2377 <message>
2378 <location filename="../rbutilqtfrm.ui" line="479"/>
2379 <source>Install Rockbox Utility on player</source>
2380 <translation>Asenna Rockbox Utility soittimeen</translation>
2381 </message>
2382 <message>
2383 <location filename="../rbutilqtfrm.ui" line="484"/>
2384 <source>&amp;Configure</source>
2385 <translation>Asetukset</translation>
2386 </message>
2387 <message>
2388 <location filename="../rbutilqtfrm.ui" line="489"/>
2389 <source>E&amp;xit</source>
2390 <translation>Poistu</translation>
2391 </message>
2392 <message>
2393 <location filename="../rbutilqtfrm.ui" line="492"/>
2394 <source>Ctrl+Q</source>
2395 <translation>Ctrl+Q</translation>
2396 </message>
2397 <message>
2398 <location filename="../rbutilqtfrm.ui" line="497"/>
2399 <source>&amp;About</source>
2400 <translation>Tietoja</translation>
2401 </message>
2402 <message>
2403 <location filename="../rbutilqtfrm.ui" line="502"/>
2404 <source>About &amp;Qt</source>
2405 <translation>Tietoja QT:stä</translation>
2406 </message>
2407 <message>
2408 <location filename="../rbutilqtfrm.ui" line="428"/>
2409 <location filename="../rbutilqtfrm.ui" line="507"/>
2410 <source>&amp;Help</source>
2411 <translation>Ohje</translation>
2412 </message>
2413 <message>
2414 <location filename="../rbutilqtfrm.ui" line="103"/>
2415 <source>&amp;Eject</source>
2416 <translation type="unfinished"></translation>
2417 </message>
2418 <message>
2419 <location filename="../rbutilqtfrm.ui" line="432"/>
2420 <source>&amp;Troubleshoot</source>
2421 <translation type="unfinished"></translation>
2422 </message>
2423 <message>
2424 <location filename="../rbutilqtfrm.ui" line="512"/>
2425 <source>Info</source>
2426 <translation>Tietoja</translation>
2427 </message>
2428 <message>
2429 <location filename="../rbutilqtfrm.ui" line="521"/>
2430 <source>&amp;Complete Installation</source>
2431 <translation>Täysasennus</translation>
2432 </message>
2433 <message>
2434 <location filename="../rbutilqtfrm.ui" line="539"/>
2435 <source>Install &amp;Bootloader</source>
2436 <translation>Asenna käynnistyslatain</translation>
2437 </message>
2438 <message>
2439 <location filename="../rbutilqtfrm.ui" line="548"/>
2440 <source>Install &amp;Rockbox</source>
2441 <translation>Asenna Rockbox</translation>
2442 </message>
2443 <message>
2444 <location filename="../rbutilqtfrm.ui" line="557"/>
2445 <source>Install &amp;Fonts Package</source>
2446 <translation>Asenna fonttipaketti</translation>
2447 </message>
2448 <message>
2449 <location filename="../rbutilqtfrm.ui" line="566"/>
2450 <source>Install &amp;Themes</source>
2451 <translation>Asenna teemoja</translation>
2452 </message>
2453 <message>
2454 <location filename="../rbutilqtfrm.ui" line="575"/>
2455 <source>Install &amp;Game Files</source>
2456 <translation>Asenna pelitiedostot</translation>
2457 </message>
2458 <message>
2459 <location filename="../rbutilqtfrm.ui" line="584"/>
2460 <source>&amp;Install Voice File</source>
2461 <translation>Asenna äänitiedostot</translation>
2462 </message>
2463 <message>
2464 <location filename="../rbutilqtfrm.ui" line="593"/>
2465 <source>Create &amp;Talk Files</source>
2466 <translation>Luo äänitiedostot</translation>
2467 </message>
2468 <message>
2469 <location filename="../rbutilqtfrm.ui" line="602"/>
2470 <source>Remove &amp;bootloader</source>
2471 <translation>Poista käynnistyslatain</translation>
2472 </message>
2473 <message>
2474 <location filename="../rbutilqtfrm.ui" line="611"/>
2475 <source>Uninstall &amp;Rockbox</source>
2476 <translation>Poista Rockbox</translation>
2477 </message>
2478 <message>
2479 <location filename="../rbutilqtfrm.ui" line="616"/>
2480 <source>Read PDF manual</source>
2481 <translation>Lue PDF-ohjekirjaa</translation>
2482 </message>
2483 <message>
2484 <location filename="../rbutilqtfrm.ui" line="621"/>
2485 <source>Read HTML manual</source>
2486 <translation>Lue HTML-ohjekirjaa</translation>
2487 </message>
2488 <message>
2489 <location filename="../rbutilqtfrm.ui" line="626"/>
2490 <source>Download PDF manual</source>
2491 <translation>Lataa PDF-ohjekirja</translation>
2492 </message>
2493 <message>
2494 <location filename="../rbutilqtfrm.ui" line="631"/>
2495 <source>Download HTML manual (zip)</source>
2496 <translation>Lataa HTML-ohjekirja (zip-pakattu)</translation>
2497 </message>
2498 <message>
2499 <location filename="../rbutilqtfrm.ui" line="640"/>
2500 <source>Create &amp;Voice File</source>
2501 <translation>Luo äänitiedosto</translation>
2502 </message>
2503 <message>
2504 <location filename="../rbutilqtfrm.ui" line="643"/>
2505 <source>Create Voice File</source>
2506 <translation>Luo äänitiedosto</translation>
2507 </message>
2508 <message>
2509 <location filename="../rbutilqtfrm.ui" line="648"/>
2510 <source>&amp;System Info</source>
2511 <translation>Järjestelmän tiedot</translation>
2512 </message>
2513 <message>
2514 <location filename="../rbutilqtfrm.ui" line="663"/>
2515 <source>Show &amp;Changelog</source>
2516 <translation type="unfinished"></translation>
2517 </message>
2518 <message>
2519 <location filename="../rbutilqtfrm.ui" line="530"/>
2520 <source>&amp;Minimal Installation</source>
2521 <translation type="unfinished"></translation>
2522 </message>
2523</context>
2524<context>
2525 <name>SelectiveInstallWidget</name>
2526 <message>
2527 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="20"/>
2528 <source>Selective Installation</source>
2529 <translation type="unfinished"></translation>
2530 </message>
2531 <message>
2532 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="26"/>
2533 <source>Rockbox version to install</source>
2534 <translation type="unfinished"></translation>
2535 </message>
2536 <message>
2537 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="35"/>
2538 <source>Version information not available yet.</source>
2539 <translation type="unfinished"></translation>
2540 </message>
2541 <message>
2542 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="54"/>
2543 <source>Rockbox components to install</source>
2544 <translation type="unfinished"></translation>
2545 </message>
2546 <message>
2547 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="60"/>
2548 <source>&amp;Bootloader</source>
2549 <translation type="unfinished"></translation>
2550 </message>
2551 <message>
2552 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="80"/>
2553 <source>The main Rockbox firmware.</source>
2554 <translation type="unfinished"></translation>
2555 </message>
2556 <message>
2557 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="90"/>
2558 <source>Fonts</source>
2559 <translation type="unfinished"></translation>
2560 </message>
2561 <message>
2562 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="104"/>
2563 <source>&amp;Rockbox</source>
2564 <translation type="unfinished"></translation>
2565 </message>
2566 <message>
2567 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="124"/>
2568 <source>Some game plugins require additional files.</source>
2569 <translation type="unfinished"></translation>
2570 </message>
2571 <message>
2572 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="140"/>
2573 <source>Additional fonts for the User Interface.</source>
2574 <translation type="unfinished"></translation>
2575 </message>
2576 <message>
2577 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="156"/>
2578 <source>The bootloader is required for starting Rockbox. Only necessary for first time install.</source>
2579 <translation type="unfinished"></translation>
2580 </message>
2581 <message>
2582 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="166"/>
2583 <source>Game Files</source>
2584 <translation type="unfinished"></translation>
2585 </message>
2586 <message>
2587 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="177"/>
2588 <source>Customize</source>
2589 <translation type="unfinished"></translation>
2590 </message>
2591 <message>
2592 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="188"/>
2593 <source>Themes</source>
2594 <translation type="unfinished"></translation>
2595 </message>
2596 <message>
2597 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="205"/>
2598 <source>Themes allow adjusting the user interface of Rockbox. Use &quot;Customize&quot; to select themes.</source>
2599 <translation type="unfinished"></translation>
2600 </message>
2601 <message>
2602 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="250"/>
2603 <source>&amp;Install</source>
2604 <translation type="unfinished">&amp;Asenna</translation>
2605 </message>
2606 <message>
2607 <location filename="../gui/selectiveinstallwidget.cpp" line="67"/>
2608 <source>This is the latest stable release available.</source>
2609 <translation type="unfinished"></translation>
2610 </message>
2611 <message>
2612 <location filename="../gui/selectiveinstallwidget.cpp" line="70"/>
2613 <source>The development version is updated on every code change. Last update was on %1</source>
2614 <translation type="unfinished"></translation>
2615 </message>
2616 <message>
2617 <location filename="../gui/selectiveinstallwidget.cpp" line="74"/>
2618 <source>This will eventually become the next Rockbox version. Install it to help testing.</source>
2619 <translation type="unfinished"></translation>
2620 </message>
2621 <message>
2622 <location filename="../gui/selectiveinstallwidget.cpp" line="100"/>
2623 <source>Stable Release (Version %1)</source>
2624 <translation type="unfinished"></translation>
2625 </message>
2626 <message>
2627 <location filename="../gui/selectiveinstallwidget.cpp" line="104"/>
2628 <source>Development Version (Revison %1)</source>
2629 <translation type="unfinished"></translation>
2630 </message>
2631 <message>
2632 <location filename="../gui/selectiveinstallwidget.cpp" line="108"/>
2633 <source>Release Candidate (Revison %1)</source>
2634 <translation type="unfinished"></translation>
2635 </message>
2636 <message>
2637 <location filename="../gui/selectiveinstallwidget.cpp" line="131"/>
2638 <source>The selected player doesn&apos;t need a bootloader.</source>
2639 <translation type="unfinished"></translation>
2640 </message>
2641 <message>
2642 <location filename="../gui/selectiveinstallwidget.cpp" line="136"/>
2643 <source>The bootloader is required for starting Rockbox. Installation of the bootloader is only necessary on first time installation.</source>
2644 <translation type="unfinished"></translation>
2645 </message>
2646 <message>
2647 <location filename="../gui/selectiveinstallwidget.cpp" line="183"/>
2648 <source>Mountpoint is wrong</source>
2649 <translation type="unfinished"></translation>
2650 </message>
2651 <message>
2652 <location filename="../gui/selectiveinstallwidget.cpp" line="239"/>
2653 <source>No install method known.</source>
2654 <translation type="unfinished"></translation>
2655 </message>
2656 <message>
2657 <location filename="../gui/selectiveinstallwidget.cpp" line="266"/>
2658 <source>Bootloader detected</source>
2659 <translation type="unfinished"></translation>
2660 </message>
2661 <message>
2662 <location filename="../gui/selectiveinstallwidget.cpp" line="267"/>
2663 <source>Bootloader already installed. Do you want to reinstall the bootloader?</source>
2664 <translation type="unfinished"></translation>
2665 </message>
2666 <message>
2667 <location filename="../gui/selectiveinstallwidget.cpp" line="271"/>
2668 <source>Bootloader installation skipped</source>
2669 <translation type="unfinished"></translation>
2670 </message>
2671 <message>
2672 <location filename="../gui/selectiveinstallwidget.cpp" line="284"/>
2673 <source>Create Bootloader backup</source>
2674 <translation type="unfinished"></translation>
2675 </message>
2676 <message>
2677 <location filename="../gui/selectiveinstallwidget.cpp" line="285"/>
2678 <source>You can create a backup of the original bootloader file. Press &quot;Yes&quot; to select an output folder on your computer to save the file to. The file will get placed in a new folder &quot;%1&quot; created below the selected folder.
2679Press &quot;No&quot; to skip this step.</source>
2680 <translation type="unfinished"></translation>
2681 </message>
2682 <message>
2683 <location filename="../gui/selectiveinstallwidget.cpp" line="292"/>
2684 <source>Browse backup folder</source>
2685 <translation type="unfinished"></translation>
2686 </message>
2687 <message>
2688 <location filename="../gui/selectiveinstallwidget.cpp" line="304"/>
2689 <source>Prerequisites</source>
2690 <translation type="unfinished"></translation>
2691 </message>
2692 <message>
2693 <location filename="../gui/selectiveinstallwidget.cpp" line="309"/>
2694 <source>Bootloader installation aborted</source>
2695 <translation type="unfinished"></translation>
2696 </message>
2697 <message>
2698 <location filename="../gui/selectiveinstallwidget.cpp" line="319"/>
2699 <source>Bootloader files (%1)</source>
2700 <translation type="unfinished"></translation>
2701 </message>
2702 <message>
2703 <location filename="../gui/selectiveinstallwidget.cpp" line="321"/>
2704 <source>All files (*)</source>
2705 <translation type="unfinished"></translation>
2706 </message>
2707 <message>
2708 <location filename="../gui/selectiveinstallwidget.cpp" line="323"/>
2709 <source>Select firmware file</source>
2710 <translation type="unfinished"></translation>
2711 </message>
2712 <message>
2713 <location filename="../gui/selectiveinstallwidget.cpp" line="325"/>
2714 <source>Error opening firmware file</source>
2715 <translation type="unfinished"></translation>
2716 </message>
2717 <message>
2718 <location filename="../gui/selectiveinstallwidget.cpp" line="331"/>
2719 <source>Error reading firmware file</source>
2720 <translation type="unfinished"></translation>
2721 </message>
2722 <message>
2723 <location filename="../gui/selectiveinstallwidget.cpp" line="341"/>
2724 <source>Backup error</source>
2725 <translation type="unfinished"></translation>
2726 </message>
2727 <message>
2728 <location filename="../gui/selectiveinstallwidget.cpp" line="342"/>
2729 <source>Could not create backup file. Continue?</source>
2730 <translation type="unfinished"></translation>
2731 </message>
2732 <message>
2733 <location filename="../gui/selectiveinstallwidget.cpp" line="366"/>
2734 <source>Manual steps required</source>
2735 <translation type="unfinished"></translation>
2736 </message>
2737 <message>
2738 <location filename="../gui/selectiveinstallwidget.cpp" line="171"/>
2739 <source>Continue with installation?</source>
2740 <translation type="unfinished"></translation>
2741 </message>
2742 <message>
2743 <location filename="../gui/selectiveinstallwidget.cpp" line="172"/>
2744 <source>Really continue?</source>
2745 <translation type="unfinished"></translation>
2746 </message>
2747 <message>
2748 <source>Aborted!</source>
2749 <translation type="obsolete">Keskeytetty!</translation>
2750 </message>
2751 <message>
2752 <location filename="../gui/selectiveinstallwidget.cpp" line="490"/>
2753 <source>Your installation doesn&apos;t require game files, skipping.</source>
2754 <translation type="unfinished"></translation>
2755 </message>
2756</context>
2757<context>
2758 <name>ServerInfo</name>
2759 <message>
2760 <location filename="../base/serverinfo.cpp" line="117"/>
2761 <source>Unknown</source>
2762 <translation type="unfinished"></translation>
2763 </message>
2764 <message>
2765 <location filename="../base/serverinfo.cpp" line="121"/>
2766 <source>Unusable</source>
2767 <translation type="unfinished"></translation>
2768 </message>
2769 <message>
2770 <location filename="../base/serverinfo.cpp" line="124"/>
2771 <source>Unstable</source>
2772 <translation type="unfinished"></translation>
2773 </message>
2774 <message>
2775 <location filename="../base/serverinfo.cpp" line="127"/>
2776 <source>Stable</source>
2777 <translation type="unfinished"></translation>
2778 </message>
2779</context>
2780<context>
2781 <name>SysTrace</name>
2782 <message>
2783 <location filename="../systrace.cpp" line="98"/>
2784 <location filename="../systrace.cpp" line="107"/>
2785 <source>Save system trace log</source>
2786 <translation type="unfinished"></translation>
2787 </message>
2788</context>
2789<context>
2790 <name>SysTraceFrm</name>
2791 <message>
2792 <location filename="../systracefrm.ui" line="14"/>
2793 <source>System Trace</source>
2794 <translation type="unfinished"></translation>
2795 </message>
2796 <message>
2797 <location filename="../systracefrm.ui" line="20"/>
2798 <source>System State trace</source>
2799 <translation type="unfinished"></translation>
2800 </message>
2801 <message>
2802 <location filename="../systracefrm.ui" line="46"/>
2803 <source>&amp;Close</source>
2804 <translation type="unfinished"></translation>
2805 </message>
2806 <message>
2807 <location filename="../systracefrm.ui" line="57"/>
2808 <source>&amp;Save</source>
2809 <translation type="unfinished"></translation>
2810 </message>
2811 <message>
2812 <location filename="../systracefrm.ui" line="68"/>
2813 <source>&amp;Refresh</source>
2814 <translation type="unfinished">&amp;Päivitä</translation>
2815 </message>
2816 <message>
2817 <location filename="../systracefrm.ui" line="79"/>
2818 <source>Save &amp;previous</source>
2819 <translation type="unfinished"></translation>
2820 </message>
2821</context>
2822<context>
2823 <name>Sysinfo</name>
2824 <message>
2825 <location filename="../sysinfo.cpp" line="45"/>
2826 <source>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</source>
2827 <translation>&lt;b&gt;Käyttöjärjestelmä&lt;/b&gt;&lt;br/&gt;</translation>
2828 </message>
2829 <message>
2830 <location filename="../sysinfo.cpp" line="46"/>
2831 <source>&lt;b&gt;Username&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2832 <translation type="unfinished"></translation>
2833 </message>
2834 <message>
2835 <location filename="../sysinfo.cpp" line="48"/>
2836 <source>&lt;b&gt;Permissions&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2837 <translation type="unfinished"></translation>
2838 </message>
2839 <message>
2840 <location filename="../sysinfo.cpp" line="50"/>
2841 <source>&lt;b&gt;Attached USB devices&lt;/b&gt;&lt;br/&gt;</source>
2842 <translation type="unfinished"></translation>
2843 </message>
2844 <message>
2845 <location filename="../sysinfo.cpp" line="54"/>
2846 <source>VID: %1 PID: %2, %3</source>
2847 <translation type="unfinished"></translation>
2848 </message>
2849 <message>
2850 <location filename="../sysinfo.cpp" line="63"/>
2851 <source>Filesystem</source>
2852 <translation type="unfinished"></translation>
2853 </message>
2854 <message>
2855 <location filename="../sysinfo.cpp" line="66"/>
2856 <source>Mountpoint</source>
2857 <translation type="unfinished"></translation>
2858 </message>
2859 <message>
2860 <location filename="../sysinfo.cpp" line="66"/>
2861 <source>Label</source>
2862 <translation type="unfinished"></translation>
2863 </message>
2864 <message>
2865 <location filename="../sysinfo.cpp" line="67"/>
2866 <source>Free</source>
2867 <translation type="unfinished"></translation>
2868 </message>
2869 <message>
2870 <location filename="../sysinfo.cpp" line="67"/>
2871 <source>Total</source>
2872 <translation type="unfinished"></translation>
2873 </message>
2874 <message>
2875 <location filename="../sysinfo.cpp" line="68"/>
2876 <source>Cluster Size</source>
2877 <translation type="unfinished"></translation>
2878 </message>
2879 <message>
2880 <location filename="../sysinfo.cpp" line="70"/>
2881 <source>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</source>
2882 <translation type="unfinished"></translation>
2883 </message>
2884</context>
2885<context>
2886 <name>SysinfoFrm</name>
2887 <message>
2888 <location filename="../sysinfofrm.ui" line="13"/>
2889 <source>System Info</source>
2890 <translation>Järjestelmän tiedot</translation>
2891 </message>
2892 <message>
2893 <location filename="../sysinfofrm.ui" line="22"/>
2894 <source>&amp;Refresh</source>
2895 <translation>&amp;Päivitä</translation>
2896 </message>
2897 <message>
2898 <location filename="../sysinfofrm.ui" line="45"/>
2899 <source>&amp;OK</source>
2900 <translation></translation>
2901 </message>
2902</context>
2903<context>
2904 <name>System</name>
2905 <message>
2906 <location filename="../base/system.cpp" line="121"/>
2907 <source>Guest</source>
2908 <translation type="unfinished">Vieras</translation>
2909 </message>
2910 <message>
2911 <location filename="../base/system.cpp" line="124"/>
2912 <source>Admin</source>
2913 <translation type="unfinished">Pääkäyttäjä</translation>
2914 </message>
2915 <message>
2916 <location filename="../base/system.cpp" line="127"/>
2917 <source>User</source>
2918 <translation type="unfinished">Käyttäjä</translation>
2919 </message>
2920 <message>
2921 <location filename="../base/system.cpp" line="130"/>
2922 <source>Error</source>
2923 <translation type="unfinished">Virhe</translation>
2924 </message>
2925 <message>
2926 <location filename="../base/system.cpp" line="278"/>
2927 <location filename="../base/system.cpp" line="323"/>
2928 <source>(no description available)</source>
2929 <translation type="unfinished">(ei kuvausta saatavilla)</translation>
2930 </message>
2931</context>
2932<context>
2933 <name>TTSBase</name>
2934 <message>
2935 <location filename="../base/ttsbase.cpp" line="45"/>
2936 <source>Espeak TTS Engine</source>
2937 <translation type="unfinished"></translation>
2938 </message>
2939 <message>
2940 <location filename="../base/ttsbase.cpp" line="47"/>
2941 <source>Flite TTS Engine</source>
2942 <translation type="unfinished"></translation>
2943 </message>
2944 <message>
2945 <location filename="../base/ttsbase.cpp" line="48"/>
2946 <source>Swift TTS Engine</source>
2947 <translation type="unfinished"></translation>
2948 </message>
2949 <message>
2950 <location filename="../base/ttsbase.cpp" line="51"/>
2951 <source>SAPI4 TTS Engine</source>
2952 <translation type="unfinished"></translation>
2953 </message>
2954 <message>
2955 <location filename="../base/ttsbase.cpp" line="53"/>
2956 <source>SAPI5 TTS Engine</source>
2957 <translation type="unfinished"></translation>
2958 </message>
2959 <message>
2960 <location filename="../base/ttsbase.cpp" line="54"/>
2961 <source>MS Speech Platform</source>
2962 <translation type="unfinished"></translation>
2963 </message>
2964 <message>
2965 <location filename="../base/ttsbase.cpp" line="57"/>
2966 <source>Festival TTS Engine</source>
2967 <translation type="unfinished"></translation>
2968 </message>
2969 <message>
2970 <location filename="../base/ttsbase.cpp" line="60"/>
2971 <source>OS X System Engine</source>
2972 <translation type="unfinished"></translation>
2973 </message>
2974</context>
2975<context>
2976 <name>TTSCarbon</name>
2977 <message>
2978 <location filename="../base/ttscarbon.cpp" line="139"/>
2979 <source>Voice:</source>
2980 <translation type="unfinished"></translation>
2981 </message>
2982 <message>
2983 <location filename="../base/ttscarbon.cpp" line="145"/>
2984 <source>Speed (words/min):</source>
2985 <translation type="unfinished"></translation>
2986 </message>
2987 <message>
2988 <location filename="../base/ttscarbon.cpp" line="152"/>
2989 <source>Pitch (0 for default):</source>
2990 <translation type="unfinished"></translation>
2991 </message>
2992 <message>
2993 <location filename="../base/ttscarbon.cpp" line="222"/>
2994 <source>Could not voice string</source>
2995 <translation type="unfinished"></translation>
2996 </message>
2997 <message>
2998 <location filename="../base/ttscarbon.cpp" line="232"/>
2999 <source>Could not convert intermediate file</source>
3000 <translation type="unfinished"></translation>
3001 </message>
3002</context>
3003<context>
3004 <name>TTSExes</name>
3005 <message>
3006 <location filename="../base/ttsexes.cpp" line="78"/>
3007 <source>TTS executable not found</source>
3008 <translation>Puhesyntetisaattoria ei löytynyt</translation>
3009 </message>
3010 <message>
3011 <location filename="../base/ttsexes.cpp" line="44"/>
3012 <source>Path to TTS engine:</source>
3013 <translation type="unfinished"></translation>
3014 </message>
3015 <message>
3016 <location filename="../base/ttsexes.cpp" line="46"/>
3017 <source>TTS engine options:</source>
3018 <translation type="unfinished"></translation>
3019 </message>
3020</context>
3021<context>
3022 <name>TTSFestival</name>
3023 <message>
3024 <location filename="../base/ttsfestival.cpp" line="207"/>
3025 <source>engine could not voice string</source>
3026 <translation type="unfinished"></translation>
3027 </message>
3028 <message>
3029 <location filename="../base/ttsfestival.cpp" line="290"/>
3030 <source>No description available</source>
3031 <translation type="unfinished"></translation>
3032 </message>
3033 <message>
3034 <location filename="../base/ttsfestival.cpp" line="53"/>
3035 <source>Path to Festival client:</source>
3036 <translation type="unfinished"></translation>
3037 </message>
3038 <message>
3039 <location filename="../base/ttsfestival.cpp" line="58"/>
3040 <source>Voice:</source>
3041 <translation type="unfinished"></translation>
3042 </message>
3043 <message>
3044 <location filename="../base/ttsfestival.cpp" line="67"/>
3045 <source>Voice description:</source>
3046 <translation type="unfinished"></translation>
3047 </message>
3048</context>
3049<context>
3050 <name>TTSSapi</name>
3051 <message>
3052 <location filename="../base/ttssapi.cpp" line="49"/>
3053 <source>Language:</source>
3054 <translation type="unfinished"></translation>
3055 </message>
3056 <message>
3057 <location filename="../base/ttssapi.cpp" line="56"/>
3058 <source>Voice:</source>
3059 <translation type="unfinished"></translation>
3060 </message>
3061 <message>
3062 <location filename="../base/ttssapi.cpp" line="68"/>
3063 <source>Speed:</source>
3064 <translation type="unfinished"></translation>
3065 </message>
3066 <message>
3067 <location filename="../base/ttssapi.cpp" line="71"/>
3068 <source>Options:</source>
3069 <translation type="unfinished"></translation>
3070 </message>
3071 <message>
3072 <location filename="../base/ttssapi.cpp" line="115"/>
3073 <source>Could not copy the SAPI script</source>
3074 <translation type="unfinished"></translation>
3075 </message>
3076 <message>
3077 <location filename="../base/ttssapi.cpp" line="133"/>
3078 <source>Could not start SAPI process</source>
3079 <translation type="unfinished"></translation>
3080 </message>
3081</context>
3082<context>
3083 <name>TalkFileCreator</name>
3084 <message>
3085 <location filename="../base/talkfile.cpp" line="68"/>
3086 <source>Copying Talkfiles...</source>
3087 <translation type="unfinished"></translation>
3088 </message>
3089 <message>
3090 <location filename="../base/talkfile.cpp" line="240"/>
3091 <source>File copy aborted</source>
3092 <translation type="unfinished"></translation>
3093 </message>
3094 <message>
3095 <location filename="../base/talkfile.cpp" line="280"/>
3096 <source>Cleaning up...</source>
3097 <translation type="unfinished"></translation>
3098 </message>
3099 <message>
3100 <location filename="../base/talkfile.cpp" line="291"/>
3101 <source>Finished</source>
3102 <translation type="unfinished"></translation>
3103 </message>
3104 <message>
3105 <location filename="../base/talkfile.cpp" line="45"/>
3106 <source>Talk file creation aborted</source>
3107 <translation>Puhetiedostojen luonti keskeytetty</translation>
3108 </message>
3109 <message>
3110 <location filename="../base/talkfile.cpp" line="36"/>
3111 <source>Starting Talk file generation for folder %1</source>
3112 <translation type="unfinished"></translation>
3113 </message>
3114 <message>
3115 <location filename="../base/talkfile.cpp" line="80"/>
3116 <source>Finished creating Talk files</source>
3117 <translation>Puhetiedostojen luonti valmis</translation>
3118 </message>
3119 <message>
3120 <location filename="../base/talkfile.cpp" line="42"/>
3121 <source>Reading Filelist...</source>
3122 <translation type="unfinished"></translation>
3123 </message>
3124 <message>
3125 <location filename="../base/talkfile.cpp" line="259"/>
3126 <source>Copying of %1 to %2 failed</source>
3127 <translation type="unfinished"></translation>
3128 </message>
3129</context>
3130<context>
3131 <name>TalkGenerator</name>
3132 <message>
3133 <location filename="../base/talkgenerator.cpp" line="39"/>
3134 <source>Starting TTS Engine</source>
3135 <translation type="unfinished"></translation>
3136 </message>
3137 <message>
3138 <location filename="../base/talkgenerator.cpp" line="44"/>
3139 <location filename="../base/talkgenerator.cpp" line="51"/>
3140 <source>Init of TTS engine failed</source>
3141 <translation type="unfinished">Puhesyntetisaattorin alustus epäonnistui</translation>
3142 </message>
3143 <message>
3144 <location filename="../base/talkgenerator.cpp" line="58"/>
3145 <source>Starting Encoder Engine</source>
3146 <translation type="unfinished"></translation>
3147 </message>
3148 <message>
3149 <location filename="../base/talkgenerator.cpp" line="62"/>
3150 <source>Init of Encoder engine failed</source>
3151 <translation type="unfinished">Pakkausohjelman alustus epäonnistui</translation>
3152 </message>
3153 <message>
3154 <location filename="../base/talkgenerator.cpp" line="72"/>
3155 <source>Voicing entries...</source>
3156 <translation type="unfinished"></translation>
3157 </message>
3158 <message>
3159 <location filename="../base/talkgenerator.cpp" line="87"/>
3160 <source>Encoding files...</source>
3161 <translation type="unfinished"></translation>
3162 </message>
3163 <message>
3164 <location filename="../base/talkgenerator.cpp" line="126"/>
3165 <source>Voicing aborted</source>
3166 <translation type="unfinished"></translation>
3167 </message>
3168 <message>
3169 <location filename="../base/talkgenerator.cpp" line="162"/>
3170 <location filename="../base/talkgenerator.cpp" line="167"/>
3171 <source>Voicing of %1 failed: %2</source>
3172 <translation type="unfinished"></translation>
3173 </message>
3174 <message>
3175 <location filename="../base/talkgenerator.cpp" line="211"/>
3176 <source>Encoding aborted</source>
3177 <translation type="unfinished"></translation>
3178 </message>
3179 <message>
3180 <location filename="../base/talkgenerator.cpp" line="239"/>
3181 <source>Encoding of %1 failed</source>
3182 <translation type="unfinished">Tiedoston %1 pakkaus epäonnistui</translation>
3183 </message>
3184</context>
3185<context>
3186 <name>ThemeInstallFrm</name>
3187 <message>
3188 <location filename="../themesinstallfrm.ui" line="13"/>
3189 <source>Theme Installation</source>
3190 <translation>Teeman asennus</translation>
3191 </message>
3192 <message>
3193 <location filename="../themesinstallfrm.ui" line="48"/>
3194 <source>Selected Theme</source>
3195 <translation>Valittu teema</translation>
3196 </message>
3197 <message>
3198 <location filename="../themesinstallfrm.ui" line="73"/>
3199 <source>Description</source>
3200 <translation>Kuvaus</translation>
3201 </message>
3202 <message>
3203 <location filename="../themesinstallfrm.ui" line="83"/>
3204 <source>Download size:</source>
3205 <translation>Ladattava:</translation>
3206 </message>
3207 <message>
3208 <location filename="../themesinstallfrm.ui" line="115"/>
3209 <source>&amp;Install</source>
3210 <translation>&amp;Asenna</translation>
3211 </message>
3212 <message>
3213 <location filename="../themesinstallfrm.ui" line="125"/>
3214 <source>&amp;Cancel</source>
3215 <translation>&amp;Peruuta</translation>
3216 </message>
3217 <message>
3218 <location filename="../themesinstallfrm.ui" line="93"/>
3219 <source>Hold Ctrl to select multiple item, Shift for a range</source>
3220 <translation type="unfinished"></translation>
3221 </message>
3222</context>
3223<context>
3224 <name>ThemesInstallWindow</name>
3225 <message>
3226 <location filename="../themesinstallwindow.cpp" line="40"/>
3227 <source>no theme selected</source>
3228 <translation>ei teemaa valittu</translation>
3229 </message>
3230 <message>
3231 <location filename="../themesinstallwindow.cpp" line="125"/>
3232 <source>Network error: %1.
3233Please check your network and proxy settings.</source>
3234 <translation>Verkkovirhe: %1
3235Tarkista verkko- ja välityspalvelinasetukset.</translation>
3236 </message>
3237 <message>
3238 <location filename="../themesinstallwindow.cpp" line="138"/>
3239 <source>the following error occured:
3240%1</source>
3241 <translation>seuraava virhe tapahtui:
3242%1</translation>
3243 </message>
3244 <message>
3245 <location filename="../themesinstallwindow.cpp" line="144"/>
3246 <source>done.</source>
3247 <translation>valmis.</translation>
3248 </message>
3249 <message>
3250 <location filename="../themesinstallwindow.cpp" line="211"/>
3251 <source>fetching details for %1</source>
3252 <translation>haetaan lisätietoja teemalle %1</translation>
3253 </message>
3254 <message>
3255 <location filename="../themesinstallwindow.cpp" line="214"/>
3256 <source>fetching preview ...</source>
3257 <translation>haetaan esikatselukuvaa ...</translation>
3258 </message>
3259 <message>
3260 <location filename="../themesinstallwindow.cpp" line="227"/>
3261 <source>&lt;b&gt;Author:&lt;/b&gt; %1&lt;hr/&gt;</source>
3262 <translation>&lt;b&gt;Tekijä:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3263 </message>
3264 <message>
3265 <location filename="../themesinstallwindow.cpp" line="228"/>
3266 <location filename="../themesinstallwindow.cpp" line="230"/>
3267 <source>unknown</source>
3268 <translation>tuntematon</translation>
3269 </message>
3270 <message>
3271 <location filename="../themesinstallwindow.cpp" line="229"/>
3272 <source>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</source>
3273 <translation>&lt;b&gt;Versio:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3274 </message>
3275 <message>
3276 <location filename="../themesinstallwindow.cpp" line="231"/>
3277 <source>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</source>
3278 <translation>&lt;b&gt;Kuvaus:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3279 </message>
3280 <message>
3281 <location filename="../themesinstallwindow.cpp" line="232"/>
3282 <source>no description</source>
3283 <translation>ei kuvausta</translation>
3284 </message>
3285 <message>
3286 <location filename="../themesinstallwindow.cpp" line="260"/>
3287 <source>no theme preview</source>
3288 <translation>ei esikatselukuvaa</translation>
3289 </message>
3290 <message>
3291 <location filename="../themesinstallwindow.cpp" line="289"/>
3292 <source>Select</source>
3293 <translation type="unfinished"></translation>
3294 </message>
3295 <message>
3296 <location filename="../themesinstallwindow.cpp" line="296"/>
3297 <source>getting themes information ...</source>
3298 <translation>haetaan teemojen tietoja ...</translation>
3299 </message>
3300 <message>
3301 <location filename="../themesinstallwindow.cpp" line="326"/>
3302 <source>No themes selected, skipping</source>
3303 <translation type="unfinished"></translation>
3304 </message>
3305 <message>
3306 <location filename="../themesinstallwindow.cpp" line="356"/>
3307 <source>Mount point is wrong!</source>
3308 <translation>Liitospiste on väärin!</translation>
3309 </message>
3310 <message>
3311 <location filename="../themesinstallwindow.cpp" line="41"/>
3312 <source>no selection</source>
3313 <translation type="unfinished"></translation>
3314 </message>
3315 <message>
3316 <location filename="../themesinstallwindow.cpp" line="181"/>
3317 <source>Information</source>
3318 <translation type="unfinished"></translation>
3319 </message>
3320 <message numerus="yes">
3321 <location filename="../themesinstallwindow.cpp" line="198"/>
3322 <source>Download size %L1 kiB (%n item(s))</source>
3323 <translation type="unfinished">
3324 <numerusform></numerusform>
3325 </translation>
3326 </message>
3327 <message>
3328 <location filename="../themesinstallwindow.cpp" line="248"/>
3329 <source>Retrieving theme preview failed.
3330HTTP response code: %1</source>
3331 <translation type="unfinished"></translation>
3332 </message>
3333</context>
3334<context>
3335 <name>UninstallFrm</name>
3336 <message>
3337 <location filename="../uninstallfrm.ui" line="16"/>
3338 <source>Uninstall Rockbox</source>
3339 <translation>Poista Rockbox</translation>
3340 </message>
3341 <message>
3342 <location filename="../uninstallfrm.ui" line="68"/>
3343 <source>Please select what you want to uninstall</source>
3344 <translation>Valitse osat, jotka haluat poistaa</translation>
3345 </message>
3346 <message>
3347 <location filename="../uninstallfrm.ui" line="128"/>
3348 <source>&amp;Uninstall</source>
3349 <translation>&amp;Poista</translation>
3350 </message>
3351 <message>
3352 <location filename="../uninstallfrm.ui" line="35"/>
3353 <source>Please select the Uninstallation Method</source>
3354 <translation>Valitse poistotapa</translation>
3355 </message>
3356 <message>
3357 <location filename="../uninstallfrm.ui" line="45"/>
3358 <source>Uninstallation Method</source>
3359 <translation>Poistotapa</translation>
3360 </message>
3361 <message>
3362 <location filename="../uninstallfrm.ui" line="51"/>
3363 <source>Complete Uninstallation</source>
3364 <translation>Kaikki pois</translation>
3365 </message>
3366 <message>
3367 <location filename="../uninstallfrm.ui" line="58"/>
3368 <source>Smart Uninstallation</source>
3369 <translation>Älykäs poisto</translation>
3370 </message>
3371 <message>
3372 <location filename="../uninstallfrm.ui" line="78"/>
3373 <source>Installed Parts</source>
3374 <translation>Asennetut osat</translation>
3375 </message>
3376 <message>
3377 <location filename="../uninstallfrm.ui" line="138"/>
3378 <source>&amp;Cancel</source>
3379 <translation>&amp;Peruuta</translation>
3380 </message>
3381</context>
3382<context>
3383 <name>Uninstaller</name>
3384 <message>
3385 <location filename="../base/uninstall.cpp" line="109"/>
3386 <source>Uninstallation finished</source>
3387 <translation>Poisto valmis</translation>
3388 </message>
3389 <message>
3390 <location filename="../base/uninstall.cpp" line="32"/>
3391 <location filename="../base/uninstall.cpp" line="43"/>
3392 <source>Starting Uninstallation</source>
3393 <translation>Aloitetaan poistoa</translation>
3394 </message>
3395 <message>
3396 <location filename="../base/uninstall.cpp" line="36"/>
3397 <source>Finished Uninstallation</source>
3398 <translation>Poisto valmis</translation>
3399 </message>
3400 <message>
3401 <location filename="../base/uninstall.cpp" line="49"/>
3402 <source>Uninstalling %1...</source>
3403 <translation type="unfinished"></translation>
3404 </message>
3405 <message>
3406 <location filename="../base/uninstall.cpp" line="80"/>
3407 <source>Could not delete %1</source>
3408 <translation type="unfinished"></translation>
3409 </message>
3410</context>
3411<context>
3412 <name>Utils</name>
3413 <message>
3414 <location filename="../base/utils.cpp" line="312"/>
3415 <source>&lt;li&gt;Permissions insufficient for bootloader installation.
3416Administrator priviledges are necessary.&lt;/li&gt;</source>
3417 <translation type="unfinished"></translation>
3418 </message>
3419 <message>
3420 <location filename="../base/utils.cpp" line="324"/>
3421 <source>&lt;li&gt;Target mismatch detected.&lt;br/&gt;Installed target: %1&lt;br/&gt;Selected target: %2.&lt;/li&gt;</source>
3422 <translation type="unfinished"></translation>
3423 </message>
3424 <message>
3425 <location filename="../base/utils.cpp" line="331"/>
3426 <source>Problem detected:</source>
3427 <translation type="unfinished"></translation>
3428 </message>
3429</context>
3430<context>
3431 <name>VoiceFileCreator</name>
3432 <message>
3433 <location filename="../base/voicefile.cpp" line="43"/>
3434 <source>Starting Voicefile generation</source>
3435 <translation>Aloitetaan äänitiedostojen luontia</translation>
3436 </message>
3437 <message>
3438 <location filename="../base/voicefile.cpp" line="90"/>
3439 <source>Extracted voice strings from installation</source>
3440 <translation type="unfinished"></translation>
3441 </message>
3442 <message>
3443 <location filename="../base/voicefile.cpp" line="100"/>
3444 <source>Extracted voice strings incompatible</source>
3445 <translation type="unfinished"></translation>
3446 </message>
3447 <message>
3448 <location filename="../base/voicefile.cpp" line="145"/>
3449 <source>Could not retrieve strings from installation, downloading</source>
3450 <translation type="unfinished"></translation>
3451 </message>
3452 <message>
3453 <location filename="../base/voicefile.cpp" line="171"/>
3454 <source>Downloading voice info...</source>
3455 <translation type="unfinished"></translation>
3456 </message>
3457 <message>
3458 <location filename="../base/voicefile.cpp" line="184"/>
3459 <source>Download error: received HTTP error %1.</source>
3460 <translation>Latausvirhe: HTTP-virhe %1.</translation>
3461 </message>
3462 <message>
3463 <location filename="../base/voicefile.cpp" line="191"/>
3464 <source>Cached file used.</source>
3465 <translation>Käytetään välimuistissa olevaa tiedostoa.</translation>
3466 </message>
3467 <message>
3468 <location filename="../base/voicefile.cpp" line="194"/>
3469 <source>Download error: %1</source>
3470 <translation>Latausvirhe: %1</translation>
3471 </message>
3472 <message>
3473 <location filename="../base/voicefile.cpp" line="199"/>
3474 <source>Download finished.</source>
3475 <translation>Lataus valmis.</translation>
3476 </message>
3477 <message>
3478 <location filename="../base/voicefile.cpp" line="212"/>
3479 <source>failed to open downloaded file</source>
3480 <translation>ladattua tiedostoa ei voitu avata</translation>
3481 </message>
3482 <message>
3483 <location filename="../base/voicefile.cpp" line="218"/>
3484 <source>Reading strings...</source>
3485 <translation type="unfinished"></translation>
3486 </message>
3487 <message>
3488 <location filename="../base/voicefile.cpp" line="297"/>
3489 <source>Creating voicefiles...</source>
3490 <translation type="unfinished"></translation>
3491 </message>
3492 <message>
3493 <location filename="../base/voicefile.cpp" line="342"/>
3494 <source>Cleaning up...</source>
3495 <translation type="unfinished"></translation>
3496 </message>
3497 <message>
3498 <location filename="../base/voicefile.cpp" line="353"/>
3499 <source>Finished</source>
3500 <translation type="unfinished"></translation>
3501 </message>
3502 <message>
3503 <location filename="../base/voicefile.cpp" line="271"/>
3504 <source>The downloaded file was empty!</source>
3505 <translation>Ladattu tiedosto oli tyhjä!</translation>
3506 </message>
3507 <message>
3508 <location filename="../base/voicefile.cpp" line="302"/>
3509 <source>Error opening downloaded file</source>
3510 <translation>Virhe avattaessa ladattua tiedostoa</translation>
3511 </message>
3512 <message>
3513 <location filename="../base/voicefile.cpp" line="313"/>
3514 <source>Error opening output file</source>
3515 <translation>Virhe avattaessa kohdetiedostoa</translation>
3516 </message>
3517 <message>
3518 <location filename="../base/voicefile.cpp" line="333"/>
3519 <source>successfully created.</source>
3520 <translation>luotu.</translation>
3521 </message>
3522 <message>
3523 <location filename="../base/voicefile.cpp" line="56"/>
3524 <source>could not find rockbox-info.txt</source>
3525 <translation type="unfinished"></translation>
3526 </message>
3527</context>
3528<context>
3529 <name>ZipInstaller</name>
3530 <message>
3531 <location filename="../base/zipinstaller.cpp" line="60"/>
3532 <source>done.</source>
3533 <translation>valmis.</translation>
3534 </message>
3535 <message>
3536 <location filename="../base/zipinstaller.cpp" line="68"/>
3537 <source>Package installation finished successfully.</source>
3538 <translation type="unfinished"></translation>
3539 </message>
3540 <message>
3541 <location filename="../base/zipinstaller.cpp" line="80"/>
3542 <source>Downloading file %1.%2</source>
3543 <translation>Ladataan tiedostoa %1.%2</translation>
3544 </message>
3545 <message>
3546 <location filename="../base/zipinstaller.cpp" line="115"/>
3547 <source>Download error: received HTTP error %1.</source>
3548 <translation>Latausvirhe: HTTP-virhe %1.</translation>
3549 </message>
3550 <message>
3551 <location filename="../base/zipinstaller.cpp" line="121"/>
3552 <source>Cached file used.</source>
3553 <translation>Käytetään välimuistissa olevaa tiedostoa.</translation>
3554 </message>
3555 <message>
3556 <location filename="../base/zipinstaller.cpp" line="123"/>
3557 <source>Download error: %1</source>
3558 <translation>Latausvirhe: %1</translation>
3559 </message>
3560 <message>
3561 <location filename="../base/zipinstaller.cpp" line="127"/>
3562 <source>Download finished.</source>
3563 <translation>Lataus valmis.</translation>
3564 </message>
3565 <message>
3566 <location filename="../base/zipinstaller.cpp" line="133"/>
3567 <source>Extracting file.</source>
3568 <translation>Puretaan tiedostoa.</translation>
3569 </message>
3570 <message>
3571 <location filename="../base/zipinstaller.cpp" line="153"/>
3572 <source>Extraction failed!</source>
3573 <translation type="unfinished"></translation>
3574 </message>
3575 <message>
3576 <location filename="../base/zipinstaller.cpp" line="162"/>
3577 <source>Installing file.</source>
3578 <translation>Asennetaan tiedostoa.</translation>
3579 </message>
3580 <message>
3581 <location filename="../base/zipinstaller.cpp" line="173"/>
3582 <source>Installing file failed.</source>
3583 <translation>Tiedoston asentaminen epäonnistui.</translation>
3584 </message>
3585 <message>
3586 <location filename="../base/zipinstaller.cpp" line="186"/>
3587 <source>Creating installation log</source>
3588 <translation>Luodaan lokitiedostoa asennuksesta</translation>
3589 </message>
3590 <message>
3591 <location filename="../base/zipinstaller.cpp" line="146"/>
3592 <source>Not enough disk space! Aborting.</source>
3593 <translation type="unfinished"></translation>
3594 </message>
3595</context>
3596<context>
3597 <name>ZipUtil</name>
3598 <message>
3599 <location filename="../base/ziputil.cpp" line="125"/>
3600 <source>Creating output path failed</source>
3601 <translation type="unfinished"></translation>
3602 </message>
3603 <message>
3604 <location filename="../base/ziputil.cpp" line="132"/>
3605 <source>Creating output file failed</source>
3606 <translation type="unfinished"></translation>
3607 </message>
3608 <message>
3609 <location filename="../base/ziputil.cpp" line="141"/>
3610 <source>Error during Zip operation</source>
3611 <translation type="unfinished"></translation>
3612 </message>
3613</context>
3614<context>
3615 <name>aboutBox</name>
3616 <message>
3617 <location filename="../aboutbox.ui" line="14"/>
3618 <source>About Rockbox Utility</source>
3619 <translation>Tietoja Rockbox Utilitystä</translation>
3620 </message>
3621 <message>
3622 <location filename="../aboutbox.ui" line="32"/>
3623 <source>The Rockbox Utility</source>
3624 <translation></translation>
3625 </message>
3626 <message utf8="true">
3627 <location filename="../aboutbox.ui" line="54"/>
3628 <source>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</source>
3629 <translation type="unfinished"></translation>
3630 </message>
3631 <message>
3632 <location filename="../aboutbox.ui" line="106"/>
3633 <source>&amp;License</source>
3634 <translation>&amp;Lisenssi</translation>
3635 </message>
3636 <message>
3637 <location filename="../aboutbox.ui" line="132"/>
3638 <source>&amp;Speex License</source>
3639 <translation type="unfinished"></translation>
3640 </message>
3641 <message>
3642 <location filename="../aboutbox.ui" line="158"/>
3643 <source>&amp;Ok</source>
3644 <translation>&amp;Ok</translation>
3645 </message>
3646 <message>
3647 <location filename="../aboutbox.ui" line="74"/>
3648 <source>&amp;Credits</source>
3649 <translation>&amp;Tietoja</translation>
3650 </message>
3651</context>
3652</TS>
diff --git a/utils/rbutilqt/lang/rbutil_fr.ts b/utils/rbutilqt/lang/rbutil_fr.ts
new file mode 100644
index 0000000000..f2104e1666
--- /dev/null
+++ b/utils/rbutilqt/lang/rbutil_fr.ts
@@ -0,0 +1,3701 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE TS>
3<TS version="2.0" language="fr">
4<context>
5 <name>BackupDialog</name>
6 <message>
7 <location filename="../gui/backupdialogfrm.ui" line="17"/>
8 <location filename="../gui/backupdialogfrm.ui" line="43"/>
9 <source>Backup</source>
10 <translation>Sauvegarde</translation>
11 </message>
12 <message>
13 <location filename="../gui/backupdialogfrm.ui" line="33"/>
14 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This dialog will create a backup by archiving the contents of the Rockbox installation on the player into a zip file. This will include installed themes and settings stored below the .rockbox folder on the player.&lt;/p&gt;&lt;p&gt;The backup filename will be created based on the installed version. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
15 <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Cette fenêtre va créer une sauvegarde de votre installation de Rockbox en archivant le contenu du lecteur dans un fichier zip. Ceci inclut les thèmes installés ainsi que les fichiers de configuration stockés sous le répertoire .rocbox du lecteur.&lt;/p&gt;&lt;p&gt;Le nom du fichier de sauvegarde sera généré à partir de la version installée.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
16 </message>
17 <message>
18 <location filename="../gui/backupdialogfrm.ui" line="49"/>
19 <source>Size: unknown</source>
20 <translation>Taille: inconnue</translation>
21 </message>
22 <message>
23 <location filename="../gui/backupdialogfrm.ui" line="56"/>
24 <source>Backup to: unknown</source>
25 <translation>Sauvegarde sous: inconnu</translation>
26 </message>
27 <message>
28 <location filename="../gui/backupdialogfrm.ui" line="76"/>
29 <source>&amp;Change</source>
30 <translation>&amp;Modifier</translation>
31 </message>
32 <message>
33 <location filename="../gui/backupdialogfrm.ui" line="116"/>
34 <source>&amp;Backup</source>
35 <translation>&amp;Sauvegarder</translation>
36 </message>
37 <message>
38 <location filename="../gui/backupdialogfrm.ui" line="127"/>
39 <source>&amp;Cancel</source>
40 <translation>&amp;Annuler</translation>
41 </message>
42 <message>
43 <location filename="../gui/backupdialog.cpp" line="70"/>
44 <source>Installation size: calculating ...</source>
45 <translation>Taille de l&apos;installation: calcul en cours...</translation>
46 </message>
47 <message>
48 <location filename="../gui/backupdialog.cpp" line="89"/>
49 <source>Select Backup Filename</source>
50 <translation>Sélectionnez un fichier de sauvegarde</translation>
51 </message>
52 <message>
53 <location filename="../gui/backupdialog.cpp" line="109"/>
54 <source>Installation size: %L1 %2</source>
55 <translation>Taille de l&apos;installation: %L1 %2</translation>
56 </message>
57 <message>
58 <location filename="../gui/backupdialog.cpp" line="116"/>
59 <source>File exists</source>
60 <translation>Fichier existant</translation>
61 </message>
62 <message>
63 <location filename="../gui/backupdialog.cpp" line="117"/>
64 <source>The selected backup file already exists. Overwrite?</source>
65 <translation>Le fichier sélectionné existe déjà. Voulez-vous vraiment l&apos;écraser ?</translation>
66 </message>
67 <message>
68 <location filename="../gui/backupdialog.cpp" line="125"/>
69 <source>Starting backup ...</source>
70 <translation>Démarrage de la sauvegarde ...</translation>
71 </message>
72 <message>
73 <location filename="../gui/backupdialog.cpp" line="144"/>
74 <source>Backup successful.</source>
75 <translation>Sauvegarde effectuée avec succès.</translation>
76 </message>
77 <message>
78 <location filename="../gui/backupdialog.cpp" line="147"/>
79 <source>Backup failed!</source>
80 <translation>La sauvegarde a échoué !</translation>
81 </message>
82</context>
83<context>
84 <name>BootloaderInstallAms</name>
85 <message>
86 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
87 <translation type="obsolete">L&apos;installation du bootloader nécessite que vous fournissiez une copie du firmware original (fichier bin). Ce firmware sera alors modifié et installé sur votre lecteur avec le bootloader de Rockbox. Vous devez télécharger ce fichier par vous-même pour des raisons légales. Veuillez vous référer au &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Forums de Sansa&lt;/a&gt; ou au &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manuel&lt;/a&gt; et à la page wiki &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; pour obtenir ce fichier.&lt;br/&gt;Appuyez sur Ok pour continuer et parcourir les fichiers sur votre ordinateur pour indiquer le fichier du firmware.</translation>
88 </message>
89 <message>
90 <location filename="../base/bootloaderinstallams.cpp" line="33"/>
91 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; This file is not present on your player and will disappear automatically after installing it.&lt;br/&gt;&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
92 <translation>L&apos;installation du bootloader nécessite que vous fournissiez une copie du firmware original (fichier bin). Ce firmware sera alors modifié et installé sur votre lecteur avec le bootloader de Rockbox. Vous devez télécharger ce fichier par vous-même pour des raisons légales. Veuillez vous référer aux &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Forums de Sansa&lt;/a&gt; ou au &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manuel&lt;/a&gt; et à la page wiki &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; pour obtenir ce fichier.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt;Ce fichier n&apos;est pas présent sur votre lecteur et disparaîtra automatiquement après l&apos;avoir installé.&lt;/br/&gt;&lt;br/&gt;Appuyez sur Ok pour continuer et parcourir les fichiers sur votre ordinateur pour indiquer le fichier du firmware.</translation>
93 </message>
94 <message>
95 <location filename="../base/bootloaderinstallams.cpp" line="58"/>
96 <source>Downloading bootloader file</source>
97 <translation>Téléchargement du bootloader</translation>
98 </message>
99 <message>
100 <location filename="../base/bootloaderinstallams.cpp" line="100"/>
101 <location filename="../base/bootloaderinstallams.cpp" line="113"/>
102 <source>Could not load %1</source>
103 <translation>Impossible de charger %1</translation>
104 </message>
105 <message>
106 <location filename="../base/bootloaderinstallams.cpp" line="127"/>
107 <source>No room to insert bootloader, try another firmware version</source>
108 <translation>Il n&apos;y a pas assez d&apos;espace pour insérer le bootloader, veuillez essayer une autre version du firmware</translation>
109 </message>
110 <message>
111 <location filename="../base/bootloaderinstallams.cpp" line="137"/>
112 <source>Patching Firmware...</source>
113 <translation>Modification du firmware...</translation>
114 </message>
115 <message>
116 <location filename="../base/bootloaderinstallams.cpp" line="148"/>
117 <source>Could not open %1 for writing</source>
118 <translation>Impossible d&apos;ouvrir %1 en écriture</translation>
119 </message>
120 <message>
121 <location filename="../base/bootloaderinstallams.cpp" line="161"/>
122 <source>Could not write firmware file</source>
123 <translation>Ecriture du firmware impossible</translation>
124 </message>
125 <message>
126 <location filename="../base/bootloaderinstallams.cpp" line="177"/>
127 <source>Success: modified firmware file created</source>
128 <translation>Le firmware a été modifié avec succès</translation>
129 </message>
130 <message>
131 <location filename="../base/bootloaderinstallams.cpp" line="185"/>
132 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
133 <translation>Pour le désinstaller, faites une mise à jour normale avec un firmware non modifié</translation>
134 </message>
135</context>
136<context>
137 <name>BootloaderInstallBase</name>
138 <message>
139 <location filename="../base/bootloaderinstallbase.cpp" line="78"/>
140 <source>Download error: received HTTP error %1.</source>
141 <translation>Erreur lors du téléchargement: erreur HTTP %1.</translation>
142 </message>
143 <message>
144 <location filename="../base/bootloaderinstallbase.cpp" line="84"/>
145 <source>Download error: %1</source>
146 <translation>Erreur lors du téléchargement : %1</translation>
147 </message>
148 <message>
149 <location filename="../base/bootloaderinstallbase.cpp" line="90"/>
150 <source>Download finished (cache used).</source>
151 <translation>Téléchargement terminé (la version du cache a été utilisée).</translation>
152 </message>
153 <message>
154 <location filename="../base/bootloaderinstallbase.cpp" line="92"/>
155 <source>Download finished.</source>
156 <translation>Téléchargement terminé.</translation>
157 </message>
158 <message>
159 <location filename="../base/bootloaderinstallbase.cpp" line="113"/>
160 <source>Creating backup of original firmware file.</source>
161 <translation>Création d&apos;une sauvegarde du firmware original.</translation>
162 </message>
163 <message>
164 <location filename="../base/bootloaderinstallbase.cpp" line="115"/>
165 <source>Creating backup folder failed</source>
166 <translation>La création du dossier de sauvegarde a échoué</translation>
167 </message>
168 <message>
169 <location filename="../base/bootloaderinstallbase.cpp" line="121"/>
170 <source>Creating backup copy failed.</source>
171 <translation>La création de la sauvegarde a échoué.</translation>
172 </message>
173 <message>
174 <location filename="../base/bootloaderinstallbase.cpp" line="124"/>
175 <source>Backup created.</source>
176 <translation>Sauvegarde effectuée.</translation>
177 </message>
178 <message>
179 <location filename="../base/bootloaderinstallbase.cpp" line="137"/>
180 <source>Creating installation log</source>
181 <translation>Création du journal d&apos;installation</translation>
182 </message>
183 <message>
184 <location filename="../base/bootloaderinstallbase.cpp" line="226"/>
185 <source>Zip file format detected</source>
186 <translation>Fichier au format zip détecté</translation>
187 </message>
188 <message>
189 <location filename="../base/bootloaderinstallbase.cpp" line="238"/>
190 <source>CAB file format detected</source>
191 <translation>Format de fichier CAB détecté</translation>
192 </message>
193 <message>
194 <location filename="../base/bootloaderinstallbase.cpp" line="259"/>
195 <source>Extracting firmware %1 from archive</source>
196 <translation>Extraction du firmware %1 depuis l&apos;archive</translation>
197 </message>
198 <message>
199 <location filename="../base/bootloaderinstallbase.cpp" line="266"/>
200 <source>Error extracting firmware from archive</source>
201 <translation>Erreur lors de l&apos;extraction du firmware depuis l&apos;archive</translation>
202 </message>
203 <message>
204 <location filename="../base/bootloaderinstallbase.cpp" line="275"/>
205 <source>Could not find firmware in archive</source>
206 <translation>Impossible de trouver le firmware original dans l&apos;archive</translation>
207 </message>
208 <message>
209 <location filename="../base/bootloaderinstallbase.cpp" line="159"/>
210 <source>Waiting for system to remount player</source>
211 <translation>Attend que le système ait remonté le lecteur</translation>
212 </message>
213 <message>
214 <location filename="../base/bootloaderinstallbase.cpp" line="189"/>
215 <source>Player remounted</source>
216 <translation>Le lecteur audio a été remonté</translation>
217 </message>
218 <message>
219 <location filename="../base/bootloaderinstallbase.cpp" line="194"/>
220 <source>Timeout on remount</source>
221 <translation>Le délai d&apos;attente lors du remontage a expiré</translation>
222 </message>
223 <message>
224 <location filename="../base/bootloaderinstallbase.cpp" line="149"/>
225 <source>Installation log created</source>
226 <translation>Le journal d&apos;installation a été crée</translation>
227 </message>
228</context>
229<context>
230 <name>BootloaderInstallChinaChip</name>
231 <message>
232 <location filename="../base/bootloaderinstallchinachip.cpp" line="33"/>
233 <source>Bootloader installation requires you to provide a firmware file of the original firmware (HXF file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
234 <translation>L&apos;installation du bootloader nécessite que vous fournissiez un fichier contenant le firmware original (fichier HXF). Vous devez télécharger ce fichier par vous-même pour des raisons légales. Veuillez consulter le &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manuel&lt;/a&gt; ou la page wiki &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; pour savoir comment obtenir ce fichier.&lt;br/&gt;Appuyez sur Ok pour continuer et parcourir les fichiers de votre ordinateur pour selectionner le fichier du firmware.</translation>
235 </message>
236 <message>
237 <location filename="../base/bootloaderinstallchinachip.cpp" line="50"/>
238 <source>Downloading bootloader file</source>
239 <translation>Téléchargement du fichier bootloader</translation>
240 </message>
241 <message>
242 <location filename="../base/bootloaderinstallchinachip.cpp" line="75"/>
243 <source>Could not open firmware file</source>
244 <translation>Impossible d&apos;ouvrir le fichier du firmware</translation>
245 </message>
246 <message>
247 <location filename="../base/bootloaderinstallchinachip.cpp" line="78"/>
248 <source>Could not open bootloader file</source>
249 <translation>impossible d&apos;ouvrir le fichier du bootloader</translation>
250 </message>
251 <message>
252 <location filename="../base/bootloaderinstallchinachip.cpp" line="81"/>
253 <source>Could not allocate memory</source>
254 <translation>Impossible d&apos;allouer de la mémoire</translation>
255 </message>
256 <message>
257 <location filename="../base/bootloaderinstallchinachip.cpp" line="84"/>
258 <source>Could not load firmware file</source>
259 <translation>Impossible de charger le fichier du firmware</translation>
260 </message>
261 <message>
262 <location filename="../base/bootloaderinstallchinachip.cpp" line="87"/>
263 <source>File is not a valid ChinaChip firmware</source>
264 <translation>Ce fichier n&apos;est un firmware ChinaChip valide</translation>
265 </message>
266 <message>
267 <location filename="../base/bootloaderinstallchinachip.cpp" line="90"/>
268 <source>Could not find ccpmp.bin in input file</source>
269 <translation>Impossible de trouver ccpmp.bin dans le fichier d&apos;entrée</translation>
270 </message>
271 <message>
272 <location filename="../base/bootloaderinstallchinachip.cpp" line="93"/>
273 <source>Could not open backup file for ccpmp.bin</source>
274 <translation>Impossible d&apos;ouvrir le fichier de sauvegarder de ccpmp.bin</translation>
275 </message>
276 <message>
277 <location filename="../base/bootloaderinstallchinachip.cpp" line="96"/>
278 <source>Could not write backup file for ccpmp.bin</source>
279 <translation>Impossible d&apos;écrire le fichier de sauvegarde de ccpmp.bin</translation>
280 </message>
281 <message>
282 <location filename="../base/bootloaderinstallchinachip.cpp" line="99"/>
283 <source>Could not load bootloader file</source>
284 <translation>Impossible de charger le fichier du bootloader</translation>
285 </message>
286 <message>
287 <location filename="../base/bootloaderinstallchinachip.cpp" line="102"/>
288 <source>Could not get current time</source>
289 <translation>Impossible d&apos;obtenir l&apos;heure actuelle</translation>
290 </message>
291 <message>
292 <location filename="../base/bootloaderinstallchinachip.cpp" line="105"/>
293 <source>Could not open output file</source>
294 <translation>Impossible d&apos;ouvrir le fichier de sortie</translation>
295 </message>
296 <message>
297 <location filename="../base/bootloaderinstallchinachip.cpp" line="108"/>
298 <source>Could not write output file</source>
299 <translation>Impossible d&apos;écrire le fichier de sortie</translation>
300 </message>
301 <message>
302 <location filename="../base/bootloaderinstallchinachip.cpp" line="111"/>
303 <source>Unexpected error from chinachippatcher</source>
304 <translation>Erreur inattendue retournée par chinachippatcher</translation>
305 </message>
306</context>
307<context>
308 <name>BootloaderInstallFile</name>
309 <message>
310 <location filename="../base/bootloaderinstallfile.cpp" line="34"/>
311 <source>Downloading bootloader</source>
312 <translation>Téléchargement du bootloader</translation>
313 </message>
314 <message>
315 <location filename="../base/bootloaderinstallfile.cpp" line="43"/>
316 <source>Installing Rockbox bootloader</source>
317 <translation>Installation du bootloader de Rockbox</translation>
318 </message>
319 <message>
320 <location filename="../base/bootloaderinstallfile.cpp" line="75"/>
321 <source>Error accessing output folder</source>
322 <translation>Erreur lors de l&apos;accès au dossier de sortie</translation>
323 </message>
324 <message>
325 <location filename="../base/bootloaderinstallfile.cpp" line="89"/>
326 <source>A firmware file is already present on player</source>
327 <translation>Un fichier contenant le firmware est déjà présent sur le lecteur</translation>
328 </message>
329 <message>
330 <location filename="../base/bootloaderinstallfile.cpp" line="94"/>
331 <source>Bootloader successful installed</source>
332 <translation>Le bootloader a été installé avec succès</translation>
333 </message>
334 <message>
335 <location filename="../base/bootloaderinstallfile.cpp" line="97"/>
336 <source>Copying modified firmware file failed</source>
337 <translation>Erreur lors de la copie du firmware modifié</translation>
338 </message>
339 <message>
340 <location filename="../base/bootloaderinstallfile.cpp" line="111"/>
341 <source>Removing Rockbox bootloader</source>
342 <translation>Suppression du bootloader de Rockbox</translation>
343 </message>
344 <message>
345 <location filename="../base/bootloaderinstallfile.cpp" line="115"/>
346 <source>No original firmware file found.</source>
347 <translation>Aucun firmware original n&apos;a été trouvé.</translation>
348 </message>
349 <message>
350 <location filename="../base/bootloaderinstallfile.cpp" line="121"/>
351 <source>Can&apos;t remove Rockbox bootloader file.</source>
352 <translation>Impossible de supprimer le bootloader de Rockbox.</translation>
353 </message>
354 <message>
355 <location filename="../base/bootloaderinstallfile.cpp" line="126"/>
356 <source>Can&apos;t restore bootloader file.</source>
357 <translation>Impossible de restaurer le fichier bootloader.</translation>
358 </message>
359 <message>
360 <location filename="../base/bootloaderinstallfile.cpp" line="130"/>
361 <source>Original bootloader restored successfully.</source>
362 <translation>Le bootloader original a été restauré avec succès.</translation>
363 </message>
364</context>
365<context>
366 <name>BootloaderInstallHex</name>
367 <message>
368 <location filename="../base/bootloaderinstallhex.cpp" line="69"/>
369 <source>checking MD5 hash of input file ...</source>
370 <translation>vérification de l&apos;empreinte MD5 du fichier d&apos;entrée...</translation>
371 </message>
372 <message>
373 <location filename="../base/bootloaderinstallhex.cpp" line="80"/>
374 <source>Could not verify original firmware file</source>
375 <translation>Impossible de vérifier le firmware original</translation>
376 </message>
377 <message>
378 <location filename="../base/bootloaderinstallhex.cpp" line="95"/>
379 <source>Firmware file not recognized.</source>
380 <translation>Le firmware n&apos;a pas été reconnu.</translation>
381 </message>
382 <message>
383 <location filename="../base/bootloaderinstallhex.cpp" line="99"/>
384 <source>MD5 hash ok</source>
385 <translation>L&apos;empreinte MD5 est correcte</translation>
386 </message>
387 <message>
388 <location filename="../base/bootloaderinstallhex.cpp" line="106"/>
389 <source>Firmware file doesn&apos;t match selected player.</source>
390 <translation>Le firmware ne correspond pas au lecteur audio choisi.</translation>
391 </message>
392 <message>
393 <location filename="../base/bootloaderinstallhex.cpp" line="111"/>
394 <source>Descrambling file</source>
395 <translation>Débrouillage du fichier</translation>
396 </message>
397 <message>
398 <location filename="../base/bootloaderinstallhex.cpp" line="119"/>
399 <source>Error in descramble: %1</source>
400 <translation>Erreur lors du débrouillage : %1</translation>
401 </message>
402 <message>
403 <location filename="../base/bootloaderinstallhex.cpp" line="124"/>
404 <source>Downloading bootloader file</source>
405 <translation>Téléchargement du fichier bootloader</translation>
406 </message>
407 <message>
408 <location filename="../base/bootloaderinstallhex.cpp" line="134"/>
409 <source>Adding bootloader to firmware file</source>
410 <translation>Ajout du bootloader au fichier firmware</translation>
411 </message>
412 <message>
413 <location filename="../base/bootloaderinstallhex.cpp" line="172"/>
414 <source>could not open input file</source>
415 <translation>impossible d&apos;ouvrir le fichier d&apos;entrée</translation>
416 </message>
417 <message>
418 <location filename="../base/bootloaderinstallhex.cpp" line="173"/>
419 <source>reading header failed</source>
420 <translation>la lecture de l&apos;en-tête a échoué</translation>
421 </message>
422 <message>
423 <location filename="../base/bootloaderinstallhex.cpp" line="174"/>
424 <source>reading firmware failed</source>
425 <translation>la lecture du firmware a échoué</translation>
426 </message>
427 <message>
428 <location filename="../base/bootloaderinstallhex.cpp" line="175"/>
429 <source>can&apos;t open bootloader file</source>
430 <translation>impossible d&apos;ouvrir le fichier bootloader</translation>
431 </message>
432 <message>
433 <location filename="../base/bootloaderinstallhex.cpp" line="176"/>
434 <source>reading bootloader file failed</source>
435 <translation>la lecture du fichier bootloader a échoué</translation>
436 </message>
437 <message>
438 <location filename="../base/bootloaderinstallhex.cpp" line="177"/>
439 <source>can&apos;t open output file</source>
440 <translation>impossible d&apos;ouvrir le fichier de sortie</translation>
441 </message>
442 <message>
443 <location filename="../base/bootloaderinstallhex.cpp" line="178"/>
444 <source>writing output file failed</source>
445 <translation>l&apos;écriture du fichier de sortie a échoué</translation>
446 </message>
447 <message>
448 <location filename="../base/bootloaderinstallhex.cpp" line="180"/>
449 <source>Error in patching: %1</source>
450 <translation>Erreur lors de la modification : %1</translation>
451 </message>
452 <message>
453 <location filename="../base/bootloaderinstallhex.cpp" line="191"/>
454 <source>Error in scramble: %1</source>
455 <translation>Erreur lors du brouillage: %1</translation>
456 </message>
457 <message>
458 <location filename="../base/bootloaderinstallhex.cpp" line="206"/>
459 <source>Checking modified firmware file</source>
460 <translation>Vérification du firmware modifié</translation>
461 </message>
462 <message>
463 <location filename="../base/bootloaderinstallhex.cpp" line="208"/>
464 <source>Error: modified file checksum wrong</source>
465 <translation>Erreur: la somme de contrôle du fichier est incorrecte</translation>
466 </message>
467 <message>
468 <location filename="../base/bootloaderinstallhex.cpp" line="215"/>
469 <source>A firmware file is already present on player</source>
470 <translation>Un fichier contenant le firmware est déjà présent sur le lecteur</translation>
471 </message>
472 <message>
473 <location filename="../base/bootloaderinstallhex.cpp" line="220"/>
474 <source>Success: modified firmware file created</source>
475 <translation>Le firmware a été modifié avec succès</translation>
476 </message>
477 <message>
478 <location filename="../base/bootloaderinstallhex.cpp" line="223"/>
479 <source>Copying modified firmware file failed</source>
480 <translation>Erreur lors de la copie du firmware modifié</translation>
481 </message>
482 <message>
483 <location filename="../base/bootloaderinstallhex.cpp" line="237"/>
484 <source>Uninstallation not possible, only installation info removed</source>
485 <translation>Désinstallation impossible, seules les infos d&apos;installation sont supprimées</translation>
486 </message>
487 <message>
488 <location filename="../base/bootloaderinstallhex.cpp" line="258"/>
489 <source>Can&apos;t open input file</source>
490 <translation>Impossible d&apos;ouvrir le fichier d&apos;entrée</translation>
491 </message>
492 <message>
493 <location filename="../base/bootloaderinstallhex.cpp" line="259"/>
494 <source>Can&apos;t open output file</source>
495 <translation>Impossible d&apos;ouvrir le fichier de sortie</translation>
496 </message>
497 <message>
498 <location filename="../base/bootloaderinstallhex.cpp" line="260"/>
499 <source>invalid file: header length wrong</source>
500 <translation>fichier invalide: longueur de l&apos;en-tête incorrecte</translation>
501 </message>
502 <message>
503 <location filename="../base/bootloaderinstallhex.cpp" line="261"/>
504 <source>invalid file: unrecognized header</source>
505 <translation>fichier invalide: en-tête non reconnue</translation>
506 </message>
507 <message>
508 <location filename="../base/bootloaderinstallhex.cpp" line="262"/>
509 <source>invalid file: &quot;length&quot; field wrong</source>
510 <translation>fichier invalide: champ &quot;longueur&quot; erroné</translation>
511 </message>
512 <message>
513 <location filename="../base/bootloaderinstallhex.cpp" line="263"/>
514 <source>invalid file: &quot;length2&quot; field wrong</source>
515 <translation>fichier invalide: champ &quot;longueur2&quot; erroné</translation>
516 </message>
517 <message>
518 <location filename="../base/bootloaderinstallhex.cpp" line="264"/>
519 <source>invalid file: internal checksum error</source>
520 <translation>fichier invalide: erreur interne de somme de contrôle</translation>
521 </message>
522 <message>
523 <location filename="../base/bootloaderinstallhex.cpp" line="265"/>
524 <source>invalid file: &quot;length3&quot; field wrong</source>
525 <translation>fichier invalide: champ &quot;longueur3&quot; erroné</translation>
526 </message>
527 <message>
528 <location filename="../base/bootloaderinstallhex.cpp" line="266"/>
529 <source>unknown</source>
530 <translation>inconnue</translation>
531 </message>
532 <message>
533 <location filename="../base/bootloaderinstallhex.cpp" line="50"/>
534 <source>Bootloader installation requires you to provide a firmware file of the original firmware (hex file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
535 <translation>L&apos;installation du bootloader nécessite que vous fournissiez un fichier contenant le firmware original (fichier hex). Vous devez télécharger ce fichier par vous-même pour des raisons légales. Veuillez vous référer au &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manuel&lt;/a&gt; et à la page wiki &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; pour obtenir ce fichier.&lt;br/&gt;Appuyez sur Ok pour continuer et parcourir les fichiers sur votre ordinateur pour indiquer le fichier du firmware.</translation>
536 </message>
537</context>
538<context>
539 <name>BootloaderInstallImx</name>
540 <message>
541 <location filename="../base/bootloaderinstallimx.cpp" line="72"/>
542 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (firmware.sb file). This file will be patched with the Rockbox bootloader and installed to your player. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
543 <translation>L&apos;installation du bootloader nécessite que vous fournissiez une copie du firmware original de Sandisk (fichier firmware.sb). Ce firmware sera alors modifié et installé sur votre lecteur avec le bootloader de Rockbox. Vous devez télécharger ce fichier par vous-même pour des raisons légales. Veuillez vous référer au &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Forums de Sansa&lt;/a&gt; ou à la page wiki &lt;a href=&apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; pour obtenir ce fichier.&lt;br/&gt;Appuyez sur Ok pour continuer et parcourir les fichiers sur votre ordinateur pour indiquer le fichier du firmware.</translation>
544 </message>
545 <message>
546 <location filename="../base/bootloaderinstallimx.cpp" line="94"/>
547 <source>Could not read original firmware file</source>
548 <translation>Impossible de lire le fichier du firmware original</translation>
549 </message>
550 <message>
551 <location filename="../base/bootloaderinstallimx.cpp" line="100"/>
552 <source>Downloading bootloader file</source>
553 <translation>Téléchargement du bootloader</translation>
554 </message>
555 <message>
556 <location filename="../base/bootloaderinstallimx.cpp" line="110"/>
557 <source>Patching file...</source>
558 <translation>Modification du firmware...</translation>
559 </message>
560 <message>
561 <location filename="../base/bootloaderinstallimx.cpp" line="137"/>
562 <source>Patching the original firmware failed</source>
563 <translation>Erreur lors de la modification du firmware</translation>
564 </message>
565 <message>
566 <location filename="../base/bootloaderinstallimx.cpp" line="143"/>
567 <source>Succesfully patched firmware file</source>
568 <translation>Le firmware a été modifié avec succès</translation>
569 </message>
570 <message>
571 <location filename="../base/bootloaderinstallimx.cpp" line="158"/>
572 <source>Bootloader successful installed</source>
573 <translation>Le bootloader a été installé avec succès</translation>
574 </message>
575 <message>
576 <location filename="../base/bootloaderinstallimx.cpp" line="164"/>
577 <source>Patched bootloader could not be installed</source>
578 <translation>L&apos;installation du bootloader modifié a échouée</translation>
579 </message>
580 <message>
581 <location filename="../base/bootloaderinstallimx.cpp" line="175"/>
582 <source>To uninstall, perform a normal upgrade with an unmodified original firmware.</source>
583 <translation>Pour le désinstaller, faites une mise à jour normale avec un firmware non modifié.</translation>
584 </message>
585</context>
586<context>
587 <name>BootloaderInstallIpod</name>
588 <message>
589 <location filename="../base/bootloaderinstallipod.cpp" line="49"/>
590 <source>Error: can&apos;t allocate buffer memory!</source>
591 <translation>Erreur: impossible d&apos;allouer de la mémoire !</translation>
592 </message>
593 <message>
594 <location filename="../base/bootloaderinstallipod.cpp" line="80"/>
595 <source>Downloading bootloader file</source>
596 <translation>Téléchargement du fichier bootloader</translation>
597 </message>
598 <message>
599 <location filename="../base/bootloaderinstallipod.cpp" line="64"/>
600 <location filename="../base/bootloaderinstallipod.cpp" line="151"/>
601 <source>Failed to read firmware directory</source>
602 <translation>La lecture du dossier du firmware a échoué</translation>
603 </message>
604 <message>
605 <location filename="../base/bootloaderinstallipod.cpp" line="69"/>
606 <location filename="../base/bootloaderinstallipod.cpp" line="156"/>
607 <source>Unknown version number in firmware (%1)</source>
608 <translation>Numéro de version inconnu dans le firmware (%1)</translation>
609 </message>
610 <message>
611 <location filename="../base/bootloaderinstallipod.cpp" line="75"/>
612 <source>Warning: This is a MacPod, Rockbox only runs on WinPods.
613See http://www.rockbox.org/wiki/IpodConversionToFAT32</source>
614 <translatorcomment>C&apos;est techniquement incorrect mais je ne sais pas trop comment le dire sinon.</translatorcomment>
615 <translation>Attention: le lecteur utilise un système de fichier MacPod, Rockbox ne peut fonctionner qu&apos;avec un système de fichier WinPods.
616Veuillez vous référer à http://www.rockbox.org/wiki/IpodConversionToFAT32</translation>
617 </message>
618 <message>
619 <location filename="../base/bootloaderinstallipod.cpp" line="94"/>
620 <location filename="../base/bootloaderinstallipod.cpp" line="163"/>
621 <source>Could not open Ipod in R/W mode</source>
622 <translation>Impossible d&apos;accéder à l&apos;Ipod en lecture et écriture</translation>
623 </message>
624 <message>
625 <location filename="../base/bootloaderinstallipod.cpp" line="104"/>
626 <source>Successfull added bootloader</source>
627 <translation>Le bootloader a été ajouté avec succès</translation>
628 </message>
629 <message>
630 <location filename="../base/bootloaderinstallipod.cpp" line="115"/>
631 <source>Failed to add bootloader</source>
632 <translation>L&apos;ajout du bootloader a échoué</translation>
633 </message>
634 <message>
635 <location filename="../base/bootloaderinstallipod.cpp" line="127"/>
636 <source>Bootloader Installation complete.</source>
637 <translation>L&apos;installation du bootloader est terminée.</translation>
638 </message>
639 <message>
640 <location filename="../base/bootloaderinstallipod.cpp" line="132"/>
641 <source>Writing log aborted</source>
642 <translation>L&apos;écriture de l&apos;historique a été interrompue</translation>
643 </message>
644 <message>
645 <location filename="../base/bootloaderinstallipod.cpp" line="169"/>
646 <source>No bootloader detected.</source>
647 <translation>Aucun bootloader détecté.</translation>
648 </message>
649 <message>
650 <location filename="../base/bootloaderinstallipod.cpp" line="175"/>
651 <source>Successfully removed bootloader</source>
652 <translation>Le bootloader a été supprimé avec succès</translation>
653 </message>
654 <message>
655 <location filename="../base/bootloaderinstallipod.cpp" line="182"/>
656 <source>Removing bootloader failed.</source>
657 <translation>La suppression du bootloader a échoué.</translation>
658 </message>
659 <message>
660 <location filename="../base/bootloaderinstallipod.cpp" line="228"/>
661 <source>Error: could not retrieve device name</source>
662 <translation>Erreur: impossible de récupérer le nom du périphérique</translation>
663 </message>
664 <message>
665 <location filename="../base/bootloaderinstallipod.cpp" line="244"/>
666 <source>Error: no mountpoint specified!</source>
667 <translation>Erreur: aucun point de montage n&apos;a été spécifié !</translation>
668 </message>
669 <message>
670 <location filename="../base/bootloaderinstallipod.cpp" line="249"/>
671 <source>Could not open Ipod: permission denied</source>
672 <translation>Impossible d&apos;accéder à l&apos;Ipod: accès refusé</translation>
673 </message>
674 <message>
675 <location filename="../base/bootloaderinstallipod.cpp" line="253"/>
676 <source>Could not open Ipod</source>
677 <translation>Impossible d&apos;accéder à l&apos;Ipod</translation>
678 </message>
679 <message>
680 <location filename="../base/bootloaderinstallipod.cpp" line="264"/>
681 <source>No firmware partition on disk</source>
682 <translation>La partition du firmware n&apos;est pas présente sur le disque</translation>
683 </message>
684 <message>
685 <location filename="../base/bootloaderinstallipod.cpp" line="90"/>
686 <source>Installing Rockbox bootloader</source>
687 <translation>Installation du bootloader de Rockbox</translation>
688 </message>
689 <message>
690 <location filename="../base/bootloaderinstallipod.cpp" line="142"/>
691 <source>Uninstalling bootloader</source>
692 <translation>Suppression du bootloader</translation>
693 </message>
694 <message>
695 <location filename="../base/bootloaderinstallipod.cpp" line="258"/>
696 <source>Error reading partition table - possibly not an Ipod</source>
697 <translation>Erreur lors de la lecteur de la table des partitions; ce lecteur audio n&apos;est peut-être pas un Ipod</translation>
698 </message>
699</context>
700<context>
701 <name>BootloaderInstallMi4</name>
702 <message>
703 <location filename="../base/bootloaderinstallmi4.cpp" line="34"/>
704 <source>Downloading bootloader</source>
705 <translation>Téléchargement du bootloader</translation>
706 </message>
707 <message>
708 <location filename="../base/bootloaderinstallmi4.cpp" line="43"/>
709 <source>Installing Rockbox bootloader</source>
710 <translation>Installation du bootloader de Rockbox</translation>
711 </message>
712 <message>
713 <location filename="../base/bootloaderinstallmi4.cpp" line="66"/>
714 <source>A firmware file is already present on player</source>
715 <translation>Un fichier contenant le firmware est déjà présent sur le lecteur</translation>
716 </message>
717 <message>
718 <location filename="../base/bootloaderinstallmi4.cpp" line="71"/>
719 <location filename="../base/bootloaderinstallmi4.cpp" line="79"/>
720 <source>Bootloader successful installed</source>
721 <translation>Le bootloader a été installé avec succès</translation>
722 </message>
723 <message>
724 <location filename="../base/bootloaderinstallmi4.cpp" line="74"/>
725 <source>Copying modified firmware file failed</source>
726 <translation>Erreur lors de la copie du firmware modifié</translation>
727 </message>
728 <message>
729 <location filename="../base/bootloaderinstallmi4.cpp" line="91"/>
730 <source>Checking for Rockbox bootloader</source>
731 <translation>Vérification du bootloader de Rockbox</translation>
732 </message>
733 <message>
734 <location filename="../base/bootloaderinstallmi4.cpp" line="93"/>
735 <source>No Rockbox bootloader found</source>
736 <translation>Le bootloader de Rockbox n&apos;a pas été trouvé</translation>
737 </message>
738 <message>
739 <location filename="../base/bootloaderinstallmi4.cpp" line="98"/>
740 <source>Checking for original firmware file</source>
741 <translation>Vérification du firmware original</translation>
742 </message>
743 <message>
744 <location filename="../base/bootloaderinstallmi4.cpp" line="103"/>
745 <source>Error finding original firmware file</source>
746 <translation>Erreur lors de la recherche du firmware original</translation>
747 </message>
748 <message>
749 <location filename="../base/bootloaderinstallmi4.cpp" line="113"/>
750 <source>Rockbox bootloader successful removed</source>
751 <translation>Le bootloader de Rockbox a été supprimé avec succès</translation>
752 </message>
753</context>
754<context>
755 <name>BootloaderInstallMpio</name>
756 <message>
757 <location filename="../base/bootloaderinstallmpio.cpp" line="34"/>
758 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
759 <translation>L&apos;installation du bootloader nécessite que vous fournissiez un fichier contenant le firmware original (fichier bin). Vous devez télécharger ce fichier par vous-même pour des raisons légales. Veuillez vous référer au &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manuel&lt;/a&gt; et à la page wiki &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; pour obtenir ce fichier.&lt;br/&gt;Appuyez sur Ok pour continuer et parcourir les fichiers sur votre ordinateur pour indiquer le fichier du firmware.</translation>
760 </message>
761 <message>
762 <location filename="../base/bootloaderinstallmpio.cpp" line="53"/>
763 <source>Downloading bootloader file</source>
764 <translation>Téléchargement du fichier bootloader</translation>
765 </message>
766 <message>
767 <location filename="../base/bootloaderinstallmpio.cpp" line="80"/>
768 <source>Could not open the original firmware.</source>
769 <translation>Impossible d&apos;ouvrir le fichier du firmware original.</translation>
770 </message>
771 <message>
772 <location filename="../base/bootloaderinstallmpio.cpp" line="83"/>
773 <source>Could not read the original firmware.</source>
774 <translation>Impossible de lire le fichier du firmware original.</translation>
775 </message>
776 <message>
777 <location filename="../base/bootloaderinstallmpio.cpp" line="86"/>
778 <source>Loaded firmware file does not look like MPIO original firmware file.</source>
779 <translation>Le contenu du fichier du firmware original ne ressemble pas à un firmware MPIO.</translation>
780 </message>
781 <message>
782 <location filename="../base/bootloaderinstallmpio.cpp" line="101"/>
783 <source>Could not open output file.</source>
784 <translation>Impossible d&apos;ouvrir le fichier de sortie.</translation>
785 </message>
786 <message>
787 <location filename="../base/bootloaderinstallmpio.cpp" line="104"/>
788 <source>Could not write output file.</source>
789 <translation>Impossible d&apos;écrire le fichier de sortie.</translation>
790 </message>
791 <message>
792 <location filename="../base/bootloaderinstallmpio.cpp" line="107"/>
793 <source>Unknown error number: %1</source>
794 <translation>Erreur inconnue: %1</translation>
795 </message>
796 <message>
797 <location filename="../base/bootloaderinstallmpio.cpp" line="89"/>
798 <source>Could not open downloaded bootloader.</source>
799 <translation>Impossible d&apos;ouvrir le fichier du bootloader téléchargé.</translation>
800 </message>
801 <message>
802 <location filename="../base/bootloaderinstallmpio.cpp" line="92"/>
803 <source>Place for bootloader in OF file not empty.</source>
804 <translation>Pas de place libre pour le bootloader dans le firmware original.</translation>
805 </message>
806 <message>
807 <location filename="../base/bootloaderinstallmpio.cpp" line="95"/>
808 <source>Could not read the downloaded bootloader.</source>
809 <translation>Impossible de lire le fichier du bootloader téléchargé.</translation>
810 </message>
811 <message>
812 <location filename="../base/bootloaderinstallmpio.cpp" line="98"/>
813 <source>Bootloader checksum error.</source>
814 <translation>La vérification de la somme de contrôle du bootloader a échoué.</translation>
815 </message>
816 <message>
817 <location filename="../base/bootloaderinstallmpio.cpp" line="112"/>
818 <source>Patching original firmware failed: %1</source>
819 <translation>Erreur lors de la modification du firmware: %1</translation>
820 </message>
821 <message>
822 <location filename="../base/bootloaderinstallmpio.cpp" line="119"/>
823 <source>Success: modified firmware file created</source>
824 <translation>Le firmware a été modifié avec succès</translation>
825 </message>
826 <message>
827 <location filename="../base/bootloaderinstallmpio.cpp" line="127"/>
828 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
829 <translation>Pour le désinstaller, faites une mise à jour normale avec un firmware non modifié</translation>
830 </message>
831</context>
832<context>
833 <name>BootloaderInstallSansa</name>
834 <message>
835 <location filename="../base/bootloaderinstallsansa.cpp" line="50"/>
836 <source>Error: can&apos;t allocate buffer memory!</source>
837 <translation>Erreur: impossible d&apos;allouer de la mémoire !</translation>
838 </message>
839 <message>
840 <location filename="../base/bootloaderinstallsansa.cpp" line="55"/>
841 <source>Searching for Sansa</source>
842 <translation>Recherche de lecteurs Sansa</translation>
843 </message>
844 <message>
845 <location filename="../base/bootloaderinstallsansa.cpp" line="59"/>
846 <source>Permission for disc access denied!
847This is required to install the bootloader</source>
848 <translation>L&apos;accès au disque a été refusé !
849Ceci est nécessaire à l&apos;installation du bootloader</translation>
850 </message>
851 <message>
852 <location filename="../base/bootloaderinstallsansa.cpp" line="66"/>
853 <source>No Sansa detected!</source>
854 <translation>Aucun lecteur Sansa n&apos;a été détecté !</translation>
855 </message>
856 <message>
857 <location filename="../base/bootloaderinstallsansa.cpp" line="79"/>
858 <source>Downloading bootloader file</source>
859 <translation>Téléchargement du bootloader</translation>
860 </message>
861 <message>
862 <location filename="../base/bootloaderinstallsansa.cpp" line="71"/>
863 <location filename="../base/bootloaderinstallsansa.cpp" line="179"/>
864 <source>OLD ROCKBOX INSTALLATION DETECTED, ABORTING.
865You must reinstall the original Sansa firmware before running
866sansapatcher for the first time.
867See http://www.rockbox.org/wiki/SansaE200Install
868</source>
869 <translation>UNE ANCIENNE INSTALLATION DE ROCKBOX A ÉTÉ DÉTECTÉE, ABANDON.
870Vous devez réinstaller le firmware original de Sansa avant de lancer
871sansapatcher pour la première fois.
872Veuillez vous référer à http://www.rockbox.org/wiki/SansaE200Install
873</translation>
874 </message>
875 <message>
876 <location filename="../base/bootloaderinstallsansa.cpp" line="102"/>
877 <location filename="../base/bootloaderinstallsansa.cpp" line="189"/>
878 <source>Could not open Sansa in R/W mode</source>
879 <translation>Impossible d&apos;accéder au lecteur Sansa en lecture et écriture</translation>
880 </message>
881 <message>
882 <location filename="../base/bootloaderinstallsansa.cpp" line="129"/>
883 <source>Successfully installed bootloader</source>
884 <translation>Le bootloader a été installé avec succès</translation>
885 </message>
886 <message>
887 <location filename="../base/bootloaderinstallsansa.cpp" line="140"/>
888 <source>Failed to install bootloader</source>
889 <translation>L&apos;installation du bootloader a échoué</translation>
890 </message>
891 <message>
892 <location filename="../base/bootloaderinstallsansa.cpp" line="153"/>
893 <source>Bootloader Installation complete.</source>
894 <translation>L&apos;installation du bootloader est terminée.</translation>
895 </message>
896 <message>
897 <location filename="../base/bootloaderinstallsansa.cpp" line="158"/>
898 <source>Writing log aborted</source>
899 <translation>L&apos;écriture de l&apos;historique a été interrompue</translation>
900 </message>
901 <message>
902 <location filename="../base/bootloaderinstallsansa.cpp" line="238"/>
903 <source>Error: could not retrieve device name</source>
904 <translation>Erreur: impossible de récupérer le nom du périphérique</translation>
905 </message>
906 <message>
907 <location filename="../base/bootloaderinstallsansa.cpp" line="254"/>
908 <source>Can&apos;t find Sansa</source>
909 <translation>Impossible de trouver un lecteur Sansa</translation>
910 </message>
911 <message>
912 <location filename="../base/bootloaderinstallsansa.cpp" line="259"/>
913 <source>Could not open Sansa</source>
914 <translation>Impossible d&apos;accéder au lecteur Sansa</translation>
915 </message>
916 <message>
917 <location filename="../base/bootloaderinstallsansa.cpp" line="264"/>
918 <source>Could not read partition table</source>
919 <translation>Impossible de lire la table des partitions</translation>
920 </message>
921 <message>
922 <location filename="../base/bootloaderinstallsansa.cpp" line="271"/>
923 <source>Disk is not a Sansa (Error %1), aborting.</source>
924 <translation>Le disque n&apos;est pas à un lecteur Sansa (Erreur %1); abandon.</translation>
925 </message>
926 <message>
927 <location filename="../base/bootloaderinstallsansa.cpp" line="195"/>
928 <source>Successfully removed bootloader</source>
929 <translation>Le bootloader a été supprimé avec succès</translation>
930 </message>
931 <message>
932 <location filename="../base/bootloaderinstallsansa.cpp" line="202"/>
933 <source>Removing bootloader failed.</source>
934 <translation>La suppression du bootloader a échoué.</translation>
935 </message>
936 <message>
937 <location filename="../base/bootloaderinstallsansa.cpp" line="94"/>
938 <source>Installing Rockbox bootloader</source>
939 <translation>Installation du bootloader de Rockbox</translation>
940 </message>
941 <message>
942 <location filename="../base/bootloaderinstallsansa.cpp" line="111"/>
943 <source>Checking downloaded bootloader</source>
944 <translation>Vérification du bootloader téléchargé</translation>
945 </message>
946 <message>
947 <location filename="../base/bootloaderinstallsansa.cpp" line="119"/>
948 <source>Bootloader mismatch! Aborting.</source>
949 <translation>Le bootloader ne correspond pas ! Abandon.</translation>
950 </message>
951 <message>
952 <location filename="../base/bootloaderinstallsansa.cpp" line="170"/>
953 <source>Uninstalling bootloader</source>
954 <translation>Suppression du bootloader</translation>
955 </message>
956</context>
957<context>
958 <name>BootloaderInstallTcc</name>
959 <message>
960 <location filename="../base/bootloaderinstalltcc.cpp" line="33"/>
961 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wiki page on how to obtain the file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
962 <translation>L&apos;installation du bootloader nécessite que vous fournissiez un fichier contenant le firmware original (fichier hin). Vous devez télécharger ce fichier par vous-même pour des raisons légales. Veuillez vous référer au &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manuel&lt;/a&gt; et à la page wiki &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; pour obtenir ce fichier.&lt;br/&gt;Appuyez sur Ok pour continuer et parcourir les fichiers sur votre ordinateur pour indiquer le fichier du firmware.</translation>
963 </message>
964 <message>
965 <location filename="../base/bootloaderinstalltcc.cpp" line="50"/>
966 <source>Downloading bootloader file</source>
967 <translation>Téléchargement du bootloader</translation>
968 </message>
969 <message>
970 <location filename="../base/bootloaderinstalltcc.cpp" line="82"/>
971 <location filename="../base/bootloaderinstalltcc.cpp" line="99"/>
972 <source>Could not load %1</source>
973 <translation>Impossible de charger %1</translation>
974 </message>
975 <message>
976 <location filename="../base/bootloaderinstalltcc.cpp" line="90"/>
977 <source>Unknown OF file used: %1</source>
978 <translation>Le fichier du firmware original n&apos;est pas valide : %1</translation>
979 </message>
980 <message>
981 <location filename="../base/bootloaderinstalltcc.cpp" line="104"/>
982 <source>Patching Firmware...</source>
983 <translation>Modification du firmware...</translation>
984 </message>
985 <message>
986 <location filename="../base/bootloaderinstalltcc.cpp" line="111"/>
987 <source>Could not patch firmware</source>
988 <translation>Modification du firmware impossible</translation>
989 </message>
990 <message>
991 <location filename="../base/bootloaderinstalltcc.cpp" line="117"/>
992 <source>Could not open %1 for writing</source>
993 <translation>Impossible d&apos;ouvrir %1 en écriture</translation>
994 </message>
995 <message>
996 <location filename="../base/bootloaderinstalltcc.cpp" line="126"/>
997 <source>Could not write firmware file</source>
998 <translation>Ecriture du firmware impossible</translation>
999 </message>
1000 <message>
1001 <location filename="../base/bootloaderinstalltcc.cpp" line="131"/>
1002 <source>Success: modified firmware file created</source>
1003 <translation>Le firmware a été modifié avec succès</translation>
1004 </message>
1005 <message>
1006 <location filename="../base/bootloaderinstalltcc.cpp" line="151"/>
1007 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
1008 <translation>Pour le désinstaller, faites une mise à jour normale avec un firmware non modifié</translation>
1009 </message>
1010</context>
1011<context>
1012 <name>Changelog</name>
1013 <message>
1014 <location filename="../gui/changelogfrm.ui" line="17"/>
1015 <source>Changelog</source>
1016 <translation>Historique des modifications</translation>
1017 </message>
1018 <message>
1019 <location filename="../gui/changelogfrm.ui" line="39"/>
1020 <source>Show on startup</source>
1021 <translation>Montrer au démarrage</translation>
1022 </message>
1023 <message>
1024 <location filename="../gui/changelogfrm.ui" line="46"/>
1025 <source>&amp;Ok</source>
1026 <translation>&amp;OK</translation>
1027 </message>
1028</context>
1029<context>
1030 <name>Config</name>
1031 <message>
1032 <location filename="../configure.cpp" line="340"/>
1033 <source>Showing disabled targets</source>
1034 <translation>Afficher les cibles d&apos;installation désactivées</translation>
1035 </message>
1036 <message>
1037 <location filename="../configure.cpp" line="341"/>
1038 <source>You just enabled showing targets that are marked disabled. Disabled targets are not recommended to end users. Please use this option only if you know what you are doing.</source>
1039 <translation>Vous venez d&apos;activer l&apos;affichage des cibles d&apos;installations indiquées comme inactives. Cette option n&apos;est pas recommandée pour l&apos;utilisateur final. Vous êtes encouragé à utiliser celle-ci uniquement si vous savez ce que vous faites.</translation>
1040 </message>
1041 <message>
1042 <location filename="../configure.cpp" line="529"/>
1043 <source>Proxy Detection</source>
1044 <translation>Détection du proxy</translation>
1045 </message>
1046 <message>
1047 <location filename="../configure.cpp" line="530"/>
1048 <source>The System Proxy settings are invalid!
1049Rockbox Utility can&apos;t work with this proxy settings. Make sure the system proxy is set correctly. Note that &quot;proxy auto-config (PAC)&quot; scripts are not supported by Rockbox Utility. If your system uses this you need to use manual proxy settings.</source>
1050 <translation>Les paramètres système Proxy sont non valides !
1051L&apos;Utilitaire Rockbox ne peut pas fonctionner avec ces réglages proxy. Vérifier que le proxy soit correctement paramétré. Notez que les scripts &quot;proxy auto-config (PAC)&quot; ne sont pas supportés. Si votre système en utilise vous devez effectuer un paramétrage manuel.</translation>
1052 </message>
1053 <message>
1054 <location filename="../configure.cpp" line="643"/>
1055 <source>Set Cache Path</source>
1056 <translation>Sélectionner le chemin vers le cache</translation>
1057 </message>
1058 <message>
1059 <location filename="../configure.cpp" line="788"/>
1060 <source>%1 &quot;MacPod&quot; found!
1061Rockbox needs a FAT formatted Ipod (so-called &quot;WinPod&quot;) to run. </source>
1062 <translation>%1 &quot;MacPod&quot; détecté !
1063Rockbox ne peut fonctionner que sur un Ipod utilisant le système de fichier FAT (aussi appelé un &quot;WinPod&quot;).</translation>
1064 </message>
1065 <message>
1066 <location filename="../configure.cpp" line="780"/>
1067 <source>%1 in MTP mode found!
1068You need to change your player to MSC mode for installation. </source>
1069 <translatorcomment>Pour effectuer l&apos;installation, il est nécessaire de mettre votre lecteur audio en mode MSC </translatorcomment>
1070 <translation>%1 est en mode MTP!
1071Pour effectuer l&apos;installation, il est nécessaire de mettre votre lecteur audio en mode MSC.</translation>
1072 </message>
1073 <message>
1074 <source>Until you change this installation will fail!</source>
1075 <translation type="obsolete">Cette installation échouera tant que vous n&apos;aurez pas modifié cela!</translation>
1076 </message>
1077 <message>
1078 <location filename="../configure.cpp" line="774"/>
1079 <source>Detected an unsupported player:
1080%1
1081Sorry, Rockbox doesn&apos;t run on your player.</source>
1082 <translation>Le lecteur audio détecté n&apos;est pas supporté:
1083%1
1084Désolé, Rockbox ne fonctionne pas sur votre lecteur audio.</translation>
1085 </message>
1086 <message>
1087 <source>Fatal: player incompatible</source>
1088 <translation type="obsolete">Erreur fatale: le lecteur audio est incompatible</translation>
1089 </message>
1090 <message>
1091 <location filename="../configure.cpp" line="858"/>
1092 <source>Autodetection</source>
1093 <translation>Autodétection</translation>
1094 </message>
1095 <message>
1096 <location filename="../configure.cpp" line="859"/>
1097 <source>Could not detect a Mountpoint.
1098Select your Mountpoint manually.</source>
1099 <translation>Impossible de détecter un point de montage.
1100Veuillez sélectionner manuellement le point de montage.</translation>
1101 </message>
1102 <message>
1103 <location filename="../configure.cpp" line="764"/>
1104 <source>Could not detect a device.
1105Select your device and Mountpoint manually.</source>
1106 <translation>Impossible de détecter le périphérique.
1107Veuillez sélectionner manuellement le type de périphérique et le point de montage.</translation>
1108 </message>
1109 <message>
1110 <location filename="../configure.cpp" line="448"/>
1111 <location filename="../configure.cpp" line="914"/>
1112 <source>TTS error</source>
1113 <translation>Erreur TTS</translation>
1114 </message>
1115 <message>
1116 <location filename="../configure.cpp" line="449"/>
1117 <location filename="../configure.cpp" line="915"/>
1118 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1119 <translation>L&apos;initialisation du TTS sélectionné a échoué. Vous ne pouvez pas utiliser ce TTS. </translation>
1120 </message>
1121 <message>
1122 <location filename="../configure.cpp" line="665"/>
1123 <source>%1 (%2 GiB of %3 GiB free)</source>
1124 <translation>%1 (%2 GiB libres sur %3 GiB)</translation>
1125 </message>
1126 <message>
1127 <location filename="../configure.cpp" line="739"/>
1128 <source>Multiple devices have been detected. Please disconnect all players but one and try again.</source>
1129 <translation>Plusieurs périphériques ont été détectés. Veuillez déconnecter tous les lecteurs sauf un et essayer à nouveau s&apos;il vous plait.</translation>
1130 </message>
1131 <message>
1132 <location filename="../configure.cpp" line="742"/>
1133 <source>Detected devices:</source>
1134 <translation>Périphériques détectés:</translation>
1135 </message>
1136 <message>
1137 <location filename="../configure.cpp" line="747"/>
1138 <source>(unknown)</source>
1139 <translation>(inconnu)</translation>
1140 </message>
1141 <message>
1142 <location filename="../configure.cpp" line="749"/>
1143 <source>%1 at %2</source>
1144 <translation>%1 à %2</translation>
1145 </message>
1146 <message>
1147 <location filename="../configure.cpp" line="755"/>
1148 <source>Note: detecting connected devices might be ambiguous. You might have less devices connected than listed. In this case it might not be possible to detect your player unambiguously.</source>
1149 <translation>Note: la détection des périphériques connectés n&apos;est pas toujours fiable. Il peut y avoir moins de périphériques connectés qu&apos;indiqué. Dans ce cas, détecter votre lecteur de manière parfaitement fiable peut s&apos;avérer impossible. </translation>
1150 </message>
1151 <message>
1152 <location filename="../configure.cpp" line="759"/>
1153 <location filename="../configure.cpp" line="763"/>
1154 <location filename="../configure.cpp" line="805"/>
1155 <source>Device Detection</source>
1156 <translation>Détection de périphérique</translation>
1157 </message>
1158 <message>
1159 <location filename="../configure.cpp" line="794"/>
1160 <source>The player contains an incompatible filesystem.
1161Make sure you selected the correct mountpoint and the player is set up to use a filesystem compatible with Rockbox.</source>
1162 <translation>Le lecteur contient un système de fichier incompatible.
1163Vérifiez que vous avez sélectionné le bon point de montage et que le baladeur est paramétré pour utiliser un système de fichier compatible avec Rockbox.</translation>
1164 </message>
1165 <message>
1166 <location filename="../configure.cpp" line="802"/>
1167 <source>An unknown error occured during player detection.</source>
1168 <translation>Une erreur inconnue s&apos;est produite pendant la détection du lecteur.</translation>
1169 </message>
1170 <message>
1171 <location filename="../configure.cpp" line="869"/>
1172 <source>Really delete cache?</source>
1173 <translation>Supprimer le cache ?</translation>
1174 </message>
1175 <message>
1176 <location filename="../configure.cpp" line="870"/>
1177 <source>Do you really want to delete the cache? Make absolutely sure this setting is correct as it will remove &lt;b&gt;all&lt;/b&gt; files in this folder!</source>
1178 <translation>Voulez-vous supprimer le cache ? Vérifier bien que ce paramètre est correct car il supprimera &lt;b&gt;tous&lt;/b&gt; les fichiers de ce répertoire !</translation>
1179 </message>
1180 <message>
1181 <location filename="../configure.cpp" line="878"/>
1182 <source>Path wrong!</source>
1183 <translation>Chemin incorrect !</translation>
1184 </message>
1185 <message>
1186 <location filename="../configure.cpp" line="879"/>
1187 <source>The cache path is invalid. Aborting.</source>
1188 <translation>Le chemin du cache est invalide. Annulation.</translation>
1189 </message>
1190 <message>
1191 <location filename="../configure.cpp" line="921"/>
1192 <source>TTS configuration invalid</source>
1193 <translation>La configuration du moteur TTS est incorrecte</translation>
1194 </message>
1195 <message>
1196 <location filename="../configure.cpp" line="922"/>
1197 <source>TTS configuration invalid.
1198 Please configure TTS engine.</source>
1199 <translation>La configuration du moteur TTS est incorrecte.
1200Veuillez configurer le moteur TTS.</translation>
1201 </message>
1202 <message>
1203 <location filename="../configure.cpp" line="927"/>
1204 <source>Could not start TTS engine.</source>
1205 <translation>Impossible lancer le moteur TTS.</translation>
1206 </message>
1207 <message>
1208 <location filename="../configure.cpp" line="928"/>
1209 <source>Could not start TTS engine.
1210</source>
1211 <translation>Impossible lancer le moteur TTS.
1212</translation>
1213 </message>
1214 <message>
1215 <location filename="../configure.cpp" line="929"/>
1216 <location filename="../configure.cpp" line="948"/>
1217 <source>
1218Please configure TTS engine.</source>
1219 <translation>
1220Veuillez configurer le moteur TTS.</translation>
1221 </message>
1222 <message>
1223 <location filename="../configure.cpp" line="943"/>
1224 <source>Rockbox Utility Voice Test</source>
1225 <translation>Test de la synthèse vocale de l&apos;utilitaire Rockbox</translation>
1226 </message>
1227 <message>
1228 <location filename="../configure.cpp" line="946"/>
1229 <source>Could not voice test string.</source>
1230 <translation>Impossible de synthétiser la phrase de test.</translation>
1231 </message>
1232 <message>
1233 <location filename="../configure.cpp" line="947"/>
1234 <source>Could not voice test string.
1235</source>
1236 <translation>Impossible de synthétiser la phrase de test.</translation>
1237 </message>
1238 <message>
1239 <source>Fatal error</source>
1240 <translation type="obsolete">Erreur fatale</translation>
1241 </message>
1242 <message>
1243 <location filename="../configure.cpp" line="322"/>
1244 <source>Current cache size is %L1 kiB.</source>
1245 <translation>La taille actuelle du cache est %L1 ko.</translation>
1246 </message>
1247 <message>
1248 <location filename="../configure.cpp" line="455"/>
1249 <location filename="../configure.cpp" line="485"/>
1250 <source>Configuration OK</source>
1251 <translation>La configuration est correcte</translation>
1252 </message>
1253 <message>
1254 <location filename="../configure.cpp" line="461"/>
1255 <location filename="../configure.cpp" line="490"/>
1256 <source>Configuration INVALID</source>
1257 <translation>La configuration est incorrecte</translation>
1258 </message>
1259 <message>
1260 <location filename="../configure.cpp" line="130"/>
1261 <source>The following errors occurred:</source>
1262 <translation>Les erreurs suivantes sont survenues:</translation>
1263 </message>
1264 <message>
1265 <location filename="../configure.cpp" line="175"/>
1266 <source>No mountpoint given</source>
1267 <translation>Aucun point de montage spécifié</translation>
1268 </message>
1269 <message>
1270 <location filename="../configure.cpp" line="179"/>
1271 <source>Mountpoint does not exist</source>
1272 <translation>Le point de montage n&apos;existe pas</translation>
1273 </message>
1274 <message>
1275 <location filename="../configure.cpp" line="183"/>
1276 <source>Mountpoint is not a directory.</source>
1277 <translation>Le point de montage n&apos;est pas un dossier.</translation>
1278 </message>
1279 <message>
1280 <location filename="../configure.cpp" line="187"/>
1281 <source>Mountpoint is not writeable</source>
1282 <translation>Le point de montage n&apos;est pas accessible en écriture</translation>
1283 </message>
1284 <message>
1285 <location filename="../configure.cpp" line="202"/>
1286 <source>No player selected</source>
1287 <translation>Aucun lecteur audio sélectionné</translation>
1288 </message>
1289 <message>
1290 <location filename="../configure.cpp" line="209"/>
1291 <source>Cache path not writeable. Leave path empty to default to systems temporary path.</source>
1292 <translation>Le chemin vers le cache n&apos;est pas accessible en écriture. Vous pouvez laisser le chemin vide pour utiliser le dossier temporaire par défaut de votre système.</translation>
1293 </message>
1294 <message>
1295 <location filename="../configure.cpp" line="228"/>
1296 <source>You need to fix the above errors before you can continue.</source>
1297 <translation>Vous devez corriger les erreurs suivantes avant de pouvoir continuer.</translation>
1298 </message>
1299 <message>
1300 <location filename="../configure.cpp" line="231"/>
1301 <source>Configuration error</source>
1302 <translation>Erreur de configuration</translation>
1303 </message>
1304</context>
1305<context>
1306 <name>ConfigForm</name>
1307 <message>
1308 <location filename="../configurefrm.ui" line="14"/>
1309 <source>Configuration</source>
1310 <translation>Configuration</translation>
1311 </message>
1312 <message>
1313 <location filename="../configurefrm.ui" line="20"/>
1314 <source>Configure Rockbox Utility</source>
1315 <translation>Configuration de l&apos;utilitaire Rockbox</translation>
1316 </message>
1317 <message>
1318 <location filename="../configurefrm.ui" line="35"/>
1319 <source>&amp;Device</source>
1320 <translation>&amp;Périphérique</translation>
1321 </message>
1322 <message>
1323 <location filename="../configurefrm.ui" line="41"/>
1324 <source>Select your device in the &amp;filesystem</source>
1325 <translation>Sélectionnez votre périphérique dans le &amp;Système de fichiers</translation>
1326 </message>
1327 <message>
1328 <location filename="../configurefrm.ui" line="319"/>
1329 <source>&amp;Browse</source>
1330 <translation>&amp;Parcourir</translation>
1331 </message>
1332 <message>
1333 <location filename="../configurefrm.ui" line="72"/>
1334 <source>&amp;Select your audio player</source>
1335 <translation>&amp;Sélectionnez votre lecteur audio</translation>
1336 </message>
1337 <message>
1338 <location filename="../configurefrm.ui" line="58"/>
1339 <source>&amp;Refresh</source>
1340 <translation>&amp;Rafraîchir</translation>
1341 </message>
1342 <message>
1343 <location filename="../configurefrm.ui" line="114"/>
1344 <source>&amp;Autodetect</source>
1345 <translation>&amp;Autodétection</translation>
1346 </message>
1347 <message>
1348 <location filename="../configurefrm.ui" line="136"/>
1349 <source>&amp;Proxy</source>
1350 <translation>P&amp;roxy</translation>
1351 </message>
1352 <message>
1353 <location filename="../configurefrm.ui" line="142"/>
1354 <source>&amp;No Proxy</source>
1355 <translation>P&amp;as de proxy</translation>
1356 </message>
1357 <message>
1358 <location filename="../configurefrm.ui" line="159"/>
1359 <source>&amp;Manual Proxy settings</source>
1360 <translation>Paramètres &amp;manuels pour le proxy</translation>
1361 </message>
1362 <message>
1363 <location filename="../configurefrm.ui" line="166"/>
1364 <source>Proxy Values</source>
1365 <translation>Valeurs du proxy</translation>
1366 </message>
1367 <message>
1368 <location filename="../configurefrm.ui" line="172"/>
1369 <source>&amp;Host:</source>
1370 <translation>&amp;Hôte:</translation>
1371 </message>
1372 <message>
1373 <location filename="../configurefrm.ui" line="182"/>
1374 <source>&amp;Port:</source>
1375 <translation>&amp;Port:</translation>
1376 </message>
1377 <message>
1378 <location filename="../configurefrm.ui" line="199"/>
1379 <source>&amp;Username</source>
1380 <translation>&amp;Nom d&apos;utilisateur</translation>
1381 </message>
1382 <message>
1383 <location filename="../configurefrm.ui" line="209"/>
1384 <source>Pass&amp;word</source>
1385 <translation>&amp;Mot de passe</translation>
1386 </message>
1387 <message>
1388 <location filename="../configurefrm.ui" line="219"/>
1389 <source>Show</source>
1390 <translation>Montrer</translation>
1391 </message>
1392 <message>
1393 <location filename="../configurefrm.ui" line="260"/>
1394 <source>&amp;Language</source>
1395 <translation>&amp;Langue</translation>
1396 </message>
1397 <message>
1398 <location filename="../configurefrm.ui" line="274"/>
1399 <source>Cac&amp;he</source>
1400 <translation>&amp;Cache</translation>
1401 </message>
1402 <message>
1403 <location filename="../configurefrm.ui" line="277"/>
1404 <source>Download cache settings</source>
1405 <translation>Paramètres du cache de téléchargement</translation>
1406 </message>
1407 <message>
1408 <location filename="../configurefrm.ui" line="283"/>
1409 <source>Rockbox Utility uses a local download cache to save network traffic. You can change the path to the cache and use it as local repository by enabling Offline mode.</source>
1410 <translation>L&apos;utilitaire Rockbox utilise un cache local de téléchargement pour économiser de la bande passante. Vous pouvez modifier le chemin du cache et l&apos;utiliser comme dépôt local en activant le mode hors-ligne.</translation>
1411 </message>
1412 <message>
1413 <location filename="../configurefrm.ui" line="293"/>
1414 <source>Current cache size is %1</source>
1415 <translation>La taille actuelle du cache est %1</translation>
1416 </message>
1417 <message>
1418 <location filename="../configurefrm.ui" line="302"/>
1419 <source>P&amp;ath</source>
1420 <translation>&amp;Chemin</translation>
1421 </message>
1422 <message>
1423 <location filename="../configurefrm.ui" line="312"/>
1424 <source>Entering an invalid folder will reset the path to the systems temporary path.</source>
1425 <translation>Entrer un répertoire invalide remettra la valeur du chemin à celle du répertoire temporaire du système.</translation>
1426 </message>
1427 <message>
1428 <location filename="../configurefrm.ui" line="334"/>
1429 <source>Disable local &amp;download cache</source>
1430 <translation>Désactiver le cache local de &amp;téléchargement</translation>
1431 </message>
1432 <message>
1433 <source>&lt;p&gt;This will try to use all information from the cache, even information about updates. Only use this option if you want to install without network connection. Note: you need to do the same install you want to perform later with network access first to download all required files to the cache.&lt;/p&gt;</source>
1434 <translation type="obsolete">&lt;p&gt;Ceci essaiera d&apos;utiliser toutes les informations du cache, même les informations de mise à jour.
1435Utilisez cette option si vous voulez installer sans connexion réseau.
1436Note : l&apos;installation que vous voudrez réaliser plus tard doit d&apos;abord être faite avec un accès réseau
1437pour télécharger tous les fichiers néecessaires dans le cache.&lt;/p&gt;</translation>
1438 </message>
1439 <message>
1440 <source>O&amp;ffline mode</source>
1441 <translation type="obsolete">Mode &amp;hors-ligne</translation>
1442 </message>
1443 <message>
1444 <location filename="../configurefrm.ui" line="369"/>
1445 <source>Clean cache &amp;now</source>
1446 <translation>Nettoyer le cache &amp;maintenant</translation>
1447 </message>
1448 <message>
1449 <location filename="../configurefrm.ui" line="385"/>
1450 <source>&amp;TTS &amp;&amp; Encoder</source>
1451 <translation>&amp;TTS &amp;&amp; Encodeur</translation>
1452 </message>
1453 <message>
1454 <location filename="../configurefrm.ui" line="391"/>
1455 <source>TTS Engine</source>
1456 <translation>Moteur TTS</translation>
1457 </message>
1458 <message>
1459 <location filename="../configurefrm.ui" line="397"/>
1460 <source>&amp;Select TTS Engine</source>
1461 <translation>&amp;Choisir un moteur TTS</translation>
1462 </message>
1463 <message>
1464 <location filename="../configurefrm.ui" line="445"/>
1465 <source>Test TTS</source>
1466 <translation>Tester le moteur</translation>
1467 </message>
1468 <message>
1469 <location filename="../configurefrm.ui" line="452"/>
1470 <source>&amp;Use string corrections for TTS</source>
1471 <translation>&amp;Utiliser la correction des phrases pour TTS</translation>
1472 </message>
1473 <message>
1474 <location filename="../configurefrm.ui" line="462"/>
1475 <source>Encoder Engine</source>
1476 <translation>Moteur d&apos;encodage</translation>
1477 </message>
1478 <message>
1479 <location filename="../configurefrm.ui" line="536"/>
1480 <source>&amp;Ok</source>
1481 <translation>&amp;OK</translation>
1482 </message>
1483 <message>
1484 <location filename="../configurefrm.ui" line="547"/>
1485 <source>&amp;Cancel</source>
1486 <translation>&amp;Annuler</translation>
1487 </message>
1488 <message>
1489 <location filename="../configurefrm.ui" line="410"/>
1490 <source>Configure TTS Engine</source>
1491 <translation>Configurer le moteur TTS</translation>
1492 </message>
1493 <message>
1494 <location filename="../configurefrm.ui" line="95"/>
1495 <source>Show disabled targets</source>
1496 <translation>Afficher les cibles d&apos;installation désactivées</translation>
1497 </message>
1498 <message>
1499 <location filename="../configurefrm.ui" line="152"/>
1500 <source>Use S&amp;ystem values</source>
1501 <translation>Utiliser les &amp;valeurs système</translation>
1502 </message>
1503 <message>
1504 <location filename="../configurefrm.ui" line="417"/>
1505 <location filename="../configurefrm.ui" line="468"/>
1506 <source>Configuration invalid!</source>
1507 <translation>Configuration invalide !</translation>
1508 </message>
1509 <message>
1510 <location filename="../configurefrm.ui" line="434"/>
1511 <source>Configure &amp;TTS</source>
1512 <translation>Configurer le moteur &amp;TTS</translation>
1513 </message>
1514 <message>
1515 <location filename="../configurefrm.ui" line="485"/>
1516 <source>Configure &amp;Enc</source>
1517 <translation>Configurer l&apos;&amp;encodage</translation>
1518 </message>
1519 <message>
1520 <location filename="../configurefrm.ui" line="496"/>
1521 <source>encoder name</source>
1522 <translation>nom de l&apos;encodeur</translation>
1523 </message>
1524</context>
1525<context>
1526 <name>Configure</name>
1527 <message>
1528 <location filename="../configure.cpp" line="589"/>
1529 <source>English</source>
1530 <comment>This is the localized language name, i.e. your language.</comment>
1531 <translation>Français</translation>
1532 </message>
1533</context>
1534<context>
1535 <name>CreateVoiceFrm</name>
1536 <message>
1537 <location filename="../createvoicefrm.ui" line="17"/>
1538 <source>Create Voice File</source>
1539 <translation>Créer un fichier de voix</translation>
1540 </message>
1541 <message>
1542 <location filename="../createvoicefrm.ui" line="42"/>
1543 <source>Select the Language you want to generate a voicefile for:</source>
1544 <translation>Sélectionner la langue pour laquelle vous souhaitez générer un fichier de voix :</translation>
1545 </message>
1546 <message>
1547 <location filename="../createvoicefrm.ui" line="55"/>
1548 <source>TTS:</source>
1549 <translation>TTS:</translation>
1550 </message>
1551 <message>
1552 <location filename="../createvoicefrm.ui" line="101"/>
1553 <source>Silence threshold</source>
1554 <translation>Seuil de silence</translation>
1555 </message>
1556 <message>
1557 <location filename="../createvoicefrm.ui" line="163"/>
1558 <source>Language</source>
1559 <translation>Langue</translation>
1560 </message>
1561 <message>
1562 <location filename="../createvoicefrm.ui" line="49"/>
1563 <source>Generation settings</source>
1564 <translation>Paramètres de génération</translation>
1565 </message>
1566 <message>
1567 <location filename="../createvoicefrm.ui" line="68"/>
1568 <source>Change</source>
1569 <translation>Modifier</translation>
1570 </message>
1571 <message>
1572 <location filename="../createvoicefrm.ui" line="139"/>
1573 <source>&amp;Install</source>
1574 <translation>&amp;Installer</translation>
1575 </message>
1576 <message>
1577 <location filename="../createvoicefrm.ui" line="150"/>
1578 <source>&amp;Cancel</source>
1579 <translation>&amp;Annuler</translation>
1580 </message>
1581 <message>
1582 <location filename="../createvoicefrm.ui" line="88"/>
1583 <source>Wavtrim Threshold</source>
1584 <translation>Seuil pour Wavtrim</translation>
1585 </message>
1586</context>
1587<context>
1588 <name>CreateVoiceWindow</name>
1589 <message>
1590 <location filename="../createvoicewindow.cpp" line="100"/>
1591 <source>TTS error</source>
1592 <translation>Erreur TTS</translation>
1593 </message>
1594 <message>
1595 <location filename="../createvoicewindow.cpp" line="101"/>
1596 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1597 <translation>L&apos;initialisation du TTS sélectionné a échoué. Vous ne pouvez pas utiliser ce TTS.</translation>
1598 </message>
1599 <message>
1600 <location filename="../createvoicewindow.cpp" line="105"/>
1601 <location filename="../createvoicewindow.cpp" line="108"/>
1602 <source>Engine: &lt;b&gt;%1&lt;/b&gt;</source>
1603 <translation>Moteur: &lt;b&gt;%1&lt;/b&gt;</translation>
1604 </message>
1605</context>
1606<context>
1607 <name>EncTtsCfgGui</name>
1608 <message>
1609 <location filename="../encttscfggui.cpp" line="45"/>
1610 <source>Waiting for engine...</source>
1611 <translation>En attente du moteur d&apos;encodage...</translation>
1612 </message>
1613 <message>
1614 <location filename="../encttscfggui.cpp" line="95"/>
1615 <source>Ok</source>
1616 <translation>Ok</translation>
1617 </message>
1618 <message>
1619 <location filename="../encttscfggui.cpp" line="98"/>
1620 <source>Cancel</source>
1621 <translation>Annuler</translation>
1622 </message>
1623 <message>
1624 <location filename="../encttscfggui.cpp" line="197"/>
1625 <source>Browse</source>
1626 <translation>Parcourir</translation>
1627 </message>
1628 <message>
1629 <location filename="../encttscfggui.cpp" line="205"/>
1630 <source>Refresh</source>
1631 <translation>Rafraîchir</translation>
1632 </message>
1633 <message>
1634 <location filename="../encttscfggui.cpp" line="377"/>
1635 <source>Select executable</source>
1636 <translation>Sélectionner l&apos;exécutable</translation>
1637 </message>
1638</context>
1639<context>
1640 <name>EncoderExe</name>
1641 <message>
1642 <location filename="../base/encoderexe.cpp" line="41"/>
1643 <source>Path to Encoder:</source>
1644 <translation>Chemin vers le moteur d&apos;encodage:</translation>
1645 </message>
1646 <message>
1647 <location filename="../base/encoderexe.cpp" line="43"/>
1648 <source>Encoder options:</source>
1649 <translation>Options du moteur d&apos;encodage:</translation>
1650 </message>
1651</context>
1652<context>
1653 <name>EncoderLame</name>
1654 <message>
1655 <location filename="../base/encoderlame.cpp" line="73"/>
1656 <location filename="../base/encoderlame.cpp" line="83"/>
1657 <source>LAME</source>
1658 <translation>LAME</translation>
1659 </message>
1660 <message>
1661 <location filename="../base/encoderlame.cpp" line="75"/>
1662 <source>Volume</source>
1663 <translation>Volume</translation>
1664 </message>
1665 <message>
1666 <location filename="../base/encoderlame.cpp" line="79"/>
1667 <source>Quality</source>
1668 <translation>Qualité</translation>
1669 </message>
1670 <message>
1671 <location filename="../base/encoderlame.cpp" line="83"/>
1672 <source>Could not find libmp3lame!</source>
1673 <translation>Impossible de trouver libmp3lame !</translation>
1674 </message>
1675</context>
1676<context>
1677 <name>EncoderRbSpeex</name>
1678 <message>
1679 <location filename="../base/encoderrbspeex.cpp" line="34"/>
1680 <source>Volume:</source>
1681 <translation>Volume:</translation>
1682 </message>
1683 <message>
1684 <location filename="../base/encoderrbspeex.cpp" line="36"/>
1685 <source>Quality:</source>
1686 <translation>Qualité:</translation>
1687 </message>
1688 <message>
1689 <location filename="../base/encoderrbspeex.cpp" line="38"/>
1690 <source>Complexity:</source>
1691 <translation>Complexité:</translation>
1692 </message>
1693 <message>
1694 <location filename="../base/encoderrbspeex.cpp" line="40"/>
1695 <source>Use Narrowband:</source>
1696 <translation>Utiliser le bas débit:</translation>
1697 </message>
1698</context>
1699<context>
1700 <name>InfoWidget</name>
1701 <message>
1702 <location filename="../gui/infowidget.cpp" line="30"/>
1703 <location filename="../gui/infowidget.cpp" line="107"/>
1704 <source>File</source>
1705 <translation>Fichier</translation>
1706 </message>
1707 <message>
1708 <location filename="../gui/infowidget.cpp" line="30"/>
1709 <location filename="../gui/infowidget.cpp" line="107"/>
1710 <source>Version</source>
1711 <translation>Version</translation>
1712 </message>
1713</context>
1714<context>
1715 <name>InfoWidgetFrm</name>
1716 <message>
1717 <location filename="../gui/infowidgetfrm.ui" line="14"/>
1718 <source>Info</source>
1719 <translation>Information</translation>
1720 </message>
1721 <message>
1722 <location filename="../gui/infowidgetfrm.ui" line="20"/>
1723 <source>Currently installed packages.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; if you manually installed packages this might not be correct!</source>
1724 <translation>Paquets actuellement installés.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt;Si vous avez installé manuellement des paquets, ceci ne sera peut-être pas correct !</translation>
1725 </message>
1726 <message>
1727 <location filename="../gui/infowidgetfrm.ui" line="34"/>
1728 <source>Package</source>
1729 <translation>Paquet</translation>
1730 </message>
1731</context>
1732<context>
1733 <name>InstallTalkFrm</name>
1734 <message>
1735 <location filename="../installtalkfrm.ui" line="17"/>
1736 <source>Install Talk Files</source>
1737 <translation>Installation des fichiers de voix</translation>
1738 </message>
1739 <message>
1740 <location filename="../installtalkfrm.ui" line="78"/>
1741 <source>TTS profile:</source>
1742 <translation>Profil TTS :</translation>
1743 </message>
1744 <message>
1745 <location filename="../installtalkfrm.ui" line="36"/>
1746 <source>Generation options</source>
1747 <translation>Options de génération</translation>
1748 </message>
1749 <message>
1750 <location filename="../installtalkfrm.ui" line="42"/>
1751 <source>Strip Extensions</source>
1752 <translation>Suppression des extensions</translation>
1753 </message>
1754 <message>
1755 <location filename="../installtalkfrm.ui" line="154"/>
1756 <source>&amp;Cancel</source>
1757 <translation>&amp;Annuler</translation>
1758 </message>
1759 <message>
1760 <location filename="../installtalkfrm.ui" line="143"/>
1761 <source>&amp;Install</source>
1762 <translation>&amp;Installer</translation>
1763 </message>
1764 <message>
1765 <location filename="../installtalkfrm.ui" line="52"/>
1766 <source>Generate for files</source>
1767 <translation>Générer pour les fichiers</translation>
1768 </message>
1769 <message>
1770 <location filename="../installtalkfrm.ui" line="85"/>
1771 <source>Generate for folders</source>
1772 <translation>Générer pour les dossiers</translation>
1773 </message>
1774 <message>
1775 <location filename="../installtalkfrm.ui" line="95"/>
1776 <source>Recurse into folders</source>
1777 <translation>Explorer l&apos;arborescence</translation>
1778 </message>
1779 <message>
1780 <location filename="../installtalkfrm.ui" line="111"/>
1781 <source>Change</source>
1782 <translation>Modifier</translation>
1783 </message>
1784 <message>
1785 <location filename="../installtalkfrm.ui" line="118"/>
1786 <source>Ignore files</source>
1787 <translation>Ignorer les fichiers</translation>
1788 </message>
1789 <message>
1790 <location filename="../installtalkfrm.ui" line="128"/>
1791 <source>Skip existing</source>
1792 <translation>Ignorer les existants</translation>
1793 </message>
1794 <message>
1795 <location filename="../installtalkfrm.ui" line="170"/>
1796 <source>Select folders for Talkfile generation (Ctrl for multiselect)</source>
1797 <translation>Sélectionnez les dossiers pour la génération des fichiers de voix (Ctrl pour en sélectionner plusieurs)</translation>
1798 </message>
1799</context>
1800<context>
1801 <name>InstallTalkWindow</name>
1802 <message>
1803 <source>&lt;b&gt;%1&lt;/b&gt;</source>
1804 <translation type="obsolete">&lt;b&gt;%1&lt;/b&gt;</translation>
1805 </message>
1806 <message>
1807 <location filename="../installtalkwindow.cpp" line="96"/>
1808 <source>Empty selection</source>
1809 <translation>Sélection vide</translation>
1810 </message>
1811 <message>
1812 <location filename="../installtalkwindow.cpp" line="97"/>
1813 <source>No files or folders selected. Please select files or folders first.</source>
1814 <translation>Pas de fichiers ou dossiers sélectionnés. Veuillez d&apos;abord sélectionner des fichiers ou des dossiers s&apos;il vous plait.</translation>
1815 </message>
1816 <message>
1817 <location filename="../installtalkwindow.cpp" line="137"/>
1818 <source>TTS error</source>
1819 <translation>Erreur TTS</translation>
1820 </message>
1821 <message>
1822 <location filename="../installtalkwindow.cpp" line="138"/>
1823 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1824 <translation>L&apos;initialisation du TTS sélectionné a échoué. Vous ne pouvez pas utiliser ce TTS.</translation>
1825 </message>
1826</context>
1827<context>
1828 <name>ManualWidget</name>
1829 <message>
1830 <location filename="../gui/manualwidget.cpp" line="44"/>
1831 <source>&lt;a href=&apos;%1&apos;&gt;PDF Manual&lt;/a&gt;</source>
1832 <translation>&lt;a href=&apos;%1&apos;&gt;Manuel PDF&lt;/a&gt;</translation>
1833 </message>
1834 <message>
1835 <location filename="../gui/manualwidget.cpp" line="46"/>
1836 <source>&lt;a href=&apos;%1&apos;&gt;HTML Manual (opens in browser)&lt;/a&gt;</source>
1837 <translation>&lt;a href=&apos;%1&apos;&gt;Manuel HTML (ouvre un navigateur)&lt;/a&gt;</translation>
1838 </message>
1839 <message>
1840 <location filename="../gui/manualwidget.cpp" line="50"/>
1841 <source>Select a device for a link to the correct manual</source>
1842 <translation>Sélectionnez un périphérique pour obtenir un lien vers le manuel approprié</translation>
1843 </message>
1844 <message>
1845 <location filename="../gui/manualwidget.cpp" line="51"/>
1846 <source>&lt;a href=&apos;%1&apos;&gt;Manual Overview&lt;/a&gt;</source>
1847 <translation>&lt;a href=&apos;%1&apos;&gt;Tous les manuels&lt;/a&gt;</translation>
1848 </message>
1849 <message>
1850 <location filename="../gui/manualwidget.cpp" line="62"/>
1851 <source>Confirm download</source>
1852 <translation>Confirmation du téléchargement</translation>
1853 </message>
1854 <message>
1855 <location filename="../gui/manualwidget.cpp" line="63"/>
1856 <source>Do you really want to download the manual? The manual will be saved to the root folder of your player.</source>
1857 <translation>Etes-vous sûr de vouloir télécharger le manuel ? Il sera sauvegardé dans le dossier racine de votre lecteur audio.</translation>
1858 </message>
1859</context>
1860<context>
1861 <name>ManualWidgetFrm</name>
1862 <message>
1863 <location filename="../gui/manualwidgetfrm.ui" line="14"/>
1864 <source>Manual</source>
1865 <translation>Manuel</translation>
1866 </message>
1867 <message>
1868 <location filename="../gui/manualwidgetfrm.ui" line="20"/>
1869 <source>Read the manual</source>
1870 <translation>Lire le manuel</translation>
1871 </message>
1872 <message>
1873 <location filename="../gui/manualwidgetfrm.ui" line="26"/>
1874 <source>PDF manual</source>
1875 <translation>Manuel PDF</translation>
1876 </message>
1877 <message>
1878 <location filename="../gui/manualwidgetfrm.ui" line="39"/>
1879 <source>HTML manual</source>
1880 <translation>Manuel HTML</translation>
1881 </message>
1882 <message>
1883 <location filename="../gui/manualwidgetfrm.ui" line="55"/>
1884 <source>Download the manual</source>
1885 <translation>Télécharger le manuel</translation>
1886 </message>
1887 <message>
1888 <location filename="../gui/manualwidgetfrm.ui" line="63"/>
1889 <source>&amp;PDF version</source>
1890 <translation>Version &amp;PDF</translation>
1891 </message>
1892 <message>
1893 <location filename="../gui/manualwidgetfrm.ui" line="70"/>
1894 <source>&amp;HTML version (zip file)</source>
1895 <translation>Version &amp;HTML (fichier zip)</translation>
1896 </message>
1897 <message>
1898 <location filename="../gui/manualwidgetfrm.ui" line="92"/>
1899 <source>Down&amp;load</source>
1900 <translation>Télé&amp;charger</translation>
1901 </message>
1902</context>
1903<context>
1904 <name>MsPackUtil</name>
1905 <message>
1906 <location filename="../base/mspackutil.cpp" line="101"/>
1907 <source>Creating output path failed</source>
1908 <translation>La création du chemin d&apos;accès cible a échoué</translation>
1909 </message>
1910 <message>
1911 <location filename="../base/mspackutil.cpp" line="109"/>
1912 <source>Error during CAB operation</source>
1913 <translation>Erreur pendant l&apos;opération CAB</translation>
1914 </message>
1915</context>
1916<context>
1917 <name>PreviewFrm</name>
1918 <message>
1919 <location filename="../previewfrm.ui" line="16"/>
1920 <source>Preview</source>
1921 <translation>Prévisualisation</translation>
1922 </message>
1923</context>
1924<context>
1925 <name>ProgressLoggerFrm</name>
1926 <message>
1927 <location filename="../progressloggerfrm.ui" line="13"/>
1928 <location filename="../progressloggerfrm.ui" line="19"/>
1929 <source>Progress</source>
1930 <translation>Avancement</translation>
1931 </message>
1932 <message>
1933 <location filename="../progressloggerfrm.ui" line="58"/>
1934 <source>Save Log</source>
1935 <translation>Sauvegarder l&apos;historique</translation>
1936 </message>
1937 <message>
1938 <location filename="../progressloggerfrm.ui" line="82"/>
1939 <source>&amp;Abort</source>
1940 <translation>&amp;Annuler</translation>
1941 </message>
1942 <message>
1943 <location filename="../progressloggerfrm.ui" line="32"/>
1944 <source>progresswindow</source>
1945 <translation>Progression</translation>
1946 </message>
1947</context>
1948<context>
1949 <name>ProgressLoggerGui</name>
1950 <message>
1951 <location filename="../progressloggergui.cpp" line="122"/>
1952 <source>&amp;Ok</source>
1953 <translation>&amp;OK</translation>
1954 </message>
1955 <message>
1956 <location filename="../progressloggergui.cpp" line="146"/>
1957 <source>Save system trace log</source>
1958 <translation>Sauvegarder l&apos;historique de la trace système</translation>
1959 </message>
1960 <message>
1961 <location filename="../progressloggergui.cpp" line="104"/>
1962 <source>&amp;Abort</source>
1963 <translation>&amp;Annuler</translation>
1964 </message>
1965</context>
1966<context>
1967 <name>QObject</name>
1968 <message>
1969 <location filename="../configure.cpp" line="625"/>
1970 <location filename="../main.cpp" line="83"/>
1971 <source>LTR</source>
1972 <extracomment>This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.
1973----------
1974This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.</extracomment>
1975 <translation></translation>
1976 </message>
1977 <message>
1978 <location filename="../base/system.cpp" line="385"/>
1979 <source>(unknown vendor name) </source>
1980 <translatorcomment>Je suppose que le nom du vendeur est l&apos;équivalent de la marque... nom du vendeur serait bizarre...</translatorcomment>
1981 <translation>(Marque du produit inconnue)</translation>
1982 </message>
1983 <message>
1984 <location filename="../base/system.cpp" line="403"/>
1985 <source>(unknown product name)</source>
1986 <translation>(Nom du produit inconnu)</translation>
1987 </message>
1988 <message>
1989 <location filename="../base/bootloaderinstallhelper.cpp" line="80"/>
1990 <source>Bootloader installation is almost complete. Installation &lt;b&gt;requires&lt;/b&gt; you to perform the following steps manually:</source>
1991 <translation>L&apos;installation du bootloader est presque complète. Vous &lt;b&gt;devez&lt;/b&gt; réaliser les étapes suivantes manuellement:</translation>
1992 </message>
1993 <message>
1994 <location filename="../base/bootloaderinstallhelper.cpp" line="86"/>
1995 <source>&lt;li&gt;Safely remove your player.&lt;/li&gt;</source>
1996 <translation>&lt;li&gt;Débranchez votre lecteur audio en toute sécurité.&lt;/li&gt;</translation>
1997 </message>
1998 <message>
1999 <location filename="../base/bootloaderinstallhelper.cpp" line="91"/>
2000 <source>&lt;li&gt;Reboot your player into the original firmware.&lt;/li&gt;&lt;li&gt;Perform a firmware upgrade using the update functionality of the original firmware. Please refer to your player&apos;s manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before starting the firmware update process.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
2001 <translation>&lt;li&gt;Redémarrez votre lecteur audio dans le firmware original.&lt;/li&gt;&lt;li&gt;Faites une mise à jour du logiciel en utilisant la fonctionnalité du firmware original. Veuillez vous référer au manuel du lecteur pour plus de détails.&lt;br/&gt;&lt;b&gt;Note importante:&lt;/b&gt;la mise à jour du logiciel est une étape critique qui ne doit en aucun cas être interrompue. &lt;b&gt;Assurez-vous que votre lecteur audio est rechargé avant de lancer une mise à jour.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Une fois la mise à jour effectuée, redémarrez votre lecteur audio.&lt;/li&gt;</translation>
2002 </message>
2003 <message>
2004 <location filename="../base/bootloaderinstallhelper.cpp" line="102"/>
2005 <source>&lt;li&gt;Remove any previously inserted microSD card&lt;/li&gt;</source>
2006 <translation>&lt;li&gt;Retirez toute card microSD insérée&lt;/li&gt;</translation>
2007 </message>
2008 <message>
2009 <location filename="../base/bootloaderinstallhelper.cpp" line="103"/>
2010 <source>&lt;li&gt;Disconnect your player. The player will reboot and perform an update of the original firmware. Please refer to your players manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before disconnecting the player.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
2011 <translation>&lt;li&gt;Déconnectez votre lecteur audio. Celui-ci va redémarrer et faire une mise à jour du logiciel. Veuillez vous référer au manuel du lecteur pour plus de détails.&lt;br/&gt;&lt;b&gt;Note importante:&lt;/b&gt; la mise à jour du logiciel est une étape critique qui ne doit en aucun cas être interrompue. &lt;b&gt;Assurez-vous que votre lecteur est rechargé avant de le déconnecter.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Une fois la mise à jour effectuée, redémarrez votre lecteur.&lt;/li&gt;</translation>
2012 </message>
2013 <message>
2014 <location filename="../base/bootloaderinstallhelper.cpp" line="114"/>
2015 <source>&lt;li&gt;Turn the player off&lt;/li&gt;&lt;li&gt;Insert the charger&lt;/li&gt;</source>
2016 <translation>&lt;li&gt;Éteignez votre lecteur audio&lt;/li&gt;&lt;li&gt;Insérer le chargeur&lt;/li&gt;</translation>
2017 </message>
2018 <message>
2019 <location filename="../base/bootloaderinstallhelper.cpp" line="119"/>
2020 <source>&lt;li&gt;Unplug USB and power adaptors&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to turn the player off&lt;/li&gt;&lt;li&gt;Toggle the battery switch on the player&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to boot into Rockbox&lt;/li&gt;</source>
2021 <translation>Débranchez le cable USB et celui d&apos;alimentation&lt;/li&gt;&lt;li&gt;Maintenez le &lt;i&gt;Bouton d&apos;alimentation&lt;/i&gt; pressé pour éteindre le lecteur&lt;/li&gt;&lt;li&gt;Basculez l&apos;interrupteur&lt;/li&gt;&lt;li&gt;Maintenez le &lt;i&gt;Bouton d&apos;alimentation&lt;/i&gt; pressé pour démarrer Rockbox&lt;/li&gt;</translation>
2022 </message>
2023 <message>
2024 <location filename="../base/bootloaderinstallhelper.cpp" line="125"/>
2025 <source>&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You can safely install other parts first, but the above steps are &lt;b&gt;required&lt;/b&gt; to finish the installation!&lt;/p&gt;</source>
2026 <translation>&lt;p&gt;&lt;b&gt;Remarque:&lt;/b&gt; Vous pouvez commencer par installer d&apos;autres parties de Rockbox, mais n&apos;oubliez pas que les étapes suivantes sont &lt;b&gt;nécessaire&lt;/b&gt; pour finir l&apos;installation !&lt;/p&gt;</translation>
2027 </message>
2028</context>
2029<context>
2030 <name>QuaZipFile</name>
2031 <message>
2032 <location filename="../quazip/quazipfile.cpp" line="141"/>
2033 <source>ZIP/UNZIP API error %1</source>
2034 <translation>Erreur de l&apos;API ZIP/UNZIP : %1</translation>
2035 </message>
2036</context>
2037<context>
2038 <name>RbUtilQt</name>
2039 <message>
2040 <location filename="../rbutilqt.cpp" line="224"/>
2041 <source>Downloading build information, please wait ...</source>
2042 <translation>Téléchargement des informations de version, veuillez patienter...</translation>
2043 </message>
2044 <message>
2045 <location filename="../rbutilqt.cpp" line="235"/>
2046 <source>Can&apos;t get version information!</source>
2047 <translation>Impossible de récupérer les informations de version !</translation>
2048 </message>
2049 <message>
2050 <location filename="../rbutilqt.cpp" line="249"/>
2051 <source>Download build information finished.</source>
2052 <translation>Le téléchargement des informations de version est terminé.</translation>
2053 </message>
2054 <message>
2055 <location filename="../rbutilqt.cpp" line="450"/>
2056 <source>Confirm Installation</source>
2057 <translation>Confirmation de l&apos;installation</translation>
2058 </message>
2059 <message>
2060 <location filename="../rbutilqt.cpp" line="582"/>
2061 <source>Mount point is wrong!</source>
2062 <translation>Le point de montage est erroné !</translation>
2063 </message>
2064 <message>
2065 <location filename="../rbutilqt.cpp" line="430"/>
2066 <source>No Rockbox installation found</source>
2067 <translation>Aucune installation de Rockbox n&apos;a été trouvé</translation>
2068 </message>
2069 <message>
2070 <location filename="../rbutilqt.cpp" line="431"/>
2071 <source>Could not determine the installed Rockbox version. Please install a Rockbox build before installing voice files.</source>
2072 <translation>Impossible de déterminer la version de Rockbox installée. Veuillez installer Rockbox avant d&apos;installer les fichiers de voix.</translation>
2073 </message>
2074 <message>
2075 <location filename="../rbutilqt.cpp" line="451"/>
2076 <source>Do you really want to install the voice file?</source>
2077 <translation>Etes-vous sûr de vouloir installer le fichier de voix ?</translation>
2078 </message>
2079 <message>
2080 <location filename="../rbutilqt.cpp" line="439"/>
2081 <source>No voice file available</source>
2082 <translation>Aucun fichier de voix disponible</translation>
2083 </message>
2084 <message>
2085 <location filename="../rbutilqt.cpp" line="440"/>
2086 <source>The installed version of Rockbox is a development version. Pre-built voices are only available for release versions of Rockbox. Please generate a voice yourself using the &quot;Create voice file&quot; functionality.</source>
2087 <translation>La version de Rockbox installée est une version de dévelopement. Des fichiers de voix précalculés sont uniquement disponible pour les versions stables de Rockbox. Veuillez générer des fichiers de voix en utilisant la fonctionnalité &quot;Création de fichiers de voix&quot;.</translation>
2088 </message>
2089 <message>
2090 <location filename="../rbutilqt.cpp" line="512"/>
2091 <source>Confirm Uninstallation</source>
2092 <translation>Confirmation de la désinstallation</translation>
2093 </message>
2094 <message>
2095 <location filename="../rbutilqt.cpp" line="513"/>
2096 <source>Do you really want to uninstall the Bootloader?</source>
2097 <translation>Etes-vous sûr de vouloir désinstaller le bootloader ?</translation>
2098 </message>
2099 <message>
2100 <location filename="../rbutilqt.cpp" line="528"/>
2101 <source>No uninstall method for this target known.</source>
2102 <translation>Aucune méthode de désinstallation n&apos;est connue pour cette plateforme.</translation>
2103 </message>
2104 <message>
2105 <location filename="../rbutilqt.cpp" line="542"/>
2106 <source>Rockbox Utility can not uninstall the bootloader on this target. Try a normal firmware update to remove the booloader.</source>
2107 <translation>L&apos;utilitaire Rockbox ne peut pas désinstaller le bootloader. Essayez de faire une mise à jour normale du firmware pour supprimer le bootloader.</translation>
2108 </message>
2109 <message>
2110 <location filename="../rbutilqt.cpp" line="550"/>
2111 <source>No Rockbox bootloader found.</source>
2112 <translation>Le bootloader de Rockbox n&apos;a pas été trouvé.</translation>
2113 </message>
2114 <message>
2115 <location filename="../rbutilqt.cpp" line="568"/>
2116 <source>Confirm installation</source>
2117 <translation>Confirmation de l&apos;installation</translation>
2118 </message>
2119 <message>
2120 <location filename="../rbutilqt.cpp" line="569"/>
2121 <source>Do you really want to install Rockbox Utility to your player? After installation you can run it from the players hard drive.</source>
2122 <translation>Etes-vous sûr de vouloir installer l&apos;utilitaire Rockbox sur votre lecteur audio ? Après l&apos;installation vous pourrez le lancer depuis le disque dur de votre lecteur audio.</translation>
2123 </message>
2124 <message>
2125 <location filename="../rbutilqt.cpp" line="578"/>
2126 <source>Installing Rockbox Utility</source>
2127 <translation>Installation de l&apos;utilitaire Rockbox</translation>
2128 </message>
2129 <message>
2130 <location filename="../rbutilqt.cpp" line="596"/>
2131 <source>Error installing Rockbox Utility</source>
2132 <translation>Erreur pendant l&apos;installation de l&apos;utilitaire Rockbox</translation>
2133 </message>
2134 <message>
2135 <location filename="../rbutilqt.cpp" line="600"/>
2136 <source>Installing user configuration</source>
2137 <translation>Installation de la configuration utilisateur</translation>
2138 </message>
2139 <message>
2140 <location filename="../rbutilqt.cpp" line="604"/>
2141 <source>Error installing user configuration</source>
2142 <translation>Erreur pendant l&apos;installation de la configuration utilisateur</translation>
2143 </message>
2144 <message>
2145 <location filename="../rbutilqt.cpp" line="608"/>
2146 <source>Successfully installed Rockbox Utility.</source>
2147 <translation>Installation de l&apos;utilitaire Rockbox terminée avec succès.</translation>
2148 </message>
2149 <message>
2150 <location filename="../rbutilqt.cpp" line="664"/>
2151 <source>Checking for update ...</source>
2152 <translation>Vérification des mises à jour...</translation>
2153 </message>
2154 <message>
2155 <location filename="../rbutilqt.cpp" line="729"/>
2156 <source>RockboxUtility Update available</source>
2157 <translation>Une mise à jour de l&apos;utilitaire Rockbox est disponible</translation>
2158 </message>
2159 <message>
2160 <location filename="../rbutilqt.cpp" line="730"/>
2161 <source>&lt;b&gt;New RockboxUtility Version available.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Download it from here: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</source>
2162 <translation>&lt;b&gt;Une nouvelle version de l&apos;utilitaire de Rockbox est disponible.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Vous pouvez la télécharger ici: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</translation>
2163 </message>
2164 <message>
2165 <location filename="../rbutilqt.cpp" line="733"/>
2166 <source>New version of Rockbox Utility available.</source>
2167 <translation>Une nouvelle version de l&apos;utilitaire Rockbox est disponible.</translation>
2168 </message>
2169 <message>
2170 <location filename="../rbutilqt.cpp" line="736"/>
2171 <source>Rockbox Utility is up to date.</source>
2172 <translation>L&apos;utilitaire Rockbox est à jour.</translation>
2173 </message>
2174 <message>
2175 <location filename="../rbutilqt.cpp" line="759"/>
2176 <source>Device ejected</source>
2177 <translation>Périphérique éjecté</translation>
2178 </message>
2179 <message>
2180 <location filename="../rbutilqt.cpp" line="760"/>
2181 <source>Device successfully ejected. You may now disconnect the player from the PC.</source>
2182 <translation>Périphérique éjecté avec succès. Vous pouvez maintenant déconnecter le lecteur du PC.</translation>
2183 </message>
2184 <message>
2185 <location filename="../rbutilqt.cpp" line="764"/>
2186 <source>Ejecting failed</source>
2187 <translation>L&apos;éjection a échoué</translation>
2188 </message>
2189 <message>
2190 <location filename="../rbutilqt.cpp" line="765"/>
2191 <source>Ejecting the device failed. Please make sure no programs are accessing files on the device. If ejecting still fails please use your computers eject funtionality.</source>
2192 <translation>L&apos;éjection du périphérique a échoué. Veuillez vérifier que les fichiers sur le lecteur ne sont pas utilisés par un autre programme. Si l&apos;éjection échoue à nouveau, veuillez utiliser la fonction d&apos;éjection de votre ordinateur s&apos;il vous plait. </translation>
2193 </message>
2194 <message>
2195 <location filename="../rbutilqt.cpp" line="337"/>
2196 <location filename="../rbutilqt.cpp" line="642"/>
2197 <source>Configuration error</source>
2198 <translation>Erreur de configuration</translation>
2199 </message>
2200 <message>
2201 <location filename="../rbutilqt.cpp" line="643"/>
2202 <source>Your configuration is invalid. Please go to the configuration dialog and make sure the selected values are correct.</source>
2203 <translation>Votre configuration est invalide. Veuillez vérifier dans la fenêtre de configuration que les valeurs sélectionnées soient correctes.</translation>
2204 </message>
2205 <message>
2206 <location filename="../rbutilqt.cpp" line="330"/>
2207 <source>This is a new installation of Rockbox Utility, or a new version. The configuration dialog will now open to allow you to setup the program, or review your settings.</source>
2208 <translation>Ceci est une nouvelle installation de l&apos;utilitaire Rockbox, ou l&apos;installation d&apos;une nouvelle version. La fenêtre de configuration va s&apos;ouvrir pour vous permettre de paramétrer le programme ou de vérifier les réglages.</translation>
2209 </message>
2210 <message>
2211 <location filename="../rbutilqt.cpp" line="110"/>
2212 <source>Wine detected!</source>
2213 <translation>Wine détecté !</translation>
2214 </message>
2215 <message>
2216 <location filename="../rbutilqt.cpp" line="111"/>
2217 <source>It seems you are trying to run this program under Wine. Please don&apos;t do this, running under Wine will fail. Use the native Linux binary instead.</source>
2218 <translation>Il semblerait que vous essayiez de faire fonctionner ce programme avec Wine. Ne faites pas cela car cela va échouer. Utilisez la version native pour Linux à la place.</translation>
2219 </message>
2220 <message>
2221 <location filename="../rbutilqt.cpp" line="237"/>
2222 <source>Can&apos;t get version information.
2223Network error: %1. Please check your network and proxy settings.</source>
2224 <translation>Impossible de récupérer les informations de version.
2225Erreur réseau: %1. Veuillez vérifier vos paramètres réseau et proxy.</translation>
2226 </message>
2227 <message>
2228 <location filename="../rbutilqt.cpp" line="416"/>
2229 <source>Warning</source>
2230 <translation>Avertissement</translation>
2231 </message>
2232 <message>
2233 <location filename="../rbutilqt.cpp" line="417"/>
2234 <source>The Application is still downloading Information about new Builds. Please try again shortly.</source>
2235 <translation>L&apos;application est encore en train de télécharger les informations sur les dernières versions. Veuillez réessayer dans un instant.</translation>
2236 </message>
2237 <message>
2238 <location filename="../rbutilqt.cpp" line="329"/>
2239 <source>New installation</source>
2240 <translation>Nouvelle installation</translation>
2241 </message>
2242 <message>
2243 <location filename="../rbutilqt.cpp" line="338"/>
2244 <source>Your configuration is invalid. This is most likely due to a changed device path. The configuration dialog will now open to allow you to correct the problem.</source>
2245 <translation>Votre configuration est invalide. Ceci est probablement dû à un changement du chemin du périphérique. La fenêtre de configuration va s&apos;ouvrir pour vous permettre de corriger le problème.</translation>
2246 </message>
2247 <message>
2248 <location filename="../rbutilqt.cpp" line="236"/>
2249 <source>Network error</source>
2250 <translation>Erreur de réseau</translation>
2251 </message>
2252</context>
2253<context>
2254 <name>RbUtilQtFrm</name>
2255 <message>
2256 <location filename="../rbutilqtfrm.ui" line="14"/>
2257 <source>Rockbox Utility</source>
2258 <translation>Utilitaire Rockbox</translation>
2259 </message>
2260 <message>
2261 <location filename="../rbutilqtfrm.ui" line="31"/>
2262 <source>Device</source>
2263 <translation>Périphérique</translation>
2264 </message>
2265 <message>
2266 <location filename="../rbutilqtfrm.ui" line="92"/>
2267 <source>&amp;Change</source>
2268 <translation>&amp;Modifier</translation>
2269 </message>
2270 <message>
2271 <location filename="../rbutilqtfrm.ui" line="163"/>
2272 <source>Welcome</source>
2273 <translation>Bienvenue</translation>
2274 </message>
2275 <message>
2276 <location filename="../rbutilqtfrm.ui" line="160"/>
2277 <location filename="../rbutilqtfrm.ui" line="658"/>
2278 <source>&amp;Installation</source>
2279 <translation>&amp;Installation</translation>
2280 </message>
2281 <message>
2282 <location filename="../rbutilqtfrm.ui" line="168"/>
2283 <location filename="../rbutilqtfrm.ui" line="450"/>
2284 <source>&amp;Accessibility</source>
2285 <translation>&amp;Accessibilité</translation>
2286 </message>
2287 <message>
2288 <location filename="../rbutilqtfrm.ui" line="171"/>
2289 <source>Install accessibility add-ons</source>
2290 <translation>Installer des add-ons pour l&apos;accessibilité</translation>
2291 </message>
2292 <message>
2293 <location filename="../rbutilqtfrm.ui" line="177"/>
2294 <source>Install Voice files</source>
2295 <translation>Installer des fichiers de voix</translation>
2296 </message>
2297 <message>
2298 <location filename="../rbutilqtfrm.ui" line="204"/>
2299 <source>Install Talk files</source>
2300 <translation>Installer des fichiers de voix</translation>
2301 </message>
2302 <message>
2303 <location filename="../rbutilqtfrm.ui" line="458"/>
2304 <source>&amp;Uninstallation</source>
2305 <translation>&amp;Désinstallation</translation>
2306 </message>
2307 <message>
2308 <location filename="../rbutilqtfrm.ui" line="286"/>
2309 <location filename="../rbutilqtfrm.ui" line="319"/>
2310 <source>Uninstall Rockbox</source>
2311 <translation>Désinstaller Rockbox</translation>
2312 </message>
2313 <message>
2314 <location filename="../rbutilqtfrm.ui" line="121"/>
2315 <source>mountpoint unknown or invalid</source>
2316 <translation>point de montage inconnu ou invalide</translation>
2317 </message>
2318 <message>
2319 <location filename="../rbutilqtfrm.ui" line="114"/>
2320 <source>Mountpoint:</source>
2321 <translation>Point de montage:</translation>
2322 </message>
2323 <message>
2324 <location filename="../rbutilqtfrm.ui" line="72"/>
2325 <source>device unknown or invalid</source>
2326 <translation>périphérique inconnu ou invalide</translation>
2327 </message>
2328 <message>
2329 <location filename="../rbutilqtfrm.ui" line="65"/>
2330 <source>Device:</source>
2331 <translation>Périphérique:</translation>
2332 </message>
2333 <message>
2334 <location filename="../rbutilqtfrm.ui" line="292"/>
2335 <source>Uninstall Bootloader</source>
2336 <translation>Désinstaller le bootloader</translation>
2337 </message>
2338 <message>
2339 <location filename="../rbutilqtfrm.ui" line="393"/>
2340 <source>&amp;Manual</source>
2341 <translation>&amp;Manuel</translation>
2342 </message>
2343 <message>
2344 <location filename="../rbutilqtfrm.ui" line="396"/>
2345 <source>View and download the manual</source>
2346 <translation>Voir et télécharger le manuel</translation>
2347 </message>
2348 <message>
2349 <location filename="../rbutilqtfrm.ui" line="401"/>
2350 <source>Inf&amp;o</source>
2351 <translation>Inf&amp;o</translation>
2352 </message>
2353 <message>
2354 <location filename="../rbutilqtfrm.ui" line="419"/>
2355 <source>&amp;File</source>
2356 <translation>&amp;Fichier</translation>
2357 </message>
2358 <message>
2359 <location filename="../rbutilqtfrm.ui" line="432"/>
2360 <source>&amp;Troubleshoot</source>
2361 <translation>&amp;Dépannage</translation>
2362 </message>
2363 <message>
2364 <location filename="../rbutilqtfrm.ui" line="497"/>
2365 <source>&amp;About</source>
2366 <translation>&amp;A propos</translation>
2367 </message>
2368 <message>
2369 <location filename="../rbutilqtfrm.ui" line="653"/>
2370 <source>System &amp;Trace</source>
2371 <translation>&amp;Trace système</translation>
2372 </message>
2373 <message>
2374 <location filename="../rbutilqtfrm.ui" line="474"/>
2375 <source>Empty local download cache</source>
2376 <translation>Vider le cache local de téléchargement</translation>
2377 </message>
2378 <message>
2379 <location filename="../rbutilqtfrm.ui" line="479"/>
2380 <source>Install Rockbox Utility on player</source>
2381 <translation>Installer l&apos;utilitaire Rockbox sur le lecteur</translation>
2382 </message>
2383 <message>
2384 <location filename="../rbutilqtfrm.ui" line="484"/>
2385 <source>&amp;Configure</source>
2386 <translation>&amp;Configuration</translation>
2387 </message>
2388 <message>
2389 <location filename="../rbutilqtfrm.ui" line="489"/>
2390 <source>E&amp;xit</source>
2391 <translation>&amp;Quitter</translation>
2392 </message>
2393 <message>
2394 <location filename="../rbutilqtfrm.ui" line="492"/>
2395 <source>Ctrl+Q</source>
2396 <translation>Ctrl+Q</translation>
2397 </message>
2398 <message>
2399 <location filename="../rbutilqtfrm.ui" line="502"/>
2400 <source>About &amp;Qt</source>
2401 <translation>A propos de &amp;Qt</translation>
2402 </message>
2403 <message>
2404 <location filename="../rbutilqtfrm.ui" line="428"/>
2405 <location filename="../rbutilqtfrm.ui" line="507"/>
2406 <source>&amp;Help</source>
2407 <translation>&amp;Aide</translation>
2408 </message>
2409 <message>
2410 <location filename="../rbutilqtfrm.ui" line="446"/>
2411 <source>Action&amp;s</source>
2412 <translation>Action&amp;s</translation>
2413 </message>
2414 <message>
2415 <location filename="../rbutilqtfrm.ui" line="512"/>
2416 <source>Info</source>
2417 <translation>Information</translation>
2418 </message>
2419 <message>
2420 <location filename="../rbutilqtfrm.ui" line="616"/>
2421 <source>Read PDF manual</source>
2422 <translation>Lire le manuel PDF</translation>
2423 </message>
2424 <message>
2425 <location filename="../rbutilqtfrm.ui" line="621"/>
2426 <source>Read HTML manual</source>
2427 <translation>Lire le manuel HTML</translation>
2428 </message>
2429 <message>
2430 <location filename="../rbutilqtfrm.ui" line="626"/>
2431 <source>Download PDF manual</source>
2432 <translation>Télécharger le manuel PDF</translation>
2433 </message>
2434 <message>
2435 <location filename="../rbutilqtfrm.ui" line="631"/>
2436 <source>Download HTML manual (zip)</source>
2437 <translation>Télécharger le manuel HTML (zip)</translation>
2438 </message>
2439 <message>
2440 <location filename="../rbutilqtfrm.ui" line="254"/>
2441 <source>Create Voice files</source>
2442 <translation>Créer des fichiers de voix</translation>
2443 </message>
2444 <message>
2445 <location filename="../rbutilqtfrm.ui" line="643"/>
2446 <source>Create Voice File</source>
2447 <translation>Créer un fichier de voix</translation>
2448 </message>
2449 <message>
2450 <location filename="../rbutilqtfrm.ui" line="194"/>
2451 <source>&lt;b&gt;Install Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so if you installed the voice file Rockbox will speak.</source>
2452 <translation>&lt;b&gt;Installer le fichier de voix&lt;/b&gt;&lt;br/&gt;Celui-ci est requis pour que Rockbox parle. La synthèse vocale est activée par défaut, donc si vous installez le fichier de voix, Rockbox parlera.</translation>
2453 </message>
2454 <message>
2455 <location filename="../rbutilqtfrm.ui" line="103"/>
2456 <source>&amp;Eject</source>
2457 <translation>&amp;Ejecter</translation>
2458 </message>
2459 <message>
2460 <location filename="../rbutilqtfrm.ui" line="221"/>
2461 <source>&lt;b&gt;Create Talk Files&lt;/b&gt;&lt;br/&gt;Talkfiles are needed to let Rockbox speak File and Foldernames</source>
2462 <translation>&lt;b&gt;Créer des fichiers d&apos;annonce&lt;/b&gt;&lt;br/&gt;Ceux-ci sont nécessaires pour que Rockbox énonce les noms des fichiers et des dossiers</translation>
2463 </message>
2464 <message>
2465 <location filename="../rbutilqtfrm.ui" line="271"/>
2466 <source>&lt;b&gt;Create Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so
2467 if you installed the voice file Rockbox will speak.</source>
2468 <translation>&lt;b&gt;Créer le fichier de voix&lt;/b&gt;&lt;br/&gt;celui-ci est requis pour que Rockbox parle. La synthèse vocale est activée par défaut, donc si vous installez le fichier de voix, Rockbox parlera.</translation>
2469 </message>
2470 <message>
2471 <location filename="../rbutilqtfrm.ui" line="283"/>
2472 <source>Backup &amp;&amp; &amp;Uninstallation</source>
2473 <translation>Sauvegarde &amp;&amp; &amp;Désinstallation</translation>
2474 </message>
2475 <message>
2476 <location filename="../rbutilqtfrm.ui" line="309"/>
2477 <source>&lt;b&gt;Remove the bootloader&lt;/b&gt;&lt;br/&gt;After removing the bootloader you won&apos;t be able to start Rockbox.</source>
2478 <translation>&lt;b&gt;Désinstaller le bootloader&lt;/b&gt;&lt;br/&gt;Après avoir supprimé le bootloader, vous ne pourrez plus démarrer Rockbox.</translation>
2479 </message>
2480 <message>
2481 <location filename="../rbutilqtfrm.ui" line="336"/>
2482 <source>&lt;b&gt;Uninstall Rockbox from your audio player.&lt;/b&gt;&lt;br/&gt;This will leave the bootloader in place (you need to remove it manually).</source>
2483 <translation>&lt;b&gt;Désinstaller Rockbox de votre lecteur audio&lt;/b&gt;&lt;br/&gt;Ceci laissera le bootloader (vous devrez le supprimer manuellement).</translation>
2484 </message>
2485 <message>
2486 <location filename="../rbutilqtfrm.ui" line="349"/>
2487 <source>Backup</source>
2488 <translation>Sauvegarde</translation>
2489 </message>
2490 <message>
2491 <location filename="../rbutilqtfrm.ui" line="366"/>
2492 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup current installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Create a backup by archiving the contents of the Rockbox installation folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2493 <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Sauvegarder l&apos;installation courante.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Créer une sauvegarde en archivant le contenu du dossier de Rockbox.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
2494 </message>
2495 <message>
2496 <location filename="../rbutilqtfrm.ui" line="539"/>
2497 <source>Install &amp;Bootloader</source>
2498 <translation>Installer le &amp;bootloader</translation>
2499 </message>
2500 <message>
2501 <location filename="../rbutilqtfrm.ui" line="548"/>
2502 <source>Install &amp;Rockbox</source>
2503 <translation>Installer &amp;Rockbox</translation>
2504 </message>
2505 <message>
2506 <location filename="../rbutilqtfrm.ui" line="557"/>
2507 <source>Install &amp;Fonts Package</source>
2508 <translation>Installer le pack des &amp;polices de caractères</translation>
2509 </message>
2510 <message>
2511 <location filename="../rbutilqtfrm.ui" line="566"/>
2512 <source>Install &amp;Themes</source>
2513 <translation>Installer des &amp;thèmes</translation>
2514 </message>
2515 <message>
2516 <location filename="../rbutilqtfrm.ui" line="575"/>
2517 <source>Install &amp;Game Files</source>
2518 <translation>Installer les fichiers de &amp;jeux</translation>
2519 </message>
2520 <message>
2521 <location filename="../rbutilqtfrm.ui" line="584"/>
2522 <source>&amp;Install Voice File</source>
2523 <translation>&amp;Installer le fichier de voix</translation>
2524 </message>
2525 <message>
2526 <location filename="../rbutilqtfrm.ui" line="593"/>
2527 <source>Create &amp;Talk Files</source>
2528 <translation>Créer les fichiers d&apos;&amp;annonce</translation>
2529 </message>
2530 <message>
2531 <location filename="../rbutilqtfrm.ui" line="602"/>
2532 <source>Remove &amp;bootloader</source>
2533 <translation>Désinstaller le &amp;bootloader</translation>
2534 </message>
2535 <message>
2536 <location filename="../rbutilqtfrm.ui" line="611"/>
2537 <source>Uninstall &amp;Rockbox</source>
2538 <translation>Désinstaller &amp;Rockbox</translation>
2539 </message>
2540 <message>
2541 <location filename="../rbutilqtfrm.ui" line="640"/>
2542 <source>Create &amp;Voice File</source>
2543 <translation>&amp;Créer le fichier de voix</translation>
2544 </message>
2545 <message>
2546 <location filename="../rbutilqtfrm.ui" line="648"/>
2547 <source>&amp;System Info</source>
2548 <translation>Informations &amp;système</translation>
2549 </message>
2550 <message>
2551 <location filename="../rbutilqtfrm.ui" line="663"/>
2552 <source>Show &amp;Changelog</source>
2553 <translation>Montrer l&apos;&amp;historique des modifications</translation>
2554 </message>
2555 <message>
2556 <location filename="../rbutilqtfrm.ui" line="521"/>
2557 <source>&amp;Complete Installation</source>
2558 <translation>Installation &amp;complète</translation>
2559 </message>
2560 <message>
2561 <location filename="../rbutilqtfrm.ui" line="530"/>
2562 <source>&amp;Minimal Installation</source>
2563 <translation>Installation &amp;minimale</translation>
2564 </message>
2565</context>
2566<context>
2567 <name>SelectiveInstallWidget</name>
2568 <message>
2569 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="20"/>
2570 <source>Selective Installation</source>
2571 <translation>Installation personnalisée</translation>
2572 </message>
2573 <message>
2574 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="26"/>
2575 <source>Rockbox version to install</source>
2576 <translation>Version de Rockbox à installer</translation>
2577 </message>
2578 <message>
2579 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="35"/>
2580 <source>Version information not available yet.</source>
2581 <translation>Les informations de version ne sont pas encore disponibles.</translation>
2582 </message>
2583 <message>
2584 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="54"/>
2585 <source>Rockbox components to install</source>
2586 <translation>Composants de Rockbox à installer</translation>
2587 </message>
2588 <message>
2589 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="60"/>
2590 <source>&amp;Bootloader</source>
2591 <translation>&amp;Bootloader</translation>
2592 </message>
2593 <message>
2594 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="80"/>
2595 <source>The main Rockbox firmware.</source>
2596 <translation>Le logiciel principal de Rockbox.</translation>
2597 </message>
2598 <message>
2599 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="90"/>
2600 <source>Fonts</source>
2601 <translation>Polices</translation>
2602 </message>
2603 <message>
2604 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="104"/>
2605 <source>&amp;Rockbox</source>
2606 <translation>&amp;Rockbox</translation>
2607 </message>
2608 <message>
2609 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="124"/>
2610 <source>Some game plugins require additional files.</source>
2611 <translation>Certains plugins de jeu nécessitent des fichiers additionnels.</translation>
2612 </message>
2613 <message>
2614 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="140"/>
2615 <source>Additional fonts for the User Interface.</source>
2616 <translation>Polices additionnelles pour l&apos;interface utilisateur.</translation>
2617 </message>
2618 <message>
2619 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="156"/>
2620 <source>The bootloader is required for starting Rockbox. Only necessary for first time install.</source>
2621 <translation>Le bootloader est nécessaire pour démarrer Rockbox. Son installation n&apos;est nécessaire que lors de la première installation.</translation>
2622 </message>
2623 <message>
2624 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="166"/>
2625 <source>Game Files</source>
2626 <translation>Fichiers de jeux</translation>
2627 </message>
2628 <message>
2629 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="177"/>
2630 <source>Customize</source>
2631 <translation>Personnaliser</translation>
2632 </message>
2633 <message>
2634 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="188"/>
2635 <source>Themes</source>
2636 <translation>Thèmes</translation>
2637 </message>
2638 <message>
2639 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="205"/>
2640 <source>Themes allow adjusting the user interface of Rockbox. Use &quot;Customize&quot; to select themes.</source>
2641 <translation>Les thèmes permettent de modifier l&apos;interface utilisateur de Rockbox. Utilisez &quot;Personnaliser&quot; pour sélectionner les thèmes.</translation>
2642 </message>
2643 <message>
2644 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="250"/>
2645 <source>&amp;Install</source>
2646 <translation>&amp;Installer</translation>
2647 </message>
2648 <message>
2649 <location filename="../gui/selectiveinstallwidget.cpp" line="67"/>
2650 <source>This is the latest stable release available.</source>
2651 <translation>Ceci est la dernière version stable de Rockbox disponible.</translation>
2652 </message>
2653 <message>
2654 <location filename="../gui/selectiveinstallwidget.cpp" line="70"/>
2655 <source>The development version is updated on every code change. Last update was on %1</source>
2656 <translation>La version de dévelopment est mise à jour à chaque changement du code. La dernière mise à jour a eu lieu le %1</translation>
2657 </message>
2658 <message>
2659 <location filename="../gui/selectiveinstallwidget.cpp" line="74"/>
2660 <source>This will eventually become the next Rockbox version. Install it to help testing.</source>
2661 <translation>Cette version est vouée à devenir la prochaine version stable. Installez-là pour la tester.</translation>
2662 </message>
2663 <message>
2664 <location filename="../gui/selectiveinstallwidget.cpp" line="100"/>
2665 <source>Stable Release (Version %1)</source>
2666 <translation>Version stable (Version %1)</translation>
2667 </message>
2668 <message>
2669 <location filename="../gui/selectiveinstallwidget.cpp" line="104"/>
2670 <source>Development Version (Revison %1)</source>
2671 <translation>Version de dévelopement (Révision %1)</translation>
2672 </message>
2673 <message>
2674 <location filename="../gui/selectiveinstallwidget.cpp" line="108"/>
2675 <source>Release Candidate (Revison %1)</source>
2676 <translation>Version pré-stable (Révision %1)</translation>
2677 </message>
2678 <message>
2679 <location filename="../gui/selectiveinstallwidget.cpp" line="131"/>
2680 <source>The selected player doesn&apos;t need a bootloader.</source>
2681 <translation>Le lecteur audio sélectionné ne nécessite pas l&apos;installation d&apos;un bootloader.</translation>
2682 </message>
2683 <message>
2684 <location filename="../gui/selectiveinstallwidget.cpp" line="136"/>
2685 <source>The bootloader is required for starting Rockbox. Installation of the bootloader is only necessary on first time installation.</source>
2686 <translation>Le bootloader est nécessaire pour démarrer Rockbox. Son installation n&apos;est nécessaire que lors de la première installation.</translation>
2687 </message>
2688 <message>
2689 <location filename="../gui/selectiveinstallwidget.cpp" line="183"/>
2690 <source>Mountpoint is wrong</source>
2691 <translation>Le point de montage est erroné</translation>
2692 </message>
2693 <message>
2694 <location filename="../gui/selectiveinstallwidget.cpp" line="239"/>
2695 <source>No install method known.</source>
2696 <translation>Aucune méthode d&apos;installation n&apos;est connue.</translation>
2697 </message>
2698 <message>
2699 <location filename="../gui/selectiveinstallwidget.cpp" line="266"/>
2700 <source>Bootloader detected</source>
2701 <translation>Le bootloader a été détecté</translation>
2702 </message>
2703 <message>
2704 <location filename="../gui/selectiveinstallwidget.cpp" line="267"/>
2705 <source>Bootloader already installed. Do you want to reinstall the bootloader?</source>
2706 <translation>Le bootloader est déjà installé. Voulez-vous le réinstaller ?</translation>
2707 </message>
2708 <message>
2709 <location filename="../gui/selectiveinstallwidget.cpp" line="271"/>
2710 <source>Bootloader installation skipped</source>
2711 <translation>Installation du bootloader ignorée</translation>
2712 </message>
2713 <message>
2714 <location filename="../gui/selectiveinstallwidget.cpp" line="284"/>
2715 <source>Create Bootloader backup</source>
2716 <translation>Sauvegarde du bootloader</translation>
2717 </message>
2718 <message>
2719 <location filename="../gui/selectiveinstallwidget.cpp" line="285"/>
2720 <source>You can create a backup of the original bootloader file. Press &quot;Yes&quot; to select an output folder on your computer to save the file to. The file will get placed in a new folder &quot;%1&quot; created below the selected folder.
2721Press &quot;No&quot; to skip this step.</source>
2722 <translation>Vous pouvez créer une sauvegarde du bootloader original. Appuyez sur &quot;Oui&quot; pour sélectionner un dossier de sortie sur votre ordinateur où le fichier sera enregistré. Le fichier sera placé dans un nouveau sous-dossier &quot;%1&quot; créé dans le dossier sélectionné. Appuyez sur &quot;Non&quot; pour ignorez cette étape.</translation>
2723 </message>
2724 <message>
2725 <location filename="../gui/selectiveinstallwidget.cpp" line="292"/>
2726 <source>Browse backup folder</source>
2727 <translation>Parcourir le dossier de sauvegarde</translation>
2728 </message>
2729 <message>
2730 <location filename="../gui/selectiveinstallwidget.cpp" line="304"/>
2731 <source>Prerequisites</source>
2732 <translation>Prérequis</translation>
2733 </message>
2734 <message>
2735 <location filename="../gui/selectiveinstallwidget.cpp" line="309"/>
2736 <source>Bootloader installation aborted</source>
2737 <translation>Installation du bootloader annulée</translation>
2738 </message>
2739 <message>
2740 <location filename="../gui/selectiveinstallwidget.cpp" line="319"/>
2741 <source>Bootloader files (%1)</source>
2742 <translation>Fichiers du bootloader (%1)</translation>
2743 </message>
2744 <message>
2745 <location filename="../gui/selectiveinstallwidget.cpp" line="321"/>
2746 <source>All files (*)</source>
2747 <translation>Tous les fichiers (*)</translation>
2748 </message>
2749 <message>
2750 <location filename="../gui/selectiveinstallwidget.cpp" line="323"/>
2751 <source>Select firmware file</source>
2752 <translation>Sélectionnez le fichier firmware</translation>
2753 </message>
2754 <message>
2755 <location filename="../gui/selectiveinstallwidget.cpp" line="325"/>
2756 <source>Error opening firmware file</source>
2757 <translation>Impossible d&apos;ouvrir le fichier firmware</translation>
2758 </message>
2759 <message>
2760 <location filename="../gui/selectiveinstallwidget.cpp" line="331"/>
2761 <source>Error reading firmware file</source>
2762 <translation>Impossible de lire le fichier firmware</translation>
2763 </message>
2764 <message>
2765 <location filename="../gui/selectiveinstallwidget.cpp" line="341"/>
2766 <source>Backup error</source>
2767 <translation>Erreur de la sauvegarde</translation>
2768 </message>
2769 <message>
2770 <location filename="../gui/selectiveinstallwidget.cpp" line="342"/>
2771 <source>Could not create backup file. Continue?</source>
2772 <translation>Impossible de créer une sauvegarde. Voulez-vous poursuivre ?</translation>
2773 </message>
2774 <message>
2775 <location filename="../gui/selectiveinstallwidget.cpp" line="366"/>
2776 <source>Manual steps required</source>
2777 <translation>Des étapes manuelles sont nécessaires</translation>
2778 </message>
2779 <message>
2780 <location filename="../gui/selectiveinstallwidget.cpp" line="171"/>
2781 <source>Continue with installation?</source>
2782 <translation>Continuer l&apos;installation ?</translation>
2783 </message>
2784 <message>
2785 <location filename="../gui/selectiveinstallwidget.cpp" line="172"/>
2786 <source>Really continue?</source>
2787 <translation>Êtes vous sûr de vouloir poursuivre ?</translation>
2788 </message>
2789 <message>
2790 <source>Aborted!</source>
2791 <translation type="obsolete">Annulé !</translation>
2792 </message>
2793 <message>
2794 <location filename="../gui/selectiveinstallwidget.cpp" line="490"/>
2795 <source>Your installation doesn&apos;t require game files, skipping.</source>
2796 <translation>Votre installation ne nécessite pas de fichier de jeu, étape ignorée.</translation>
2797 </message>
2798</context>
2799<context>
2800 <name>ServerInfo</name>
2801 <message>
2802 <location filename="../base/serverinfo.cpp" line="117"/>
2803 <source>Unknown</source>
2804 <translation>Inconnu</translation>
2805 </message>
2806 <message>
2807 <location filename="../base/serverinfo.cpp" line="121"/>
2808 <source>Unusable</source>
2809 <translation>Inutilisable</translation>
2810 </message>
2811 <message>
2812 <location filename="../base/serverinfo.cpp" line="124"/>
2813 <source>Unstable</source>
2814 <translation>Instable</translation>
2815 </message>
2816 <message>
2817 <location filename="../base/serverinfo.cpp" line="127"/>
2818 <source>Stable</source>
2819 <translation>Stable</translation>
2820 </message>
2821</context>
2822<context>
2823 <name>SysTrace</name>
2824 <message>
2825 <location filename="../systrace.cpp" line="98"/>
2826 <location filename="../systrace.cpp" line="107"/>
2827 <source>Save system trace log</source>
2828 <translation>Sauvegarde de la trace système</translation>
2829 </message>
2830</context>
2831<context>
2832 <name>SysTraceFrm</name>
2833 <message>
2834 <location filename="../systracefrm.ui" line="14"/>
2835 <source>System Trace</source>
2836 <translation>Trace système</translation>
2837 </message>
2838 <message>
2839 <location filename="../systracefrm.ui" line="20"/>
2840 <source>System State trace</source>
2841 <translation>Trace état du système</translation>
2842 </message>
2843 <message>
2844 <location filename="../systracefrm.ui" line="46"/>
2845 <source>&amp;Close</source>
2846 <translation>&amp;Fermer</translation>
2847 </message>
2848 <message>
2849 <location filename="../systracefrm.ui" line="57"/>
2850 <source>&amp;Save</source>
2851 <translation>&amp;Enregistrer</translation>
2852 </message>
2853 <message>
2854 <location filename="../systracefrm.ui" line="68"/>
2855 <source>&amp;Refresh</source>
2856 <translation>&amp;Rafraîchir</translation>
2857 </message>
2858 <message>
2859 <location filename="../systracefrm.ui" line="79"/>
2860 <source>Save &amp;previous</source>
2861 <translation>Sauvegarder &amp;la précédente</translation>
2862 </message>
2863</context>
2864<context>
2865 <name>Sysinfo</name>
2866 <message>
2867 <location filename="../sysinfo.cpp" line="45"/>
2868 <source>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</source>
2869 <translation>&lt;b&gt;Système d&apos;exploitation&lt;/b&gt;&lt;br/&gt;</translation>
2870 </message>
2871 <message>
2872 <location filename="../sysinfo.cpp" line="46"/>
2873 <source>&lt;b&gt;Username&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2874 <translation>&lt;b&gt;Nom d&apos;utilisateur&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2875 </message>
2876 <message>
2877 <location filename="../sysinfo.cpp" line="48"/>
2878 <source>&lt;b&gt;Permissions&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2879 <translation>&lt;b&gt;Permissions&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2880 </message>
2881 <message>
2882 <location filename="../sysinfo.cpp" line="50"/>
2883 <source>&lt;b&gt;Attached USB devices&lt;/b&gt;&lt;br/&gt;</source>
2884 <translation>&lt;b&gt;Périphériques USB branchés&lt;/b&gt;&lt;br/&gt;</translation>
2885 </message>
2886 <message>
2887 <location filename="../sysinfo.cpp" line="54"/>
2888 <source>VID: %1 PID: %2, %3</source>
2889 <translation>VID: %1 PID: %2, %3</translation>
2890 </message>
2891 <message>
2892 <location filename="../sysinfo.cpp" line="63"/>
2893 <source>Filesystem</source>
2894 <translation>Fichier système</translation>
2895 </message>
2896 <message>
2897 <location filename="../sysinfo.cpp" line="66"/>
2898 <source>Mountpoint</source>
2899 <translation>Point de montage</translation>
2900 </message>
2901 <message>
2902 <location filename="../sysinfo.cpp" line="66"/>
2903 <source>Label</source>
2904 <translation>Libellé</translation>
2905 </message>
2906 <message>
2907 <location filename="../sysinfo.cpp" line="67"/>
2908 <source>Free</source>
2909 <translation>Libre</translation>
2910 </message>
2911 <message>
2912 <location filename="../sysinfo.cpp" line="67"/>
2913 <source>Total</source>
2914 <translation>Total</translation>
2915 </message>
2916 <message>
2917 <location filename="../sysinfo.cpp" line="68"/>
2918 <source>Cluster Size</source>
2919 <translation>Taille des clusters</translation>
2920 </message>
2921 <message>
2922 <location filename="../sysinfo.cpp" line="70"/>
2923 <source>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</source>
2924 <translation>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 Gio&lt;/td&gt;&lt;td&gt;%3 Gio&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</translation>
2925 </message>
2926</context>
2927<context>
2928 <name>SysinfoFrm</name>
2929 <message>
2930 <location filename="../sysinfofrm.ui" line="13"/>
2931 <source>System Info</source>
2932 <translation>Informations système</translation>
2933 </message>
2934 <message>
2935 <location filename="../sysinfofrm.ui" line="22"/>
2936 <source>&amp;Refresh</source>
2937 <translation>&amp;Rafraîchir</translation>
2938 </message>
2939 <message>
2940 <location filename="../sysinfofrm.ui" line="45"/>
2941 <source>&amp;OK</source>
2942 <translation>&amp;OK</translation>
2943 </message>
2944</context>
2945<context>
2946 <name>System</name>
2947 <message>
2948 <location filename="../base/system.cpp" line="121"/>
2949 <source>Guest</source>
2950 <translation>Invité</translation>
2951 </message>
2952 <message>
2953 <location filename="../base/system.cpp" line="124"/>
2954 <source>Admin</source>
2955 <translation>Administrateur</translation>
2956 </message>
2957 <message>
2958 <location filename="../base/system.cpp" line="127"/>
2959 <source>User</source>
2960 <translation>Utilisateur</translation>
2961 </message>
2962 <message>
2963 <location filename="../base/system.cpp" line="130"/>
2964 <source>Error</source>
2965 <translation>Erreur</translation>
2966 </message>
2967 <message>
2968 <location filename="../base/system.cpp" line="278"/>
2969 <location filename="../base/system.cpp" line="323"/>
2970 <source>(no description available)</source>
2971 <translation>(aucune description disponible)</translation>
2972 </message>
2973</context>
2974<context>
2975 <name>TTSBase</name>
2976 <message>
2977 <location filename="../base/ttsbase.cpp" line="45"/>
2978 <source>Espeak TTS Engine</source>
2979 <translation>Synthèse vocale basée sur Espeak</translation>
2980 </message>
2981 <message>
2982 <location filename="../base/ttsbase.cpp" line="47"/>
2983 <source>Flite TTS Engine</source>
2984 <translation>Synthèse vocale basée sur Flite</translation>
2985 </message>
2986 <message>
2987 <location filename="../base/ttsbase.cpp" line="48"/>
2988 <source>Swift TTS Engine</source>
2989 <translation>Synthèse vocale basée sur Swift</translation>
2990 </message>
2991 <message>
2992 <location filename="../base/ttsbase.cpp" line="51"/>
2993 <source>SAPI4 TTS Engine</source>
2994 <translation>Moteur TTS SAPI4</translation>
2995 </message>
2996 <message>
2997 <location filename="../base/ttsbase.cpp" line="53"/>
2998 <source>SAPI5 TTS Engine</source>
2999 <translation>Moteur TTS SAPI5</translation>
3000 </message>
3001 <message>
3002 <location filename="../base/ttsbase.cpp" line="54"/>
3003 <source>MS Speech Platform</source>
3004 <translation>Plateforme MS Speech</translation>
3005 </message>
3006 <message>
3007 <source>SAPI TTS Engine</source>
3008 <translation type="obsolete">Synthèse vocale basée sur SAPI</translation>
3009 </message>
3010 <message>
3011 <location filename="../base/ttsbase.cpp" line="57"/>
3012 <source>Festival TTS Engine</source>
3013 <translation>Synthèse vocale basée sur Festival</translation>
3014 </message>
3015 <message>
3016 <location filename="../base/ttsbase.cpp" line="60"/>
3017 <source>OS X System Engine</source>
3018 <translation>Synthèse vocale basée sur le système OS X</translation>
3019 </message>
3020</context>
3021<context>
3022 <name>TTSCarbon</name>
3023 <message>
3024 <location filename="../base/ttscarbon.cpp" line="139"/>
3025 <source>Voice:</source>
3026 <translation>Voix:</translation>
3027 </message>
3028 <message>
3029 <location filename="../base/ttscarbon.cpp" line="145"/>
3030 <source>Speed (words/min):</source>
3031 <translation>Vitesse (mots/min):</translation>
3032 </message>
3033 <message>
3034 <location filename="../base/ttscarbon.cpp" line="152"/>
3035 <source>Pitch (0 for default):</source>
3036 <translation>Hauteur de ton (0 est la valeur par defaut) :</translation>
3037 </message>
3038 <message>
3039 <location filename="../base/ttscarbon.cpp" line="222"/>
3040 <source>Could not voice string</source>
3041 <translation>Impossible de synthétiser la phrase</translation>
3042 </message>
3043 <message>
3044 <location filename="../base/ttscarbon.cpp" line="232"/>
3045 <source>Could not convert intermediate file</source>
3046 <translation>Impossible de convertir le fichier intermédiaire</translation>
3047 </message>
3048</context>
3049<context>
3050 <name>TTSExes</name>
3051 <message>
3052 <location filename="../base/ttsexes.cpp" line="78"/>
3053 <source>TTS executable not found</source>
3054 <translation>Exécutable TTS non trouvé</translation>
3055 </message>
3056 <message>
3057 <location filename="../base/ttsexes.cpp" line="44"/>
3058 <source>Path to TTS engine:</source>
3059 <translation>Chemin vers le moteur TTS:</translation>
3060 </message>
3061 <message>
3062 <location filename="../base/ttsexes.cpp" line="46"/>
3063 <source>TTS engine options:</source>
3064 <translation>Option du moteur TTS:</translation>
3065 </message>
3066</context>
3067<context>
3068 <name>TTSFestival</name>
3069 <message>
3070 <location filename="../base/ttsfestival.cpp" line="207"/>
3071 <source>engine could not voice string</source>
3072 <translation>le moteur n&apos;a pas pu synthétiser la phrase</translation>
3073 </message>
3074 <message>
3075 <location filename="../base/ttsfestival.cpp" line="290"/>
3076 <source>No description available</source>
3077 <translation>Aucune description n&apos;est disponible</translation>
3078 </message>
3079 <message>
3080 <location filename="../base/ttsfestival.cpp" line="53"/>
3081 <source>Path to Festival client:</source>
3082 <translation>Chemin vers le client Festival:</translation>
3083 </message>
3084 <message>
3085 <location filename="../base/ttsfestival.cpp" line="58"/>
3086 <source>Voice:</source>
3087 <translation>Voix:</translation>
3088 </message>
3089 <message>
3090 <location filename="../base/ttsfestival.cpp" line="67"/>
3091 <source>Voice description:</source>
3092 <translation>Description de la voix:</translation>
3093 </message>
3094</context>
3095<context>
3096 <name>TTSSapi</name>
3097 <message>
3098 <location filename="../base/ttssapi.cpp" line="49"/>
3099 <source>Language:</source>
3100 <translation>Langue:</translation>
3101 </message>
3102 <message>
3103 <location filename="../base/ttssapi.cpp" line="56"/>
3104 <source>Voice:</source>
3105 <translation>Voix:</translation>
3106 </message>
3107 <message>
3108 <location filename="../base/ttssapi.cpp" line="68"/>
3109 <source>Speed:</source>
3110 <translation>Vitesse:</translation>
3111 </message>
3112 <message>
3113 <location filename="../base/ttssapi.cpp" line="71"/>
3114 <source>Options:</source>
3115 <translation>Options:</translation>
3116 </message>
3117 <message>
3118 <location filename="../base/ttssapi.cpp" line="115"/>
3119 <source>Could not copy the SAPI script</source>
3120 <translation>Impossible de copy the script SAPI</translation>
3121 </message>
3122 <message>
3123 <location filename="../base/ttssapi.cpp" line="133"/>
3124 <source>Could not start SAPI process</source>
3125 <translation>Impossible lancer le processus SAPI</translation>
3126 </message>
3127</context>
3128<context>
3129 <name>TalkFileCreator</name>
3130 <message>
3131 <location filename="../base/talkfile.cpp" line="68"/>
3132 <source>Copying Talkfiles...</source>
3133 <translation>Copie des fichiers d&apos;annonce...</translation>
3134 </message>
3135 <message>
3136 <location filename="../base/talkfile.cpp" line="240"/>
3137 <source>File copy aborted</source>
3138 <translation>Copie du fichier annulée</translation>
3139 </message>
3140 <message>
3141 <location filename="../base/talkfile.cpp" line="280"/>
3142 <source>Cleaning up...</source>
3143 <translation>Nettoyage...</translation>
3144 </message>
3145 <message>
3146 <location filename="../base/talkfile.cpp" line="291"/>
3147 <source>Finished</source>
3148 <translation>Terminé</translation>
3149 </message>
3150 <message>
3151 <location filename="../base/talkfile.cpp" line="45"/>
3152 <source>Talk file creation aborted</source>
3153 <translation>Création des fichiers d&apos;annonce abandonnée</translation>
3154 </message>
3155 <message>
3156 <location filename="../base/talkfile.cpp" line="36"/>
3157 <source>Starting Talk file generation for folder %1</source>
3158 <translation>Début de la génération des fichiers de voix pour le dossier %1</translation>
3159 </message>
3160 <message>
3161 <location filename="../base/talkfile.cpp" line="80"/>
3162 <source>Finished creating Talk files</source>
3163 <translation>Création des fichiers d&apos;annonce terminée</translation>
3164 </message>
3165 <message>
3166 <location filename="../base/talkfile.cpp" line="42"/>
3167 <source>Reading Filelist...</source>
3168 <translation>Lecture de la liste des fichiers...</translation>
3169 </message>
3170 <message>
3171 <location filename="../base/talkfile.cpp" line="259"/>
3172 <source>Copying of %1 to %2 failed</source>
3173 <translation>La copie de %1 vers %2 a échoué</translation>
3174 </message>
3175</context>
3176<context>
3177 <name>TalkGenerator</name>
3178 <message>
3179 <location filename="../base/talkgenerator.cpp" line="39"/>
3180 <source>Starting TTS Engine</source>
3181 <translation>Démarrage du moteur TTS</translation>
3182 </message>
3183 <message>
3184 <location filename="../base/talkgenerator.cpp" line="44"/>
3185 <location filename="../base/talkgenerator.cpp" line="51"/>
3186 <source>Init of TTS engine failed</source>
3187 <translation>L&apos;initialisation du moteur TTS a échoué</translation>
3188 </message>
3189 <message>
3190 <location filename="../base/talkgenerator.cpp" line="58"/>
3191 <source>Starting Encoder Engine</source>
3192 <translation>Démarrage du moteur d&apos;encodage</translation>
3193 </message>
3194 <message>
3195 <location filename="../base/talkgenerator.cpp" line="62"/>
3196 <source>Init of Encoder engine failed</source>
3197 <translation>L&apos;initialisation de l&apos;encodeur a échoué</translation>
3198 </message>
3199 <message>
3200 <location filename="../base/talkgenerator.cpp" line="72"/>
3201 <source>Voicing entries...</source>
3202 <translation>Synthèse des entrées...</translation>
3203 </message>
3204 <message>
3205 <location filename="../base/talkgenerator.cpp" line="87"/>
3206 <source>Encoding files...</source>
3207 <translation>Encodage des fichiers...</translation>
3208 </message>
3209 <message>
3210 <location filename="../base/talkgenerator.cpp" line="126"/>
3211 <source>Voicing aborted</source>
3212 <translation>Synthèse vocale annulée</translation>
3213 </message>
3214 <message>
3215 <location filename="../base/talkgenerator.cpp" line="162"/>
3216 <location filename="../base/talkgenerator.cpp" line="167"/>
3217 <source>Voicing of %1 failed: %2</source>
3218 <translation>La synthèse vocale de %1 a échoué: %2</translation>
3219 </message>
3220 <message>
3221 <location filename="../base/talkgenerator.cpp" line="211"/>
3222 <source>Encoding aborted</source>
3223 <translation>Encodage interrompu</translation>
3224 </message>
3225 <message>
3226 <location filename="../base/talkgenerator.cpp" line="239"/>
3227 <source>Encoding of %1 failed</source>
3228 <translation>L&apos;encodage de %1 a échoué</translation>
3229 </message>
3230</context>
3231<context>
3232 <name>ThemeInstallFrm</name>
3233 <message>
3234 <location filename="../themesinstallfrm.ui" line="13"/>
3235 <source>Theme Installation</source>
3236 <translation>Installation de thèmes</translation>
3237 </message>
3238 <message>
3239 <location filename="../themesinstallfrm.ui" line="48"/>
3240 <source>Selected Theme</source>
3241 <translation>Thème sélectionné</translation>
3242 </message>
3243 <message>
3244 <location filename="../themesinstallfrm.ui" line="73"/>
3245 <source>Description</source>
3246 <translation>Description</translation>
3247 </message>
3248 <message>
3249 <location filename="../themesinstallfrm.ui" line="83"/>
3250 <source>Download size:</source>
3251 <translation>Taille du téléchargement:</translation>
3252 </message>
3253 <message>
3254 <location filename="../themesinstallfrm.ui" line="125"/>
3255 <source>&amp;Cancel</source>
3256 <translation>&amp;Annuler</translation>
3257 </message>
3258 <message>
3259 <location filename="../themesinstallfrm.ui" line="115"/>
3260 <source>&amp;Install</source>
3261 <translation>&amp;Installer</translation>
3262 </message>
3263 <message>
3264 <location filename="../themesinstallfrm.ui" line="93"/>
3265 <source>Hold Ctrl to select multiple item, Shift for a range</source>
3266 <translation>Maintenez Ctrl appuyé pour sélectionner plusieurs éléments, et Shift pour sélectionner des éléments consécutifs</translation>
3267 </message>
3268</context>
3269<context>
3270 <name>ThemesInstallWindow</name>
3271 <message>
3272 <location filename="../themesinstallwindow.cpp" line="40"/>
3273 <source>no theme selected</source>
3274 <translation>pas de thème sélectionné</translation>
3275 </message>
3276 <message>
3277 <location filename="../themesinstallwindow.cpp" line="125"/>
3278 <source>Network error: %1.
3279Please check your network and proxy settings.</source>
3280 <translation>Erreur réseau: %1.
3281Veuillez vérifier vos paramètres réseau et proxy.</translation>
3282 </message>
3283 <message>
3284 <location filename="../themesinstallwindow.cpp" line="138"/>
3285 <source>the following error occured:
3286%1</source>
3287 <translation>L&apos;erreur suivante s&apos;est produite :
3288%1</translation>
3289 </message>
3290 <message>
3291 <location filename="../themesinstallwindow.cpp" line="144"/>
3292 <source>done.</source>
3293 <translation>terminé.</translation>
3294 </message>
3295 <message>
3296 <location filename="../themesinstallwindow.cpp" line="211"/>
3297 <source>fetching details for %1</source>
3298 <translation>récupération des détails pour %1</translation>
3299 </message>
3300 <message>
3301 <location filename="../themesinstallwindow.cpp" line="214"/>
3302 <source>fetching preview ...</source>
3303 <translation>récupération de l&apos;aperçu ...</translation>
3304 </message>
3305 <message>
3306 <location filename="../themesinstallwindow.cpp" line="227"/>
3307 <source>&lt;b&gt;Author:&lt;/b&gt; %1&lt;hr/&gt;</source>
3308 <translation>&lt;b&gt;Auteur:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3309 </message>
3310 <message>
3311 <location filename="../themesinstallwindow.cpp" line="228"/>
3312 <location filename="../themesinstallwindow.cpp" line="230"/>
3313 <source>unknown</source>
3314 <translation>inconnu</translation>
3315 </message>
3316 <message>
3317 <location filename="../themesinstallwindow.cpp" line="229"/>
3318 <source>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</source>
3319 <translation>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3320 </message>
3321 <message>
3322 <location filename="../themesinstallwindow.cpp" line="231"/>
3323 <source>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</source>
3324 <translation>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3325 </message>
3326 <message>
3327 <location filename="../themesinstallwindow.cpp" line="232"/>
3328 <source>no description</source>
3329 <translation>pas de description</translation>
3330 </message>
3331 <message>
3332 <location filename="../themesinstallwindow.cpp" line="260"/>
3333 <source>no theme preview</source>
3334 <translation>pas d&apos;aperçu du thème</translation>
3335 </message>
3336 <message>
3337 <location filename="../themesinstallwindow.cpp" line="289"/>
3338 <source>Select</source>
3339 <translation>Sélectionner</translation>
3340 </message>
3341 <message>
3342 <location filename="../themesinstallwindow.cpp" line="296"/>
3343 <source>getting themes information ...</source>
3344 <translation>récupération des informations sur le thème ...</translation>
3345 </message>
3346 <message>
3347 <location filename="../themesinstallwindow.cpp" line="326"/>
3348 <source>No themes selected, skipping</source>
3349 <translation>Aucun thème sélectionné, étape ignorée</translation>
3350 </message>
3351 <message>
3352 <location filename="../themesinstallwindow.cpp" line="356"/>
3353 <source>Mount point is wrong!</source>
3354 <translation>Le point de montage est incorrect !</translation>
3355 </message>
3356 <message>
3357 <location filename="../themesinstallwindow.cpp" line="41"/>
3358 <source>no selection</source>
3359 <translation>Aucune sélection</translation>
3360 </message>
3361 <message>
3362 <location filename="../themesinstallwindow.cpp" line="181"/>
3363 <source>Information</source>
3364 <translation>Informations</translation>
3365 </message>
3366 <message numerus="yes">
3367 <location filename="../themesinstallwindow.cpp" line="198"/>
3368 <source>Download size %L1 kiB (%n item(s))</source>
3369 <translation>
3370 <numerusform>Taille du téléchargement: %L1 Kio (%n élément)</numerusform>
3371 <numerusform>Taille du téléchargement: %L1 Kio (%n élément(s))</numerusform>
3372 </translation>
3373 </message>
3374 <message>
3375 <location filename="../themesinstallwindow.cpp" line="248"/>
3376 <source>Retrieving theme preview failed.
3377HTTP response code: %1</source>
3378 <translation>La récupération d&apos;un aperçu du thème a échoué.
3379Code de réponse HHTP: %1</translation>
3380 </message>
3381</context>
3382<context>
3383 <name>UninstallFrm</name>
3384 <message>
3385 <location filename="../uninstallfrm.ui" line="16"/>
3386 <source>Uninstall Rockbox</source>
3387 <translation>Désinstaller Rockbox</translation>
3388 </message>
3389 <message>
3390 <location filename="../uninstallfrm.ui" line="35"/>
3391 <source>Please select the Uninstallation Method</source>
3392 <translation>Veuillez choisir la méthode de désinstallation</translation>
3393 </message>
3394 <message>
3395 <location filename="../uninstallfrm.ui" line="45"/>
3396 <source>Uninstallation Method</source>
3397 <translation>Méthode de désinstallation</translation>
3398 </message>
3399 <message>
3400 <location filename="../uninstallfrm.ui" line="51"/>
3401 <source>Complete Uninstallation</source>
3402 <translation>Désinstallation complète</translation>
3403 </message>
3404 <message>
3405 <location filename="../uninstallfrm.ui" line="58"/>
3406 <source>Smart Uninstallation</source>
3407 <translation>Désinstallation personnalisée</translation>
3408 </message>
3409 <message>
3410 <location filename="../uninstallfrm.ui" line="68"/>
3411 <source>Please select what you want to uninstall</source>
3412 <translation>Veuillez sélectionner ce que vous désirez désinstaller</translation>
3413 </message>
3414 <message>
3415 <location filename="../uninstallfrm.ui" line="78"/>
3416 <source>Installed Parts</source>
3417 <translation>Composants installés</translation>
3418 </message>
3419 <message>
3420 <location filename="../uninstallfrm.ui" line="138"/>
3421 <source>&amp;Cancel</source>
3422 <translation>&amp;Annuler</translation>
3423 </message>
3424 <message>
3425 <location filename="../uninstallfrm.ui" line="128"/>
3426 <source>&amp;Uninstall</source>
3427 <translation>&amp;Désinstaller</translation>
3428 </message>
3429</context>
3430<context>
3431 <name>Uninstaller</name>
3432 <message>
3433 <location filename="../base/uninstall.cpp" line="32"/>
3434 <location filename="../base/uninstall.cpp" line="43"/>
3435 <source>Starting Uninstallation</source>
3436 <translation>Démarrage de la désinstallation</translation>
3437 </message>
3438 <message>
3439 <location filename="../base/uninstall.cpp" line="36"/>
3440 <source>Finished Uninstallation</source>
3441 <translation>Désinstallation terminée</translation>
3442 </message>
3443 <message>
3444 <location filename="../base/uninstall.cpp" line="49"/>
3445 <source>Uninstalling %1...</source>
3446 <translation>Suppression de %1...</translation>
3447 </message>
3448 <message>
3449 <location filename="../base/uninstall.cpp" line="80"/>
3450 <source>Could not delete %1</source>
3451 <translation>Impossible de supprimer %1</translation>
3452 </message>
3453 <message>
3454 <location filename="../base/uninstall.cpp" line="109"/>
3455 <source>Uninstallation finished</source>
3456 <translation>Désinstallation terminée</translation>
3457 </message>
3458</context>
3459<context>
3460 <name>Utils</name>
3461 <message>
3462 <location filename="../base/utils.cpp" line="312"/>
3463 <source>&lt;li&gt;Permissions insufficient for bootloader installation.
3464Administrator priviledges are necessary.&lt;/li&gt;</source>
3465 <translation>&lt;li&gt;Permissions insuffisantes pour l&apos;installation du bootloader.
3466Les privilèges administrateur sont requis.&lt;/li&gt;</translation>
3467 </message>
3468 <message>
3469 <location filename="../base/utils.cpp" line="324"/>
3470 <source>&lt;li&gt;Target mismatch detected.&lt;br/&gt;Installed target: %1&lt;br/&gt;Selected target: %2.&lt;/li&gt;</source>
3471 <translation>&lt;li&gt;Incompatibilité de modèles détectée. &lt;br/&gt;Modèle installé: %1&lt;br/&gt;Modèle sélectionné: %2&lt;/li&gt;</translation>
3472 </message>
3473 <message>
3474 <location filename="../base/utils.cpp" line="331"/>
3475 <source>Problem detected:</source>
3476 <translation>Problème détecté:</translation>
3477 </message>
3478</context>
3479<context>
3480 <name>VoiceFileCreator</name>
3481 <message>
3482 <location filename="../base/voicefile.cpp" line="43"/>
3483 <source>Starting Voicefile generation</source>
3484 <translation>Démarrage de la génération du fichier de voix</translation>
3485 </message>
3486 <message>
3487 <location filename="../base/voicefile.cpp" line="90"/>
3488 <source>Extracted voice strings from installation</source>
3489 <translation>Fichiers de voix extrait depuis l&apos;installation</translation>
3490 </message>
3491 <message>
3492 <location filename="../base/voicefile.cpp" line="100"/>
3493 <source>Extracted voice strings incompatible</source>
3494 <translation>Les fichiers de voix extraits sont incompatibles</translation>
3495 </message>
3496 <message>
3497 <location filename="../base/voicefile.cpp" line="145"/>
3498 <source>Could not retrieve strings from installation, downloading</source>
3499 <translation>Impossible d&apos;extraire les fichiers de voix depuis l&apos;installation, téléchargement</translation>
3500 </message>
3501 <message>
3502 <location filename="../base/voicefile.cpp" line="171"/>
3503 <source>Downloading voice info...</source>
3504 <translation>Téléchargement des informations d&apos;annonces...</translation>
3505 </message>
3506 <message>
3507 <location filename="../base/voicefile.cpp" line="184"/>
3508 <source>Download error: received HTTP error %1.</source>
3509 <translation>Erreur de téléchargement: Erreur HTTP %1.</translation>
3510 </message>
3511 <message>
3512 <location filename="../base/voicefile.cpp" line="191"/>
3513 <source>Cached file used.</source>
3514 <translation>Fichier en cache utilisé.</translation>
3515 </message>
3516 <message>
3517 <location filename="../base/voicefile.cpp" line="194"/>
3518 <source>Download error: %1</source>
3519 <translation>Erreur de téléchargement: %1</translation>
3520 </message>
3521 <message>
3522 <location filename="../base/voicefile.cpp" line="199"/>
3523 <source>Download finished.</source>
3524 <translation>Téléchargement terminé.</translation>
3525 </message>
3526 <message>
3527 <location filename="../base/voicefile.cpp" line="212"/>
3528 <source>failed to open downloaded file</source>
3529 <translation>Impossible d&apos;ouvrir le fichier téléchargé</translation>
3530 </message>
3531 <message>
3532 <location filename="../base/voicefile.cpp" line="218"/>
3533 <source>Reading strings...</source>
3534 <translation>Lecture des phrases...</translation>
3535 </message>
3536 <message>
3537 <location filename="../base/voicefile.cpp" line="297"/>
3538 <source>Creating voicefiles...</source>
3539 <translation>Création des fichiers de voix...</translation>
3540 </message>
3541 <message>
3542 <location filename="../base/voicefile.cpp" line="342"/>
3543 <source>Cleaning up...</source>
3544 <translation>Nettoyage...</translation>
3545 </message>
3546 <message>
3547 <location filename="../base/voicefile.cpp" line="353"/>
3548 <source>Finished</source>
3549 <translation>Terminé</translation>
3550 </message>
3551 <message>
3552 <location filename="../base/voicefile.cpp" line="271"/>
3553 <source>The downloaded file was empty!</source>
3554 <translation>Le fichier téléchargé est vide !</translation>
3555 </message>
3556 <message>
3557 <location filename="../base/voicefile.cpp" line="302"/>
3558 <source>Error opening downloaded file</source>
3559 <translation>Erreur lors de l&apos;ouverture du fichier téléchargé</translation>
3560 </message>
3561 <message>
3562 <location filename="../base/voicefile.cpp" line="313"/>
3563 <source>Error opening output file</source>
3564 <translation>Erreur lors de l&apos;ouverture du fichier de sortie</translation>
3565 </message>
3566 <message>
3567 <location filename="../base/voicefile.cpp" line="333"/>
3568 <source>successfully created.</source>
3569 <translation>Créé avec succès.</translation>
3570 </message>
3571 <message>
3572 <location filename="../base/voicefile.cpp" line="56"/>
3573 <source>could not find rockbox-info.txt</source>
3574 <translation>Impossible de trouver rockbox-info.txt</translation>
3575 </message>
3576</context>
3577<context>
3578 <name>ZipInstaller</name>
3579 <message>
3580 <location filename="../base/zipinstaller.cpp" line="60"/>
3581 <source>done.</source>
3582 <translation>terminé.</translation>
3583 </message>
3584 <message>
3585 <location filename="../base/zipinstaller.cpp" line="68"/>
3586 <source>Package installation finished successfully.</source>
3587 <translation>Le paquet a été installé avec succès.</translation>
3588 </message>
3589 <message>
3590 <location filename="../base/zipinstaller.cpp" line="80"/>
3591 <source>Downloading file %1.%2</source>
3592 <translation>Téléchargement du fichier %1.%2</translation>
3593 </message>
3594 <message>
3595 <location filename="../base/zipinstaller.cpp" line="115"/>
3596 <source>Download error: received HTTP error %1.</source>
3597 <translation>Erreur de téléchargement: Erreur HTTP %1.</translation>
3598 </message>
3599 <message>
3600 <location filename="../base/zipinstaller.cpp" line="121"/>
3601 <source>Cached file used.</source>
3602 <translation>Fichier en cache utilisé.</translation>
3603 </message>
3604 <message>
3605 <location filename="../base/zipinstaller.cpp" line="123"/>
3606 <source>Download error: %1</source>
3607 <translation>Erreur de téléchargement: %1</translation>
3608 </message>
3609 <message>
3610 <location filename="../base/zipinstaller.cpp" line="127"/>
3611 <source>Download finished.</source>
3612 <translation>Téléchargement terminé.</translation>
3613 </message>
3614 <message>
3615 <location filename="../base/zipinstaller.cpp" line="133"/>
3616 <source>Extracting file.</source>
3617 <translation>Extraction du fichier.</translation>
3618 </message>
3619 <message>
3620 <location filename="../base/zipinstaller.cpp" line="153"/>
3621 <source>Extraction failed!</source>
3622 <translation>L&apos;extraction a échoué !</translation>
3623 </message>
3624 <message>
3625 <location filename="../base/zipinstaller.cpp" line="162"/>
3626 <source>Installing file.</source>
3627 <translation>Installation du fichier.</translation>
3628 </message>
3629 <message>
3630 <location filename="../base/zipinstaller.cpp" line="173"/>
3631 <source>Installing file failed.</source>
3632 <translation>L&apos;installation du fichier a échoué.</translation>
3633 </message>
3634 <message>
3635 <location filename="../base/zipinstaller.cpp" line="186"/>
3636 <source>Creating installation log</source>
3637 <translation>Création du journal d&apos;installation</translation>
3638 </message>
3639 <message>
3640 <location filename="../base/zipinstaller.cpp" line="146"/>
3641 <source>Not enough disk space! Aborting.</source>
3642 <translation>Espace disque insuffisant ! Abandon.</translation>
3643 </message>
3644</context>
3645<context>
3646 <name>ZipUtil</name>
3647 <message>
3648 <location filename="../base/ziputil.cpp" line="125"/>
3649 <source>Creating output path failed</source>
3650 <translation>La création du chemin d&apos;installation a échoué</translation>
3651 </message>
3652 <message>
3653 <location filename="../base/ziputil.cpp" line="132"/>
3654 <source>Creating output file failed</source>
3655 <translation>La création du fichier à installer a échoué</translation>
3656 </message>
3657 <message>
3658 <location filename="../base/ziputil.cpp" line="141"/>
3659 <source>Error during Zip operation</source>
3660 <translation>Erreur lors de l&apos;utilisation de Zip</translation>
3661 </message>
3662</context>
3663<context>
3664 <name>aboutBox</name>
3665 <message>
3666 <location filename="../aboutbox.ui" line="14"/>
3667 <source>About Rockbox Utility</source>
3668 <translation>A propos de l&apos;utilitaire Rockbox</translation>
3669 </message>
3670 <message>
3671 <location filename="../aboutbox.ui" line="32"/>
3672 <source>The Rockbox Utility</source>
3673 <translation>L&apos;utilitaire Rockbox</translation>
3674 </message>
3675 <message utf8="true">
3676 <location filename="../aboutbox.ui" line="54"/>
3677 <source>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</source>
3678 <translation>Installeur et utilitaire d&apos;entretien du firmware libre pour lecteurs audio Rockbox.&lt;br/&gt;© L&apos;équipe Rockbox.&lt;br/&gt;Publié sous Licence Publique Générale GNU GPL v2.&lt;br/&gt;Icônes utilisées grâce au &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</translation>
3679 </message>
3680 <message>
3681 <location filename="../aboutbox.ui" line="74"/>
3682 <source>&amp;Credits</source>
3683 <translation>&amp;Crédits</translation>
3684 </message>
3685 <message>
3686 <location filename="../aboutbox.ui" line="106"/>
3687 <source>&amp;License</source>
3688 <translation>&amp;Licence</translation>
3689 </message>
3690 <message>
3691 <location filename="../aboutbox.ui" line="132"/>
3692 <source>&amp;Speex License</source>
3693 <translation>Licence de &amp;Speex</translation>
3694 </message>
3695 <message>
3696 <location filename="../aboutbox.ui" line="158"/>
3697 <source>&amp;Ok</source>
3698 <translation>&amp;OK</translation>
3699 </message>
3700</context>
3701</TS>
diff --git a/utils/rbutilqt/lang/rbutil_gr.ts b/utils/rbutilqt/lang/rbutil_gr.ts
new file mode 100644
index 0000000000..bfa600954b
--- /dev/null
+++ b/utils/rbutilqt/lang/rbutil_gr.ts
@@ -0,0 +1,3667 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE TS>
3<TS version="2.0" language="el_GR">
4<context>
5 <name>BackupDialog</name>
6 <message>
7 <location filename="../gui/backupdialogfrm.ui" line="17"/>
8 <location filename="../gui/backupdialogfrm.ui" line="43"/>
9 <source>Backup</source>
10 <translation type="unfinished">Αντίγραφο ασφαλείας</translation>
11 </message>
12 <message>
13 <location filename="../gui/backupdialogfrm.ui" line="33"/>
14 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This dialog will create a backup by archiving the contents of the Rockbox installation on the player into a zip file. This will include installed themes and settings stored below the .rockbox folder on the player.&lt;/p&gt;&lt;p&gt;The backup filename will be created based on the installed version. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
15 <translation type="unfinished"></translation>
16 </message>
17 <message>
18 <location filename="../gui/backupdialogfrm.ui" line="49"/>
19 <source>Size: unknown</source>
20 <translation type="unfinished"></translation>
21 </message>
22 <message>
23 <location filename="../gui/backupdialogfrm.ui" line="56"/>
24 <source>Backup to: unknown</source>
25 <translation type="unfinished"></translation>
26 </message>
27 <message>
28 <location filename="../gui/backupdialogfrm.ui" line="76"/>
29 <source>&amp;Change</source>
30 <translation type="unfinished">&amp;Τροποποίηση</translation>
31 </message>
32 <message>
33 <location filename="../gui/backupdialogfrm.ui" line="116"/>
34 <source>&amp;Backup</source>
35 <translation type="unfinished"></translation>
36 </message>
37 <message>
38 <location filename="../gui/backupdialogfrm.ui" line="127"/>
39 <source>&amp;Cancel</source>
40 <translation type="unfinished">Ά&amp;κυρο</translation>
41 </message>
42 <message>
43 <location filename="../gui/backupdialog.cpp" line="70"/>
44 <source>Installation size: calculating ...</source>
45 <translation type="unfinished"></translation>
46 </message>
47 <message>
48 <location filename="../gui/backupdialog.cpp" line="89"/>
49 <source>Select Backup Filename</source>
50 <translation type="unfinished"></translation>
51 </message>
52 <message>
53 <location filename="../gui/backupdialog.cpp" line="109"/>
54 <source>Installation size: %L1 %2</source>
55 <translation type="unfinished"></translation>
56 </message>
57 <message>
58 <location filename="../gui/backupdialog.cpp" line="116"/>
59 <source>File exists</source>
60 <translation type="unfinished"></translation>
61 </message>
62 <message>
63 <location filename="../gui/backupdialog.cpp" line="117"/>
64 <source>The selected backup file already exists. Overwrite?</source>
65 <translation type="unfinished"></translation>
66 </message>
67 <message>
68 <location filename="../gui/backupdialog.cpp" line="125"/>
69 <source>Starting backup ...</source>
70 <translation type="unfinished"></translation>
71 </message>
72 <message>
73 <location filename="../gui/backupdialog.cpp" line="144"/>
74 <source>Backup successful.</source>
75 <translation type="unfinished"></translation>
76 </message>
77 <message>
78 <location filename="../gui/backupdialog.cpp" line="147"/>
79 <source>Backup failed!</source>
80 <translation type="unfinished">Αποτυχία αντίγραφου ασφάλειας!</translation>
81 </message>
82</context>
83<context>
84 <name>BootloaderInstallAms</name>
85 <message>
86 <location filename="../base/bootloaderinstallams.cpp" line="33"/>
87 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; This file is not present on your player and will disappear automatically after installing it.&lt;br/&gt;&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
88 <translation type="unfinished"></translation>
89 </message>
90 <message>
91 <location filename="../base/bootloaderinstallams.cpp" line="58"/>
92 <source>Downloading bootloader file</source>
93 <translation type="unfinished">Λήψη αρχείου bootloader</translation>
94 </message>
95 <message>
96 <location filename="../base/bootloaderinstallams.cpp" line="100"/>
97 <location filename="../base/bootloaderinstallams.cpp" line="113"/>
98 <source>Could not load %1</source>
99 <translation type="unfinished"></translation>
100 </message>
101 <message>
102 <location filename="../base/bootloaderinstallams.cpp" line="127"/>
103 <source>No room to insert bootloader, try another firmware version</source>
104 <translation type="unfinished"></translation>
105 </message>
106 <message>
107 <location filename="../base/bootloaderinstallams.cpp" line="137"/>
108 <source>Patching Firmware...</source>
109 <translation type="unfinished"></translation>
110 </message>
111 <message>
112 <location filename="../base/bootloaderinstallams.cpp" line="148"/>
113 <source>Could not open %1 for writing</source>
114 <translation type="unfinished"></translation>
115 </message>
116 <message>
117 <location filename="../base/bootloaderinstallams.cpp" line="161"/>
118 <source>Could not write firmware file</source>
119 <translation type="unfinished"></translation>
120 </message>
121 <message>
122 <location filename="../base/bootloaderinstallams.cpp" line="177"/>
123 <source>Success: modified firmware file created</source>
124 <translation type="unfinished">Επιτυχία: Τροποποιημένο αρχείο firmware δημιουργήθηκε</translation>
125 </message>
126 <message>
127 <location filename="../base/bootloaderinstallams.cpp" line="185"/>
128 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
129 <translation type="unfinished"></translation>
130 </message>
131</context>
132<context>
133 <name>BootloaderInstallBase</name>
134 <message>
135 <location filename="../base/bootloaderinstallbase.cpp" line="78"/>
136 <source>Download error: received HTTP error %1.</source>
137 <translation>Σφάλμα λήψης: σφάλμα HTTP %1.</translation>
138 </message>
139 <message>
140 <location filename="../base/bootloaderinstallbase.cpp" line="84"/>
141 <source>Download error: %1</source>
142 <translation>Σφάλμα λήψης: %1</translation>
143 </message>
144 <message>
145 <location filename="../base/bootloaderinstallbase.cpp" line="90"/>
146 <source>Download finished (cache used).</source>
147 <translation>Η λήψη ολοκληρώθηκε (χρήση προσωρινής μνήμης λήψεων).</translation>
148 </message>
149 <message>
150 <location filename="../base/bootloaderinstallbase.cpp" line="92"/>
151 <source>Download finished.</source>
152 <translation>Η λήψη ολοκληρώθηκε.</translation>
153 </message>
154 <message>
155 <location filename="../base/bootloaderinstallbase.cpp" line="113"/>
156 <source>Creating backup of original firmware file.</source>
157 <translation>Δημιουργία αντίγραφου ασφάλειας αυθεντικού firmware.</translation>
158 </message>
159 <message>
160 <location filename="../base/bootloaderinstallbase.cpp" line="115"/>
161 <source>Creating backup folder failed</source>
162 <translation>Η δημιουργία φακέλου αντίγραφου ασφάλειας απέτυχε</translation>
163 </message>
164 <message>
165 <location filename="../base/bootloaderinstallbase.cpp" line="121"/>
166 <source>Creating backup copy failed.</source>
167 <translation>Η δημιουργία αντίγραφου ασφάλειας απέτυχε.</translation>
168 </message>
169 <message>
170 <location filename="../base/bootloaderinstallbase.cpp" line="124"/>
171 <source>Backup created.</source>
172 <translation>Δημιουργήθηκε αντίγραφο ασφάλειας.</translation>
173 </message>
174 <message>
175 <location filename="../base/bootloaderinstallbase.cpp" line="137"/>
176 <source>Creating installation log</source>
177 <translation>Δημιουργία αρχείου καταγραφής εγκατάστασης</translation>
178 </message>
179 <message>
180 <location filename="../base/bootloaderinstallbase.cpp" line="226"/>
181 <source>Zip file format detected</source>
182 <translation type="unfinished"></translation>
183 </message>
184 <message>
185 <location filename="../base/bootloaderinstallbase.cpp" line="238"/>
186 <source>CAB file format detected</source>
187 <translation type="unfinished"></translation>
188 </message>
189 <message>
190 <location filename="../base/bootloaderinstallbase.cpp" line="259"/>
191 <source>Extracting firmware %1 from archive</source>
192 <translation type="unfinished"></translation>
193 </message>
194 <message>
195 <location filename="../base/bootloaderinstallbase.cpp" line="266"/>
196 <source>Error extracting firmware from archive</source>
197 <translation type="unfinished"></translation>
198 </message>
199 <message>
200 <location filename="../base/bootloaderinstallbase.cpp" line="275"/>
201 <source>Could not find firmware in archive</source>
202 <translation type="unfinished"></translation>
203 </message>
204 <message>
205 <location filename="../base/bootloaderinstallbase.cpp" line="159"/>
206 <source>Waiting for system to remount player</source>
207 <translation type="unfinished"></translation>
208 </message>
209 <message>
210 <location filename="../base/bootloaderinstallbase.cpp" line="189"/>
211 <source>Player remounted</source>
212 <translation type="unfinished"></translation>
213 </message>
214 <message>
215 <location filename="../base/bootloaderinstallbase.cpp" line="194"/>
216 <source>Timeout on remount</source>
217 <translation type="unfinished"></translation>
218 </message>
219 <message>
220 <location filename="../base/bootloaderinstallbase.cpp" line="149"/>
221 <source>Installation log created</source>
222 <translation type="unfinished"></translation>
223 </message>
224</context>
225<context>
226 <name>BootloaderInstallChinaChip</name>
227 <message>
228 <location filename="../base/bootloaderinstallchinachip.cpp" line="33"/>
229 <source>Bootloader installation requires you to provide a firmware file of the original firmware (HXF file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
230 <translation type="unfinished"></translation>
231 </message>
232 <message>
233 <location filename="../base/bootloaderinstallchinachip.cpp" line="50"/>
234 <source>Downloading bootloader file</source>
235 <translation type="unfinished">Λήψη αρχείου bootloader</translation>
236 </message>
237 <message>
238 <location filename="../base/bootloaderinstallchinachip.cpp" line="75"/>
239 <source>Could not open firmware file</source>
240 <translation type="unfinished"></translation>
241 </message>
242 <message>
243 <location filename="../base/bootloaderinstallchinachip.cpp" line="78"/>
244 <source>Could not open bootloader file</source>
245 <translation type="unfinished"></translation>
246 </message>
247 <message>
248 <location filename="../base/bootloaderinstallchinachip.cpp" line="81"/>
249 <source>Could not allocate memory</source>
250 <translation type="unfinished"></translation>
251 </message>
252 <message>
253 <location filename="../base/bootloaderinstallchinachip.cpp" line="84"/>
254 <source>Could not load firmware file</source>
255 <translation type="unfinished"></translation>
256 </message>
257 <message>
258 <location filename="../base/bootloaderinstallchinachip.cpp" line="87"/>
259 <source>File is not a valid ChinaChip firmware</source>
260 <translation type="unfinished"></translation>
261 </message>
262 <message>
263 <location filename="../base/bootloaderinstallchinachip.cpp" line="90"/>
264 <source>Could not find ccpmp.bin in input file</source>
265 <translation type="unfinished"></translation>
266 </message>
267 <message>
268 <location filename="../base/bootloaderinstallchinachip.cpp" line="93"/>
269 <source>Could not open backup file for ccpmp.bin</source>
270 <translation type="unfinished"></translation>
271 </message>
272 <message>
273 <location filename="../base/bootloaderinstallchinachip.cpp" line="96"/>
274 <source>Could not write backup file for ccpmp.bin</source>
275 <translation type="unfinished"></translation>
276 </message>
277 <message>
278 <location filename="../base/bootloaderinstallchinachip.cpp" line="99"/>
279 <source>Could not load bootloader file</source>
280 <translation type="unfinished"></translation>
281 </message>
282 <message>
283 <location filename="../base/bootloaderinstallchinachip.cpp" line="102"/>
284 <source>Could not get current time</source>
285 <translation type="unfinished"></translation>
286 </message>
287 <message>
288 <location filename="../base/bootloaderinstallchinachip.cpp" line="105"/>
289 <source>Could not open output file</source>
290 <translation type="unfinished"></translation>
291 </message>
292 <message>
293 <location filename="../base/bootloaderinstallchinachip.cpp" line="108"/>
294 <source>Could not write output file</source>
295 <translation type="unfinished"></translation>
296 </message>
297 <message>
298 <location filename="../base/bootloaderinstallchinachip.cpp" line="111"/>
299 <source>Unexpected error from chinachippatcher</source>
300 <translation type="unfinished"></translation>
301 </message>
302</context>
303<context>
304 <name>BootloaderInstallFile</name>
305 <message>
306 <location filename="../base/bootloaderinstallfile.cpp" line="34"/>
307 <source>Downloading bootloader</source>
308 <translation>Λήψη bootloader</translation>
309 </message>
310 <message>
311 <location filename="../base/bootloaderinstallfile.cpp" line="43"/>
312 <source>Installing Rockbox bootloader</source>
313 <translation>Εγκατάσταση Rockbox bootloader</translation>
314 </message>
315 <message>
316 <location filename="../base/bootloaderinstallfile.cpp" line="75"/>
317 <source>Error accessing output folder</source>
318 <translation>Σφάλμα προσπέλασης αρχείου εξόδου</translation>
319 </message>
320 <message>
321 <location filename="../base/bootloaderinstallfile.cpp" line="89"/>
322 <source>A firmware file is already present on player</source>
323 <translation type="unfinished"></translation>
324 </message>
325 <message>
326 <location filename="../base/bootloaderinstallfile.cpp" line="94"/>
327 <source>Bootloader successful installed</source>
328 <translation>Η εγκατάσταση του Rockbox bootloader ολοκληρώθηκε με επιτυχία.</translation>
329 </message>
330 <message>
331 <location filename="../base/bootloaderinstallfile.cpp" line="97"/>
332 <source>Copying modified firmware file failed</source>
333 <translation type="unfinished"></translation>
334 </message>
335 <message>
336 <location filename="../base/bootloaderinstallfile.cpp" line="111"/>
337 <source>Removing Rockbox bootloader</source>
338 <translation>Κατάργηση Rockbox bootloader</translation>
339 </message>
340 <message>
341 <location filename="../base/bootloaderinstallfile.cpp" line="115"/>
342 <source>No original firmware file found.</source>
343 <translation>Δεν βρέθηκε αρχείο αυθεντικού firmware.</translation>
344 </message>
345 <message>
346 <location filename="../base/bootloaderinstallfile.cpp" line="121"/>
347 <source>Can&apos;t remove Rockbox bootloader file.</source>
348 <translation>Αδύνατη η κατάργηση του αρχείου Rockbox bootloader.</translation>
349 </message>
350 <message>
351 <location filename="../base/bootloaderinstallfile.cpp" line="126"/>
352 <source>Can&apos;t restore bootloader file.</source>
353 <translation>Αδύνατη επαναφορά του αρχείου bootloader.</translation>
354 </message>
355 <message>
356 <location filename="../base/bootloaderinstallfile.cpp" line="130"/>
357 <source>Original bootloader restored successfully.</source>
358 <translation>Επιτυχής επαναφορά του αυθεντικού bootloader.</translation>
359 </message>
360</context>
361<context>
362 <name>BootloaderInstallHex</name>
363 <message>
364 <location filename="../base/bootloaderinstallhex.cpp" line="69"/>
365 <source>checking MD5 hash of input file ...</source>
366 <translation>Έλεγχος σύνοψης MD5 του αρχείου εισαγωγής ...</translation>
367 </message>
368 <message>
369 <location filename="../base/bootloaderinstallhex.cpp" line="80"/>
370 <source>Could not verify original firmware file</source>
371 <translation>Αδύνατη η επαλήθευση το αυθεντικού αρχείου firmware</translation>
372 </message>
373 <message>
374 <location filename="../base/bootloaderinstallhex.cpp" line="95"/>
375 <source>Firmware file not recognized.</source>
376 <translation>Το αρχείο firmware δεν είναι αναγνωρίσιμο.</translation>
377 </message>
378 <message>
379 <location filename="../base/bootloaderinstallhex.cpp" line="99"/>
380 <source>MD5 hash ok</source>
381 <translation>Η σύνοψη MD5 είναι εντάξει</translation>
382 </message>
383 <message>
384 <location filename="../base/bootloaderinstallhex.cpp" line="106"/>
385 <source>Firmware file doesn&apos;t match selected player.</source>
386 <translation>Το αρχείο firmware δεν ταιριάζει με την επιλεγμένη συσκευή.</translation>
387 </message>
388 <message>
389 <location filename="../base/bootloaderinstallhex.cpp" line="111"/>
390 <source>Descrambling file</source>
391 <translation>Γίνεται descrambling στο αρχείο</translation>
392 </message>
393 <message>
394 <location filename="../base/bootloaderinstallhex.cpp" line="119"/>
395 <source>Error in descramble: %1</source>
396 <translation>Σφάλμα διαδικασίας descramble: %1</translation>
397 </message>
398 <message>
399 <location filename="../base/bootloaderinstallhex.cpp" line="124"/>
400 <source>Downloading bootloader file</source>
401 <translation>Λήψη αρχείου bootloader</translation>
402 </message>
403 <message>
404 <location filename="../base/bootloaderinstallhex.cpp" line="134"/>
405 <source>Adding bootloader to firmware file</source>
406 <translation>Προσθήκεη bootloader στο αρχείο firmware</translation>
407 </message>
408 <message>
409 <location filename="../base/bootloaderinstallhex.cpp" line="172"/>
410 <source>could not open input file</source>
411 <translation>Αδύνατο άνοιγμα αρχείο εισόδου</translation>
412 </message>
413 <message>
414 <location filename="../base/bootloaderinstallhex.cpp" line="173"/>
415 <source>reading header failed</source>
416 <translation>Αποτυχία ανάγνωσης της κεφαλίδας</translation>
417 </message>
418 <message>
419 <location filename="../base/bootloaderinstallhex.cpp" line="174"/>
420 <source>reading firmware failed</source>
421 <translation>Αποτυχια ανάγνωσης του firmware</translation>
422 </message>
423 <message>
424 <location filename="../base/bootloaderinstallhex.cpp" line="175"/>
425 <source>can&apos;t open bootloader file</source>
426 <translation>Αδύνατο το άνοιγμα του αρχείου bootloader</translation>
427 </message>
428 <message>
429 <location filename="../base/bootloaderinstallhex.cpp" line="176"/>
430 <source>reading bootloader file failed</source>
431 <translation>Αποτυχία ανάγνωσης του αρχείου bootloader</translation>
432 </message>
433 <message>
434 <location filename="../base/bootloaderinstallhex.cpp" line="177"/>
435 <source>can&apos;t open output file</source>
436 <translation>Αδύνατο άνοιγμα αρχείο εξόδου</translation>
437 </message>
438 <message>
439 <location filename="../base/bootloaderinstallhex.cpp" line="178"/>
440 <source>writing output file failed</source>
441 <translation>Αποτυχία εγγραφής αρχείου εξόδου</translation>
442 </message>
443 <message>
444 <location filename="../base/bootloaderinstallhex.cpp" line="180"/>
445 <source>Error in patching: %1</source>
446 <translation>Σφάλμα διαδικασίας patching: %1</translation>
447 </message>
448 <message>
449 <location filename="../base/bootloaderinstallhex.cpp" line="191"/>
450 <source>Error in scramble: %1</source>
451 <translation>Σφάλμα διαδικασίας scramble: %1</translation>
452 </message>
453 <message>
454 <location filename="../base/bootloaderinstallhex.cpp" line="206"/>
455 <source>Checking modified firmware file</source>
456 <translation>Έλεγχος τροποποιημένου αρχείου firmware</translation>
457 </message>
458 <message>
459 <location filename="../base/bootloaderinstallhex.cpp" line="208"/>
460 <source>Error: modified file checksum wrong</source>
461 <translation>Σφάλμα: το άθροισμα ελέγχου του τροποποιημένου αρχείου είναι λάθος</translation>
462 </message>
463 <message>
464 <location filename="../base/bootloaderinstallhex.cpp" line="215"/>
465 <source>A firmware file is already present on player</source>
466 <translation type="unfinished"></translation>
467 </message>
468 <message>
469 <location filename="../base/bootloaderinstallhex.cpp" line="220"/>
470 <source>Success: modified firmware file created</source>
471 <translation>Επιτυχία: Τροποποιημένο αρχείο firmware δημιουργήθηκε</translation>
472 </message>
473 <message>
474 <location filename="../base/bootloaderinstallhex.cpp" line="223"/>
475 <source>Copying modified firmware file failed</source>
476 <translation type="unfinished"></translation>
477 </message>
478 <message>
479 <location filename="../base/bootloaderinstallhex.cpp" line="237"/>
480 <source>Uninstallation not possible, only installation info removed</source>
481 <translation type="unfinished"></translation>
482 </message>
483 <message>
484 <location filename="../base/bootloaderinstallhex.cpp" line="258"/>
485 <source>Can&apos;t open input file</source>
486 <translation>Αδύνατο άνοιγμα αρχείο εισόδου</translation>
487 </message>
488 <message>
489 <location filename="../base/bootloaderinstallhex.cpp" line="259"/>
490 <source>Can&apos;t open output file</source>
491 <translation>Αδύνατο άνοιγμα αρχείο εξόδου</translation>
492 </message>
493 <message>
494 <location filename="../base/bootloaderinstallhex.cpp" line="260"/>
495 <source>invalid file: header length wrong</source>
496 <translation>Μη έγκυρο αρχείο: λάθος μήκος κεφαλίδας</translation>
497 </message>
498 <message>
499 <location filename="../base/bootloaderinstallhex.cpp" line="261"/>
500 <source>invalid file: unrecognized header</source>
501 <translation>Μη έγκυρο αρχείο: μη αναγνωρίσιμη κεφαλίδα</translation>
502 </message>
503 <message>
504 <location filename="../base/bootloaderinstallhex.cpp" line="262"/>
505 <source>invalid file: &quot;length&quot; field wrong</source>
506 <translation>Μη έγκυρο αρχείο: λάθος πεδίο &quot;μήκους&quot;</translation>
507 </message>
508 <message>
509 <location filename="../base/bootloaderinstallhex.cpp" line="263"/>
510 <source>invalid file: &quot;length2&quot; field wrong</source>
511 <translation>Μη έγκυρο αρχείο: λάθος πεδίο &quot;μήκους2&quot;</translation>
512 </message>
513 <message>
514 <location filename="../base/bootloaderinstallhex.cpp" line="264"/>
515 <source>invalid file: internal checksum error</source>
516 <translation>Μη έγκυρο αρχείο: λάθος εσωτερικό άθροισμα ελέγχου</translation>
517 </message>
518 <message>
519 <location filename="../base/bootloaderinstallhex.cpp" line="265"/>
520 <source>invalid file: &quot;length3&quot; field wrong</source>
521 <translation>Μη έγκυρο αρχείο: λάθος πεδίο &quot;μήκους3&quot;</translation>
522 </message>
523 <message>
524 <location filename="../base/bootloaderinstallhex.cpp" line="266"/>
525 <source>unknown</source>
526 <translation>Άγνωστο</translation>
527 </message>
528 <message>
529 <location filename="../base/bootloaderinstallhex.cpp" line="50"/>
530 <source>Bootloader installation requires you to provide a firmware file of the original firmware (hex file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
531 <translation type="unfinished">Η εγκατάσταση του bootloader απαιτεί την παροχή ενός firmware αρχείου από το αυθεντικό firmware (αρχείο hex). Χρειάζεται να κάνετε λήψη αυτού του αρχείου μόνοι σας για λόγους νομιμότητας. Παρακαλώ δείτε &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;τις οδηγίες χρήσης&lt;/a&gt; και την σελίδα &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; για τον τρόπο όπου μπορείτε να αποκτήσετε αυτό το αρχείο.&lt;br/&gt;Πατήστε OK για να συνεχίστε και να αναζητήσετε στον υπολογιστή σας το αρχείο firmware.</translation>
532 </message>
533</context>
534<context>
535 <name>BootloaderInstallImx</name>
536 <message>
537 <location filename="../base/bootloaderinstallimx.cpp" line="72"/>
538 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (firmware.sb file). This file will be patched with the Rockbox bootloader and installed to your player. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
539 <translation type="unfinished"></translation>
540 </message>
541 <message>
542 <location filename="../base/bootloaderinstallimx.cpp" line="94"/>
543 <source>Could not read original firmware file</source>
544 <translation type="unfinished"></translation>
545 </message>
546 <message>
547 <location filename="../base/bootloaderinstallimx.cpp" line="100"/>
548 <source>Downloading bootloader file</source>
549 <translation type="unfinished">Λήψη αρχείου bootloader</translation>
550 </message>
551 <message>
552 <location filename="../base/bootloaderinstallimx.cpp" line="110"/>
553 <source>Patching file...</source>
554 <translation type="unfinished"></translation>
555 </message>
556 <message>
557 <location filename="../base/bootloaderinstallimx.cpp" line="137"/>
558 <source>Patching the original firmware failed</source>
559 <translation type="unfinished"></translation>
560 </message>
561 <message>
562 <location filename="../base/bootloaderinstallimx.cpp" line="143"/>
563 <source>Succesfully patched firmware file</source>
564 <translation type="unfinished"></translation>
565 </message>
566 <message>
567 <location filename="../base/bootloaderinstallimx.cpp" line="158"/>
568 <source>Bootloader successful installed</source>
569 <translation type="unfinished">Η εγκατάσταση του Rockbox bootloader ολοκληρώθηκε με επιτυχία.</translation>
570 </message>
571 <message>
572 <location filename="../base/bootloaderinstallimx.cpp" line="164"/>
573 <source>Patched bootloader could not be installed</source>
574 <translation type="unfinished"></translation>
575 </message>
576 <message>
577 <location filename="../base/bootloaderinstallimx.cpp" line="175"/>
578 <source>To uninstall, perform a normal upgrade with an unmodified original firmware.</source>
579 <translation type="unfinished"></translation>
580 </message>
581</context>
582<context>
583 <name>BootloaderInstallIpod</name>
584 <message>
585 <location filename="../base/bootloaderinstallipod.cpp" line="49"/>
586 <source>Error: can&apos;t allocate buffer memory!</source>
587 <translation>Σφάλμα: αδύνατη κατανομή buffer μνήμης!</translation>
588 </message>
589 <message>
590 <location filename="../base/bootloaderinstallipod.cpp" line="80"/>
591 <source>Downloading bootloader file</source>
592 <translation>Λήψη αρχείου bootloader</translation>
593 </message>
594 <message>
595 <location filename="../base/bootloaderinstallipod.cpp" line="64"/>
596 <location filename="../base/bootloaderinstallipod.cpp" line="151"/>
597 <source>Failed to read firmware directory</source>
598 <translation>Αποτυχία ανάγνωσης του φακέλου που βρίσκεται το firmware</translation>
599 </message>
600 <message>
601 <location filename="../base/bootloaderinstallipod.cpp" line="69"/>
602 <location filename="../base/bootloaderinstallipod.cpp" line="156"/>
603 <source>Unknown version number in firmware (%1)</source>
604 <translation>Άγνωστος αριθμός έκδοσης firmware (%1)</translation>
605 </message>
606 <message>
607 <location filename="../base/bootloaderinstallipod.cpp" line="75"/>
608 <source>Warning: This is a MacPod, Rockbox only runs on WinPods.
609See http://www.rockbox.org/wiki/IpodConversionToFAT32</source>
610 <translation type="unfinished"></translation>
611 </message>
612 <message>
613 <location filename="../base/bootloaderinstallipod.cpp" line="94"/>
614 <location filename="../base/bootloaderinstallipod.cpp" line="163"/>
615 <source>Could not open Ipod in R/W mode</source>
616 <translation>Αδύνατη η προσπέλαση του ipod με τρόπο RW</translation>
617 </message>
618 <message>
619 <location filename="../base/bootloaderinstallipod.cpp" line="104"/>
620 <source>Successfull added bootloader</source>
621 <translation>Επιτυχής προσθήκη bootloader</translation>
622 </message>
623 <message>
624 <location filename="../base/bootloaderinstallipod.cpp" line="115"/>
625 <source>Failed to add bootloader</source>
626 <translation>Αποτυχία προσθήκης bootloader</translation>
627 </message>
628 <message>
629 <location filename="../base/bootloaderinstallipod.cpp" line="127"/>
630 <source>Bootloader Installation complete.</source>
631 <translation type="unfinished"></translation>
632 </message>
633 <message>
634 <location filename="../base/bootloaderinstallipod.cpp" line="132"/>
635 <source>Writing log aborted</source>
636 <translation type="unfinished"></translation>
637 </message>
638 <message>
639 <location filename="../base/bootloaderinstallipod.cpp" line="169"/>
640 <source>No bootloader detected.</source>
641 <translation>Δεν ανιχνεύθηκε bootloader.</translation>
642 </message>
643 <message>
644 <location filename="../base/bootloaderinstallipod.cpp" line="175"/>
645 <source>Successfully removed bootloader</source>
646 <translation>Επιτυχής κατάργηση bootloader</translation>
647 </message>
648 <message>
649 <location filename="../base/bootloaderinstallipod.cpp" line="182"/>
650 <source>Removing bootloader failed.</source>
651 <translation>Η κατάργηση του bootloader απέτυχε.</translation>
652 </message>
653 <message>
654 <location filename="../base/bootloaderinstallipod.cpp" line="228"/>
655 <source>Error: could not retrieve device name</source>
656 <translation type="unfinished"></translation>
657 </message>
658 <message>
659 <location filename="../base/bootloaderinstallipod.cpp" line="244"/>
660 <source>Error: no mountpoint specified!</source>
661 <translation type="unfinished"></translation>
662 </message>
663 <message>
664 <location filename="../base/bootloaderinstallipod.cpp" line="249"/>
665 <source>Could not open Ipod: permission denied</source>
666 <translation type="unfinished"></translation>
667 </message>
668 <message>
669 <location filename="../base/bootloaderinstallipod.cpp" line="253"/>
670 <source>Could not open Ipod</source>
671 <translation>Αδύνατο το άνοιγμα του ipod</translation>
672 </message>
673 <message>
674 <location filename="../base/bootloaderinstallipod.cpp" line="264"/>
675 <source>No firmware partition on disk</source>
676 <translation>Δεν υπάρχει τμήμα firmware στο δίσκο</translation>
677 </message>
678 <message>
679 <location filename="../base/bootloaderinstallipod.cpp" line="90"/>
680 <source>Installing Rockbox bootloader</source>
681 <translation type="unfinished">Εγκατάσταση Rockbox bootloader</translation>
682 </message>
683 <message>
684 <location filename="../base/bootloaderinstallipod.cpp" line="142"/>
685 <source>Uninstalling bootloader</source>
686 <translation type="unfinished"></translation>
687 </message>
688 <message>
689 <location filename="../base/bootloaderinstallipod.cpp" line="258"/>
690 <source>Error reading partition table - possibly not an Ipod</source>
691 <translation type="unfinished"></translation>
692 </message>
693</context>
694<context>
695 <name>BootloaderInstallMi4</name>
696 <message>
697 <location filename="../base/bootloaderinstallmi4.cpp" line="34"/>
698 <source>Downloading bootloader</source>
699 <translation>Λήψη bootloader</translation>
700 </message>
701 <message>
702 <location filename="../base/bootloaderinstallmi4.cpp" line="43"/>
703 <source>Installing Rockbox bootloader</source>
704 <translation>Εγκατάσταση Rockbox bootloader</translation>
705 </message>
706 <message>
707 <location filename="../base/bootloaderinstallmi4.cpp" line="66"/>
708 <source>A firmware file is already present on player</source>
709 <translation type="unfinished"></translation>
710 </message>
711 <message>
712 <location filename="../base/bootloaderinstallmi4.cpp" line="71"/>
713 <location filename="../base/bootloaderinstallmi4.cpp" line="79"/>
714 <source>Bootloader successful installed</source>
715 <translation>Η εγκατάσταση του Rockbox bootloader ολοκληρώθηκε με επιτυχία.</translation>
716 </message>
717 <message>
718 <location filename="../base/bootloaderinstallmi4.cpp" line="74"/>
719 <source>Copying modified firmware file failed</source>
720 <translation type="unfinished"></translation>
721 </message>
722 <message>
723 <location filename="../base/bootloaderinstallmi4.cpp" line="91"/>
724 <source>Checking for Rockbox bootloader</source>
725 <translation>Έλεγχος Rockbox bootloader</translation>
726 </message>
727 <message>
728 <location filename="../base/bootloaderinstallmi4.cpp" line="93"/>
729 <source>No Rockbox bootloader found</source>
730 <translation>Ο Rockbox bootloader δεν βρέθηκε</translation>
731 </message>
732 <message>
733 <location filename="../base/bootloaderinstallmi4.cpp" line="98"/>
734 <source>Checking for original firmware file</source>
735 <translation>Έλεγχος αρχείου αυθεντικού firmware</translation>
736 </message>
737 <message>
738 <location filename="../base/bootloaderinstallmi4.cpp" line="103"/>
739 <source>Error finding original firmware file</source>
740 <translation>Σφάλμα εύρεσης αρχείου αυθεντικού firmware</translation>
741 </message>
742 <message>
743 <location filename="../base/bootloaderinstallmi4.cpp" line="113"/>
744 <source>Rockbox bootloader successful removed</source>
745 <translation>Επιτυχής απεγκατάσταση του Rockbox bootloader</translation>
746 </message>
747</context>
748<context>
749 <name>BootloaderInstallMpio</name>
750 <message>
751 <location filename="../base/bootloaderinstallmpio.cpp" line="34"/>
752 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
753 <translation type="unfinished"></translation>
754 </message>
755 <message>
756 <location filename="../base/bootloaderinstallmpio.cpp" line="53"/>
757 <source>Downloading bootloader file</source>
758 <translation type="unfinished">Λήψη αρχείου bootloader</translation>
759 </message>
760 <message>
761 <location filename="../base/bootloaderinstallmpio.cpp" line="80"/>
762 <source>Could not open the original firmware.</source>
763 <translation type="unfinished"></translation>
764 </message>
765 <message>
766 <location filename="../base/bootloaderinstallmpio.cpp" line="83"/>
767 <source>Could not read the original firmware.</source>
768 <translation type="unfinished"></translation>
769 </message>
770 <message>
771 <location filename="../base/bootloaderinstallmpio.cpp" line="86"/>
772 <source>Loaded firmware file does not look like MPIO original firmware file.</source>
773 <translation type="unfinished"></translation>
774 </message>
775 <message>
776 <location filename="../base/bootloaderinstallmpio.cpp" line="101"/>
777 <source>Could not open output file.</source>
778 <translation type="unfinished"></translation>
779 </message>
780 <message>
781 <location filename="../base/bootloaderinstallmpio.cpp" line="104"/>
782 <source>Could not write output file.</source>
783 <translation type="unfinished"></translation>
784 </message>
785 <message>
786 <location filename="../base/bootloaderinstallmpio.cpp" line="107"/>
787 <source>Unknown error number: %1</source>
788 <translation type="unfinished"></translation>
789 </message>
790 <message>
791 <location filename="../base/bootloaderinstallmpio.cpp" line="89"/>
792 <source>Could not open downloaded bootloader.</source>
793 <translation type="unfinished"></translation>
794 </message>
795 <message>
796 <location filename="../base/bootloaderinstallmpio.cpp" line="92"/>
797 <source>Place for bootloader in OF file not empty.</source>
798 <translation type="unfinished"></translation>
799 </message>
800 <message>
801 <location filename="../base/bootloaderinstallmpio.cpp" line="95"/>
802 <source>Could not read the downloaded bootloader.</source>
803 <translation type="unfinished"></translation>
804 </message>
805 <message>
806 <location filename="../base/bootloaderinstallmpio.cpp" line="98"/>
807 <source>Bootloader checksum error.</source>
808 <translation type="unfinished"></translation>
809 </message>
810 <message>
811 <location filename="../base/bootloaderinstallmpio.cpp" line="112"/>
812 <source>Patching original firmware failed: %1</source>
813 <translation type="unfinished"></translation>
814 </message>
815 <message>
816 <location filename="../base/bootloaderinstallmpio.cpp" line="119"/>
817 <source>Success: modified firmware file created</source>
818 <translation type="unfinished">Επιτυχία: Τροποποιημένο αρχείο firmware δημιουργήθηκε</translation>
819 </message>
820 <message>
821 <location filename="../base/bootloaderinstallmpio.cpp" line="127"/>
822 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
823 <translation type="unfinished"></translation>
824 </message>
825</context>
826<context>
827 <name>BootloaderInstallSansa</name>
828 <message>
829 <location filename="../base/bootloaderinstallsansa.cpp" line="50"/>
830 <source>Error: can&apos;t allocate buffer memory!</source>
831 <translation>Σφάλμα: αδύνατη κατανομή buffer μνήμης!</translation>
832 </message>
833 <message>
834 <location filename="../base/bootloaderinstallsansa.cpp" line="55"/>
835 <source>Searching for Sansa</source>
836 <translation>Αναζήτηση συσκευών sansa</translation>
837 </message>
838 <message>
839 <location filename="../base/bootloaderinstallsansa.cpp" line="59"/>
840 <source>Permission for disc access denied!
841This is required to install the bootloader</source>
842 <translation>Ανεπαρκή δικαιώματα προσπέλασης δίσκου!
843Απαιτούνται κατάλληλα δικαιώματα για την εγκατάσταση του bootloader</translation>
844 </message>
845 <message>
846 <location filename="../base/bootloaderinstallsansa.cpp" line="66"/>
847 <source>No Sansa detected!</source>
848 <translation>Δεν βρέθηκαν συσκευές sansa!</translation>
849 </message>
850 <message>
851 <location filename="../base/bootloaderinstallsansa.cpp" line="79"/>
852 <source>Downloading bootloader file</source>
853 <translation>Λήψη αρχείου bootloader</translation>
854 </message>
855 <message>
856 <location filename="../base/bootloaderinstallsansa.cpp" line="71"/>
857 <location filename="../base/bootloaderinstallsansa.cpp" line="179"/>
858 <source>OLD ROCKBOX INSTALLATION DETECTED, ABORTING.
859You must reinstall the original Sansa firmware before running
860sansapatcher for the first time.
861See http://www.rockbox.org/wiki/SansaE200Install
862</source>
863 <translation>ΑΝΙΧΝΕΥΘΗΚΕ ΠΑΛΑΙΟΣ ΤΡΟΠΟΣ ΕΓΚΑΤΑΣΤΑΣΗΣ, ΜΑΤΑΙΩΣΗ.
864Πρέπει να επανεγκαταστήσετε το αυθεντικό sansa firmware
865πριν τρέξετε το sansapatcher για πρώτη φορά.
866Βλέπετε http://www.rockbox.org/wiki/SansaE200Install</translation>
867 </message>
868 <message>
869 <location filename="../base/bootloaderinstallsansa.cpp" line="102"/>
870 <location filename="../base/bootloaderinstallsansa.cpp" line="189"/>
871 <source>Could not open Sansa in R/W mode</source>
872 <translation>Αδύνατη η προσπέλαση του sansa με τρόπο R/W</translation>
873 </message>
874 <message>
875 <location filename="../base/bootloaderinstallsansa.cpp" line="129"/>
876 <source>Successfully installed bootloader</source>
877 <translation>Επιτυχής εγκατάσταση bootloader</translation>
878 </message>
879 <message>
880 <location filename="../base/bootloaderinstallsansa.cpp" line="140"/>
881 <source>Failed to install bootloader</source>
882 <translation>Αποτυχία εγκατάστασης bootloader</translation>
883 </message>
884 <message>
885 <location filename="../base/bootloaderinstallsansa.cpp" line="153"/>
886 <source>Bootloader Installation complete.</source>
887 <translation type="unfinished"></translation>
888 </message>
889 <message>
890 <location filename="../base/bootloaderinstallsansa.cpp" line="158"/>
891 <source>Writing log aborted</source>
892 <translation type="unfinished"></translation>
893 </message>
894 <message>
895 <location filename="../base/bootloaderinstallsansa.cpp" line="238"/>
896 <source>Error: could not retrieve device name</source>
897 <translation type="unfinished"></translation>
898 </message>
899 <message>
900 <location filename="../base/bootloaderinstallsansa.cpp" line="254"/>
901 <source>Can&apos;t find Sansa</source>
902 <translation>Δεν βρέθηκε συσκευή sansa</translation>
903 </message>
904 <message>
905 <location filename="../base/bootloaderinstallsansa.cpp" line="259"/>
906 <source>Could not open Sansa</source>
907 <translation>Αδύνατο το άνοιγμα του sansa</translation>
908 </message>
909 <message>
910 <location filename="../base/bootloaderinstallsansa.cpp" line="264"/>
911 <source>Could not read partition table</source>
912 <translation>Αδύνατη η ανάγνωση του πίνακα κατάτμησης</translation>
913 </message>
914 <message>
915 <location filename="../base/bootloaderinstallsansa.cpp" line="271"/>
916 <source>Disk is not a Sansa (Error %1), aborting.</source>
917 <translation>Ο δίσκος δεν είναι sansa (%1), ματαίωση.</translation>
918 </message>
919 <message>
920 <location filename="../base/bootloaderinstallsansa.cpp" line="195"/>
921 <source>Successfully removed bootloader</source>
922 <translation>Επιτυχής κατάργηση bootloader</translation>
923 </message>
924 <message>
925 <location filename="../base/bootloaderinstallsansa.cpp" line="202"/>
926 <source>Removing bootloader failed.</source>
927 <translation>Η κατάργηση του bootloader απέτυχε.</translation>
928 </message>
929 <message>
930 <location filename="../base/bootloaderinstallsansa.cpp" line="94"/>
931 <source>Installing Rockbox bootloader</source>
932 <translation type="unfinished">Εγκατάσταση Rockbox bootloader</translation>
933 </message>
934 <message>
935 <location filename="../base/bootloaderinstallsansa.cpp" line="111"/>
936 <source>Checking downloaded bootloader</source>
937 <translation type="unfinished"></translation>
938 </message>
939 <message>
940 <location filename="../base/bootloaderinstallsansa.cpp" line="119"/>
941 <source>Bootloader mismatch! Aborting.</source>
942 <translation type="unfinished"></translation>
943 </message>
944 <message>
945 <location filename="../base/bootloaderinstallsansa.cpp" line="170"/>
946 <source>Uninstalling bootloader</source>
947 <translation type="unfinished"></translation>
948 </message>
949</context>
950<context>
951 <name>BootloaderInstallTcc</name>
952 <message>
953 <location filename="../base/bootloaderinstalltcc.cpp" line="33"/>
954 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wiki page on how to obtain the file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
955 <translation type="unfinished"></translation>
956 </message>
957 <message>
958 <location filename="../base/bootloaderinstalltcc.cpp" line="50"/>
959 <source>Downloading bootloader file</source>
960 <translation type="unfinished">Λήψη αρχείου bootloader</translation>
961 </message>
962 <message>
963 <location filename="../base/bootloaderinstalltcc.cpp" line="82"/>
964 <location filename="../base/bootloaderinstalltcc.cpp" line="99"/>
965 <source>Could not load %1</source>
966 <translation type="unfinished"></translation>
967 </message>
968 <message>
969 <location filename="../base/bootloaderinstalltcc.cpp" line="90"/>
970 <source>Unknown OF file used: %1</source>
971 <translation type="unfinished"></translation>
972 </message>
973 <message>
974 <location filename="../base/bootloaderinstalltcc.cpp" line="104"/>
975 <source>Patching Firmware...</source>
976 <translation type="unfinished"></translation>
977 </message>
978 <message>
979 <location filename="../base/bootloaderinstalltcc.cpp" line="111"/>
980 <source>Could not patch firmware</source>
981 <translation type="unfinished"></translation>
982 </message>
983 <message>
984 <location filename="../base/bootloaderinstalltcc.cpp" line="117"/>
985 <source>Could not open %1 for writing</source>
986 <translation type="unfinished"></translation>
987 </message>
988 <message>
989 <location filename="../base/bootloaderinstalltcc.cpp" line="126"/>
990 <source>Could not write firmware file</source>
991 <translation type="unfinished"></translation>
992 </message>
993 <message>
994 <location filename="../base/bootloaderinstalltcc.cpp" line="131"/>
995 <source>Success: modified firmware file created</source>
996 <translation type="unfinished">Επιτυχία: Τροποποιημένο αρχείο firmware δημιουργήθηκε</translation>
997 </message>
998 <message>
999 <location filename="../base/bootloaderinstalltcc.cpp" line="151"/>
1000 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
1001 <translation type="unfinished"></translation>
1002 </message>
1003</context>
1004<context>
1005 <name>Changelog</name>
1006 <message>
1007 <location filename="../gui/changelogfrm.ui" line="17"/>
1008 <source>Changelog</source>
1009 <translation type="unfinished"></translation>
1010 </message>
1011 <message>
1012 <location filename="../gui/changelogfrm.ui" line="39"/>
1013 <source>Show on startup</source>
1014 <translation type="unfinished"></translation>
1015 </message>
1016 <message>
1017 <location filename="../gui/changelogfrm.ui" line="46"/>
1018 <source>&amp;Ok</source>
1019 <translation type="unfinished">&amp;ΟΚ</translation>
1020 </message>
1021</context>
1022<context>
1023 <name>Config</name>
1024 <message>
1025 <location filename="../configure.cpp" line="322"/>
1026 <source>Current cache size is %L1 kiB.</source>
1027 <translation>Το μέγεθος της τρέχουσας προσωρινής μνήμης είναι %L1 kiB.</translation>
1028 </message>
1029 <message>
1030 <location filename="../configure.cpp" line="340"/>
1031 <source>Showing disabled targets</source>
1032 <translation type="unfinished"></translation>
1033 </message>
1034 <message>
1035 <location filename="../configure.cpp" line="341"/>
1036 <source>You just enabled showing targets that are marked disabled. Disabled targets are not recommended to end users. Please use this option only if you know what you are doing.</source>
1037 <translation type="unfinished"></translation>
1038 </message>
1039 <message>
1040 <location filename="../configure.cpp" line="448"/>
1041 <location filename="../configure.cpp" line="914"/>
1042 <source>TTS error</source>
1043 <translation type="unfinished"></translation>
1044 </message>
1045 <message>
1046 <location filename="../configure.cpp" line="449"/>
1047 <location filename="../configure.cpp" line="915"/>
1048 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1049 <translation type="unfinished"></translation>
1050 </message>
1051 <message>
1052 <location filename="../configure.cpp" line="455"/>
1053 <location filename="../configure.cpp" line="485"/>
1054 <source>Configuration OK</source>
1055 <translation>Ρυθμίσεις εντάξει</translation>
1056 </message>
1057 <message>
1058 <location filename="../configure.cpp" line="461"/>
1059 <location filename="../configure.cpp" line="490"/>
1060 <source>Configuration INVALID</source>
1061 <translation>Μη επιτρεπτές ρυθμίσεις</translation>
1062 </message>
1063 <message>
1064 <location filename="../configure.cpp" line="529"/>
1065 <source>Proxy Detection</source>
1066 <translation type="unfinished"></translation>
1067 </message>
1068 <message>
1069 <location filename="../configure.cpp" line="530"/>
1070 <source>The System Proxy settings are invalid!
1071Rockbox Utility can&apos;t work with this proxy settings. Make sure the system proxy is set correctly. Note that &quot;proxy auto-config (PAC)&quot; scripts are not supported by Rockbox Utility. If your system uses this you need to use manual proxy settings.</source>
1072 <translation type="unfinished"></translation>
1073 </message>
1074 <message>
1075 <location filename="../configure.cpp" line="643"/>
1076 <source>Set Cache Path</source>
1077 <translation type="unfinished"></translation>
1078 </message>
1079 <message>
1080 <location filename="../configure.cpp" line="665"/>
1081 <source>%1 (%2 GiB of %3 GiB free)</source>
1082 <translation type="unfinished"></translation>
1083 </message>
1084 <message>
1085 <location filename="../configure.cpp" line="739"/>
1086 <source>Multiple devices have been detected. Please disconnect all players but one and try again.</source>
1087 <translation type="unfinished"></translation>
1088 </message>
1089 <message>
1090 <location filename="../configure.cpp" line="742"/>
1091 <source>Detected devices:</source>
1092 <translation type="unfinished"></translation>
1093 </message>
1094 <message>
1095 <location filename="../configure.cpp" line="747"/>
1096 <source>(unknown)</source>
1097 <translation type="unfinished"></translation>
1098 </message>
1099 <message>
1100 <location filename="../configure.cpp" line="749"/>
1101 <source>%1 at %2</source>
1102 <translation type="unfinished"></translation>
1103 </message>
1104 <message>
1105 <location filename="../configure.cpp" line="755"/>
1106 <source>Note: detecting connected devices might be ambiguous. You might have less devices connected than listed. In this case it might not be possible to detect your player unambiguously.</source>
1107 <translation type="unfinished"></translation>
1108 </message>
1109 <message>
1110 <location filename="../configure.cpp" line="759"/>
1111 <location filename="../configure.cpp" line="763"/>
1112 <location filename="../configure.cpp" line="805"/>
1113 <source>Device Detection</source>
1114 <translation type="unfinished"></translation>
1115 </message>
1116 <message>
1117 <location filename="../configure.cpp" line="788"/>
1118 <source>%1 &quot;MacPod&quot; found!
1119Rockbox needs a FAT formatted Ipod (so-called &quot;WinPod&quot;) to run. </source>
1120 <translation type="unfinished"></translation>
1121 </message>
1122 <message>
1123 <source>Fatal error</source>
1124 <translation type="obsolete">Κρίσιμο σφάλμα</translation>
1125 </message>
1126 <message>
1127 <location filename="../configure.cpp" line="774"/>
1128 <source>Detected an unsupported player:
1129%1
1130Sorry, Rockbox doesn&apos;t run on your player.</source>
1131 <translation type="unfinished"></translation>
1132 </message>
1133 <message>
1134 <location filename="../configure.cpp" line="921"/>
1135 <source>TTS configuration invalid</source>
1136 <translation type="unfinished"></translation>
1137 </message>
1138 <message>
1139 <location filename="../configure.cpp" line="922"/>
1140 <source>TTS configuration invalid.
1141 Please configure TTS engine.</source>
1142 <translation type="unfinished"></translation>
1143 </message>
1144 <message>
1145 <location filename="../configure.cpp" line="927"/>
1146 <source>Could not start TTS engine.</source>
1147 <translation type="unfinished"></translation>
1148 </message>
1149 <message>
1150 <location filename="../configure.cpp" line="928"/>
1151 <source>Could not start TTS engine.
1152</source>
1153 <translation type="unfinished"></translation>
1154 </message>
1155 <message>
1156 <location filename="../configure.cpp" line="929"/>
1157 <location filename="../configure.cpp" line="948"/>
1158 <source>
1159Please configure TTS engine.</source>
1160 <translation type="unfinished"></translation>
1161 </message>
1162 <message>
1163 <location filename="../configure.cpp" line="943"/>
1164 <source>Rockbox Utility Voice Test</source>
1165 <translation type="unfinished"></translation>
1166 </message>
1167 <message>
1168 <location filename="../configure.cpp" line="946"/>
1169 <source>Could not voice test string.</source>
1170 <translation type="unfinished"></translation>
1171 </message>
1172 <message>
1173 <location filename="../configure.cpp" line="947"/>
1174 <source>Could not voice test string.
1175</source>
1176 <translation type="unfinished"></translation>
1177 </message>
1178 <message>
1179 <location filename="../configure.cpp" line="858"/>
1180 <source>Autodetection</source>
1181 <translation>Αυτόματος εντοπισμός</translation>
1182 </message>
1183 <message>
1184 <location filename="../configure.cpp" line="780"/>
1185 <source>%1 in MTP mode found!
1186You need to change your player to MSC mode for installation. </source>
1187 <translation type="unfinished"></translation>
1188 </message>
1189 <message>
1190 <location filename="../configure.cpp" line="859"/>
1191 <source>Could not detect a Mountpoint.
1192Select your Mountpoint manually.</source>
1193 <translation>Δεν εντοπίστηκε κάποιο σημείο προσάρτησης.
1194Επιλέξτε το σημείο προσάρτησης χειροκίνητα.</translation>
1195 </message>
1196 <message>
1197 <location filename="../configure.cpp" line="764"/>
1198 <source>Could not detect a device.
1199Select your device and Mountpoint manually.</source>
1200 <translation>Δεν εντοπίστηκε κάποια συσκευή.
1201Επιλέξτε τη συσκευή σας και το σημείο προσάρτησης χειροκίνητα.</translation>
1202 </message>
1203 <message>
1204 <location filename="../configure.cpp" line="794"/>
1205 <source>The player contains an incompatible filesystem.
1206Make sure you selected the correct mountpoint and the player is set up to use a filesystem compatible with Rockbox.</source>
1207 <translation type="unfinished"></translation>
1208 </message>
1209 <message>
1210 <location filename="../configure.cpp" line="802"/>
1211 <source>An unknown error occured during player detection.</source>
1212 <translation type="unfinished"></translation>
1213 </message>
1214 <message>
1215 <location filename="../configure.cpp" line="869"/>
1216 <source>Really delete cache?</source>
1217 <translation>Σίγουρα διαγραφή προσωρινής μνήμης;</translation>
1218 </message>
1219 <message>
1220 <location filename="../configure.cpp" line="870"/>
1221 <source>Do you really want to delete the cache? Make absolutely sure this setting is correct as it will remove &lt;b&gt;all&lt;/b&gt; files in this folder!</source>
1222 <translation>Θέλετε σίγουρα να διαγραφεί η προσωρινή μνήμη; Κάντε απόλυτα σίγουρο ότι αυτή η επιλογή είναι σωστή καθώς θα αφαιρεθούν &lt;b&gt;όλα&lt;/b&gt; τα αρχεία και οι φάκελοι!</translation>
1223 </message>
1224 <message>
1225 <location filename="../configure.cpp" line="878"/>
1226 <source>Path wrong!</source>
1227 <translation>Λάθος διαδρομή!</translation>
1228 </message>
1229 <message>
1230 <location filename="../configure.cpp" line="879"/>
1231 <source>The cache path is invalid. Aborting.</source>
1232 <translation>Η διαδρομή της προσωρινής μνήμης δεν είναι επιτρεπτή. Ακύρωση.</translation>
1233 </message>
1234 <message>
1235 <location filename="../configure.cpp" line="130"/>
1236 <source>The following errors occurred:</source>
1237 <translation type="unfinished"></translation>
1238 </message>
1239 <message>
1240 <location filename="../configure.cpp" line="175"/>
1241 <source>No mountpoint given</source>
1242 <translation type="unfinished"></translation>
1243 </message>
1244 <message>
1245 <location filename="../configure.cpp" line="179"/>
1246 <source>Mountpoint does not exist</source>
1247 <translation type="unfinished"></translation>
1248 </message>
1249 <message>
1250 <location filename="../configure.cpp" line="183"/>
1251 <source>Mountpoint is not a directory.</source>
1252 <translation type="unfinished"></translation>
1253 </message>
1254 <message>
1255 <location filename="../configure.cpp" line="187"/>
1256 <source>Mountpoint is not writeable</source>
1257 <translation type="unfinished"></translation>
1258 </message>
1259 <message>
1260 <location filename="../configure.cpp" line="202"/>
1261 <source>No player selected</source>
1262 <translation type="unfinished"></translation>
1263 </message>
1264 <message>
1265 <location filename="../configure.cpp" line="209"/>
1266 <source>Cache path not writeable. Leave path empty to default to systems temporary path.</source>
1267 <translation type="unfinished"></translation>
1268 </message>
1269 <message>
1270 <location filename="../configure.cpp" line="228"/>
1271 <source>You need to fix the above errors before you can continue.</source>
1272 <translation type="unfinished"></translation>
1273 </message>
1274 <message>
1275 <location filename="../configure.cpp" line="231"/>
1276 <source>Configuration error</source>
1277 <translation type="unfinished">Σφάλμα ρυθμίσεων</translation>
1278 </message>
1279</context>
1280<context>
1281 <name>ConfigForm</name>
1282 <message>
1283 <location filename="../configurefrm.ui" line="14"/>
1284 <source>Configuration</source>
1285 <translation>Ρυθμίσεις</translation>
1286 </message>
1287 <message>
1288 <location filename="../configurefrm.ui" line="20"/>
1289 <source>Configure Rockbox Utility</source>
1290 <translation>Παραμετροποίηση Rockbox Utility</translation>
1291 </message>
1292 <message>
1293 <location filename="../configurefrm.ui" line="35"/>
1294 <source>&amp;Device</source>
1295 <translation>&amp;Συσκευή</translation>
1296 </message>
1297 <message>
1298 <location filename="../configurefrm.ui" line="41"/>
1299 <source>Select your device in the &amp;filesystem</source>
1300 <translation>Επιλέξτε τη συσκευή σας στο &amp;σύστημα αρχείων</translation>
1301 </message>
1302 <message>
1303 <location filename="../configurefrm.ui" line="319"/>
1304 <source>&amp;Browse</source>
1305 <translation>Ανα&amp;ζήτηση</translation>
1306 </message>
1307 <message>
1308 <location filename="../configurefrm.ui" line="72"/>
1309 <source>&amp;Select your audio player</source>
1310 <translation>Επιλέξτε τη συσκευή ψηφιακού &amp;ήχου που έχετε</translation>
1311 </message>
1312 <message>
1313 <location filename="../configurefrm.ui" line="58"/>
1314 <source>&amp;Refresh</source>
1315 <translation type="unfinished">&amp;Ανανέωση</translation>
1316 </message>
1317 <message>
1318 <location filename="../configurefrm.ui" line="95"/>
1319 <source>Show disabled targets</source>
1320 <translation type="unfinished"></translation>
1321 </message>
1322 <message>
1323 <location filename="../configurefrm.ui" line="114"/>
1324 <source>&amp;Autodetect</source>
1325 <translation>&amp;Αυτόματος εντοπισμός</translation>
1326 </message>
1327 <message>
1328 <location filename="../configurefrm.ui" line="136"/>
1329 <source>&amp;Proxy</source>
1330 <translation>&amp;Διαμεσολαβητής</translation>
1331 </message>
1332 <message>
1333 <location filename="../configurefrm.ui" line="142"/>
1334 <source>&amp;No Proxy</source>
1335 <translation>&amp;Χωρίς διαμεσολαβητή</translation>
1336 </message>
1337 <message>
1338 <location filename="../configurefrm.ui" line="152"/>
1339 <source>Use S&amp;ystem values</source>
1340 <translation>Χρήση επιλογών &amp;συστήματος</translation>
1341 </message>
1342 <message>
1343 <location filename="../configurefrm.ui" line="159"/>
1344 <source>&amp;Manual Proxy settings</source>
1345 <translation>Χειροκίνητη &amp;ρύθμιση διαμεσολαβητή</translation>
1346 </message>
1347 <message>
1348 <location filename="../configurefrm.ui" line="166"/>
1349 <source>Proxy Values</source>
1350 <translation>Τιμές διαμεσολαβητή</translation>
1351 </message>
1352 <message>
1353 <location filename="../configurefrm.ui" line="172"/>
1354 <source>&amp;Host:</source>
1355 <translation>&amp;Ξενιστής:</translation>
1356 </message>
1357 <message>
1358 <location filename="../configurefrm.ui" line="182"/>
1359 <source>&amp;Port:</source>
1360 <translation>&amp;Θύρα:</translation>
1361 </message>
1362 <message>
1363 <location filename="../configurefrm.ui" line="199"/>
1364 <source>&amp;Username</source>
1365 <translation>Ό&amp;νομα χρήστη</translation>
1366 </message>
1367 <message>
1368 <location filename="../configurefrm.ui" line="209"/>
1369 <source>Pass&amp;word</source>
1370 <translation>Κ&amp;ωδικός</translation>
1371 </message>
1372 <message>
1373 <location filename="../configurefrm.ui" line="219"/>
1374 <source>Show</source>
1375 <translation type="unfinished"></translation>
1376 </message>
1377 <message>
1378 <location filename="../configurefrm.ui" line="260"/>
1379 <source>&amp;Language</source>
1380 <translation>&amp;Γλώσσα</translation>
1381 </message>
1382 <message>
1383 <location filename="../configurefrm.ui" line="274"/>
1384 <source>Cac&amp;he</source>
1385 <translation>&amp;Προσωρινή μνήμη</translation>
1386 </message>
1387 <message>
1388 <location filename="../configurefrm.ui" line="277"/>
1389 <source>Download cache settings</source>
1390 <translation>Ρυθμίσεις προσωρινής μνήμης λήψεων</translation>
1391 </message>
1392 <message>
1393 <location filename="../configurefrm.ui" line="283"/>
1394 <source>Rockbox Utility uses a local download cache to save network traffic. You can change the path to the cache and use it as local repository by enabling Offline mode.</source>
1395 <translation>Το Rockbox Utility χρησιμοποιεί μια τοπική προσωρινή μνήμη λήψεων για οικονομία των δικτυακών πόρων. Μπορείτε να αλλάξετε τη διαδρομή σε αυτήν της προσωρινής μνήμης και να τη χρησιμοποιήσετε ως τοπικό αποθετήριο, ενεργοποιώντας την επιλογή Εργασία χωρίς σύνδεση.</translation>
1396 </message>
1397 <message>
1398 <location filename="../configurefrm.ui" line="293"/>
1399 <source>Current cache size is %1</source>
1400 <translation>Το μέγεθος της τρέχουσας προσωρινής μνήμης είναι %1</translation>
1401 </message>
1402 <message>
1403 <location filename="../configurefrm.ui" line="302"/>
1404 <source>P&amp;ath</source>
1405 <translation>&amp;Διαδρομή</translation>
1406 </message>
1407 <message>
1408 <location filename="../configurefrm.ui" line="312"/>
1409 <source>Entering an invalid folder will reset the path to the systems temporary path.</source>
1410 <translation>Χρησιμοποιώντας ένα μη έγκυρο φάκελο θα επαναφέρει τη διαδρομή στον προσωρινό φάκελο του συστήματος.</translation>
1411 </message>
1412 <message>
1413 <location filename="../configurefrm.ui" line="334"/>
1414 <source>Disable local &amp;download cache</source>
1415 <translation>&amp;Απενεργοποίηση της τοπικής προσωρινής μνήμης λήψεων</translation>
1416 </message>
1417 <message>
1418 <source>&lt;p&gt;This will try to use all information from the cache, even information about updates. Only use this option if you want to install without network connection. Note: you need to do the same install you want to perform later with network access first to download all required files to the cache.&lt;/p&gt;</source>
1419 <translation type="obsolete">&lt;p&gt;Αυτή η επιλογή προσπαθεί να χρησιμοποιήσει όλες τις πληροφορίες από την προσωρινή μνήμη, ακόμα και αν πρόκειται για ενημερώσεις.
1420Χρησιμοποιήστε αυτήν την επιλογή μόνο εάν θέλετε να κάνετε εγκατάσταση χωρίς σύνδεση δικτύου.
1421Σημείωση: Αυτό προϋποθέτει ότι έχετε είδη κάνει μία εγκατάσταση με πρόσβαση στο δίκτυο,
1422έτσι ώστε η προσωρινή μνήμη να έχει λάβει τα απαραίτητα αρχεία.&lt;/p&gt;</translation>
1423 </message>
1424 <message>
1425 <source>O&amp;ffline mode</source>
1426 <translation type="obsolete">&amp;Εργασία χωρίς σύνδεση</translation>
1427 </message>
1428 <message>
1429 <location filename="../configurefrm.ui" line="369"/>
1430 <source>Clean cache &amp;now</source>
1431 <translation>&amp;Καθαρισμός προσωρινής μνήμης</translation>
1432 </message>
1433 <message>
1434 <location filename="../configurefrm.ui" line="385"/>
1435 <source>&amp;TTS &amp;&amp; Encoder</source>
1436 <translation>&amp;Μηχανή TTS &amp;&amp; κωδικοποιητής</translation>
1437 </message>
1438 <message>
1439 <location filename="../configurefrm.ui" line="391"/>
1440 <source>TTS Engine</source>
1441 <translation>Μηχανή TTS</translation>
1442 </message>
1443 <message>
1444 <location filename="../configurefrm.ui" line="397"/>
1445 <source>&amp;Select TTS Engine</source>
1446 <translation>&amp;Επιλέξτε μηχανή TTS</translation>
1447 </message>
1448 <message>
1449 <location filename="../configurefrm.ui" line="410"/>
1450 <source>Configure TTS Engine</source>
1451 <translation>Παραμετροποίηση μηχανής TTS</translation>
1452 </message>
1453 <message>
1454 <location filename="../configurefrm.ui" line="417"/>
1455 <location filename="../configurefrm.ui" line="468"/>
1456 <source>Configuration invalid!</source>
1457 <translation>Μη επιτρεπτές ρυθμίσεις!</translation>
1458 </message>
1459 <message>
1460 <location filename="../configurefrm.ui" line="434"/>
1461 <source>Configure &amp;TTS</source>
1462 <translation>Παραμετροποίηση &amp;TTS</translation>
1463 </message>
1464 <message>
1465 <location filename="../configurefrm.ui" line="445"/>
1466 <source>Test TTS</source>
1467 <translation type="unfinished"></translation>
1468 </message>
1469 <message>
1470 <location filename="../configurefrm.ui" line="452"/>
1471 <source>&amp;Use string corrections for TTS</source>
1472 <translation type="unfinished"></translation>
1473 </message>
1474 <message>
1475 <location filename="../configurefrm.ui" line="462"/>
1476 <source>Encoder Engine</source>
1477 <translation>Μηχανή κωδικοποιητή</translation>
1478 </message>
1479 <message>
1480 <location filename="../configurefrm.ui" line="485"/>
1481 <source>Configure &amp;Enc</source>
1482 <translation>Παραμετροποίηση κ&amp;ωδικοποιητή</translation>
1483 </message>
1484 <message>
1485 <location filename="../configurefrm.ui" line="496"/>
1486 <source>encoder name</source>
1487 <translation>Όνομα κωδικοποιητή</translation>
1488 </message>
1489 <message>
1490 <location filename="../configurefrm.ui" line="536"/>
1491 <source>&amp;Ok</source>
1492 <translation>&amp;ΟΚ</translation>
1493 </message>
1494 <message>
1495 <location filename="../configurefrm.ui" line="547"/>
1496 <source>&amp;Cancel</source>
1497 <translation>Ά&amp;κυρο</translation>
1498 </message>
1499</context>
1500<context>
1501 <name>Configure</name>
1502 <message>
1503 <location filename="../configure.cpp" line="589"/>
1504 <source>English</source>
1505 <comment>This is the localized language name, i.e. your language.</comment>
1506 <translation>Ελληνικά</translation>
1507 </message>
1508</context>
1509<context>
1510 <name>CreateVoiceFrm</name>
1511 <message>
1512 <location filename="../createvoicefrm.ui" line="17"/>
1513 <source>Create Voice File</source>
1514 <translation>Δημιουργία αρχείου φωνής</translation>
1515 </message>
1516 <message>
1517 <location filename="../createvoicefrm.ui" line="42"/>
1518 <source>Select the Language you want to generate a voicefile for:</source>
1519 <translation>Επιλέξτε τη γλώσσα που θέλετε για να δημιουργήσετε ένα αρχείο φωνής:</translation>
1520 </message>
1521 <message>
1522 <location filename="../createvoicefrm.ui" line="55"/>
1523 <source>TTS:</source>
1524 <translation type="unfinished"></translation>
1525 </message>
1526 <message>
1527 <location filename="../createvoicefrm.ui" line="101"/>
1528 <source>Silence threshold</source>
1529 <translation type="unfinished"></translation>
1530 </message>
1531 <message>
1532 <location filename="../createvoicefrm.ui" line="163"/>
1533 <source>Language</source>
1534 <translation type="unfinished"></translation>
1535 </message>
1536 <message>
1537 <location filename="../createvoicefrm.ui" line="49"/>
1538 <source>Generation settings</source>
1539 <translation>Ρυθμίσεις δημιουργίας</translation>
1540 </message>
1541 <message>
1542 <location filename="../createvoicefrm.ui" line="68"/>
1543 <source>Change</source>
1544 <translation>Τροποποίηση</translation>
1545 </message>
1546 <message>
1547 <location filename="../createvoicefrm.ui" line="139"/>
1548 <source>&amp;Install</source>
1549 <translation>&amp;Εγκατάσταση</translation>
1550 </message>
1551 <message>
1552 <location filename="../createvoicefrm.ui" line="150"/>
1553 <source>&amp;Cancel</source>
1554 <translation>Ά&amp;κυρο</translation>
1555 </message>
1556 <message>
1557 <location filename="../createvoicefrm.ui" line="88"/>
1558 <source>Wavtrim Threshold</source>
1559 <translation>Όριο Wavtrim</translation>
1560 </message>
1561</context>
1562<context>
1563 <name>CreateVoiceWindow</name>
1564 <message>
1565 <location filename="../createvoicewindow.cpp" line="100"/>
1566 <source>TTS error</source>
1567 <translation type="unfinished"></translation>
1568 </message>
1569 <message>
1570 <location filename="../createvoicewindow.cpp" line="101"/>
1571 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1572 <translation type="unfinished"></translation>
1573 </message>
1574 <message>
1575 <location filename="../createvoicewindow.cpp" line="105"/>
1576 <location filename="../createvoicewindow.cpp" line="108"/>
1577 <source>Engine: &lt;b&gt;%1&lt;/b&gt;</source>
1578 <translation type="unfinished"></translation>
1579 </message>
1580</context>
1581<context>
1582 <name>EncTtsCfgGui</name>
1583 <message>
1584 <location filename="../encttscfggui.cpp" line="45"/>
1585 <source>Waiting for engine...</source>
1586 <translation type="unfinished"></translation>
1587 </message>
1588 <message>
1589 <location filename="../encttscfggui.cpp" line="95"/>
1590 <source>Ok</source>
1591 <translation type="unfinished"></translation>
1592 </message>
1593 <message>
1594 <location filename="../encttscfggui.cpp" line="98"/>
1595 <source>Cancel</source>
1596 <translation type="unfinished"></translation>
1597 </message>
1598 <message>
1599 <location filename="../encttscfggui.cpp" line="197"/>
1600 <source>Browse</source>
1601 <translation type="unfinished"></translation>
1602 </message>
1603 <message>
1604 <location filename="../encttscfggui.cpp" line="205"/>
1605 <source>Refresh</source>
1606 <translation type="unfinished"></translation>
1607 </message>
1608 <message>
1609 <location filename="../encttscfggui.cpp" line="377"/>
1610 <source>Select executable</source>
1611 <translation type="unfinished"></translation>
1612 </message>
1613</context>
1614<context>
1615 <name>EncoderExe</name>
1616 <message>
1617 <location filename="../base/encoderexe.cpp" line="41"/>
1618 <source>Path to Encoder:</source>
1619 <translation type="unfinished"></translation>
1620 </message>
1621 <message>
1622 <location filename="../base/encoderexe.cpp" line="43"/>
1623 <source>Encoder options:</source>
1624 <translation type="unfinished"></translation>
1625 </message>
1626</context>
1627<context>
1628 <name>EncoderLame</name>
1629 <message>
1630 <location filename="../base/encoderlame.cpp" line="73"/>
1631 <location filename="../base/encoderlame.cpp" line="83"/>
1632 <source>LAME</source>
1633 <translation type="unfinished"></translation>
1634 </message>
1635 <message>
1636 <location filename="../base/encoderlame.cpp" line="75"/>
1637 <source>Volume</source>
1638 <translation type="unfinished"></translation>
1639 </message>
1640 <message>
1641 <location filename="../base/encoderlame.cpp" line="79"/>
1642 <source>Quality</source>
1643 <translation type="unfinished"></translation>
1644 </message>
1645 <message>
1646 <location filename="../base/encoderlame.cpp" line="83"/>
1647 <source>Could not find libmp3lame!</source>
1648 <translation type="unfinished"></translation>
1649 </message>
1650</context>
1651<context>
1652 <name>EncoderRbSpeex</name>
1653 <message>
1654 <location filename="../base/encoderrbspeex.cpp" line="34"/>
1655 <source>Volume:</source>
1656 <translation type="unfinished"></translation>
1657 </message>
1658 <message>
1659 <location filename="../base/encoderrbspeex.cpp" line="36"/>
1660 <source>Quality:</source>
1661 <translation type="unfinished"></translation>
1662 </message>
1663 <message>
1664 <location filename="../base/encoderrbspeex.cpp" line="38"/>
1665 <source>Complexity:</source>
1666 <translation type="unfinished"></translation>
1667 </message>
1668 <message>
1669 <location filename="../base/encoderrbspeex.cpp" line="40"/>
1670 <source>Use Narrowband:</source>
1671 <translation type="unfinished"></translation>
1672 </message>
1673</context>
1674<context>
1675 <name>InfoWidget</name>
1676 <message>
1677 <location filename="../gui/infowidget.cpp" line="30"/>
1678 <location filename="../gui/infowidget.cpp" line="107"/>
1679 <source>File</source>
1680 <translation type="unfinished">Αρχείο</translation>
1681 </message>
1682 <message>
1683 <location filename="../gui/infowidget.cpp" line="30"/>
1684 <location filename="../gui/infowidget.cpp" line="107"/>
1685 <source>Version</source>
1686 <translation type="unfinished">Έκδοση</translation>
1687 </message>
1688</context>
1689<context>
1690 <name>InfoWidgetFrm</name>
1691 <message>
1692 <location filename="../gui/infowidgetfrm.ui" line="14"/>
1693 <source>Info</source>
1694 <translation type="unfinished">Βοήθεια</translation>
1695 </message>
1696 <message>
1697 <location filename="../gui/infowidgetfrm.ui" line="20"/>
1698 <source>Currently installed packages.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; if you manually installed packages this might not be correct!</source>
1699 <translation type="unfinished">Εγκατεστημένα πακέτα.&lt;br/&gt;&lt;b&gt;Σημείωση:&lt;/b&gt; Εάν εγκαταστήσατε πακέτα χειροκίνητα, οι πληροφορίες εδώ μπορεί να είναι λάθος!</translation>
1700 </message>
1701 <message>
1702 <location filename="../gui/infowidgetfrm.ui" line="34"/>
1703 <source>Package</source>
1704 <translation type="unfinished"></translation>
1705 </message>
1706</context>
1707<context>
1708 <name>InstallTalkFrm</name>
1709 <message>
1710 <location filename="../installtalkfrm.ui" line="17"/>
1711 <source>Install Talk Files</source>
1712 <translation>Εγκατάσταση αρχείων ομιλίας</translation>
1713 </message>
1714 <message>
1715 <location filename="../installtalkfrm.ui" line="52"/>
1716 <source>Generate for files</source>
1717 <translation type="unfinished"></translation>
1718 </message>
1719 <message>
1720 <location filename="../installtalkfrm.ui" line="78"/>
1721 <source>TTS profile:</source>
1722 <translation>Προφίλ TTS:</translation>
1723 </message>
1724 <message>
1725 <location filename="../installtalkfrm.ui" line="85"/>
1726 <source>Generate for folders</source>
1727 <translation type="unfinished"></translation>
1728 </message>
1729 <message>
1730 <location filename="../installtalkfrm.ui" line="95"/>
1731 <source>Recurse into folders</source>
1732 <translation type="unfinished"></translation>
1733 </message>
1734 <message>
1735 <location filename="../installtalkfrm.ui" line="111"/>
1736 <source>Change</source>
1737 <translation>Τροποποίηση</translation>
1738 </message>
1739 <message>
1740 <location filename="../installtalkfrm.ui" line="118"/>
1741 <source>Ignore files</source>
1742 <translation type="unfinished"></translation>
1743 </message>
1744 <message>
1745 <location filename="../installtalkfrm.ui" line="128"/>
1746 <source>Skip existing</source>
1747 <translation type="unfinished"></translation>
1748 </message>
1749 <message>
1750 <location filename="../installtalkfrm.ui" line="170"/>
1751 <source>Select folders for Talkfile generation (Ctrl for multiselect)</source>
1752 <translation type="unfinished"></translation>
1753 </message>
1754 <message>
1755 <location filename="../installtalkfrm.ui" line="36"/>
1756 <source>Generation options</source>
1757 <translation>Επιλογές δημιουργίας</translation>
1758 </message>
1759 <message>
1760 <location filename="../installtalkfrm.ui" line="42"/>
1761 <source>Strip Extensions</source>
1762 <translation>Αφαίρεση επέκτασης αρχείων</translation>
1763 </message>
1764 <message>
1765 <location filename="../installtalkfrm.ui" line="143"/>
1766 <source>&amp;Install</source>
1767 <translation>&amp;Εγκατάσταση</translation>
1768 </message>
1769 <message>
1770 <location filename="../installtalkfrm.ui" line="154"/>
1771 <source>&amp;Cancel</source>
1772 <translation>Ά&amp;κυρο</translation>
1773 </message>
1774</context>
1775<context>
1776 <name>InstallTalkWindow</name>
1777 <message>
1778 <location filename="../installtalkwindow.cpp" line="96"/>
1779 <source>Empty selection</source>
1780 <translation type="unfinished"></translation>
1781 </message>
1782 <message>
1783 <location filename="../installtalkwindow.cpp" line="97"/>
1784 <source>No files or folders selected. Please select files or folders first.</source>
1785 <translation type="unfinished"></translation>
1786 </message>
1787 <message>
1788 <location filename="../installtalkwindow.cpp" line="137"/>
1789 <source>TTS error</source>
1790 <translation type="unfinished"></translation>
1791 </message>
1792 <message>
1793 <location filename="../installtalkwindow.cpp" line="138"/>
1794 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1795 <translation type="unfinished"></translation>
1796 </message>
1797</context>
1798<context>
1799 <name>ManualWidget</name>
1800 <message>
1801 <location filename="../gui/manualwidget.cpp" line="44"/>
1802 <source>&lt;a href=&apos;%1&apos;&gt;PDF Manual&lt;/a&gt;</source>
1803 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Εγχειρίδιο μορφής PDF&lt;/a&gt;</translation>
1804 </message>
1805 <message>
1806 <location filename="../gui/manualwidget.cpp" line="46"/>
1807 <source>&lt;a href=&apos;%1&apos;&gt;HTML Manual (opens in browser)&lt;/a&gt;</source>
1808 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Εγχειρίδιο μορφής HTML (ανοίγει σε πλοηγό)&lt;/a&gt;</translation>
1809 </message>
1810 <message>
1811 <location filename="../gui/manualwidget.cpp" line="50"/>
1812 <source>Select a device for a link to the correct manual</source>
1813 <translation type="unfinished">Επιλέξτε συσκευή για ένα σύνδεσμο για το σωστό εγχειρίδιο</translation>
1814 </message>
1815 <message>
1816 <location filename="../gui/manualwidget.cpp" line="51"/>
1817 <source>&lt;a href=&apos;%1&apos;&gt;Manual Overview&lt;/a&gt;</source>
1818 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Περίληψη εγχειριδίου&lt;/a&gt;</translation>
1819 </message>
1820 <message>
1821 <location filename="../gui/manualwidget.cpp" line="62"/>
1822 <source>Confirm download</source>
1823 <translation type="unfinished">Επαλήθευση λήψης</translation>
1824 </message>
1825 <message>
1826 <location filename="../gui/manualwidget.cpp" line="63"/>
1827 <source>Do you really want to download the manual? The manual will be saved to the root folder of your player.</source>
1828 <translation type="unfinished">Θέλετε σιγουρα να λάβετε το εγχειρίδιο; Το εγχειρίδιο θα αποθηκευθεί στον αρχικό φάκλεο της συσκευής σας.</translation>
1829 </message>
1830</context>
1831<context>
1832 <name>ManualWidgetFrm</name>
1833 <message>
1834 <location filename="../gui/manualwidgetfrm.ui" line="14"/>
1835 <source>Manual</source>
1836 <translation type="unfinished"></translation>
1837 </message>
1838 <message>
1839 <location filename="../gui/manualwidgetfrm.ui" line="20"/>
1840 <source>Read the manual</source>
1841 <translation type="unfinished">Ανάγνωση του εγχειριδίου</translation>
1842 </message>
1843 <message>
1844 <location filename="../gui/manualwidgetfrm.ui" line="26"/>
1845 <source>PDF manual</source>
1846 <translation type="unfinished">Εγχειρίδιο μορφής PDF</translation>
1847 </message>
1848 <message>
1849 <location filename="../gui/manualwidgetfrm.ui" line="39"/>
1850 <source>HTML manual</source>
1851 <translation type="unfinished">Εγχειρίδιο μορφής HTML</translation>
1852 </message>
1853 <message>
1854 <location filename="../gui/manualwidgetfrm.ui" line="55"/>
1855 <source>Download the manual</source>
1856 <translation type="unfinished">Λήψη του εγχειριδίου</translation>
1857 </message>
1858 <message>
1859 <location filename="../gui/manualwidgetfrm.ui" line="63"/>
1860 <source>&amp;PDF version</source>
1861 <translation type="unfinished">Μορφής &amp;PDF</translation>
1862 </message>
1863 <message>
1864 <location filename="../gui/manualwidgetfrm.ui" line="70"/>
1865 <source>&amp;HTML version (zip file)</source>
1866 <translation type="unfinished">Μορφής &amp;HTML (αρχείο zip)</translation>
1867 </message>
1868 <message>
1869 <location filename="../gui/manualwidgetfrm.ui" line="92"/>
1870 <source>Down&amp;load</source>
1871 <translation type="unfinished">Λή&amp;ψη</translation>
1872 </message>
1873</context>
1874<context>
1875 <name>MsPackUtil</name>
1876 <message>
1877 <location filename="../base/mspackutil.cpp" line="101"/>
1878 <source>Creating output path failed</source>
1879 <translation type="unfinished"></translation>
1880 </message>
1881 <message>
1882 <location filename="../base/mspackutil.cpp" line="109"/>
1883 <source>Error during CAB operation</source>
1884 <translation type="unfinished"></translation>
1885 </message>
1886</context>
1887<context>
1888 <name>PreviewFrm</name>
1889 <message>
1890 <location filename="../previewfrm.ui" line="16"/>
1891 <source>Preview</source>
1892 <translation>Προεπισκόπηση</translation>
1893 </message>
1894</context>
1895<context>
1896 <name>ProgressLoggerFrm</name>
1897 <message>
1898 <location filename="../progressloggerfrm.ui" line="13"/>
1899 <location filename="../progressloggerfrm.ui" line="19"/>
1900 <source>Progress</source>
1901 <translation>Πρόοδος</translation>
1902 </message>
1903 <message>
1904 <location filename="../progressloggerfrm.ui" line="58"/>
1905 <source>Save Log</source>
1906 <translation type="unfinished"></translation>
1907 </message>
1908 <message>
1909 <location filename="../progressloggerfrm.ui" line="82"/>
1910 <source>&amp;Abort</source>
1911 <translation>&amp;Ματαίωση</translation>
1912 </message>
1913 <message>
1914 <location filename="../progressloggerfrm.ui" line="32"/>
1915 <source>progresswindow</source>
1916 <translation>παράθυροπροόδου</translation>
1917 </message>
1918</context>
1919<context>
1920 <name>ProgressLoggerGui</name>
1921 <message>
1922 <location filename="../progressloggergui.cpp" line="122"/>
1923 <source>&amp;Ok</source>
1924 <translation>&amp;ΟΚ</translation>
1925 </message>
1926 <message>
1927 <location filename="../progressloggergui.cpp" line="146"/>
1928 <source>Save system trace log</source>
1929 <translation type="unfinished"></translation>
1930 </message>
1931 <message>
1932 <location filename="../progressloggergui.cpp" line="104"/>
1933 <source>&amp;Abort</source>
1934 <translation>&amp;Ματαίωση</translation>
1935 </message>
1936</context>
1937<context>
1938 <name>QObject</name>
1939 <message>
1940 <location filename="../configure.cpp" line="625"/>
1941 <location filename="../main.cpp" line="83"/>
1942 <source>LTR</source>
1943 <extracomment>This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.
1944----------
1945This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.</extracomment>
1946 <translation type="unfinished"></translation>
1947 </message>
1948 <message>
1949 <location filename="../base/system.cpp" line="385"/>
1950 <source>(unknown vendor name) </source>
1951 <translation type="unfinished"></translation>
1952 </message>
1953 <message>
1954 <location filename="../base/system.cpp" line="403"/>
1955 <source>(unknown product name)</source>
1956 <translation type="unfinished"></translation>
1957 </message>
1958 <message>
1959 <location filename="../base/bootloaderinstallhelper.cpp" line="80"/>
1960 <source>Bootloader installation is almost complete. Installation &lt;b&gt;requires&lt;/b&gt; you to perform the following steps manually:</source>
1961 <translation type="unfinished">Η εγκατάσταση του bootloader σχεδόν ολοκληρώθηκε. &lt;b&gt;Απαιτείται&lt;/b&gt; να κάνετε τα ακόλουθα βήματα χειροκίνητα:</translation>
1962 </message>
1963 <message>
1964 <location filename="../base/bootloaderinstallhelper.cpp" line="86"/>
1965 <source>&lt;li&gt;Safely remove your player.&lt;/li&gt;</source>
1966 <translation type="unfinished">&lt;li&gt;Κάντε ασφαλή κατάργηση της συσκευή σας.&lt;/li&gt;</translation>
1967 </message>
1968 <message>
1969 <location filename="../base/bootloaderinstallhelper.cpp" line="91"/>
1970 <source>&lt;li&gt;Reboot your player into the original firmware.&lt;/li&gt;&lt;li&gt;Perform a firmware upgrade using the update functionality of the original firmware. Please refer to your player&apos;s manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before starting the firmware update process.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1971 <translation type="unfinished"></translation>
1972 </message>
1973 <message>
1974 <location filename="../base/bootloaderinstallhelper.cpp" line="102"/>
1975 <source>&lt;li&gt;Remove any previously inserted microSD card&lt;/li&gt;</source>
1976 <translation type="unfinished"></translation>
1977 </message>
1978 <message>
1979 <location filename="../base/bootloaderinstallhelper.cpp" line="103"/>
1980 <source>&lt;li&gt;Disconnect your player. The player will reboot and perform an update of the original firmware. Please refer to your players manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before disconnecting the player.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1981 <translation type="unfinished"></translation>
1982 </message>
1983 <message>
1984 <location filename="../base/bootloaderinstallhelper.cpp" line="114"/>
1985 <source>&lt;li&gt;Turn the player off&lt;/li&gt;&lt;li&gt;Insert the charger&lt;/li&gt;</source>
1986 <translation type="unfinished">&lt;li&gt;Απενεργοποιήστε τη συσκευή&lt;/li&gt;&lt;li&gt;Εισάγετε το φορτιστή&lt;/li&gt;</translation>
1987 </message>
1988 <message>
1989 <location filename="../base/bootloaderinstallhelper.cpp" line="119"/>
1990 <source>&lt;li&gt;Unplug USB and power adaptors&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to turn the player off&lt;/li&gt;&lt;li&gt;Toggle the battery switch on the player&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to boot into Rockbox&lt;/li&gt;</source>
1991 <translation type="unfinished">&lt;li&gt;Αφαιρέστε το καλώδιο USB και το φορτιστή/li&gt;&lt;li&gt;Κρατήστε το κουμπί &lt;i&gt; Ενεργοποίησης&lt;/i&gt; για να απενεργοποιήσετε τη συσκευή&lt;/li&gt;&lt;li&gt;&lt;/li&gt;&lt;li&gt;Κρατήστε το κουμπί &lt;i&gt; Ενεργοποίησης&lt;/ι&gt; για να ξεκινήσετε το Rockbox&lt;/li&gt;</translation>
1992 </message>
1993 <message>
1994 <location filename="../base/bootloaderinstallhelper.cpp" line="125"/>
1995 <source>&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You can safely install other parts first, but the above steps are &lt;b&gt;required&lt;/b&gt; to finish the installation!&lt;/p&gt;</source>
1996 <translation type="unfinished">&lt;p&gt;&lt;b&gt;Σημείωση:&lt;/b&gt; Μπορείτε να εγκαταστήσετε και άλλα μέρη πρώτα, αλλά τα παραπάνω βήματα &lt;b&gt;απαιτούνται&lt;/b&gt; για να ολοκληρώσετε την εγκατάσταση!&lt;/p&gt;</translation>
1997 </message>
1998</context>
1999<context>
2000 <name>QuaZipFile</name>
2001 <message>
2002 <location filename="../quazip/quazipfile.cpp" line="141"/>
2003 <source>ZIP/UNZIP API error %1</source>
2004 <translation type="unfinished"></translation>
2005 </message>
2006</context>
2007<context>
2008 <name>RbUtilQt</name>
2009 <message>
2010 <location filename="../rbutilqt.cpp" line="329"/>
2011 <source>New installation</source>
2012 <translation>Νέα εγκατάσταση</translation>
2013 </message>
2014 <message>
2015 <location filename="../rbutilqt.cpp" line="330"/>
2016 <source>This is a new installation of Rockbox Utility, or a new version. The configuration dialog will now open to allow you to setup the program, or review your settings.</source>
2017 <translation>Αυτή είναι μια καινούργια εγκατάσταση του Rockbox Utility ή πρόκειται για μια νέα έκδοση. Το παράθυρο ρυθμίσεων θα εμφανισθεί τώρα για να σας επιτρέψει να παραμετροποιήσετε το πρόγραμμα ή να δείτε ξανά τις ρυθμίσεις σας. </translation>
2018 </message>
2019 <message>
2020 <location filename="../rbutilqt.cpp" line="337"/>
2021 <location filename="../rbutilqt.cpp" line="642"/>
2022 <source>Configuration error</source>
2023 <translation>Σφάλμα ρυθμίσεων</translation>
2024 </message>
2025 <message>
2026 <location filename="../rbutilqt.cpp" line="338"/>
2027 <source>Your configuration is invalid. This is most likely due to a changed device path. The configuration dialog will now open to allow you to correct the problem.</source>
2028 <translation>Οι ρυθμίσεις σας δεν είναι έγκυρες. Πιθανότατα αυτό συμβαίνει λόγο αλλαγής διαδρομής της συσκευής. Το παράθυρο ρυθμίσεων θα εμφανισθεί τώρα για να σας επιτρέψει να διορθώσετε το πρόβλημα.</translation>
2029 </message>
2030 <message>
2031 <location filename="../rbutilqt.cpp" line="110"/>
2032 <source>Wine detected!</source>
2033 <translation type="unfinished"></translation>
2034 </message>
2035 <message>
2036 <location filename="../rbutilqt.cpp" line="111"/>
2037 <source>It seems you are trying to run this program under Wine. Please don&apos;t do this, running under Wine will fail. Use the native Linux binary instead.</source>
2038 <translation type="unfinished"></translation>
2039 </message>
2040 <message>
2041 <location filename="../rbutilqt.cpp" line="224"/>
2042 <source>Downloading build information, please wait ...</source>
2043 <translation type="unfinished"></translation>
2044 </message>
2045 <message>
2046 <location filename="../rbutilqt.cpp" line="235"/>
2047 <source>Can&apos;t get version information!</source>
2048 <translation type="unfinished"></translation>
2049 </message>
2050 <message>
2051 <location filename="../rbutilqt.cpp" line="237"/>
2052 <source>Can&apos;t get version information.
2053Network error: %1. Please check your network and proxy settings.</source>
2054 <translation type="unfinished"></translation>
2055 </message>
2056 <message>
2057 <location filename="../rbutilqt.cpp" line="249"/>
2058 <source>Download build information finished.</source>
2059 <translation type="unfinished"></translation>
2060 </message>
2061 <message>
2062 <location filename="../rbutilqt.cpp" line="450"/>
2063 <source>Confirm Installation</source>
2064 <translation>Επαλήθευση εγκατάστασης</translation>
2065 </message>
2066 <message>
2067 <location filename="../rbutilqt.cpp" line="582"/>
2068 <source>Mount point is wrong!</source>
2069 <translation>Το σημείο προσάρτησης είναι λάθος!</translation>
2070 </message>
2071 <message>
2072 <location filename="../rbutilqt.cpp" line="430"/>
2073 <source>No Rockbox installation found</source>
2074 <translation type="unfinished"></translation>
2075 </message>
2076 <message>
2077 <location filename="../rbutilqt.cpp" line="416"/>
2078 <source>Warning</source>
2079 <translation>Προσοχη</translation>
2080 </message>
2081 <message>
2082 <location filename="../rbutilqt.cpp" line="417"/>
2083 <source>The Application is still downloading Information about new Builds. Please try again shortly.</source>
2084 <translation>Η εφαρμογή λαμβάνει ακόμα πληροφορίες για καινούργιες εκδόσεις. Παρακαλώ προσπαθήστε ξανά σύντομα.</translation>
2085 </message>
2086 <message>
2087 <location filename="../rbutilqt.cpp" line="431"/>
2088 <source>Could not determine the installed Rockbox version. Please install a Rockbox build before installing voice files.</source>
2089 <translation type="unfinished"></translation>
2090 </message>
2091 <message>
2092 <location filename="../rbutilqt.cpp" line="451"/>
2093 <source>Do you really want to install the voice file?</source>
2094 <translation>Θέλετε σίγουρα να εγκαταστήσετε το αρχείο φωνής;</translation>
2095 </message>
2096 <message>
2097 <location filename="../rbutilqt.cpp" line="439"/>
2098 <source>No voice file available</source>
2099 <translation type="unfinished"></translation>
2100 </message>
2101 <message>
2102 <location filename="../rbutilqt.cpp" line="440"/>
2103 <source>The installed version of Rockbox is a development version. Pre-built voices are only available for release versions of Rockbox. Please generate a voice yourself using the &quot;Create voice file&quot; functionality.</source>
2104 <translation type="unfinished"></translation>
2105 </message>
2106 <message>
2107 <location filename="../rbutilqt.cpp" line="512"/>
2108 <source>Confirm Uninstallation</source>
2109 <translation>Επαλήθευση απεγκατάστασης</translation>
2110 </message>
2111 <message>
2112 <location filename="../rbutilqt.cpp" line="513"/>
2113 <source>Do you really want to uninstall the Bootloader?</source>
2114 <translation>Θέλετε σίγουρα να απεγκαταστήσετε το bootloader;</translation>
2115 </message>
2116 <message>
2117 <location filename="../rbutilqt.cpp" line="528"/>
2118 <source>No uninstall method for this target known.</source>
2119 <translation type="unfinished"></translation>
2120 </message>
2121 <message>
2122 <location filename="../rbutilqt.cpp" line="542"/>
2123 <source>Rockbox Utility can not uninstall the bootloader on this target. Try a normal firmware update to remove the booloader.</source>
2124 <translation type="unfinished"></translation>
2125 </message>
2126 <message>
2127 <location filename="../rbutilqt.cpp" line="550"/>
2128 <source>No Rockbox bootloader found.</source>
2129 <translation type="unfinished"></translation>
2130 </message>
2131 <message>
2132 <location filename="../rbutilqt.cpp" line="568"/>
2133 <source>Confirm installation</source>
2134 <translation>Επαλήθευση εγκατάστασης</translation>
2135 </message>
2136 <message>
2137 <location filename="../rbutilqt.cpp" line="569"/>
2138 <source>Do you really want to install Rockbox Utility to your player? After installation you can run it from the players hard drive.</source>
2139 <translation>Θέλετε σίγουρα να εγκαταστήσετε το Rockbox Utility στη συσκευή σας; Μετά την εγκατάσταση θα μπορείτε να το τρέξετε από το σκληρό δίσκο της συσκευής σας.</translation>
2140 </message>
2141 <message>
2142 <location filename="../rbutilqt.cpp" line="578"/>
2143 <source>Installing Rockbox Utility</source>
2144 <translation>Εγκατάσταση Rockbox Utility</translation>
2145 </message>
2146 <message>
2147 <location filename="../rbutilqt.cpp" line="596"/>
2148 <source>Error installing Rockbox Utility</source>
2149 <translation>Σφάλμα εγκατάστασης Rockbox Utility</translation>
2150 </message>
2151 <message>
2152 <location filename="../rbutilqt.cpp" line="600"/>
2153 <source>Installing user configuration</source>
2154 <translation>Εγκατάσταση ρυθμίσεων χρήστη</translation>
2155 </message>
2156 <message>
2157 <location filename="../rbutilqt.cpp" line="604"/>
2158 <source>Error installing user configuration</source>
2159 <translation>Σφάλμα εγκατάστασης ρυθμίσεων χρήστη</translation>
2160 </message>
2161 <message>
2162 <location filename="../rbutilqt.cpp" line="608"/>
2163 <source>Successfully installed Rockbox Utility.</source>
2164 <translation>Επιτυχία εγκατάστασης Rockbox Utility.</translation>
2165 </message>
2166 <message>
2167 <location filename="../rbutilqt.cpp" line="643"/>
2168 <source>Your configuration is invalid. Please go to the configuration dialog and make sure the selected values are correct.</source>
2169 <translation>Οι ρυθμίσεις σας δεν είναι έγκυρες. Παρακαλώ δείτε το παράθυρο ρυθμίσεων και σιγουρευτείτε ότι οι επιλεγμένες τιμές είναι σωστές.</translation>
2170 </message>
2171 <message>
2172 <location filename="../rbutilqt.cpp" line="664"/>
2173 <source>Checking for update ...</source>
2174 <translation type="unfinished"></translation>
2175 </message>
2176 <message>
2177 <location filename="../rbutilqt.cpp" line="729"/>
2178 <source>RockboxUtility Update available</source>
2179 <translation type="unfinished"></translation>
2180 </message>
2181 <message>
2182 <location filename="../rbutilqt.cpp" line="730"/>
2183 <source>&lt;b&gt;New RockboxUtility Version available.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Download it from here: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</source>
2184 <translation type="unfinished"></translation>
2185 </message>
2186 <message>
2187 <location filename="../rbutilqt.cpp" line="733"/>
2188 <source>New version of Rockbox Utility available.</source>
2189 <translation type="unfinished"></translation>
2190 </message>
2191 <message>
2192 <location filename="../rbutilqt.cpp" line="736"/>
2193 <source>Rockbox Utility is up to date.</source>
2194 <translation type="unfinished"></translation>
2195 </message>
2196 <message>
2197 <location filename="../rbutilqt.cpp" line="759"/>
2198 <source>Device ejected</source>
2199 <translation type="unfinished"></translation>
2200 </message>
2201 <message>
2202 <location filename="../rbutilqt.cpp" line="760"/>
2203 <source>Device successfully ejected. You may now disconnect the player from the PC.</source>
2204 <translation type="unfinished"></translation>
2205 </message>
2206 <message>
2207 <location filename="../rbutilqt.cpp" line="764"/>
2208 <source>Ejecting failed</source>
2209 <translation type="unfinished"></translation>
2210 </message>
2211 <message>
2212 <location filename="../rbutilqt.cpp" line="765"/>
2213 <source>Ejecting the device failed. Please make sure no programs are accessing files on the device. If ejecting still fails please use your computers eject funtionality.</source>
2214 <translation type="unfinished"></translation>
2215 </message>
2216 <message>
2217 <location filename="../rbutilqt.cpp" line="236"/>
2218 <source>Network error</source>
2219 <translation>Σφάλμα δικτύου</translation>
2220 </message>
2221</context>
2222<context>
2223 <name>RbUtilQtFrm</name>
2224 <message>
2225 <location filename="../rbutilqtfrm.ui" line="14"/>
2226 <source>Rockbox Utility</source>
2227 <translation>Rockbox Utility</translation>
2228 </message>
2229 <message>
2230 <location filename="../rbutilqtfrm.ui" line="31"/>
2231 <source>Device</source>
2232 <translation>Συσκευή</translation>
2233 </message>
2234 <message>
2235 <location filename="../rbutilqtfrm.ui" line="92"/>
2236 <source>&amp;Change</source>
2237 <translation>&amp;Τροποποίηση</translation>
2238 </message>
2239 <message>
2240 <location filename="../rbutilqtfrm.ui" line="163"/>
2241 <source>Welcome</source>
2242 <translation>Καλώς ορίσατε</translation>
2243 </message>
2244 <message>
2245 <location filename="../rbutilqtfrm.ui" line="160"/>
2246 <location filename="../rbutilqtfrm.ui" line="658"/>
2247 <source>&amp;Installation</source>
2248 <translation>&amp;Εγκατάσταση</translation>
2249 </message>
2250 <message>
2251 <location filename="../rbutilqtfrm.ui" line="168"/>
2252 <location filename="../rbutilqtfrm.ui" line="450"/>
2253 <source>&amp;Accessibility</source>
2254 <translation>&amp;Προσβασιμότητα</translation>
2255 </message>
2256 <message>
2257 <location filename="../rbutilqtfrm.ui" line="171"/>
2258 <source>Install accessibility add-ons</source>
2259 <translation>Εγκατάσταση πρόσθετων προσβασιμότητας</translation>
2260 </message>
2261 <message>
2262 <location filename="../rbutilqtfrm.ui" line="177"/>
2263 <source>Install Voice files</source>
2264 <translation>Εγκατάσταση αρχείων φωνής</translation>
2265 </message>
2266 <message>
2267 <location filename="../rbutilqtfrm.ui" line="194"/>
2268 <source>&lt;b&gt;Install Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so if you installed the voice file Rockbox will speak.</source>
2269 <translation>&lt;b&gt;Εγκατάσταση αρχείων φωνής&lt;/b&gt;&lt;br/&gt;Τα αρχεία φωνής χρειάζονται για να επιτρέψουν στο Rockbox να εκφωνεί τη διεπαφή χρήστη. Η ομιλία είναι προεπιλεγμένη, έτσι εάν εγκαταστήσατε κάποιο αρχείο φωνής το Rockbox θα σας μιλάει.</translation>
2270 </message>
2271 <message>
2272 <location filename="../rbutilqtfrm.ui" line="204"/>
2273 <source>Install Talk files</source>
2274 <translation>Εγκατάσταση αρχείων ομιλίας</translation>
2275 </message>
2276 <message>
2277 <location filename="../rbutilqtfrm.ui" line="221"/>
2278 <source>&lt;b&gt;Create Talk Files&lt;/b&gt;&lt;br/&gt;Talkfiles are needed to let Rockbox speak File and Foldernames</source>
2279 <translation>&lt;b&gt;Δημιουργία αρχείων ομιλίας&lt;/b&gt;&lt;br/&gt;Τα αρχεία ομιλίας χρειάζονται για να επιτρέψουν στο Rockbox να εκφωνεί, ονόματα αρχείων και φακέλων</translation>
2280 </message>
2281 <message>
2282 <location filename="../rbutilqtfrm.ui" line="254"/>
2283 <source>Create Voice files</source>
2284 <translation>Δημιουργία αρχείων φωνής</translation>
2285 </message>
2286 <message>
2287 <location filename="../rbutilqtfrm.ui" line="271"/>
2288 <source>&lt;b&gt;Create Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so
2289 if you installed the voice file Rockbox will speak.</source>
2290 <translation>&lt;b&gt;Δημιουργία αρχείου φωνής&lt;/b&gt;&lt;br/&gt;Τα αρχεία φωνής χρειάζονται για να επιτρέψουν στο Rockbox να εκφωνεί τη διεπαφή χρήστη.
2291Η ομιλία είναι προεπιλεγμένη, έτσι εάν εγκαταστήσατε κάποιο αρχείο φωνής το Rockbox θα σας μιλάει.</translation>
2292 </message>
2293 <message>
2294 <location filename="../rbutilqtfrm.ui" line="458"/>
2295 <source>&amp;Uninstallation</source>
2296 <translation>Απεγκατά&amp;σταση</translation>
2297 </message>
2298 <message>
2299 <location filename="../rbutilqtfrm.ui" line="286"/>
2300 <location filename="../rbutilqtfrm.ui" line="319"/>
2301 <source>Uninstall Rockbox</source>
2302 <translation>Απεγκατάσταση Rockbox</translation>
2303 </message>
2304 <message>
2305 <location filename="../rbutilqtfrm.ui" line="121"/>
2306 <source>mountpoint unknown or invalid</source>
2307 <translation type="unfinished"></translation>
2308 </message>
2309 <message>
2310 <location filename="../rbutilqtfrm.ui" line="114"/>
2311 <source>Mountpoint:</source>
2312 <translation type="unfinished"></translation>
2313 </message>
2314 <message>
2315 <location filename="../rbutilqtfrm.ui" line="72"/>
2316 <source>device unknown or invalid</source>
2317 <translation type="unfinished"></translation>
2318 </message>
2319 <message>
2320 <location filename="../rbutilqtfrm.ui" line="65"/>
2321 <source>Device:</source>
2322 <translation type="unfinished"></translation>
2323 </message>
2324 <message>
2325 <location filename="../rbutilqtfrm.ui" line="283"/>
2326 <source>Backup &amp;&amp; &amp;Uninstallation</source>
2327 <translation type="unfinished"></translation>
2328 </message>
2329 <message>
2330 <location filename="../rbutilqtfrm.ui" line="292"/>
2331 <source>Uninstall Bootloader</source>
2332 <translation>Απεγκατάσταση bootloader</translation>
2333 </message>
2334 <message>
2335 <location filename="../rbutilqtfrm.ui" line="309"/>
2336 <source>&lt;b&gt;Remove the bootloader&lt;/b&gt;&lt;br/&gt;After removing the bootloader you won&apos;t be able to start Rockbox.</source>
2337 <translation>&lt;b&gt;Αφαίρεση του bootloader&lt;/b&gt;&lt;br/&gt;Μετά την αφαίρεση του bootloader δεν θα μπορείτε πλέον να κανετε εκκίνηση το Rockbox.</translation>
2338 </message>
2339 <message>
2340 <location filename="../rbutilqtfrm.ui" line="336"/>
2341 <source>&lt;b&gt;Uninstall Rockbox from your audio player.&lt;/b&gt;&lt;br/&gt;This will leave the bootloader in place (you need to remove it manually).</source>
2342 <translation>&lt;b&gt;Απεγκατάσταση Rockbox από τη συσκευή σας.&lt;/b&gt;&lt;br/&gt;Ο bootloader θα παραμείνει (θα πρέπει να τον αφαιρέσετε χειροκίνητα).</translation>
2343 </message>
2344 <message>
2345 <location filename="../rbutilqtfrm.ui" line="349"/>
2346 <source>Backup</source>
2347 <translation type="unfinished">Αντίγραφο ασφαλείας</translation>
2348 </message>
2349 <message>
2350 <location filename="../rbutilqtfrm.ui" line="366"/>
2351 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup current installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Create a backup by archiving the contents of the Rockbox installation folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2352 <translation type="unfinished"></translation>
2353 </message>
2354 <message>
2355 <location filename="../rbutilqtfrm.ui" line="393"/>
2356 <source>&amp;Manual</source>
2357 <translation>Εγ&amp;χειρίδιο</translation>
2358 </message>
2359 <message>
2360 <location filename="../rbutilqtfrm.ui" line="396"/>
2361 <source>View and download the manual</source>
2362 <translation>Επισκόπηση και λήψη του εγχειριδίου</translation>
2363 </message>
2364 <message>
2365 <location filename="../rbutilqtfrm.ui" line="401"/>
2366 <source>Inf&amp;o</source>
2367 <translation>Πληρο&amp;φορίες</translation>
2368 </message>
2369 <message>
2370 <location filename="../rbutilqtfrm.ui" line="419"/>
2371 <source>&amp;File</source>
2372 <translation>&amp;Αρχείο</translation>
2373 </message>
2374 <message>
2375 <location filename="../rbutilqtfrm.ui" line="653"/>
2376 <source>System &amp;Trace</source>
2377 <translation type="unfinished"></translation>
2378 </message>
2379 <message>
2380 <location filename="../rbutilqtfrm.ui" line="446"/>
2381 <source>Action&amp;s</source>
2382 <translation>Ε&amp;νέργειες</translation>
2383 </message>
2384 <message>
2385 <location filename="../rbutilqtfrm.ui" line="474"/>
2386 <source>Empty local download cache</source>
2387 <translation>Καθαρισμός της τοπικής προσωρινής μνήμης λήψεων</translation>
2388 </message>
2389 <message>
2390 <location filename="../rbutilqtfrm.ui" line="479"/>
2391 <source>Install Rockbox Utility on player</source>
2392 <translation>Εγκατάσταση Rockbox Utility στη συσκευή</translation>
2393 </message>
2394 <message>
2395 <location filename="../rbutilqtfrm.ui" line="484"/>
2396 <source>&amp;Configure</source>
2397 <translation>&amp;Παραμετροποίηση</translation>
2398 </message>
2399 <message>
2400 <location filename="../rbutilqtfrm.ui" line="489"/>
2401 <source>E&amp;xit</source>
2402 <translation>Έ&amp;ξοδος</translation>
2403 </message>
2404 <message>
2405 <location filename="../rbutilqtfrm.ui" line="492"/>
2406 <source>Ctrl+Q</source>
2407 <translation>Ctrl+Q</translation>
2408 </message>
2409 <message>
2410 <location filename="../rbutilqtfrm.ui" line="497"/>
2411 <source>&amp;About</source>
2412 <translation>Περί &amp;Rockbox Utility</translation>
2413 </message>
2414 <message>
2415 <location filename="../rbutilqtfrm.ui" line="502"/>
2416 <source>About &amp;Qt</source>
2417 <translation>Περί του &amp;Qt</translation>
2418 </message>
2419 <message>
2420 <location filename="../rbutilqtfrm.ui" line="428"/>
2421 <location filename="../rbutilqtfrm.ui" line="507"/>
2422 <source>&amp;Help</source>
2423 <translation>&amp;Βοήθεια</translation>
2424 </message>
2425 <message>
2426 <location filename="../rbutilqtfrm.ui" line="103"/>
2427 <source>&amp;Eject</source>
2428 <translation type="unfinished"></translation>
2429 </message>
2430 <message>
2431 <location filename="../rbutilqtfrm.ui" line="432"/>
2432 <source>&amp;Troubleshoot</source>
2433 <translation type="unfinished"></translation>
2434 </message>
2435 <message>
2436 <location filename="../rbutilqtfrm.ui" line="512"/>
2437 <source>Info</source>
2438 <translation>Βοήθεια</translation>
2439 </message>
2440 <message>
2441 <location filename="../rbutilqtfrm.ui" line="521"/>
2442 <source>&amp;Complete Installation</source>
2443 <translation>&amp;Πλήρης εγκατάσταση</translation>
2444 </message>
2445 <message>
2446 <location filename="../rbutilqtfrm.ui" line="539"/>
2447 <source>Install &amp;Bootloader</source>
2448 <translation>Εγκατάσταση &amp;bootloader</translation>
2449 </message>
2450 <message>
2451 <location filename="../rbutilqtfrm.ui" line="548"/>
2452 <source>Install &amp;Rockbox</source>
2453 <translation>Εγκατάσταση &amp;Rockbox</translation>
2454 </message>
2455 <message>
2456 <location filename="../rbutilqtfrm.ui" line="557"/>
2457 <source>Install &amp;Fonts Package</source>
2458 <translation>Εγκατάσταση πακέτου &amp;γραμματοσειρών</translation>
2459 </message>
2460 <message>
2461 <location filename="../rbutilqtfrm.ui" line="566"/>
2462 <source>Install &amp;Themes</source>
2463 <translation>Εγκατάσταση &amp;θεμάτων</translation>
2464 </message>
2465 <message>
2466 <location filename="../rbutilqtfrm.ui" line="575"/>
2467 <source>Install &amp;Game Files</source>
2468 <translation>Εγκατάσταση αρχείων &amp;παιχνιδιών</translation>
2469 </message>
2470 <message>
2471 <location filename="../rbutilqtfrm.ui" line="584"/>
2472 <source>&amp;Install Voice File</source>
2473 <translation>Εγκατάσταση αρχείων &amp;φωνής</translation>
2474 </message>
2475 <message>
2476 <location filename="../rbutilqtfrm.ui" line="593"/>
2477 <source>Create &amp;Talk Files</source>
2478 <translation>Δημιουργία αρχείων &amp;ομιλίας</translation>
2479 </message>
2480 <message>
2481 <location filename="../rbutilqtfrm.ui" line="602"/>
2482 <source>Remove &amp;bootloader</source>
2483 <translation>Αφαίρεση &amp;bootloader</translation>
2484 </message>
2485 <message>
2486 <location filename="../rbutilqtfrm.ui" line="611"/>
2487 <source>Uninstall &amp;Rockbox</source>
2488 <translation>Απεγκατάσταση &amp;Rockbox</translation>
2489 </message>
2490 <message>
2491 <location filename="../rbutilqtfrm.ui" line="616"/>
2492 <source>Read PDF manual</source>
2493 <translation>Ανάγνωση εγχειριδίου σε μοφρή PDF</translation>
2494 </message>
2495 <message>
2496 <location filename="../rbutilqtfrm.ui" line="621"/>
2497 <source>Read HTML manual</source>
2498 <translation>Ανάγνωση εγχειριδίου σε μοφρή HTML</translation>
2499 </message>
2500 <message>
2501 <location filename="../rbutilqtfrm.ui" line="626"/>
2502 <source>Download PDF manual</source>
2503 <translation>Λήψη εγχειριδίου σε μορφή PDF</translation>
2504 </message>
2505 <message>
2506 <location filename="../rbutilqtfrm.ui" line="631"/>
2507 <source>Download HTML manual (zip)</source>
2508 <translation>Λήψη εγχειριδίου σε μορφή HTML (zip)</translation>
2509 </message>
2510 <message>
2511 <location filename="../rbutilqtfrm.ui" line="640"/>
2512 <source>Create &amp;Voice File</source>
2513 <translation>Δημιουργία αρχείου &amp;φωνής</translation>
2514 </message>
2515 <message>
2516 <location filename="../rbutilqtfrm.ui" line="643"/>
2517 <source>Create Voice File</source>
2518 <translation>Δημιουργία αρχείου φωνής</translation>
2519 </message>
2520 <message>
2521 <location filename="../rbutilqtfrm.ui" line="648"/>
2522 <source>&amp;System Info</source>
2523 <translation>Πληροφορίες &amp;συστήματος</translation>
2524 </message>
2525 <message>
2526 <location filename="../rbutilqtfrm.ui" line="663"/>
2527 <source>Show &amp;Changelog</source>
2528 <translation type="unfinished"></translation>
2529 </message>
2530 <message>
2531 <location filename="../rbutilqtfrm.ui" line="530"/>
2532 <source>&amp;Minimal Installation</source>
2533 <translation>&amp;Ελάχιστη εγκατάσταση</translation>
2534 </message>
2535</context>
2536<context>
2537 <name>SelectiveInstallWidget</name>
2538 <message>
2539 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="20"/>
2540 <source>Selective Installation</source>
2541 <translation type="unfinished"></translation>
2542 </message>
2543 <message>
2544 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="26"/>
2545 <source>Rockbox version to install</source>
2546 <translation type="unfinished"></translation>
2547 </message>
2548 <message>
2549 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="35"/>
2550 <source>Version information not available yet.</source>
2551 <translation type="unfinished"></translation>
2552 </message>
2553 <message>
2554 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="54"/>
2555 <source>Rockbox components to install</source>
2556 <translation type="unfinished"></translation>
2557 </message>
2558 <message>
2559 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="60"/>
2560 <source>&amp;Bootloader</source>
2561 <translation type="unfinished"></translation>
2562 </message>
2563 <message>
2564 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="80"/>
2565 <source>The main Rockbox firmware.</source>
2566 <translation type="unfinished"></translation>
2567 </message>
2568 <message>
2569 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="90"/>
2570 <source>Fonts</source>
2571 <translation type="unfinished"></translation>
2572 </message>
2573 <message>
2574 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="104"/>
2575 <source>&amp;Rockbox</source>
2576 <translation type="unfinished"></translation>
2577 </message>
2578 <message>
2579 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="124"/>
2580 <source>Some game plugins require additional files.</source>
2581 <translation type="unfinished"></translation>
2582 </message>
2583 <message>
2584 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="140"/>
2585 <source>Additional fonts for the User Interface.</source>
2586 <translation type="unfinished"></translation>
2587 </message>
2588 <message>
2589 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="156"/>
2590 <source>The bootloader is required for starting Rockbox. Only necessary for first time install.</source>
2591 <translation type="unfinished"></translation>
2592 </message>
2593 <message>
2594 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="166"/>
2595 <source>Game Files</source>
2596 <translation type="unfinished"></translation>
2597 </message>
2598 <message>
2599 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="177"/>
2600 <source>Customize</source>
2601 <translation type="unfinished"></translation>
2602 </message>
2603 <message>
2604 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="188"/>
2605 <source>Themes</source>
2606 <translation type="unfinished"></translation>
2607 </message>
2608 <message>
2609 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="205"/>
2610 <source>Themes allow adjusting the user interface of Rockbox. Use &quot;Customize&quot; to select themes.</source>
2611 <translation type="unfinished"></translation>
2612 </message>
2613 <message>
2614 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="250"/>
2615 <source>&amp;Install</source>
2616 <translation type="unfinished">&amp;Εγκατάσταση</translation>
2617 </message>
2618 <message>
2619 <location filename="../gui/selectiveinstallwidget.cpp" line="67"/>
2620 <source>This is the latest stable release available.</source>
2621 <translation type="unfinished"></translation>
2622 </message>
2623 <message>
2624 <location filename="../gui/selectiveinstallwidget.cpp" line="70"/>
2625 <source>The development version is updated on every code change. Last update was on %1</source>
2626 <translation type="unfinished"></translation>
2627 </message>
2628 <message>
2629 <location filename="../gui/selectiveinstallwidget.cpp" line="74"/>
2630 <source>This will eventually become the next Rockbox version. Install it to help testing.</source>
2631 <translation type="unfinished"></translation>
2632 </message>
2633 <message>
2634 <location filename="../gui/selectiveinstallwidget.cpp" line="100"/>
2635 <source>Stable Release (Version %1)</source>
2636 <translation type="unfinished"></translation>
2637 </message>
2638 <message>
2639 <location filename="../gui/selectiveinstallwidget.cpp" line="104"/>
2640 <source>Development Version (Revison %1)</source>
2641 <translation type="unfinished"></translation>
2642 </message>
2643 <message>
2644 <location filename="../gui/selectiveinstallwidget.cpp" line="108"/>
2645 <source>Release Candidate (Revison %1)</source>
2646 <translation type="unfinished"></translation>
2647 </message>
2648 <message>
2649 <location filename="../gui/selectiveinstallwidget.cpp" line="131"/>
2650 <source>The selected player doesn&apos;t need a bootloader.</source>
2651 <translation type="unfinished"></translation>
2652 </message>
2653 <message>
2654 <location filename="../gui/selectiveinstallwidget.cpp" line="136"/>
2655 <source>The bootloader is required for starting Rockbox. Installation of the bootloader is only necessary on first time installation.</source>
2656 <translation type="unfinished"></translation>
2657 </message>
2658 <message>
2659 <location filename="../gui/selectiveinstallwidget.cpp" line="183"/>
2660 <source>Mountpoint is wrong</source>
2661 <translation type="unfinished"></translation>
2662 </message>
2663 <message>
2664 <location filename="../gui/selectiveinstallwidget.cpp" line="239"/>
2665 <source>No install method known.</source>
2666 <translation type="unfinished">Δεν είναι γνωστή κάποια μέθοδος εγκατάστασης.</translation>
2667 </message>
2668 <message>
2669 <location filename="../gui/selectiveinstallwidget.cpp" line="266"/>
2670 <source>Bootloader detected</source>
2671 <translation type="unfinished">Ανιχνεύθηκε bootloader</translation>
2672 </message>
2673 <message>
2674 <location filename="../gui/selectiveinstallwidget.cpp" line="267"/>
2675 <source>Bootloader already installed. Do you want to reinstall the bootloader?</source>
2676 <translation type="unfinished">Ο bootloader είναι ήδη εγκατεστημένος. Θέλετε να επανεγκαταστήσετε το bootloader;</translation>
2677 </message>
2678 <message>
2679 <location filename="../gui/selectiveinstallwidget.cpp" line="271"/>
2680 <source>Bootloader installation skipped</source>
2681 <translation type="unfinished"></translation>
2682 </message>
2683 <message>
2684 <location filename="../gui/selectiveinstallwidget.cpp" line="284"/>
2685 <source>Create Bootloader backup</source>
2686 <translation type="unfinished">Δημιουργία αντίγραφου ασφαλείας του bootloader</translation>
2687 </message>
2688 <message>
2689 <location filename="../gui/selectiveinstallwidget.cpp" line="285"/>
2690 <source>You can create a backup of the original bootloader file. Press &quot;Yes&quot; to select an output folder on your computer to save the file to. The file will get placed in a new folder &quot;%1&quot; created below the selected folder.
2691Press &quot;No&quot; to skip this step.</source>
2692 <translation type="unfinished">Μπορείτε να δημιουργήσετε ένα αντίγραφο ασφαλείας του αυθεντικού bootloader. Πατήστε &quot;Ναι&quot; για να επιλέξετε έναν φάκελο στον υπολογιστή σας για να σώσετε το αρχείο. Το αρχείο θα τοποθετηθεί σε έναν νέο φάκελο &quot;%1&quot; δημιουργώντας τον παρακάτω επιλεγμένο φάκελο.
2693Πατήστε &quot;Όχι&quot; για να παραλείψετε αυτό το βήμα.</translation>
2694 </message>
2695 <message>
2696 <location filename="../gui/selectiveinstallwidget.cpp" line="292"/>
2697 <source>Browse backup folder</source>
2698 <translation type="unfinished">Αναζήτηση φακέλου αντίγραφου ασφαλείας</translation>
2699 </message>
2700 <message>
2701 <location filename="../gui/selectiveinstallwidget.cpp" line="304"/>
2702 <source>Prerequisites</source>
2703 <translation type="unfinished">Προϋποθέσεις</translation>
2704 </message>
2705 <message>
2706 <location filename="../gui/selectiveinstallwidget.cpp" line="309"/>
2707 <source>Bootloader installation aborted</source>
2708 <translation type="unfinished"></translation>
2709 </message>
2710 <message>
2711 <location filename="../gui/selectiveinstallwidget.cpp" line="319"/>
2712 <source>Bootloader files (%1)</source>
2713 <translation type="unfinished"></translation>
2714 </message>
2715 <message>
2716 <location filename="../gui/selectiveinstallwidget.cpp" line="321"/>
2717 <source>All files (*)</source>
2718 <translation type="unfinished"></translation>
2719 </message>
2720 <message>
2721 <location filename="../gui/selectiveinstallwidget.cpp" line="323"/>
2722 <source>Select firmware file</source>
2723 <translation type="unfinished">Επιλέξτε αρχείο firmware</translation>
2724 </message>
2725 <message>
2726 <location filename="../gui/selectiveinstallwidget.cpp" line="325"/>
2727 <source>Error opening firmware file</source>
2728 <translation type="unfinished">Σφάλμα ανοίγματος αρχείου firmware</translation>
2729 </message>
2730 <message>
2731 <location filename="../gui/selectiveinstallwidget.cpp" line="331"/>
2732 <source>Error reading firmware file</source>
2733 <translation type="unfinished"></translation>
2734 </message>
2735 <message>
2736 <location filename="../gui/selectiveinstallwidget.cpp" line="341"/>
2737 <source>Backup error</source>
2738 <translation type="unfinished">Σφάλμα αντίγραφου ασφαλείας!</translation>
2739 </message>
2740 <message>
2741 <location filename="../gui/selectiveinstallwidget.cpp" line="342"/>
2742 <source>Could not create backup file. Continue?</source>
2743 <translation type="unfinished">Δεν ήταν δυνατή η δημιουργία αντίγραφου ασφαλείας. Συνέχεια;</translation>
2744 </message>
2745 <message>
2746 <location filename="../gui/selectiveinstallwidget.cpp" line="366"/>
2747 <source>Manual steps required</source>
2748 <translation type="unfinished">Απαιτούνται χειροκίνητα βήματα</translation>
2749 </message>
2750 <message>
2751 <location filename="../gui/selectiveinstallwidget.cpp" line="171"/>
2752 <source>Continue with installation?</source>
2753 <translation type="unfinished"></translation>
2754 </message>
2755 <message>
2756 <location filename="../gui/selectiveinstallwidget.cpp" line="172"/>
2757 <source>Really continue?</source>
2758 <translation type="unfinished">Σίγουρα θέλετε να συνεχίσετε;</translation>
2759 </message>
2760 <message>
2761 <source>Aborted!</source>
2762 <translation type="obsolete">Ματαιώθηκε!</translation>
2763 </message>
2764 <message>
2765 <location filename="../gui/selectiveinstallwidget.cpp" line="490"/>
2766 <source>Your installation doesn&apos;t require game files, skipping.</source>
2767 <translation type="unfinished"></translation>
2768 </message>
2769</context>
2770<context>
2771 <name>ServerInfo</name>
2772 <message>
2773 <location filename="../base/serverinfo.cpp" line="117"/>
2774 <source>Unknown</source>
2775 <translation type="unfinished"></translation>
2776 </message>
2777 <message>
2778 <location filename="../base/serverinfo.cpp" line="121"/>
2779 <source>Unusable</source>
2780 <translation type="unfinished"></translation>
2781 </message>
2782 <message>
2783 <location filename="../base/serverinfo.cpp" line="124"/>
2784 <source>Unstable</source>
2785 <translation type="unfinished"></translation>
2786 </message>
2787 <message>
2788 <location filename="../base/serverinfo.cpp" line="127"/>
2789 <source>Stable</source>
2790 <translation type="unfinished"></translation>
2791 </message>
2792</context>
2793<context>
2794 <name>SysTrace</name>
2795 <message>
2796 <location filename="../systrace.cpp" line="98"/>
2797 <location filename="../systrace.cpp" line="107"/>
2798 <source>Save system trace log</source>
2799 <translation type="unfinished"></translation>
2800 </message>
2801</context>
2802<context>
2803 <name>SysTraceFrm</name>
2804 <message>
2805 <location filename="../systracefrm.ui" line="14"/>
2806 <source>System Trace</source>
2807 <translation type="unfinished"></translation>
2808 </message>
2809 <message>
2810 <location filename="../systracefrm.ui" line="20"/>
2811 <source>System State trace</source>
2812 <translation type="unfinished"></translation>
2813 </message>
2814 <message>
2815 <location filename="../systracefrm.ui" line="46"/>
2816 <source>&amp;Close</source>
2817 <translation type="unfinished"></translation>
2818 </message>
2819 <message>
2820 <location filename="../systracefrm.ui" line="57"/>
2821 <source>&amp;Save</source>
2822 <translation type="unfinished"></translation>
2823 </message>
2824 <message>
2825 <location filename="../systracefrm.ui" line="68"/>
2826 <source>&amp;Refresh</source>
2827 <translation type="unfinished">&amp;Ανανέωση</translation>
2828 </message>
2829 <message>
2830 <location filename="../systracefrm.ui" line="79"/>
2831 <source>Save &amp;previous</source>
2832 <translation type="unfinished"></translation>
2833 </message>
2834</context>
2835<context>
2836 <name>Sysinfo</name>
2837 <message>
2838 <location filename="../sysinfo.cpp" line="45"/>
2839 <source>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</source>
2840 <translation>&lt;b&gt;Λειτουργικό σύστημα&lt;/b&gt;&lt;br/&gt;</translation>
2841 </message>
2842 <message>
2843 <location filename="../sysinfo.cpp" line="46"/>
2844 <source>&lt;b&gt;Username&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2845 <translation>&lt;b&gt;Όνομα χρήστη&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2846 </message>
2847 <message>
2848 <location filename="../sysinfo.cpp" line="48"/>
2849 <source>&lt;b&gt;Permissions&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2850 <translation>&lt;b&gt;Δικαιώματα&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2851 </message>
2852 <message>
2853 <location filename="../sysinfo.cpp" line="50"/>
2854 <source>&lt;b&gt;Attached USB devices&lt;/b&gt;&lt;br/&gt;</source>
2855 <translation>&lt;b&gt;Προσαρτημένες συσκευές USB&lt;/b&gt;&lt;br/&gt;</translation>
2856 </message>
2857 <message>
2858 <location filename="../sysinfo.cpp" line="54"/>
2859 <source>VID: %1 PID: %2, %3</source>
2860 <translation>VID: %1 PID: %2, %3</translation>
2861 </message>
2862 <message>
2863 <location filename="../sysinfo.cpp" line="63"/>
2864 <source>Filesystem</source>
2865 <translation>Σύστημα αρχείων</translation>
2866 </message>
2867 <message>
2868 <location filename="../sysinfo.cpp" line="66"/>
2869 <source>Mountpoint</source>
2870 <translation type="unfinished"></translation>
2871 </message>
2872 <message>
2873 <location filename="../sysinfo.cpp" line="66"/>
2874 <source>Label</source>
2875 <translation type="unfinished"></translation>
2876 </message>
2877 <message>
2878 <location filename="../sysinfo.cpp" line="67"/>
2879 <source>Free</source>
2880 <translation type="unfinished"></translation>
2881 </message>
2882 <message>
2883 <location filename="../sysinfo.cpp" line="67"/>
2884 <source>Total</source>
2885 <translation type="unfinished"></translation>
2886 </message>
2887 <message>
2888 <location filename="../sysinfo.cpp" line="68"/>
2889 <source>Cluster Size</source>
2890 <translation type="unfinished"></translation>
2891 </message>
2892 <message>
2893 <location filename="../sysinfo.cpp" line="70"/>
2894 <source>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</source>
2895 <translation type="unfinished"></translation>
2896 </message>
2897</context>
2898<context>
2899 <name>SysinfoFrm</name>
2900 <message>
2901 <location filename="../sysinfofrm.ui" line="13"/>
2902 <source>System Info</source>
2903 <translation>Πληροφορίες συστήματος</translation>
2904 </message>
2905 <message>
2906 <location filename="../sysinfofrm.ui" line="22"/>
2907 <source>&amp;Refresh</source>
2908 <translation>&amp;Ανανέωση</translation>
2909 </message>
2910 <message>
2911 <location filename="../sysinfofrm.ui" line="45"/>
2912 <source>&amp;OK</source>
2913 <translation>&amp;ΟΚ</translation>
2914 </message>
2915</context>
2916<context>
2917 <name>System</name>
2918 <message>
2919 <location filename="../base/system.cpp" line="121"/>
2920 <source>Guest</source>
2921 <translation type="unfinished">Επισκέπτης</translation>
2922 </message>
2923 <message>
2924 <location filename="../base/system.cpp" line="124"/>
2925 <source>Admin</source>
2926 <translation type="unfinished">Διαχειριστής</translation>
2927 </message>
2928 <message>
2929 <location filename="../base/system.cpp" line="127"/>
2930 <source>User</source>
2931 <translation type="unfinished">Χρήστης</translation>
2932 </message>
2933 <message>
2934 <location filename="../base/system.cpp" line="130"/>
2935 <source>Error</source>
2936 <translation type="unfinished">Σφάλμα</translation>
2937 </message>
2938 <message>
2939 <location filename="../base/system.cpp" line="278"/>
2940 <location filename="../base/system.cpp" line="323"/>
2941 <source>(no description available)</source>
2942 <translation type="unfinished">(δεν υπάρχει διαθέσιμη περιγραφή)</translation>
2943 </message>
2944</context>
2945<context>
2946 <name>TTSBase</name>
2947 <message>
2948 <location filename="../base/ttsbase.cpp" line="45"/>
2949 <source>Espeak TTS Engine</source>
2950 <translation type="unfinished"></translation>
2951 </message>
2952 <message>
2953 <location filename="../base/ttsbase.cpp" line="47"/>
2954 <source>Flite TTS Engine</source>
2955 <translation type="unfinished"></translation>
2956 </message>
2957 <message>
2958 <location filename="../base/ttsbase.cpp" line="48"/>
2959 <source>Swift TTS Engine</source>
2960 <translation type="unfinished"></translation>
2961 </message>
2962 <message>
2963 <location filename="../base/ttsbase.cpp" line="51"/>
2964 <source>SAPI4 TTS Engine</source>
2965 <translation type="unfinished"></translation>
2966 </message>
2967 <message>
2968 <location filename="../base/ttsbase.cpp" line="53"/>
2969 <source>SAPI5 TTS Engine</source>
2970 <translation type="unfinished"></translation>
2971 </message>
2972 <message>
2973 <location filename="../base/ttsbase.cpp" line="54"/>
2974 <source>MS Speech Platform</source>
2975 <translation type="unfinished"></translation>
2976 </message>
2977 <message>
2978 <location filename="../base/ttsbase.cpp" line="57"/>
2979 <source>Festival TTS Engine</source>
2980 <translation type="unfinished"></translation>
2981 </message>
2982 <message>
2983 <location filename="../base/ttsbase.cpp" line="60"/>
2984 <source>OS X System Engine</source>
2985 <translation type="unfinished"></translation>
2986 </message>
2987</context>
2988<context>
2989 <name>TTSCarbon</name>
2990 <message>
2991 <location filename="../base/ttscarbon.cpp" line="139"/>
2992 <source>Voice:</source>
2993 <translation type="unfinished"></translation>
2994 </message>
2995 <message>
2996 <location filename="../base/ttscarbon.cpp" line="145"/>
2997 <source>Speed (words/min):</source>
2998 <translation type="unfinished"></translation>
2999 </message>
3000 <message>
3001 <location filename="../base/ttscarbon.cpp" line="152"/>
3002 <source>Pitch (0 for default):</source>
3003 <translation type="unfinished"></translation>
3004 </message>
3005 <message>
3006 <location filename="../base/ttscarbon.cpp" line="222"/>
3007 <source>Could not voice string</source>
3008 <translation type="unfinished"></translation>
3009 </message>
3010 <message>
3011 <location filename="../base/ttscarbon.cpp" line="232"/>
3012 <source>Could not convert intermediate file</source>
3013 <translation type="unfinished"></translation>
3014 </message>
3015</context>
3016<context>
3017 <name>TTSExes</name>
3018 <message>
3019 <location filename="../base/ttsexes.cpp" line="78"/>
3020 <source>TTS executable not found</source>
3021 <translation>Δεν βρέθηκε εκτελέσιμο μηχανής TTS</translation>
3022 </message>
3023 <message>
3024 <location filename="../base/ttsexes.cpp" line="44"/>
3025 <source>Path to TTS engine:</source>
3026 <translation type="unfinished"></translation>
3027 </message>
3028 <message>
3029 <location filename="../base/ttsexes.cpp" line="46"/>
3030 <source>TTS engine options:</source>
3031 <translation type="unfinished"></translation>
3032 </message>
3033</context>
3034<context>
3035 <name>TTSFestival</name>
3036 <message>
3037 <location filename="../base/ttsfestival.cpp" line="207"/>
3038 <source>engine could not voice string</source>
3039 <translation type="unfinished"></translation>
3040 </message>
3041 <message>
3042 <location filename="../base/ttsfestival.cpp" line="290"/>
3043 <source>No description available</source>
3044 <translation type="unfinished"></translation>
3045 </message>
3046 <message>
3047 <location filename="../base/ttsfestival.cpp" line="53"/>
3048 <source>Path to Festival client:</source>
3049 <translation type="unfinished"></translation>
3050 </message>
3051 <message>
3052 <location filename="../base/ttsfestival.cpp" line="58"/>
3053 <source>Voice:</source>
3054 <translation type="unfinished"></translation>
3055 </message>
3056 <message>
3057 <location filename="../base/ttsfestival.cpp" line="67"/>
3058 <source>Voice description:</source>
3059 <translation type="unfinished"></translation>
3060 </message>
3061</context>
3062<context>
3063 <name>TTSSapi</name>
3064 <message>
3065 <location filename="../base/ttssapi.cpp" line="49"/>
3066 <source>Language:</source>
3067 <translation type="unfinished"></translation>
3068 </message>
3069 <message>
3070 <location filename="../base/ttssapi.cpp" line="56"/>
3071 <source>Voice:</source>
3072 <translation type="unfinished"></translation>
3073 </message>
3074 <message>
3075 <location filename="../base/ttssapi.cpp" line="68"/>
3076 <source>Speed:</source>
3077 <translation type="unfinished"></translation>
3078 </message>
3079 <message>
3080 <location filename="../base/ttssapi.cpp" line="71"/>
3081 <source>Options:</source>
3082 <translation type="unfinished"></translation>
3083 </message>
3084 <message>
3085 <location filename="../base/ttssapi.cpp" line="115"/>
3086 <source>Could not copy the SAPI script</source>
3087 <translation type="unfinished"></translation>
3088 </message>
3089 <message>
3090 <location filename="../base/ttssapi.cpp" line="133"/>
3091 <source>Could not start SAPI process</source>
3092 <translation type="unfinished"></translation>
3093 </message>
3094</context>
3095<context>
3096 <name>TalkFileCreator</name>
3097 <message>
3098 <location filename="../base/talkfile.cpp" line="42"/>
3099 <source>Reading Filelist...</source>
3100 <translation>Ανάγνωση λίστας αρχείων...</translation>
3101 </message>
3102 <message>
3103 <location filename="../base/talkfile.cpp" line="45"/>
3104 <source>Talk file creation aborted</source>
3105 <translation>Η δημιουργία αρχείου ομιλίας ματαιώθηκε</translation>
3106 </message>
3107 <message>
3108 <location filename="../base/talkfile.cpp" line="68"/>
3109 <source>Copying Talkfiles...</source>
3110 <translation type="unfinished"></translation>
3111 </message>
3112 <message>
3113 <location filename="../base/talkfile.cpp" line="240"/>
3114 <source>File copy aborted</source>
3115 <translation type="unfinished"></translation>
3116 </message>
3117 <message>
3118 <location filename="../base/talkfile.cpp" line="280"/>
3119 <source>Cleaning up...</source>
3120 <translation type="unfinished"></translation>
3121 </message>
3122 <message>
3123 <location filename="../base/talkfile.cpp" line="291"/>
3124 <source>Finished</source>
3125 <translation type="unfinished"></translation>
3126 </message>
3127 <message>
3128 <location filename="../base/talkfile.cpp" line="80"/>
3129 <source>Finished creating Talk files</source>
3130 <translation>Η δημιουργία αρχείων ομιλίας ολοκληρώθηκε</translation>
3131 </message>
3132 <message>
3133 <location filename="../base/talkfile.cpp" line="36"/>
3134 <source>Starting Talk file generation for folder %1</source>
3135 <translation type="unfinished"></translation>
3136 </message>
3137 <message>
3138 <location filename="../base/talkfile.cpp" line="259"/>
3139 <source>Copying of %1 to %2 failed</source>
3140 <translation>Η αντιγραφή του %1 στο %2 απέτυχε</translation>
3141 </message>
3142</context>
3143<context>
3144 <name>TalkGenerator</name>
3145 <message>
3146 <location filename="../base/talkgenerator.cpp" line="39"/>
3147 <source>Starting TTS Engine</source>
3148 <translation type="unfinished"></translation>
3149 </message>
3150 <message>
3151 <location filename="../base/talkgenerator.cpp" line="44"/>
3152 <location filename="../base/talkgenerator.cpp" line="51"/>
3153 <source>Init of TTS engine failed</source>
3154 <translation type="unfinished">Η αρχικοποίηση της μηχανής TTS απέτυχε</translation>
3155 </message>
3156 <message>
3157 <location filename="../base/talkgenerator.cpp" line="58"/>
3158 <source>Starting Encoder Engine</source>
3159 <translation type="unfinished"></translation>
3160 </message>
3161 <message>
3162 <location filename="../base/talkgenerator.cpp" line="62"/>
3163 <source>Init of Encoder engine failed</source>
3164 <translation type="unfinished">Η αρχικοποίηση του κωδικοποιητή απέτυχε</translation>
3165 </message>
3166 <message>
3167 <location filename="../base/talkgenerator.cpp" line="72"/>
3168 <source>Voicing entries...</source>
3169 <translation type="unfinished">Εκφώνηση καταχωρήσεων...</translation>
3170 </message>
3171 <message>
3172 <location filename="../base/talkgenerator.cpp" line="87"/>
3173 <source>Encoding files...</source>
3174 <translation type="unfinished">Κωδικοποίηση αρχείων...</translation>
3175 </message>
3176 <message>
3177 <location filename="../base/talkgenerator.cpp" line="126"/>
3178 <source>Voicing aborted</source>
3179 <translation type="unfinished"></translation>
3180 </message>
3181 <message>
3182 <location filename="../base/talkgenerator.cpp" line="162"/>
3183 <location filename="../base/talkgenerator.cpp" line="167"/>
3184 <source>Voicing of %1 failed: %2</source>
3185 <translation type="unfinished"></translation>
3186 </message>
3187 <message>
3188 <location filename="../base/talkgenerator.cpp" line="211"/>
3189 <source>Encoding aborted</source>
3190 <translation type="unfinished"></translation>
3191 </message>
3192 <message>
3193 <location filename="../base/talkgenerator.cpp" line="239"/>
3194 <source>Encoding of %1 failed</source>
3195 <translation type="unfinished">Η κωδικοποίηση του %1 απέτυχε</translation>
3196 </message>
3197</context>
3198<context>
3199 <name>ThemeInstallFrm</name>
3200 <message>
3201 <location filename="../themesinstallfrm.ui" line="13"/>
3202 <source>Theme Installation</source>
3203 <translation>Εγκατάσταση θέματος</translation>
3204 </message>
3205 <message>
3206 <location filename="../themesinstallfrm.ui" line="48"/>
3207 <source>Selected Theme</source>
3208 <translation>Επιλεγμένο θέμα</translation>
3209 </message>
3210 <message>
3211 <location filename="../themesinstallfrm.ui" line="73"/>
3212 <source>Description</source>
3213 <translation>Περιγραφή</translation>
3214 </message>
3215 <message>
3216 <location filename="../themesinstallfrm.ui" line="83"/>
3217 <source>Download size:</source>
3218 <translation>Μέγεθος λήψης:</translation>
3219 </message>
3220 <message>
3221 <location filename="../themesinstallfrm.ui" line="115"/>
3222 <source>&amp;Install</source>
3223 <translation>&amp;Εγκατάσταση</translation>
3224 </message>
3225 <message>
3226 <location filename="../themesinstallfrm.ui" line="125"/>
3227 <source>&amp;Cancel</source>
3228 <translation>Ά&amp;κυρο</translation>
3229 </message>
3230 <message>
3231 <location filename="../themesinstallfrm.ui" line="93"/>
3232 <source>Hold Ctrl to select multiple item, Shift for a range</source>
3233 <translation>Κρατήστε το πλήκτρο Ctrl για να επιλέξετε πολλαπλές καταχωρήσεις, Shift για ένα εύρος</translation>
3234 </message>
3235</context>
3236<context>
3237 <name>ThemesInstallWindow</name>
3238 <message>
3239 <location filename="../themesinstallwindow.cpp" line="40"/>
3240 <source>no theme selected</source>
3241 <translation>Δεν υπάρχει επιλεγμένο θέμα</translation>
3242 </message>
3243 <message>
3244 <location filename="../themesinstallwindow.cpp" line="125"/>
3245 <source>Network error: %1.
3246Please check your network and proxy settings.</source>
3247 <translation>Σφάλμα δικτύου: %1.
3248Παρακαλώ ελέγξτε τις ρυθμίσεις δικτύου.</translation>
3249 </message>
3250 <message>
3251 <location filename="../themesinstallwindow.cpp" line="138"/>
3252 <source>the following error occured:
3253%1</source>
3254 <translation>Εμφανίσθηκε το παρακάτω σφάλμα:
3255%1</translation>
3256 </message>
3257 <message>
3258 <location filename="../themesinstallwindow.cpp" line="144"/>
3259 <source>done.</source>
3260 <translation>Ολοκληρώθηκε.</translation>
3261 </message>
3262 <message>
3263 <location filename="../themesinstallwindow.cpp" line="211"/>
3264 <source>fetching details for %1</source>
3265 <translation>Λήψη λεπτομερειών για %1</translation>
3266 </message>
3267 <message>
3268 <location filename="../themesinstallwindow.cpp" line="214"/>
3269 <source>fetching preview ...</source>
3270 <translation>Λήψη προεπισκόπησης...</translation>
3271 </message>
3272 <message>
3273 <location filename="../themesinstallwindow.cpp" line="227"/>
3274 <source>&lt;b&gt;Author:&lt;/b&gt; %1&lt;hr/&gt;</source>
3275 <translation>&lt;b&gt;Συντάκτης:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3276 </message>
3277 <message>
3278 <location filename="../themesinstallwindow.cpp" line="228"/>
3279 <location filename="../themesinstallwindow.cpp" line="230"/>
3280 <source>unknown</source>
3281 <translation>Άγνωστο</translation>
3282 </message>
3283 <message>
3284 <location filename="../themesinstallwindow.cpp" line="229"/>
3285 <source>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</source>
3286 <translation>&lt;b&gt;Έκδοση:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3287 </message>
3288 <message>
3289 <location filename="../themesinstallwindow.cpp" line="231"/>
3290 <source>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</source>
3291 <translation>&lt;b&gt;Περιγραφή:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3292 </message>
3293 <message>
3294 <location filename="../themesinstallwindow.cpp" line="232"/>
3295 <source>no description</source>
3296 <translation>Δεν υπάρχει περιγραφή</translation>
3297 </message>
3298 <message>
3299 <location filename="../themesinstallwindow.cpp" line="260"/>
3300 <source>no theme preview</source>
3301 <translation>Δεν υπάρχει προεπισκόπηση θέματος</translation>
3302 </message>
3303 <message>
3304 <location filename="../themesinstallwindow.cpp" line="289"/>
3305 <source>Select</source>
3306 <translation type="unfinished"></translation>
3307 </message>
3308 <message>
3309 <location filename="../themesinstallwindow.cpp" line="296"/>
3310 <source>getting themes information ...</source>
3311 <translation>Λήψη πληροφοριών θέματος...</translation>
3312 </message>
3313 <message>
3314 <location filename="../themesinstallwindow.cpp" line="326"/>
3315 <source>No themes selected, skipping</source>
3316 <translation type="unfinished"></translation>
3317 </message>
3318 <message>
3319 <location filename="../themesinstallwindow.cpp" line="356"/>
3320 <source>Mount point is wrong!</source>
3321 <translation>Το σημείο προσάρτησης είναι λάθος!</translation>
3322 </message>
3323 <message>
3324 <location filename="../themesinstallwindow.cpp" line="41"/>
3325 <source>no selection</source>
3326 <translation type="unfinished"></translation>
3327 </message>
3328 <message>
3329 <location filename="../themesinstallwindow.cpp" line="181"/>
3330 <source>Information</source>
3331 <translation type="unfinished"></translation>
3332 </message>
3333 <message numerus="yes">
3334 <location filename="../themesinstallwindow.cpp" line="198"/>
3335 <source>Download size %L1 kiB (%n item(s))</source>
3336 <translation type="unfinished">
3337 <numerusform></numerusform>
3338 <numerusform></numerusform>
3339 </translation>
3340 </message>
3341 <message>
3342 <location filename="../themesinstallwindow.cpp" line="248"/>
3343 <source>Retrieving theme preview failed.
3344HTTP response code: %1</source>
3345 <translation type="unfinished"></translation>
3346 </message>
3347</context>
3348<context>
3349 <name>UninstallFrm</name>
3350 <message>
3351 <location filename="../uninstallfrm.ui" line="16"/>
3352 <source>Uninstall Rockbox</source>
3353 <translation>Απεγκατάσταση Rockbox</translation>
3354 </message>
3355 <message>
3356 <location filename="../uninstallfrm.ui" line="35"/>
3357 <source>Please select the Uninstallation Method</source>
3358 <translation>Παρακαλώ επιλέξτε τον τρόπο απεγκατάστασης</translation>
3359 </message>
3360 <message>
3361 <location filename="../uninstallfrm.ui" line="45"/>
3362 <source>Uninstallation Method</source>
3363 <translation>Τρόπος απεγκατάστασης</translation>
3364 </message>
3365 <message>
3366 <location filename="../uninstallfrm.ui" line="51"/>
3367 <source>Complete Uninstallation</source>
3368 <translation>Πλήρης απεγκατάσταση</translation>
3369 </message>
3370 <message>
3371 <location filename="../uninstallfrm.ui" line="58"/>
3372 <source>Smart Uninstallation</source>
3373 <translation>Έξυπνη απεγκατάσταση</translation>
3374 </message>
3375 <message>
3376 <location filename="../uninstallfrm.ui" line="68"/>
3377 <source>Please select what you want to uninstall</source>
3378 <translation>Παρακαλώ επιλέξτε τι θέλετε να απεγκαταστήσετε</translation>
3379 </message>
3380 <message>
3381 <location filename="../uninstallfrm.ui" line="78"/>
3382 <source>Installed Parts</source>
3383 <translation>Εγκατεστημένα μέρη</translation>
3384 </message>
3385 <message>
3386 <location filename="../uninstallfrm.ui" line="128"/>
3387 <source>&amp;Uninstall</source>
3388 <translation>Απεγκατά&amp;σταση</translation>
3389 </message>
3390 <message>
3391 <location filename="../uninstallfrm.ui" line="138"/>
3392 <source>&amp;Cancel</source>
3393 <translation>Ά&amp;κυρο</translation>
3394 </message>
3395</context>
3396<context>
3397 <name>Uninstaller</name>
3398 <message>
3399 <location filename="../base/uninstall.cpp" line="32"/>
3400 <location filename="../base/uninstall.cpp" line="43"/>
3401 <source>Starting Uninstallation</source>
3402 <translation>Έναρξη απεγκατάστασης</translation>
3403 </message>
3404 <message>
3405 <location filename="../base/uninstall.cpp" line="36"/>
3406 <source>Finished Uninstallation</source>
3407 <translation>Ολοκληρώθηκε η απεγκατάσταση</translation>
3408 </message>
3409 <message>
3410 <location filename="../base/uninstall.cpp" line="49"/>
3411 <source>Uninstalling %1...</source>
3412 <translation type="unfinished"></translation>
3413 </message>
3414 <message>
3415 <location filename="../base/uninstall.cpp" line="80"/>
3416 <source>Could not delete %1</source>
3417 <translation type="unfinished"></translation>
3418 </message>
3419 <message>
3420 <location filename="../base/uninstall.cpp" line="109"/>
3421 <source>Uninstallation finished</source>
3422 <translation>Η απεγκατάσταση ολοκληρώθηκε</translation>
3423 </message>
3424</context>
3425<context>
3426 <name>Utils</name>
3427 <message>
3428 <location filename="../base/utils.cpp" line="312"/>
3429 <source>&lt;li&gt;Permissions insufficient for bootloader installation.
3430Administrator priviledges are necessary.&lt;/li&gt;</source>
3431 <translation type="unfinished">&lt;li&gt;Ανεπαρκή δικαιώματα για την εγκατάσταση του bootloader.
3432Απαιτούνται δικαιώματα διαχειριστή.&lt;/li&gt;</translation>
3433 </message>
3434 <message>
3435 <location filename="../base/utils.cpp" line="324"/>
3436 <source>&lt;li&gt;Target mismatch detected.&lt;br/&gt;Installed target: %1&lt;br/&gt;Selected target: %2.&lt;/li&gt;</source>
3437 <translation type="unfinished"></translation>
3438 </message>
3439 <message>
3440 <location filename="../base/utils.cpp" line="331"/>
3441 <source>Problem detected:</source>
3442 <translation type="unfinished">Εντοπίστηκε πρόβλημα:</translation>
3443 </message>
3444</context>
3445<context>
3446 <name>VoiceFileCreator</name>
3447 <message>
3448 <location filename="../base/voicefile.cpp" line="43"/>
3449 <source>Starting Voicefile generation</source>
3450 <translation>Εκκίνηση δημιουργίας αρχείου φωνής</translation>
3451 </message>
3452 <message>
3453 <location filename="../base/voicefile.cpp" line="90"/>
3454 <source>Extracted voice strings from installation</source>
3455 <translation type="unfinished"></translation>
3456 </message>
3457 <message>
3458 <location filename="../base/voicefile.cpp" line="100"/>
3459 <source>Extracted voice strings incompatible</source>
3460 <translation type="unfinished"></translation>
3461 </message>
3462 <message>
3463 <location filename="../base/voicefile.cpp" line="145"/>
3464 <source>Could not retrieve strings from installation, downloading</source>
3465 <translation type="unfinished"></translation>
3466 </message>
3467 <message>
3468 <location filename="../base/voicefile.cpp" line="171"/>
3469 <source>Downloading voice info...</source>
3470 <translation type="unfinished"></translation>
3471 </message>
3472 <message>
3473 <location filename="../base/voicefile.cpp" line="184"/>
3474 <source>Download error: received HTTP error %1.</source>
3475 <translation>Σφάλμα λήψης: σφάλμα HTTP %1.</translation>
3476 </message>
3477 <message>
3478 <location filename="../base/voicefile.cpp" line="191"/>
3479 <source>Cached file used.</source>
3480 <translation>Χρησιμοποιήθηκε προσωρινά αποθηκευμένο αρχείο.</translation>
3481 </message>
3482 <message>
3483 <location filename="../base/voicefile.cpp" line="194"/>
3484 <source>Download error: %1</source>
3485 <translation>Σφάλμα λήψης: %1</translation>
3486 </message>
3487 <message>
3488 <location filename="../base/voicefile.cpp" line="199"/>
3489 <source>Download finished.</source>
3490 <translation>Η λήψη ολοκληρώθηκε.</translation>
3491 </message>
3492 <message>
3493 <location filename="../base/voicefile.cpp" line="212"/>
3494 <source>failed to open downloaded file</source>
3495 <translation>Το άνοιγμα του ληφθέν αρχείου απέτυχε</translation>
3496 </message>
3497 <message>
3498 <location filename="../base/voicefile.cpp" line="218"/>
3499 <source>Reading strings...</source>
3500 <translation type="unfinished"></translation>
3501 </message>
3502 <message>
3503 <location filename="../base/voicefile.cpp" line="297"/>
3504 <source>Creating voicefiles...</source>
3505 <translation type="unfinished"></translation>
3506 </message>
3507 <message>
3508 <location filename="../base/voicefile.cpp" line="342"/>
3509 <source>Cleaning up...</source>
3510 <translation type="unfinished"></translation>
3511 </message>
3512 <message>
3513 <location filename="../base/voicefile.cpp" line="353"/>
3514 <source>Finished</source>
3515 <translation type="unfinished"></translation>
3516 </message>
3517 <message>
3518 <location filename="../base/voicefile.cpp" line="271"/>
3519 <source>The downloaded file was empty!</source>
3520 <translation>Το ληφθέν αρχείο ήταν άδειο!</translation>
3521 </message>
3522 <message>
3523 <location filename="../base/voicefile.cpp" line="302"/>
3524 <source>Error opening downloaded file</source>
3525 <translation>Σφάλμα ανοίγματος ληφθέν αρχείου</translation>
3526 </message>
3527 <message>
3528 <location filename="../base/voicefile.cpp" line="313"/>
3529 <source>Error opening output file</source>
3530 <translation>Σφάλμα ανοίγματος αρχείου εξόδου</translation>
3531 </message>
3532 <message>
3533 <location filename="../base/voicefile.cpp" line="333"/>
3534 <source>successfully created.</source>
3535 <translation>Επιτυχής δημιουργία.</translation>
3536 </message>
3537 <message>
3538 <location filename="../base/voicefile.cpp" line="56"/>
3539 <source>could not find rockbox-info.txt</source>
3540 <translation type="unfinished"></translation>
3541 </message>
3542</context>
3543<context>
3544 <name>ZipInstaller</name>
3545 <message>
3546 <location filename="../base/zipinstaller.cpp" line="60"/>
3547 <source>done.</source>
3548 <translation>Ολοκληρώθηκε.</translation>
3549 </message>
3550 <message>
3551 <location filename="../base/zipinstaller.cpp" line="68"/>
3552 <source>Package installation finished successfully.</source>
3553 <translation type="unfinished"></translation>
3554 </message>
3555 <message>
3556 <location filename="../base/zipinstaller.cpp" line="80"/>
3557 <source>Downloading file %1.%2</source>
3558 <translation>Λήψη αρχείου %1. %2</translation>
3559 </message>
3560 <message>
3561 <location filename="../base/zipinstaller.cpp" line="115"/>
3562 <source>Download error: received HTTP error %1.</source>
3563 <translation>Σφάλμα λήψης: σφάλμα HTTP %1.</translation>
3564 </message>
3565 <message>
3566 <location filename="../base/zipinstaller.cpp" line="121"/>
3567 <source>Cached file used.</source>
3568 <translation>Χρήση αρχείου προσωρινής μνήμης.</translation>
3569 </message>
3570 <message>
3571 <location filename="../base/zipinstaller.cpp" line="123"/>
3572 <source>Download error: %1</source>
3573 <translation>Σφάλμα λήψης: %1</translation>
3574 </message>
3575 <message>
3576 <location filename="../base/zipinstaller.cpp" line="127"/>
3577 <source>Download finished.</source>
3578 <translation>Η λήψη ολοκληρώθηκε.</translation>
3579 </message>
3580 <message>
3581 <location filename="../base/zipinstaller.cpp" line="133"/>
3582 <source>Extracting file.</source>
3583 <translation>Εξαγωγή αρχείου.</translation>
3584 </message>
3585 <message>
3586 <location filename="../base/zipinstaller.cpp" line="153"/>
3587 <source>Extraction failed!</source>
3588 <translation type="unfinished"></translation>
3589 </message>
3590 <message>
3591 <location filename="../base/zipinstaller.cpp" line="162"/>
3592 <source>Installing file.</source>
3593 <translation>Εγκατάσταση αρχείου.</translation>
3594 </message>
3595 <message>
3596 <location filename="../base/zipinstaller.cpp" line="173"/>
3597 <source>Installing file failed.</source>
3598 <translation>Εγκατάσταση αρχείου απέτυχε.</translation>
3599 </message>
3600 <message>
3601 <location filename="../base/zipinstaller.cpp" line="186"/>
3602 <source>Creating installation log</source>
3603 <translation>Δημιουργία αρχείου καταγραφής εγκατάστασης</translation>
3604 </message>
3605 <message>
3606 <location filename="../base/zipinstaller.cpp" line="146"/>
3607 <source>Not enough disk space! Aborting.</source>
3608 <translation>Δεν υπάρχει αρκετός χώρος στο δίσκο. Ματαίωση.</translation>
3609 </message>
3610</context>
3611<context>
3612 <name>ZipUtil</name>
3613 <message>
3614 <location filename="../base/ziputil.cpp" line="125"/>
3615 <source>Creating output path failed</source>
3616 <translation type="unfinished"></translation>
3617 </message>
3618 <message>
3619 <location filename="../base/ziputil.cpp" line="132"/>
3620 <source>Creating output file failed</source>
3621 <translation type="unfinished"></translation>
3622 </message>
3623 <message>
3624 <location filename="../base/ziputil.cpp" line="141"/>
3625 <source>Error during Zip operation</source>
3626 <translation type="unfinished"></translation>
3627 </message>
3628</context>
3629<context>
3630 <name>aboutBox</name>
3631 <message>
3632 <location filename="../aboutbox.ui" line="14"/>
3633 <source>About Rockbox Utility</source>
3634 <translation>Περί Rockbox Utility</translation>
3635 </message>
3636 <message>
3637 <location filename="../aboutbox.ui" line="32"/>
3638 <source>The Rockbox Utility</source>
3639 <translation>Το Rockbox Utility</translation>
3640 </message>
3641 <message utf8="true">
3642 <location filename="../aboutbox.ui" line="54"/>
3643 <source>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</source>
3644 <translation type="unfinished"></translation>
3645 </message>
3646 <message>
3647 <location filename="../aboutbox.ui" line="74"/>
3648 <source>&amp;Credits</source>
3649 <translation>&amp;Συντελεστές</translation>
3650 </message>
3651 <message>
3652 <location filename="../aboutbox.ui" line="106"/>
3653 <source>&amp;License</source>
3654 <translation>&amp;Άδεια χρήσης</translation>
3655 </message>
3656 <message>
3657 <location filename="../aboutbox.ui" line="132"/>
3658 <source>&amp;Speex License</source>
3659 <translation type="unfinished"></translation>
3660 </message>
3661 <message>
3662 <location filename="../aboutbox.ui" line="158"/>
3663 <source>&amp;Ok</source>
3664 <translation>&amp;ΟΚ</translation>
3665 </message>
3666</context>
3667</TS>
diff --git a/utils/rbutilqt/lang/rbutil_he.ts b/utils/rbutilqt/lang/rbutil_he.ts
new file mode 100644
index 0000000000..1b9854cdf6
--- /dev/null
+++ b/utils/rbutilqt/lang/rbutil_he.ts
@@ -0,0 +1,3683 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE TS>
3<TS version="2.0" language="he">
4<context>
5 <name>BackupDialog</name>
6 <message>
7 <location filename="../gui/backupdialogfrm.ui" line="17"/>
8 <location filename="../gui/backupdialogfrm.ui" line="43"/>
9 <source>Backup</source>
10 <translation type="unfinished">גיבוי</translation>
11 </message>
12 <message>
13 <location filename="../gui/backupdialogfrm.ui" line="33"/>
14 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This dialog will create a backup by archiving the contents of the Rockbox installation on the player into a zip file. This will include installed themes and settings stored below the .rockbox folder on the player.&lt;/p&gt;&lt;p&gt;The backup filename will be created based on the installed version. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
15 <translation type="unfinished"></translation>
16 </message>
17 <message>
18 <location filename="../gui/backupdialogfrm.ui" line="49"/>
19 <source>Size: unknown</source>
20 <translation type="unfinished"></translation>
21 </message>
22 <message>
23 <location filename="../gui/backupdialogfrm.ui" line="56"/>
24 <source>Backup to: unknown</source>
25 <translation type="unfinished"></translation>
26 </message>
27 <message>
28 <location filename="../gui/backupdialogfrm.ui" line="76"/>
29 <source>&amp;Change</source>
30 <translation type="unfinished">&amp;שינוי</translation>
31 </message>
32 <message>
33 <location filename="../gui/backupdialogfrm.ui" line="116"/>
34 <source>&amp;Backup</source>
35 <translation type="unfinished"></translation>
36 </message>
37 <message>
38 <location filename="../gui/backupdialogfrm.ui" line="127"/>
39 <source>&amp;Cancel</source>
40 <translation type="unfinished">&amp;ביטול</translation>
41 </message>
42 <message>
43 <location filename="../gui/backupdialog.cpp" line="70"/>
44 <source>Installation size: calculating ...</source>
45 <translation type="unfinished"></translation>
46 </message>
47 <message>
48 <location filename="../gui/backupdialog.cpp" line="89"/>
49 <source>Select Backup Filename</source>
50 <translation type="unfinished">בחר את שם קובץ הגיבוי</translation>
51 </message>
52 <message>
53 <location filename="../gui/backupdialog.cpp" line="109"/>
54 <source>Installation size: %L1 %2</source>
55 <translation type="unfinished"></translation>
56 </message>
57 <message>
58 <location filename="../gui/backupdialog.cpp" line="116"/>
59 <source>File exists</source>
60 <translation type="unfinished"></translation>
61 </message>
62 <message>
63 <location filename="../gui/backupdialog.cpp" line="117"/>
64 <source>The selected backup file already exists. Overwrite?</source>
65 <translation type="unfinished"></translation>
66 </message>
67 <message>
68 <location filename="../gui/backupdialog.cpp" line="125"/>
69 <source>Starting backup ...</source>
70 <translation type="unfinished"></translation>
71 </message>
72 <message>
73 <location filename="../gui/backupdialog.cpp" line="144"/>
74 <source>Backup successful.</source>
75 <translation type="unfinished"></translation>
76 </message>
77 <message>
78 <location filename="../gui/backupdialog.cpp" line="147"/>
79 <source>Backup failed!</source>
80 <translation type="unfinished">הגיבוי נכשל!</translation>
81 </message>
82</context>
83<context>
84 <name>BootloaderInstallAms</name>
85 <message>
86 <location filename="../base/bootloaderinstallams.cpp" line="33"/>
87 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; This file is not present on your player and will disappear automatically after installing it.&lt;br/&gt;&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
88 <translation type="unfinished"></translation>
89 </message>
90 <message>
91 <location filename="../base/bootloaderinstallams.cpp" line="58"/>
92 <source>Downloading bootloader file</source>
93 <translation>מוריד את קובץ מנהל האיתחול</translation>
94 </message>
95 <message>
96 <location filename="../base/bootloaderinstallams.cpp" line="100"/>
97 <location filename="../base/bootloaderinstallams.cpp" line="113"/>
98 <source>Could not load %1</source>
99 <translation>לא מצליח לטעון את %1</translation>
100 </message>
101 <message>
102 <location filename="../base/bootloaderinstallams.cpp" line="127"/>
103 <source>No room to insert bootloader, try another firmware version</source>
104 <translation>אין מספיק מקום להכנסת מנהל האיתחול, נסה גירסת קושחה אחרת</translation>
105 </message>
106 <message>
107 <location filename="../base/bootloaderinstallams.cpp" line="137"/>
108 <source>Patching Firmware...</source>
109 <translation>תופר קושחה...</translation>
110 </message>
111 <message>
112 <location filename="../base/bootloaderinstallams.cpp" line="148"/>
113 <source>Could not open %1 for writing</source>
114 <translation>לא מצליח לפתוח את %1 לכתיבה</translation>
115 </message>
116 <message>
117 <location filename="../base/bootloaderinstallams.cpp" line="161"/>
118 <source>Could not write firmware file</source>
119 <translation>לא מצליח לכתוב קובץ קושחה</translation>
120 </message>
121 <message>
122 <location filename="../base/bootloaderinstallams.cpp" line="177"/>
123 <source>Success: modified firmware file created</source>
124 <translation>הצלחה: קובץ קושחה מוסגל נוצר</translation>
125 </message>
126 <message>
127 <location filename="../base/bootloaderinstallams.cpp" line="185"/>
128 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
129 <translation>כדי להסיר את ההתקנה, בצע שדרוג רגיל עם קובץ קושחה מקורי שלא נעשה בו שינוי</translation>
130 </message>
131</context>
132<context>
133 <name>BootloaderInstallBase</name>
134 <message>
135 <location filename="../base/bootloaderinstallbase.cpp" line="78"/>
136 <source>Download error: received HTTP error %1.</source>
137 <translation>שגיאת הורדה: התקבלה שגיאת HTTP: %1.</translation>
138 </message>
139 <message>
140 <location filename="../base/bootloaderinstallbase.cpp" line="84"/>
141 <source>Download error: %1</source>
142 <translation>שגיאת הורדה: %1</translation>
143 </message>
144 <message>
145 <location filename="../base/bootloaderinstallbase.cpp" line="90"/>
146 <source>Download finished (cache used).</source>
147 <translation>הורדה הסתיימה (נעשה שימוש במטמון).</translation>
148 </message>
149 <message>
150 <location filename="../base/bootloaderinstallbase.cpp" line="92"/>
151 <source>Download finished.</source>
152 <translation>הורדה הסתיימה.</translation>
153 </message>
154 <message>
155 <location filename="../base/bootloaderinstallbase.cpp" line="113"/>
156 <source>Creating backup of original firmware file.</source>
157 <translation>יוצר גיבוי של קובץ מנהל האיתחול המקורי.</translation>
158 </message>
159 <message>
160 <location filename="../base/bootloaderinstallbase.cpp" line="115"/>
161 <source>Creating backup folder failed</source>
162 <translation>יצירת ספריית גיבוי נכשלה</translation>
163 </message>
164 <message>
165 <location filename="../base/bootloaderinstallbase.cpp" line="121"/>
166 <source>Creating backup copy failed.</source>
167 <translation>יצירת עותק גיבוי נכשלה.</translation>
168 </message>
169 <message>
170 <location filename="../base/bootloaderinstallbase.cpp" line="124"/>
171 <source>Backup created.</source>
172 <translation>גיבוי נוצר.</translation>
173 </message>
174 <message>
175 <location filename="../base/bootloaderinstallbase.cpp" line="137"/>
176 <source>Creating installation log</source>
177 <translation>יוצר קובץ רישום של ההתקנה</translation>
178 </message>
179 <message>
180 <location filename="../base/bootloaderinstallbase.cpp" line="226"/>
181 <source>Zip file format detected</source>
182 <translation type="unfinished"></translation>
183 </message>
184 <message>
185 <location filename="../base/bootloaderinstallbase.cpp" line="238"/>
186 <source>CAB file format detected</source>
187 <translation type="unfinished"></translation>
188 </message>
189 <message>
190 <location filename="../base/bootloaderinstallbase.cpp" line="259"/>
191 <source>Extracting firmware %1 from archive</source>
192 <translation type="unfinished"></translation>
193 </message>
194 <message>
195 <location filename="../base/bootloaderinstallbase.cpp" line="266"/>
196 <source>Error extracting firmware from archive</source>
197 <translation type="unfinished"></translation>
198 </message>
199 <message>
200 <location filename="../base/bootloaderinstallbase.cpp" line="275"/>
201 <source>Could not find firmware in archive</source>
202 <translation type="unfinished"></translation>
203 </message>
204 <message>
205 <location filename="../base/bootloaderinstallbase.cpp" line="159"/>
206 <source>Waiting for system to remount player</source>
207 <translation>ממתין למערכת שתעגון את הנגן מחדש</translation>
208 </message>
209 <message>
210 <location filename="../base/bootloaderinstallbase.cpp" line="189"/>
211 <source>Player remounted</source>
212 <translation>הנגן עוגן מחדש</translation>
213 </message>
214 <message>
215 <location filename="../base/bootloaderinstallbase.cpp" line="194"/>
216 <source>Timeout on remount</source>
217 <translation>העגינה ארכה זמן רב מדי</translation>
218 </message>
219 <message>
220 <location filename="../base/bootloaderinstallbase.cpp" line="149"/>
221 <source>Installation log created</source>
222 <translation>קובץ רישום של ההתקנה נוצר</translation>
223 </message>
224</context>
225<context>
226 <name>BootloaderInstallChinaChip</name>
227 <message>
228 <location filename="../base/bootloaderinstallchinachip.cpp" line="33"/>
229 <source>Bootloader installation requires you to provide a firmware file of the original firmware (HXF file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
230 <translation>התקנת מנהל האיתחול דורשת שתספק קובץ קושחה של הקושחה המקורית (קובץ HXF). עליך להוריד קובץ זה בעצמך מסיבות משפטיות. אנא פנה אל &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;המדריך למשתמש&lt;/a&gt; ולדף הויקי &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; לגבי מידע על איך להשיג קובץ זה.&lt;br/&gt;לחץ OK כדי להמשיך ולהפנות את התוכנה לקובץ הקושחה שברשותך.</translation>
231 </message>
232 <message>
233 <location filename="../base/bootloaderinstallchinachip.cpp" line="50"/>
234 <source>Downloading bootloader file</source>
235 <translation>מוריד את קובץ מנהל האיתחול</translation>
236 </message>
237 <message>
238 <location filename="../base/bootloaderinstallchinachip.cpp" line="75"/>
239 <source>Could not open firmware file</source>
240 <translation type="unfinished"></translation>
241 </message>
242 <message>
243 <location filename="../base/bootloaderinstallchinachip.cpp" line="78"/>
244 <source>Could not open bootloader file</source>
245 <translation type="unfinished"></translation>
246 </message>
247 <message>
248 <location filename="../base/bootloaderinstallchinachip.cpp" line="81"/>
249 <source>Could not allocate memory</source>
250 <translation type="unfinished"></translation>
251 </message>
252 <message>
253 <location filename="../base/bootloaderinstallchinachip.cpp" line="84"/>
254 <source>Could not load firmware file</source>
255 <translation type="unfinished"></translation>
256 </message>
257 <message>
258 <location filename="../base/bootloaderinstallchinachip.cpp" line="87"/>
259 <source>File is not a valid ChinaChip firmware</source>
260 <translation type="unfinished"></translation>
261 </message>
262 <message>
263 <location filename="../base/bootloaderinstallchinachip.cpp" line="90"/>
264 <source>Could not find ccpmp.bin in input file</source>
265 <translation type="unfinished"></translation>
266 </message>
267 <message>
268 <location filename="../base/bootloaderinstallchinachip.cpp" line="93"/>
269 <source>Could not open backup file for ccpmp.bin</source>
270 <translation type="unfinished"></translation>
271 </message>
272 <message>
273 <location filename="../base/bootloaderinstallchinachip.cpp" line="96"/>
274 <source>Could not write backup file for ccpmp.bin</source>
275 <translation type="unfinished"></translation>
276 </message>
277 <message>
278 <location filename="../base/bootloaderinstallchinachip.cpp" line="99"/>
279 <source>Could not load bootloader file</source>
280 <translation type="unfinished"></translation>
281 </message>
282 <message>
283 <location filename="../base/bootloaderinstallchinachip.cpp" line="102"/>
284 <source>Could not get current time</source>
285 <translation type="unfinished"></translation>
286 </message>
287 <message>
288 <location filename="../base/bootloaderinstallchinachip.cpp" line="105"/>
289 <source>Could not open output file</source>
290 <translation type="unfinished"></translation>
291 </message>
292 <message>
293 <location filename="../base/bootloaderinstallchinachip.cpp" line="108"/>
294 <source>Could not write output file</source>
295 <translation type="unfinished"></translation>
296 </message>
297 <message>
298 <location filename="../base/bootloaderinstallchinachip.cpp" line="111"/>
299 <source>Unexpected error from chinachippatcher</source>
300 <translation type="unfinished"></translation>
301 </message>
302</context>
303<context>
304 <name>BootloaderInstallFile</name>
305 <message>
306 <location filename="../base/bootloaderinstallfile.cpp" line="34"/>
307 <source>Downloading bootloader</source>
308 <translation>מוריד את קובץ מנהל האיתחול</translation>
309 </message>
310 <message>
311 <location filename="../base/bootloaderinstallfile.cpp" line="43"/>
312 <source>Installing Rockbox bootloader</source>
313 <translation>מתקין את מנהל האיתחול של רוקבוקס</translation>
314 </message>
315 <message>
316 <location filename="../base/bootloaderinstallfile.cpp" line="75"/>
317 <source>Error accessing output folder</source>
318 <translation>שגיאה בגישה לספריית הקלט</translation>
319 </message>
320 <message>
321 <location filename="../base/bootloaderinstallfile.cpp" line="89"/>
322 <source>A firmware file is already present on player</source>
323 <translation type="unfinished"></translation>
324 </message>
325 <message>
326 <location filename="../base/bootloaderinstallfile.cpp" line="94"/>
327 <source>Bootloader successful installed</source>
328 <translation>מנהל האיתחול הותקן בהצלחה</translation>
329 </message>
330 <message>
331 <location filename="../base/bootloaderinstallfile.cpp" line="97"/>
332 <source>Copying modified firmware file failed</source>
333 <translation type="unfinished"></translation>
334 </message>
335 <message>
336 <location filename="../base/bootloaderinstallfile.cpp" line="111"/>
337 <source>Removing Rockbox bootloader</source>
338 <translation>מסיר את מנהל האיתחול של רוקבוקס</translation>
339 </message>
340 <message>
341 <location filename="../base/bootloaderinstallfile.cpp" line="115"/>
342 <source>No original firmware file found.</source>
343 <translation>קובץ קושחה מקורי לא נמצא.</translation>
344 </message>
345 <message>
346 <location filename="../base/bootloaderinstallfile.cpp" line="121"/>
347 <source>Can&apos;t remove Rockbox bootloader file.</source>
348 <translation>לא מצליח להסיר את מנהל האיתחול של רוקבוקס.</translation>
349 </message>
350 <message>
351 <location filename="../base/bootloaderinstallfile.cpp" line="126"/>
352 <source>Can&apos;t restore bootloader file.</source>
353 <translation>לא מצליח לשחזר את קובץ מנהל האיתחול.</translation>
354 </message>
355 <message>
356 <location filename="../base/bootloaderinstallfile.cpp" line="130"/>
357 <source>Original bootloader restored successfully.</source>
358 <translation>קובץ איתחול מקורי שוחזר בהצלחה.</translation>
359 </message>
360</context>
361<context>
362 <name>BootloaderInstallHex</name>
363 <message>
364 <location filename="../base/bootloaderinstallhex.cpp" line="69"/>
365 <source>checking MD5 hash of input file ...</source>
366 <translation>בודק MD5 hash של קובץ הקלט...</translation>
367 </message>
368 <message>
369 <location filename="../base/bootloaderinstallhex.cpp" line="80"/>
370 <source>Could not verify original firmware file</source>
371 <translation>לא מצליח לאמת קובץ קושחה מקורית</translation>
372 </message>
373 <message>
374 <location filename="../base/bootloaderinstallhex.cpp" line="95"/>
375 <source>Firmware file not recognized.</source>
376 <translation>קובץ קושחה לא מזוהה.</translation>
377 </message>
378 <message>
379 <location filename="../base/bootloaderinstallhex.cpp" line="99"/>
380 <source>MD5 hash ok</source>
381 <translation></translation>
382 </message>
383 <message>
384 <location filename="../base/bootloaderinstallhex.cpp" line="106"/>
385 <source>Firmware file doesn&apos;t match selected player.</source>
386 <translation>קובץ קושחה לא מתאים לנגן שזוהה.</translation>
387 </message>
388 <message>
389 <location filename="../base/bootloaderinstallhex.cpp" line="111"/>
390 <source>Descrambling file</source>
391 <translation>מפענח קובץ</translation>
392 </message>
393 <message>
394 <location filename="../base/bootloaderinstallhex.cpp" line="119"/>
395 <source>Error in descramble: %1</source>
396 <translation>שגיאה בפיענוח: %1</translation>
397 </message>
398 <message>
399 <location filename="../base/bootloaderinstallhex.cpp" line="124"/>
400 <source>Downloading bootloader file</source>
401 <translation>מוריד את קובץ מנהל האיתחול</translation>
402 </message>
403 <message>
404 <location filename="../base/bootloaderinstallhex.cpp" line="134"/>
405 <source>Adding bootloader to firmware file</source>
406 <translation>מוסיף את מנהל האיתחול לקובץ הקושחה</translation>
407 </message>
408 <message>
409 <location filename="../base/bootloaderinstallhex.cpp" line="172"/>
410 <source>could not open input file</source>
411 <translation>לא מצליח לפתוח קובץ קלט</translation>
412 </message>
413 <message>
414 <location filename="../base/bootloaderinstallhex.cpp" line="173"/>
415 <source>reading header failed</source>
416 <translation>קריאת כותרת נכשלה</translation>
417 </message>
418 <message>
419 <location filename="../base/bootloaderinstallhex.cpp" line="174"/>
420 <source>reading firmware failed</source>
421 <translation>קריאת קושחה נכשלה</translation>
422 </message>
423 <message>
424 <location filename="../base/bootloaderinstallhex.cpp" line="175"/>
425 <source>can&apos;t open bootloader file</source>
426 <translation>לא מצליח לפתוח קובץ מנהל איתחול</translation>
427 </message>
428 <message>
429 <location filename="../base/bootloaderinstallhex.cpp" line="176"/>
430 <source>reading bootloader file failed</source>
431 <translation>קריאת קובץ מנהל האיתחול נכשלה</translation>
432 </message>
433 <message>
434 <location filename="../base/bootloaderinstallhex.cpp" line="177"/>
435 <source>can&apos;t open output file</source>
436 <translation>לא מצליח לפתוח קובץ פלט</translation>
437 </message>
438 <message>
439 <location filename="../base/bootloaderinstallhex.cpp" line="178"/>
440 <source>writing output file failed</source>
441 <translation>כתיבת קובץ פלט נכשלה</translation>
442 </message>
443 <message>
444 <location filename="../base/bootloaderinstallhex.cpp" line="180"/>
445 <source>Error in patching: %1</source>
446 <translation>שגיאה בתפירה: %1</translation>
447 </message>
448 <message>
449 <location filename="../base/bootloaderinstallhex.cpp" line="191"/>
450 <source>Error in scramble: %1</source>
451 <translation>שגיאה בהצפנה (ערבוב): %1</translation>
452 </message>
453 <message>
454 <location filename="../base/bootloaderinstallhex.cpp" line="206"/>
455 <source>Checking modified firmware file</source>
456 <translation>בודק את קובץ הקושחה המוסגל</translation>
457 </message>
458 <message>
459 <location filename="../base/bootloaderinstallhex.cpp" line="208"/>
460 <source>Error: modified file checksum wrong</source>
461 <translation>שגיאה: חישוב checksum של קובץ הקושחה המוסגל נכשל</translation>
462 </message>
463 <message>
464 <location filename="../base/bootloaderinstallhex.cpp" line="215"/>
465 <source>A firmware file is already present on player</source>
466 <translation type="unfinished"></translation>
467 </message>
468 <message>
469 <location filename="../base/bootloaderinstallhex.cpp" line="220"/>
470 <source>Success: modified firmware file created</source>
471 <translation>הצלחה: קובץ קושחה מוסגל נוצר</translation>
472 </message>
473 <message>
474 <location filename="../base/bootloaderinstallhex.cpp" line="223"/>
475 <source>Copying modified firmware file failed</source>
476 <translation type="unfinished"></translation>
477 </message>
478 <message>
479 <location filename="../base/bootloaderinstallhex.cpp" line="237"/>
480 <source>Uninstallation not possible, only installation info removed</source>
481 <translation>הסרת ההתקנה אינה אפשרית, רק מידע ההתקנה הוסר</translation>
482 </message>
483 <message>
484 <location filename="../base/bootloaderinstallhex.cpp" line="258"/>
485 <source>Can&apos;t open input file</source>
486 <translation>לא מצליח לפתוח קובץ קלט</translation>
487 </message>
488 <message>
489 <location filename="../base/bootloaderinstallhex.cpp" line="259"/>
490 <source>Can&apos;t open output file</source>
491 <translation>לא מצליח לפתוח קובץ פלט</translation>
492 </message>
493 <message>
494 <location filename="../base/bootloaderinstallhex.cpp" line="260"/>
495 <source>invalid file: header length wrong</source>
496 <translation>קובץ לא תקין: אורך הכותרת אינו נכון</translation>
497 </message>
498 <message>
499 <location filename="../base/bootloaderinstallhex.cpp" line="261"/>
500 <source>invalid file: unrecognized header</source>
501 <translation>קובץ לא תקין: כותרת לא מזוהה</translation>
502 </message>
503 <message>
504 <location filename="../base/bootloaderinstallhex.cpp" line="262"/>
505 <source>invalid file: &quot;length&quot; field wrong</source>
506 <translation>קובץ לא תקין: שדה &quot;length&quot; אינו תקין</translation>
507 </message>
508 <message>
509 <location filename="../base/bootloaderinstallhex.cpp" line="263"/>
510 <source>invalid file: &quot;length2&quot; field wrong</source>
511 <translation>קובץ לא תקין: שדה &quot;length2&quot; אינו תקין</translation>
512 </message>
513 <message>
514 <location filename="../base/bootloaderinstallhex.cpp" line="264"/>
515 <source>invalid file: internal checksum error</source>
516 <translation>קובץ לא תקין: שגיאה פנימית בחישוב checksum</translation>
517 </message>
518 <message>
519 <location filename="../base/bootloaderinstallhex.cpp" line="265"/>
520 <source>invalid file: &quot;length3&quot; field wrong</source>
521 <translation>קובץ לא תקין: שדה &quot;length3&quot; אינו תקין</translation>
522 </message>
523 <message>
524 <location filename="../base/bootloaderinstallhex.cpp" line="266"/>
525 <source>unknown</source>
526 <translation>לא ידוע</translation>
527 </message>
528 <message>
529 <location filename="../base/bootloaderinstallhex.cpp" line="50"/>
530 <source>Bootloader installation requires you to provide a firmware file of the original firmware (hex file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
531 <translation>התקנת מנהל האיתחול דורשת שתספק קובץ קושחה של הקושחה המקורית (קובץ bin). עליך להוריד קובץ זה בעצמך מסיבות משפטיות. אנא פנה אל &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;המדריך למשתמש&lt;/a&gt; ולדף הויקי &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; לגבי מידע על איך להשיג קובץ זה.&lt;br/&gt;לחץ OK כדי להמשיך ולהפנות את התוכנה לקובץ הקושחה שברשותך.</translation>
532 </message>
533</context>
534<context>
535 <name>BootloaderInstallImx</name>
536 <message>
537 <location filename="../base/bootloaderinstallimx.cpp" line="72"/>
538 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (firmware.sb file). This file will be patched with the Rockbox bootloader and installed to your player. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
539 <translation type="unfinished"></translation>
540 </message>
541 <message>
542 <location filename="../base/bootloaderinstallimx.cpp" line="94"/>
543 <source>Could not read original firmware file</source>
544 <translation type="unfinished"></translation>
545 </message>
546 <message>
547 <location filename="../base/bootloaderinstallimx.cpp" line="100"/>
548 <source>Downloading bootloader file</source>
549 <translation type="unfinished">מוריד את קובץ מנהל האיתחול</translation>
550 </message>
551 <message>
552 <location filename="../base/bootloaderinstallimx.cpp" line="110"/>
553 <source>Patching file...</source>
554 <translation type="unfinished"></translation>
555 </message>
556 <message>
557 <location filename="../base/bootloaderinstallimx.cpp" line="137"/>
558 <source>Patching the original firmware failed</source>
559 <translation type="unfinished"></translation>
560 </message>
561 <message>
562 <location filename="../base/bootloaderinstallimx.cpp" line="143"/>
563 <source>Succesfully patched firmware file</source>
564 <translation type="unfinished"></translation>
565 </message>
566 <message>
567 <location filename="../base/bootloaderinstallimx.cpp" line="158"/>
568 <source>Bootloader successful installed</source>
569 <translation type="unfinished">מנהל האיתחול הותקן בהצלחה</translation>
570 </message>
571 <message>
572 <location filename="../base/bootloaderinstallimx.cpp" line="164"/>
573 <source>Patched bootloader could not be installed</source>
574 <translation type="unfinished"></translation>
575 </message>
576 <message>
577 <location filename="../base/bootloaderinstallimx.cpp" line="175"/>
578 <source>To uninstall, perform a normal upgrade with an unmodified original firmware.</source>
579 <translation type="unfinished"></translation>
580 </message>
581</context>
582<context>
583 <name>BootloaderInstallIpod</name>
584 <message>
585 <location filename="../base/bootloaderinstallipod.cpp" line="49"/>
586 <source>Error: can&apos;t allocate buffer memory!</source>
587 <translation>שגיאה: לא יכול להקצות זיכרון חוצץ!</translation>
588 </message>
589 <message>
590 <location filename="../base/bootloaderinstallipod.cpp" line="80"/>
591 <source>Downloading bootloader file</source>
592 <translation>מוריד את קובץ מנהל האיתחול</translation>
593 </message>
594 <message>
595 <location filename="../base/bootloaderinstallipod.cpp" line="64"/>
596 <location filename="../base/bootloaderinstallipod.cpp" line="151"/>
597 <source>Failed to read firmware directory</source>
598 <translation>לא מצליח לקרוא את ספריית מנהל האיתחול</translation>
599 </message>
600 <message>
601 <location filename="../base/bootloaderinstallipod.cpp" line="69"/>
602 <location filename="../base/bootloaderinstallipod.cpp" line="156"/>
603 <source>Unknown version number in firmware (%1)</source>
604 <translation>מספר גירסה לא מוכר בקושחה (%1)</translation>
605 </message>
606 <message>
607 <location filename="../base/bootloaderinstallipod.cpp" line="75"/>
608 <source>Warning: This is a MacPod, Rockbox only runs on WinPods.
609See http://www.rockbox.org/wiki/IpodConversionToFAT32</source>
610 <translation>אזהרה: זוהי גירסת MacPod, רוקבוקס רצה רק על נגני WinPos.
611ראה http://www.rockbox.org/wiki/IpodConversionToFAT32</translation>
612 </message>
613 <message>
614 <location filename="../base/bootloaderinstallipod.cpp" line="94"/>
615 <location filename="../base/bootloaderinstallipod.cpp" line="163"/>
616 <source>Could not open Ipod in R/W mode</source>
617 <translation>לא מצליח לפתוח את האייפוד במצב קריאה/כתיבה</translation>
618 </message>
619 <message>
620 <location filename="../base/bootloaderinstallipod.cpp" line="104"/>
621 <source>Successfull added bootloader</source>
622 <translation>מנהל האיתחול התווסף בהצלחה</translation>
623 </message>
624 <message>
625 <location filename="../base/bootloaderinstallipod.cpp" line="115"/>
626 <source>Failed to add bootloader</source>
627 <translation>כישלון בהוספת מנהל האיתחול</translation>
628 </message>
629 <message>
630 <location filename="../base/bootloaderinstallipod.cpp" line="127"/>
631 <source>Bootloader Installation complete.</source>
632 <translation>מנהל האיתחול הותקן בהצלחה</translation>
633 </message>
634 <message>
635 <location filename="../base/bootloaderinstallipod.cpp" line="132"/>
636 <source>Writing log aborted</source>
637 <translation>כתיבת היומן בוטלה</translation>
638 </message>
639 <message>
640 <location filename="../base/bootloaderinstallipod.cpp" line="169"/>
641 <source>No bootloader detected.</source>
642 <translation>לא זוהה מנהל איתחול.</translation>
643 </message>
644 <message>
645 <location filename="../base/bootloaderinstallipod.cpp" line="175"/>
646 <source>Successfully removed bootloader</source>
647 <translation>מנהל האיתחול הוסר בהצלחה</translation>
648 </message>
649 <message>
650 <location filename="../base/bootloaderinstallipod.cpp" line="182"/>
651 <source>Removing bootloader failed.</source>
652 <translation>הסרת מנהל האיתחול נכשלה.</translation>
653 </message>
654 <message>
655 <location filename="../base/bootloaderinstallipod.cpp" line="228"/>
656 <source>Error: could not retrieve device name</source>
657 <translation type="unfinished"></translation>
658 </message>
659 <message>
660 <location filename="../base/bootloaderinstallipod.cpp" line="244"/>
661 <source>Error: no mountpoint specified!</source>
662 <translation>שגיאה: נקודת עגינה לא צויינה!</translation>
663 </message>
664 <message>
665 <location filename="../base/bootloaderinstallipod.cpp" line="249"/>
666 <source>Could not open Ipod: permission denied</source>
667 <translation>לא מצליח לפתוח את האייפוד: הגישה נדחתה</translation>
668 </message>
669 <message>
670 <location filename="../base/bootloaderinstallipod.cpp" line="253"/>
671 <source>Could not open Ipod</source>
672 <translation>לא מצליח לפתוח אייפוד</translation>
673 </message>
674 <message>
675 <location filename="../base/bootloaderinstallipod.cpp" line="264"/>
676 <source>No firmware partition on disk</source>
677 <translation>אין מחיצת מנהל איתחול על הדיסק</translation>
678 </message>
679 <message>
680 <location filename="../base/bootloaderinstallipod.cpp" line="90"/>
681 <source>Installing Rockbox bootloader</source>
682 <translation>מתקין את מנהל האיתחול של רוקבוקס</translation>
683 </message>
684 <message>
685 <location filename="../base/bootloaderinstallipod.cpp" line="142"/>
686 <source>Uninstalling bootloader</source>
687 <translation>מסיר את מנהל האיתחול</translation>
688 </message>
689 <message>
690 <location filename="../base/bootloaderinstallipod.cpp" line="258"/>
691 <source>Error reading partition table - possibly not an Ipod</source>
692 <translation>שגיאה בקריאת טבלת המחיצות - ככל הנראה נגן זה אינו אייפוד</translation>
693 </message>
694</context>
695<context>
696 <name>BootloaderInstallMi4</name>
697 <message>
698 <location filename="../base/bootloaderinstallmi4.cpp" line="34"/>
699 <source>Downloading bootloader</source>
700 <translation>מוריד את קובץ מנהל האיתחול</translation>
701 </message>
702 <message>
703 <location filename="../base/bootloaderinstallmi4.cpp" line="43"/>
704 <source>Installing Rockbox bootloader</source>
705 <translation>מתקין את מנהל האיתחול של רוקבוקס</translation>
706 </message>
707 <message>
708 <location filename="../base/bootloaderinstallmi4.cpp" line="66"/>
709 <source>A firmware file is already present on player</source>
710 <translation type="unfinished"></translation>
711 </message>
712 <message>
713 <location filename="../base/bootloaderinstallmi4.cpp" line="71"/>
714 <location filename="../base/bootloaderinstallmi4.cpp" line="79"/>
715 <source>Bootloader successful installed</source>
716 <translation>מנהל האיתחול הותקן בהצלחה</translation>
717 </message>
718 <message>
719 <location filename="../base/bootloaderinstallmi4.cpp" line="74"/>
720 <source>Copying modified firmware file failed</source>
721 <translation type="unfinished"></translation>
722 </message>
723 <message>
724 <location filename="../base/bootloaderinstallmi4.cpp" line="91"/>
725 <source>Checking for Rockbox bootloader</source>
726 <translation>מחפש את מנהל האיתחול של רוקבוקס</translation>
727 </message>
728 <message>
729 <location filename="../base/bootloaderinstallmi4.cpp" line="93"/>
730 <source>No Rockbox bootloader found</source>
731 <translation>לא נמצא מנהל איתחול של רוקבוקס</translation>
732 </message>
733 <message>
734 <location filename="../base/bootloaderinstallmi4.cpp" line="98"/>
735 <source>Checking for original firmware file</source>
736 <translation>מחפש קובץ קושחה מקורי</translation>
737 </message>
738 <message>
739 <location filename="../base/bootloaderinstallmi4.cpp" line="103"/>
740 <source>Error finding original firmware file</source>
741 <translation>שגיאה בחיפוש קובץ קושחה מקורי</translation>
742 </message>
743 <message>
744 <location filename="../base/bootloaderinstallmi4.cpp" line="113"/>
745 <source>Rockbox bootloader successful removed</source>
746 <translation>מנהל האיתחול של רוקבוקס הוסר בהצלחה</translation>
747 </message>
748</context>
749<context>
750 <name>BootloaderInstallMpio</name>
751 <message>
752 <location filename="../base/bootloaderinstallmpio.cpp" line="34"/>
753 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
754 <translation type="unfinished"></translation>
755 </message>
756 <message>
757 <location filename="../base/bootloaderinstallmpio.cpp" line="53"/>
758 <source>Downloading bootloader file</source>
759 <translation type="unfinished">מוריד את קובץ מנהל האיתחול</translation>
760 </message>
761 <message>
762 <location filename="../base/bootloaderinstallmpio.cpp" line="80"/>
763 <source>Could not open the original firmware.</source>
764 <translation type="unfinished"></translation>
765 </message>
766 <message>
767 <location filename="../base/bootloaderinstallmpio.cpp" line="83"/>
768 <source>Could not read the original firmware.</source>
769 <translation type="unfinished"></translation>
770 </message>
771 <message>
772 <location filename="../base/bootloaderinstallmpio.cpp" line="86"/>
773 <source>Loaded firmware file does not look like MPIO original firmware file.</source>
774 <translation type="unfinished"></translation>
775 </message>
776 <message>
777 <location filename="../base/bootloaderinstallmpio.cpp" line="101"/>
778 <source>Could not open output file.</source>
779 <translation type="unfinished"></translation>
780 </message>
781 <message>
782 <location filename="../base/bootloaderinstallmpio.cpp" line="104"/>
783 <source>Could not write output file.</source>
784 <translation type="unfinished"></translation>
785 </message>
786 <message>
787 <location filename="../base/bootloaderinstallmpio.cpp" line="107"/>
788 <source>Unknown error number: %1</source>
789 <translation type="unfinished"></translation>
790 </message>
791 <message>
792 <location filename="../base/bootloaderinstallmpio.cpp" line="89"/>
793 <source>Could not open downloaded bootloader.</source>
794 <translation type="unfinished"></translation>
795 </message>
796 <message>
797 <location filename="../base/bootloaderinstallmpio.cpp" line="92"/>
798 <source>Place for bootloader in OF file not empty.</source>
799 <translation type="unfinished"></translation>
800 </message>
801 <message>
802 <location filename="../base/bootloaderinstallmpio.cpp" line="95"/>
803 <source>Could not read the downloaded bootloader.</source>
804 <translation type="unfinished"></translation>
805 </message>
806 <message>
807 <location filename="../base/bootloaderinstallmpio.cpp" line="98"/>
808 <source>Bootloader checksum error.</source>
809 <translation type="unfinished"></translation>
810 </message>
811 <message>
812 <location filename="../base/bootloaderinstallmpio.cpp" line="112"/>
813 <source>Patching original firmware failed: %1</source>
814 <translation type="unfinished"></translation>
815 </message>
816 <message>
817 <location filename="../base/bootloaderinstallmpio.cpp" line="119"/>
818 <source>Success: modified firmware file created</source>
819 <translation type="unfinished">הצלחה: קובץ קושחה מוסגל נוצר</translation>
820 </message>
821 <message>
822 <location filename="../base/bootloaderinstallmpio.cpp" line="127"/>
823 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
824 <translation type="unfinished">כדי להסיר את ההתקנה, בצע שדרוג רגיל עם קובץ קושחה מקורי שלא נעשה בו שינוי</translation>
825 </message>
826</context>
827<context>
828 <name>BootloaderInstallSansa</name>
829 <message>
830 <location filename="../base/bootloaderinstallsansa.cpp" line="50"/>
831 <source>Error: can&apos;t allocate buffer memory!</source>
832 <translation>שגיאה: לא יכול להקצות זיכרון חוצץ!</translation>
833 </message>
834 <message>
835 <location filename="../base/bootloaderinstallsansa.cpp" line="55"/>
836 <source>Searching for Sansa</source>
837 <translation>מחפש נגן מסוג סנסה</translation>
838 </message>
839 <message>
840 <location filename="../base/bootloaderinstallsansa.cpp" line="59"/>
841 <source>Permission for disc access denied!
842This is required to install the bootloader</source>
843 <translation>אין גישה לדיסק!
844דבר זה נדרש על מנת להתקין את מנהל האיתחול</translation>
845 </message>
846 <message>
847 <location filename="../base/bootloaderinstallsansa.cpp" line="66"/>
848 <source>No Sansa detected!</source>
849 <translation>לא נמצאו נגני סנסה!</translation>
850 </message>
851 <message>
852 <location filename="../base/bootloaderinstallsansa.cpp" line="79"/>
853 <source>Downloading bootloader file</source>
854 <translation>מוריד את קובץ מנהל האיתחול</translation>
855 </message>
856 <message>
857 <location filename="../base/bootloaderinstallsansa.cpp" line="71"/>
858 <location filename="../base/bootloaderinstallsansa.cpp" line="179"/>
859 <source>OLD ROCKBOX INSTALLATION DETECTED, ABORTING.
860You must reinstall the original Sansa firmware before running
861sansapatcher for the first time.
862See http://www.rockbox.org/wiki/SansaE200Install
863</source>
864 <translation>זוהתה התקנה ישנה של רוקבוקס. מבטל.
865עליך להתקין מחדש את הקושחה המקורית של הנגן בטרם תפעיל
866את sansapatcher בפעם הראשונה.
867ראה http://www.rockbox.org/wiki/SansaE200Install
868</translation>
869 </message>
870 <message>
871 <location filename="../base/bootloaderinstallsansa.cpp" line="102"/>
872 <location filename="../base/bootloaderinstallsansa.cpp" line="189"/>
873 <source>Could not open Sansa in R/W mode</source>
874 <translation>לא מצליח לפתוח את נגן הסנסה במצב קריאה/כתיבה</translation>
875 </message>
876 <message>
877 <location filename="../base/bootloaderinstallsansa.cpp" line="129"/>
878 <source>Successfully installed bootloader</source>
879 <translation>מנהל האיתחול הותקן בהצלחה</translation>
880 </message>
881 <message>
882 <location filename="../base/bootloaderinstallsansa.cpp" line="140"/>
883 <source>Failed to install bootloader</source>
884 <translation>התקנת מנהל האיתחול נכשלה</translation>
885 </message>
886 <message>
887 <location filename="../base/bootloaderinstallsansa.cpp" line="153"/>
888 <source>Bootloader Installation complete.</source>
889 <translation>מנהל האיתחול הותקן בהצלחה</translation>
890 </message>
891 <message>
892 <location filename="../base/bootloaderinstallsansa.cpp" line="158"/>
893 <source>Writing log aborted</source>
894 <translation>כתיבת היומן בוטלה</translation>
895 </message>
896 <message>
897 <location filename="../base/bootloaderinstallsansa.cpp" line="238"/>
898 <source>Error: could not retrieve device name</source>
899 <translation type="unfinished"></translation>
900 </message>
901 <message>
902 <location filename="../base/bootloaderinstallsansa.cpp" line="254"/>
903 <source>Can&apos;t find Sansa</source>
904 <translation>לא מצליח למצוא נגן סנסה</translation>
905 </message>
906 <message>
907 <location filename="../base/bootloaderinstallsansa.cpp" line="259"/>
908 <source>Could not open Sansa</source>
909 <translation>לא מצליח לפתוח את נגן הסנסה</translation>
910 </message>
911 <message>
912 <location filename="../base/bootloaderinstallsansa.cpp" line="264"/>
913 <source>Could not read partition table</source>
914 <translation>לא מצליח לקרוא את טבלת המחיצות</translation>
915 </message>
916 <message>
917 <location filename="../base/bootloaderinstallsansa.cpp" line="271"/>
918 <source>Disk is not a Sansa (Error %1), aborting.</source>
919 <translation>הדיסק אינו נגן סנסה (שגיאה %1), מבטל.</translation>
920 </message>
921 <message>
922 <location filename="../base/bootloaderinstallsansa.cpp" line="195"/>
923 <source>Successfully removed bootloader</source>
924 <translation>מנהל האיתחול הוסר בהצלחה</translation>
925 </message>
926 <message>
927 <location filename="../base/bootloaderinstallsansa.cpp" line="202"/>
928 <source>Removing bootloader failed.</source>
929 <translation>הסרת מנהל האיתחול נכשלה.</translation>
930 </message>
931 <message>
932 <location filename="../base/bootloaderinstallsansa.cpp" line="94"/>
933 <source>Installing Rockbox bootloader</source>
934 <translation>מתקין את מנהל האיתחול של רוקבוקס</translation>
935 </message>
936 <message>
937 <location filename="../base/bootloaderinstallsansa.cpp" line="111"/>
938 <source>Checking downloaded bootloader</source>
939 <translation>בודק את מנהל האיתחול שהורד</translation>
940 </message>
941 <message>
942 <location filename="../base/bootloaderinstallsansa.cpp" line="119"/>
943 <source>Bootloader mismatch! Aborting.</source>
944 <translation>מנהל האיתחול אינו תואם! מבטל.</translation>
945 </message>
946 <message>
947 <location filename="../base/bootloaderinstallsansa.cpp" line="170"/>
948 <source>Uninstalling bootloader</source>
949 <translation>מסיר את מנהל האיתחול</translation>
950 </message>
951</context>
952<context>
953 <name>BootloaderInstallTcc</name>
954 <message>
955 <location filename="../base/bootloaderinstalltcc.cpp" line="33"/>
956 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wiki page on how to obtain the file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
957 <translation>התקנת מנהל האיתחול דורשת שתספק קובץ קושחה של הקושחה המקורית (קובץ bin). עליך להוריד קובץ זה בעצמך מסיבות משפטיות. אנא פנה אל &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;המדריך למשתמש&lt;/a&gt; ולדף הויקי &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; לגבי מידע על איך להשיג קובץ זה.&lt;br/&gt;לחץ OK כדי להמשיך ולהפנות את התוכנה לקובץ הקושחה שברשותך.</translation>
958 </message>
959 <message>
960 <location filename="../base/bootloaderinstalltcc.cpp" line="50"/>
961 <source>Downloading bootloader file</source>
962 <translation>מוריד את קובץ מנהל האיתחול</translation>
963 </message>
964 <message>
965 <location filename="../base/bootloaderinstalltcc.cpp" line="82"/>
966 <location filename="../base/bootloaderinstalltcc.cpp" line="99"/>
967 <source>Could not load %1</source>
968 <translation>לא מצליח לטעון את %1</translation>
969 </message>
970 <message>
971 <location filename="../base/bootloaderinstalltcc.cpp" line="90"/>
972 <source>Unknown OF file used: %1</source>
973 <translation>משתמש בקובץ קושחה מקורית לא ידוע: %1</translation>
974 </message>
975 <message>
976 <location filename="../base/bootloaderinstalltcc.cpp" line="104"/>
977 <source>Patching Firmware...</source>
978 <translation>תופר קושחה...</translation>
979 </message>
980 <message>
981 <location filename="../base/bootloaderinstalltcc.cpp" line="111"/>
982 <source>Could not patch firmware</source>
983 <translation>לא מצליח לתפור את הקושחה</translation>
984 </message>
985 <message>
986 <location filename="../base/bootloaderinstalltcc.cpp" line="117"/>
987 <source>Could not open %1 for writing</source>
988 <translation>לא מצליח לפתוח את %1 לכתיבה</translation>
989 </message>
990 <message>
991 <location filename="../base/bootloaderinstalltcc.cpp" line="126"/>
992 <source>Could not write firmware file</source>
993 <translation>לא מצליח לכתוב קובץ קושחה</translation>
994 </message>
995 <message>
996 <location filename="../base/bootloaderinstalltcc.cpp" line="131"/>
997 <source>Success: modified firmware file created</source>
998 <translation>הצלחה: קובץ קושחה מוסגל נוצר</translation>
999 </message>
1000 <message>
1001 <location filename="../base/bootloaderinstalltcc.cpp" line="151"/>
1002 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
1003 <translation>כדי להסיר את ההתקנה, בצע שדרוג רגיל עם קובץ קושחה מקורי שלא נעשה בו שינוי</translation>
1004 </message>
1005</context>
1006<context>
1007 <name>Changelog</name>
1008 <message>
1009 <location filename="../gui/changelogfrm.ui" line="17"/>
1010 <source>Changelog</source>
1011 <translation type="unfinished"></translation>
1012 </message>
1013 <message>
1014 <location filename="../gui/changelogfrm.ui" line="39"/>
1015 <source>Show on startup</source>
1016 <translation type="unfinished"></translation>
1017 </message>
1018 <message>
1019 <location filename="../gui/changelogfrm.ui" line="46"/>
1020 <source>&amp;Ok</source>
1021 <translation type="unfinished">&amp;אישור</translation>
1022 </message>
1023</context>
1024<context>
1025 <name>Config</name>
1026 <message>
1027 <location filename="../configure.cpp" line="322"/>
1028 <source>Current cache size is %L1 kiB.</source>
1029 <translation>גודל זכרון מטמון נוכחי הוא %L1 kiB.</translation>
1030 </message>
1031 <message>
1032 <location filename="../configure.cpp" line="340"/>
1033 <source>Showing disabled targets</source>
1034 <translation>מציג נגנים שאינם מאופשרים</translation>
1035 </message>
1036 <message>
1037 <location filename="../configure.cpp" line="341"/>
1038 <source>You just enabled showing targets that are marked disabled. Disabled targets are not recommended to end users. Please use this option only if you know what you are doing.</source>
1039 <translation>אפשרת הצגת נגנים המסומנים כלא מאופשרים. נגנים אלו אינם מומלצים למשתמשי קצה. אנא השתמש באפשרות זו רק אם אתה יודע מה אתה עושה.</translation>
1040 </message>
1041 <message>
1042 <location filename="../configure.cpp" line="448"/>
1043 <location filename="../configure.cpp" line="914"/>
1044 <source>TTS error</source>
1045 <translation type="unfinished"></translation>
1046 </message>
1047 <message>
1048 <location filename="../configure.cpp" line="449"/>
1049 <location filename="../configure.cpp" line="915"/>
1050 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1051 <translation type="unfinished"></translation>
1052 </message>
1053 <message>
1054 <location filename="../configure.cpp" line="455"/>
1055 <location filename="../configure.cpp" line="485"/>
1056 <source>Configuration OK</source>
1057 <translation>ההגדרות תקינות</translation>
1058 </message>
1059 <message>
1060 <location filename="../configure.cpp" line="461"/>
1061 <location filename="../configure.cpp" line="490"/>
1062 <source>Configuration INVALID</source>
1063 <translation>ההגדרות אינן תקינות</translation>
1064 </message>
1065 <message>
1066 <location filename="../configure.cpp" line="529"/>
1067 <source>Proxy Detection</source>
1068 <translation>זיהוי פרוקסי</translation>
1069 </message>
1070 <message>
1071 <location filename="../configure.cpp" line="530"/>
1072 <source>The System Proxy settings are invalid!
1073Rockbox Utility can&apos;t work with this proxy settings. Make sure the system proxy is set correctly. Note that &quot;proxy auto-config (PAC)&quot; scripts are not supported by Rockbox Utility. If your system uses this you need to use manual proxy settings.</source>
1074 <translation>הגדרות הפרוקסי של המערכת אינן תקינות
1075תוכנת השירות של רוקבוקס אינה יכולה לעבוד עם הגדרות פרוקסי אלו. אנא וודא שהגדרות הפרוקסי של המערכת הינן נכונות. שים לב שהגדרות פרוקסי אוטומאטיות (proxy auto config - PAC) אינן נתמכות על ידי תוכנה זו. אם אלו הן הגדרות המערכת שלך עליך להשתמש בהגדרות פרוקסי ידניות.</translation>
1076 </message>
1077 <message>
1078 <location filename="../configure.cpp" line="643"/>
1079 <source>Set Cache Path</source>
1080 <translation>קבע נתיב מטמון</translation>
1081 </message>
1082 <message>
1083 <location filename="../configure.cpp" line="665"/>
1084 <source>%1 (%2 GiB of %3 GiB free)</source>
1085 <translation type="unfinished"></translation>
1086 </message>
1087 <message>
1088 <location filename="../configure.cpp" line="739"/>
1089 <source>Multiple devices have been detected. Please disconnect all players but one and try again.</source>
1090 <translation type="unfinished"></translation>
1091 </message>
1092 <message>
1093 <location filename="../configure.cpp" line="742"/>
1094 <source>Detected devices:</source>
1095 <translation type="unfinished"></translation>
1096 </message>
1097 <message>
1098 <location filename="../configure.cpp" line="747"/>
1099 <source>(unknown)</source>
1100 <translation type="unfinished"></translation>
1101 </message>
1102 <message>
1103 <location filename="../configure.cpp" line="749"/>
1104 <source>%1 at %2</source>
1105 <translation type="unfinished"></translation>
1106 </message>
1107 <message>
1108 <location filename="../configure.cpp" line="755"/>
1109 <source>Note: detecting connected devices might be ambiguous. You might have less devices connected than listed. In this case it might not be possible to detect your player unambiguously.</source>
1110 <translation type="unfinished"></translation>
1111 </message>
1112 <message>
1113 <location filename="../configure.cpp" line="759"/>
1114 <location filename="../configure.cpp" line="763"/>
1115 <location filename="../configure.cpp" line="805"/>
1116 <source>Device Detection</source>
1117 <translation type="unfinished"></translation>
1118 </message>
1119 <message>
1120 <location filename="../configure.cpp" line="788"/>
1121 <source>%1 &quot;MacPod&quot; found!
1122Rockbox needs a FAT formatted Ipod (so-called &quot;WinPod&quot;) to run. </source>
1123 <translation>נמצא %1 &quot;MacPod&quot;!
1124רוקבוקס זקוקה לאייפוד המפורמט בשיטת FAT (נגנים אלי מכונים WinPod) על מנת לרוץ.</translation>
1125 </message>
1126 <message>
1127 <source>Fatal error</source>
1128 <translation type="obsolete">טעות מכרעת</translation>
1129 </message>
1130 <message>
1131 <location filename="../configure.cpp" line="774"/>
1132 <source>Detected an unsupported player:
1133%1
1134Sorry, Rockbox doesn&apos;t run on your player.</source>
1135 <translation>זוהה נגן לא נתמך:
1136%1
1137מצטערים, רוקבוקס איננה יכולה לרוץ על הנגן שלך.</translation>
1138 </message>
1139 <message>
1140 <source>Fatal: player incompatible</source>
1141 <translation type="obsolete">תקלה מכרעת: נגן לא תואם</translation>
1142 </message>
1143 <message>
1144 <location filename="../configure.cpp" line="921"/>
1145 <source>TTS configuration invalid</source>
1146 <translation>הגדרות מנוע דיבור אינן תקינות</translation>
1147 </message>
1148 <message>
1149 <location filename="../configure.cpp" line="922"/>
1150 <source>TTS configuration invalid.
1151 Please configure TTS engine.</source>
1152 <translation>הגדרות מנוע דיבור אינן תקינות.
1153אנא הגדר את תצורת מנוע הדיבור.</translation>
1154 </message>
1155 <message>
1156 <location filename="../configure.cpp" line="927"/>
1157 <source>Could not start TTS engine.</source>
1158 <translation>לא מצליח להתחיל את מנוע הדיבור.</translation>
1159 </message>
1160 <message>
1161 <location filename="../configure.cpp" line="928"/>
1162 <source>Could not start TTS engine.
1163</source>
1164 <translation>לא מצליח להתחיל את מנוע הדיבור.
1165</translation>
1166 </message>
1167 <message>
1168 <location filename="../configure.cpp" line="929"/>
1169 <location filename="../configure.cpp" line="948"/>
1170 <source>
1171Please configure TTS engine.</source>
1172 <translation>
1173אנא הגדר את תצורת מנוע הדיבור.</translation>
1174 </message>
1175 <message>
1176 <location filename="../configure.cpp" line="943"/>
1177 <source>Rockbox Utility Voice Test</source>
1178 <translation>בדיקת דיבור של תוכנת השרות של רוקבוקס</translation>
1179 </message>
1180 <message>
1181 <location filename="../configure.cpp" line="946"/>
1182 <source>Could not voice test string.</source>
1183 <translation>לא מצליח להקריא את מחרוזת הבדיקה.</translation>
1184 </message>
1185 <message>
1186 <location filename="../configure.cpp" line="947"/>
1187 <source>Could not voice test string.
1188</source>
1189 <translation>לא מצליח להקריא את מחרוזת הבדיקה.
1190</translation>
1191 </message>
1192 <message>
1193 <location filename="../configure.cpp" line="858"/>
1194 <source>Autodetection</source>
1195 <translation>זיהוי אוטומטי</translation>
1196 </message>
1197 <message>
1198 <location filename="../configure.cpp" line="780"/>
1199 <source>%1 in MTP mode found!
1200You need to change your player to MSC mode for installation. </source>
1201 <translation type="unfinished"></translation>
1202 </message>
1203 <message>
1204 <location filename="../configure.cpp" line="859"/>
1205 <source>Could not detect a Mountpoint.
1206Select your Mountpoint manually.</source>
1207 <translation>לא מזהה נקודת עגינה.
1208בחר את נקודת העגינה ידנית.</translation>
1209 </message>
1210 <message>
1211 <location filename="../configure.cpp" line="764"/>
1212 <source>Could not detect a device.
1213Select your device and Mountpoint manually.</source>
1214 <translation>לא מזהה נגן.
1215בחר את הנגן ונקודת העגינה ידנית.</translation>
1216 </message>
1217 <message>
1218 <location filename="../configure.cpp" line="794"/>
1219 <source>The player contains an incompatible filesystem.
1220Make sure you selected the correct mountpoint and the player is set up to use a filesystem compatible with Rockbox.</source>
1221 <translation type="unfinished"></translation>
1222 </message>
1223 <message>
1224 <location filename="../configure.cpp" line="802"/>
1225 <source>An unknown error occured during player detection.</source>
1226 <translation type="unfinished"></translation>
1227 </message>
1228 <message>
1229 <location filename="../configure.cpp" line="869"/>
1230 <source>Really delete cache?</source>
1231 <translation>באמת למחוק את המטמון?</translation>
1232 </message>
1233 <message>
1234 <location filename="../configure.cpp" line="870"/>
1235 <source>Do you really want to delete the cache? Make absolutely sure this setting is correct as it will remove &lt;b&gt;all&lt;/b&gt; files in this folder!</source>
1236 <translation>האם באמת ברצונך למחוק את המטמון? אנא וודא שברצונך לבצע פעולה זו נכונה, כיוון שהיא תמחק את &lt;b&gt;כל&lt;/b&gt; הקבצים בספרייה זו!</translation>
1237 </message>
1238 <message>
1239 <location filename="../configure.cpp" line="878"/>
1240 <source>Path wrong!</source>
1241 <translation>נתיב שגוי!</translation>
1242 </message>
1243 <message>
1244 <location filename="../configure.cpp" line="879"/>
1245 <source>The cache path is invalid. Aborting.</source>
1246 <translation>נתיב זכרון המטמון שגוי. מבטל.</translation>
1247 </message>
1248 <message>
1249 <location filename="../configure.cpp" line="130"/>
1250 <source>The following errors occurred:</source>
1251 <translation>השגיאות הבאות התרחשו:</translation>
1252 </message>
1253 <message>
1254 <location filename="../configure.cpp" line="175"/>
1255 <source>No mountpoint given</source>
1256 <translation>לא ניתנה נקודת עגינה</translation>
1257 </message>
1258 <message>
1259 <location filename="../configure.cpp" line="179"/>
1260 <source>Mountpoint does not exist</source>
1261 <translation>נקודת העגינה אינה קיימת</translation>
1262 </message>
1263 <message>
1264 <location filename="../configure.cpp" line="183"/>
1265 <source>Mountpoint is not a directory.</source>
1266 <translation>נקודת העגינה איננה ספרייה.</translation>
1267 </message>
1268 <message>
1269 <location filename="../configure.cpp" line="187"/>
1270 <source>Mountpoint is not writeable</source>
1271 <translation>נקודת העגינה אינה ניתנת לכתיבה</translation>
1272 </message>
1273 <message>
1274 <location filename="../configure.cpp" line="202"/>
1275 <source>No player selected</source>
1276 <translation>לא נבחר כל נגן</translation>
1277 </message>
1278 <message>
1279 <location filename="../configure.cpp" line="209"/>
1280 <source>Cache path not writeable. Leave path empty to default to systems temporary path.</source>
1281 <translation>נתיב המטמון אינו ניתן לכתיבה. השאר את הנתיב ריק על מנת להשתמש בנתיב הקבצים הזמניים לפי ברירת המחדל של המערכת.</translation>
1282 </message>
1283 <message>
1284 <location filename="../configure.cpp" line="228"/>
1285 <source>You need to fix the above errors before you can continue.</source>
1286 <translation>עליך לתקן את השגיאות לעיל לפני שאתה יכול להמשיך.</translation>
1287 </message>
1288 <message>
1289 <location filename="../configure.cpp" line="231"/>
1290 <source>Configuration error</source>
1291 <translation>שגיאת הגדרות</translation>
1292 </message>
1293</context>
1294<context>
1295 <name>ConfigForm</name>
1296 <message>
1297 <location filename="../configurefrm.ui" line="14"/>
1298 <source>Configuration</source>
1299 <translation>הגדרות</translation>
1300 </message>
1301 <message>
1302 <location filename="../configurefrm.ui" line="20"/>
1303 <source>Configure Rockbox Utility</source>
1304 <translation>הגדרות תוכנת השירות של רוקבוקס</translation>
1305 </message>
1306 <message>
1307 <location filename="../configurefrm.ui" line="35"/>
1308 <source>&amp;Device</source>
1309 <translation>&amp;נגן</translation>
1310 </message>
1311 <message>
1312 <location filename="../configurefrm.ui" line="41"/>
1313 <source>Select your device in the &amp;filesystem</source>
1314 <translation>בחר את הנגן שלך ב&amp;מערכת הקבצים</translation>
1315 </message>
1316 <message>
1317 <location filename="../configurefrm.ui" line="319"/>
1318 <source>&amp;Browse</source>
1319 <translation>&amp;עיון</translation>
1320 </message>
1321 <message>
1322 <location filename="../configurefrm.ui" line="72"/>
1323 <source>&amp;Select your audio player</source>
1324 <translation>&amp;בחר את נגן השמע שלך</translation>
1325 </message>
1326 <message>
1327 <location filename="../configurefrm.ui" line="58"/>
1328 <source>&amp;Refresh</source>
1329 <translation type="unfinished">&amp;רענן</translation>
1330 </message>
1331 <message>
1332 <location filename="../configurefrm.ui" line="95"/>
1333 <source>Show disabled targets</source>
1334 <translation>הצג נגנים שאינם מאופשרים</translation>
1335 </message>
1336 <message>
1337 <location filename="../configurefrm.ui" line="114"/>
1338 <source>&amp;Autodetect</source>
1339 <translation>&amp;זיהוי אוטומטי</translation>
1340 </message>
1341 <message>
1342 <location filename="../configurefrm.ui" line="136"/>
1343 <source>&amp;Proxy</source>
1344 <translation>&amp;פרוקסי</translation>
1345 </message>
1346 <message>
1347 <location filename="../configurefrm.ui" line="142"/>
1348 <source>&amp;No Proxy</source>
1349 <translation>&amp;ללא פרוקסי</translation>
1350 </message>
1351 <message>
1352 <location filename="../configurefrm.ui" line="152"/>
1353 <source>Use S&amp;ystem values</source>
1354 <translation>השתמש בהגדרות &amp;מערכת</translation>
1355 </message>
1356 <message>
1357 <location filename="../configurefrm.ui" line="159"/>
1358 <source>&amp;Manual Proxy settings</source>
1359 <translation>הגדרות פרוקסי &amp;ידניות</translation>
1360 </message>
1361 <message>
1362 <location filename="../configurefrm.ui" line="166"/>
1363 <source>Proxy Values</source>
1364 <translation>ערכי פרוקסי</translation>
1365 </message>
1366 <message>
1367 <location filename="../configurefrm.ui" line="172"/>
1368 <source>&amp;Host:</source>
1369 <translation>&amp;שרת:</translation>
1370 </message>
1371 <message>
1372 <location filename="../configurefrm.ui" line="182"/>
1373 <source>&amp;Port:</source>
1374 <translation>&amp;פורט:</translation>
1375 </message>
1376 <message>
1377 <location filename="../configurefrm.ui" line="199"/>
1378 <source>&amp;Username</source>
1379 <translation>&amp;שם משתמש</translation>
1380 </message>
1381 <message>
1382 <location filename="../configurefrm.ui" line="209"/>
1383 <source>Pass&amp;word</source>
1384 <translation>&amp;סיסמה</translation>
1385 </message>
1386 <message>
1387 <location filename="../configurefrm.ui" line="219"/>
1388 <source>Show</source>
1389 <translation type="unfinished"></translation>
1390 </message>
1391 <message>
1392 <location filename="../configurefrm.ui" line="260"/>
1393 <source>&amp;Language</source>
1394 <translation>ש&amp;פה</translation>
1395 </message>
1396 <message>
1397 <location filename="../configurefrm.ui" line="274"/>
1398 <source>Cac&amp;he</source>
1399 <translation>מ&amp;טמון</translation>
1400 </message>
1401 <message>
1402 <location filename="../configurefrm.ui" line="277"/>
1403 <source>Download cache settings</source>
1404 <translation>הגדרות זכרון מטמון של הורדות</translation>
1405 </message>
1406 <message>
1407 <location filename="../configurefrm.ui" line="283"/>
1408 <source>Rockbox Utility uses a local download cache to save network traffic. You can change the path to the cache and use it as local repository by enabling Offline mode.</source>
1409 <translation>תוכנת רוקבוקס משתמשת במטמון הורדות מקומי על מנת לחסוך בתעבורת רשת. באפשרותך לשנות את הנתיב למטמון ולהשתמש בו כמאגר מקומי, באמצעות איפשור מצב לא מקוון.</translation>
1410 </message>
1411 <message>
1412 <location filename="../configurefrm.ui" line="293"/>
1413 <source>Current cache size is %1</source>
1414 <translation>גודל מטמון נוכחי הוא %1</translation>
1415 </message>
1416 <message>
1417 <location filename="../configurefrm.ui" line="302"/>
1418 <source>P&amp;ath</source>
1419 <translation>&amp;נתיב</translation>
1420 </message>
1421 <message>
1422 <location filename="../configurefrm.ui" line="312"/>
1423 <source>Entering an invalid folder will reset the path to the systems temporary path.</source>
1424 <translation>הזנת נתיב שגוי תאפס את הנתיב לספריית הקבצים הזמניים של המערכת.</translation>
1425 </message>
1426 <message>
1427 <location filename="../configurefrm.ui" line="334"/>
1428 <source>Disable local &amp;download cache</source>
1429 <translation>ביטול מטמון &amp;הורדות מקומי</translation>
1430 </message>
1431 <message>
1432 <source>&lt;p&gt;This will try to use all information from the cache, even information about updates. Only use this option if you want to install without network connection. Note: you need to do the same install you want to perform later with network access first to download all required files to the cache.&lt;/p&gt;</source>
1433 <translation type="obsolete">&lt;p&gt;בצורה זו התוכנה תנסה להשתמש בכל במידע מהמטמון, אף כאשר מדובר במידע על עדכונים. השתמש באפשרות זו רק אם ברצונך להתקין ללא חיבור לרשת. הערה: אם ברצונך לבצע התקנות חוזרות ללא חיבור לרשת, עליך לבצע התקנה ראשונה במצב מקוון על מנת להוריד את כל הקבצים הדרושים למטמון.&lt;/p&gt;</translation>
1434 </message>
1435 <message>
1436 <source>O&amp;ffline mode</source>
1437 <translation type="obsolete">מצב &amp;לא מקוון</translation>
1438 </message>
1439 <message>
1440 <location filename="../configurefrm.ui" line="369"/>
1441 <source>Clean cache &amp;now</source>
1442 <translation>&amp;נקה מטמון עכשיו</translation>
1443 </message>
1444 <message>
1445 <location filename="../configurefrm.ui" line="385"/>
1446 <source>&amp;TTS &amp;&amp; Encoder</source>
1447 <translation>מנוע &amp;דיבור ומקודד</translation>
1448 </message>
1449 <message>
1450 <location filename="../configurefrm.ui" line="391"/>
1451 <source>TTS Engine</source>
1452 <translation>מנוע דיבור</translation>
1453 </message>
1454 <message>
1455 <location filename="../configurefrm.ui" line="397"/>
1456 <source>&amp;Select TTS Engine</source>
1457 <translation>&amp;בחר מנוע דיבור</translation>
1458 </message>
1459 <message>
1460 <location filename="../configurefrm.ui" line="410"/>
1461 <source>Configure TTS Engine</source>
1462 <translation>הגדרות מנוע דיבור</translation>
1463 </message>
1464 <message>
1465 <location filename="../configurefrm.ui" line="417"/>
1466 <location filename="../configurefrm.ui" line="468"/>
1467 <source>Configuration invalid!</source>
1468 <translation>הגדרות שגויות!</translation>
1469 </message>
1470 <message>
1471 <location filename="../configurefrm.ui" line="434"/>
1472 <source>Configure &amp;TTS</source>
1473 <translation>הגדרות מנוע &amp;דיבור</translation>
1474 </message>
1475 <message>
1476 <location filename="../configurefrm.ui" line="445"/>
1477 <source>Test TTS</source>
1478 <translation>בדוק מנוע דיבור</translation>
1479 </message>
1480 <message>
1481 <location filename="../configurefrm.ui" line="452"/>
1482 <source>&amp;Use string corrections for TTS</source>
1483 <translation type="unfinished"></translation>
1484 </message>
1485 <message>
1486 <location filename="../configurefrm.ui" line="462"/>
1487 <source>Encoder Engine</source>
1488 <translation>מנוע מקודד</translation>
1489 </message>
1490 <message>
1491 <location filename="../configurefrm.ui" line="485"/>
1492 <source>Configure &amp;Enc</source>
1493 <translation>הגדרות &amp;מקודד</translation>
1494 </message>
1495 <message>
1496 <location filename="../configurefrm.ui" line="496"/>
1497 <source>encoder name</source>
1498 <translation>שם מקודד</translation>
1499 </message>
1500 <message>
1501 <location filename="../configurefrm.ui" line="536"/>
1502 <source>&amp;Ok</source>
1503 <translation>&amp;אישור</translation>
1504 </message>
1505 <message>
1506 <location filename="../configurefrm.ui" line="547"/>
1507 <source>&amp;Cancel</source>
1508 <translation>&amp;ביטול</translation>
1509 </message>
1510</context>
1511<context>
1512 <name>Configure</name>
1513 <message>
1514 <location filename="../configure.cpp" line="589"/>
1515 <source>English</source>
1516 <comment>This is the localized language name, i.e. your language.</comment>
1517 <translation>עברית</translation>
1518 </message>
1519</context>
1520<context>
1521 <name>CreateVoiceFrm</name>
1522 <message>
1523 <location filename="../createvoicefrm.ui" line="17"/>
1524 <source>Create Voice File</source>
1525 <translation>צור קובץ הקראת תפריטים</translation>
1526 </message>
1527 <message>
1528 <location filename="../createvoicefrm.ui" line="42"/>
1529 <source>Select the Language you want to generate a voicefile for:</source>
1530 <translation>בחר את השפה עבור הינך מעונייך ליצור קובץ הקראת תפריטים:</translation>
1531 </message>
1532 <message>
1533 <location filename="../createvoicefrm.ui" line="55"/>
1534 <source>TTS:</source>
1535 <translation type="unfinished"></translation>
1536 </message>
1537 <message>
1538 <location filename="../createvoicefrm.ui" line="101"/>
1539 <source>Silence threshold</source>
1540 <translation type="unfinished"></translation>
1541 </message>
1542 <message>
1543 <location filename="../createvoicefrm.ui" line="163"/>
1544 <source>Language</source>
1545 <translation>שפה</translation>
1546 </message>
1547 <message>
1548 <location filename="../createvoicefrm.ui" line="49"/>
1549 <source>Generation settings</source>
1550 <translation>הגדרות יצירת קובץ הקראה</translation>
1551 </message>
1552 <message>
1553 <location filename="../createvoicefrm.ui" line="68"/>
1554 <source>Change</source>
1555 <translation>שינוי</translation>
1556 </message>
1557 <message>
1558 <location filename="../createvoicefrm.ui" line="139"/>
1559 <source>&amp;Install</source>
1560 <translation>&amp;התקנה</translation>
1561 </message>
1562 <message>
1563 <location filename="../createvoicefrm.ui" line="150"/>
1564 <source>&amp;Cancel</source>
1565 <translation>&amp;ביטול</translation>
1566 </message>
1567 <message>
1568 <location filename="../createvoicefrm.ui" line="88"/>
1569 <source>Wavtrim Threshold</source>
1570 <translation>ערך סף לקטעון</translation>
1571 </message>
1572</context>
1573<context>
1574 <name>CreateVoiceWindow</name>
1575 <message>
1576 <location filename="../createvoicewindow.cpp" line="100"/>
1577 <source>TTS error</source>
1578 <translation type="unfinished"></translation>
1579 </message>
1580 <message>
1581 <location filename="../createvoicewindow.cpp" line="101"/>
1582 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1583 <translation type="unfinished"></translation>
1584 </message>
1585 <message>
1586 <location filename="../createvoicewindow.cpp" line="105"/>
1587 <location filename="../createvoicewindow.cpp" line="108"/>
1588 <source>Engine: &lt;b&gt;%1&lt;/b&gt;</source>
1589 <translation type="unfinished"></translation>
1590 </message>
1591</context>
1592<context>
1593 <name>EncTtsCfgGui</name>
1594 <message>
1595 <location filename="../encttscfggui.cpp" line="45"/>
1596 <source>Waiting for engine...</source>
1597 <translation>ממתין למנוע...</translation>
1598 </message>
1599 <message>
1600 <location filename="../encttscfggui.cpp" line="95"/>
1601 <source>Ok</source>
1602 <translation>אישור</translation>
1603 </message>
1604 <message>
1605 <location filename="../encttscfggui.cpp" line="98"/>
1606 <source>Cancel</source>
1607 <translation>ביטול</translation>
1608 </message>
1609 <message>
1610 <location filename="../encttscfggui.cpp" line="197"/>
1611 <source>Browse</source>
1612 <translation>עיין</translation>
1613 </message>
1614 <message>
1615 <location filename="../encttscfggui.cpp" line="205"/>
1616 <source>Refresh</source>
1617 <translation>רענן</translation>
1618 </message>
1619 <message>
1620 <location filename="../encttscfggui.cpp" line="377"/>
1621 <source>Select executable</source>
1622 <translation type="unfinished"></translation>
1623 </message>
1624</context>
1625<context>
1626 <name>EncoderExe</name>
1627 <message>
1628 <location filename="../base/encoderexe.cpp" line="41"/>
1629 <source>Path to Encoder:</source>
1630 <translation type="unfinished">נתיב למקודד:</translation>
1631 </message>
1632 <message>
1633 <location filename="../base/encoderexe.cpp" line="43"/>
1634 <source>Encoder options:</source>
1635 <translation type="unfinished">אפשרויות קידוד:</translation>
1636 </message>
1637</context>
1638<context>
1639 <name>EncoderLame</name>
1640 <message>
1641 <location filename="../base/encoderlame.cpp" line="73"/>
1642 <location filename="../base/encoderlame.cpp" line="83"/>
1643 <source>LAME</source>
1644 <translation type="unfinished"></translation>
1645 </message>
1646 <message>
1647 <location filename="../base/encoderlame.cpp" line="75"/>
1648 <source>Volume</source>
1649 <translation type="unfinished"></translation>
1650 </message>
1651 <message>
1652 <location filename="../base/encoderlame.cpp" line="79"/>
1653 <source>Quality</source>
1654 <translation type="unfinished"></translation>
1655 </message>
1656 <message>
1657 <location filename="../base/encoderlame.cpp" line="83"/>
1658 <source>Could not find libmp3lame!</source>
1659 <translation type="unfinished"></translation>
1660 </message>
1661</context>
1662<context>
1663 <name>EncoderRbSpeex</name>
1664 <message>
1665 <location filename="../base/encoderrbspeex.cpp" line="34"/>
1666 <source>Volume:</source>
1667 <translation type="unfinished">עוצמת קול:</translation>
1668 </message>
1669 <message>
1670 <location filename="../base/encoderrbspeex.cpp" line="36"/>
1671 <source>Quality:</source>
1672 <translation type="unfinished">איכות:</translation>
1673 </message>
1674 <message>
1675 <location filename="../base/encoderrbspeex.cpp" line="38"/>
1676 <source>Complexity:</source>
1677 <translation type="unfinished">מורכבות:</translation>
1678 </message>
1679 <message>
1680 <location filename="../base/encoderrbspeex.cpp" line="40"/>
1681 <source>Use Narrowband:</source>
1682 <translation type="unfinished">השתמש בפס-צר:</translation>
1683 </message>
1684</context>
1685<context>
1686 <name>InfoWidget</name>
1687 <message>
1688 <location filename="../gui/infowidget.cpp" line="30"/>
1689 <location filename="../gui/infowidget.cpp" line="107"/>
1690 <source>File</source>
1691 <translation type="unfinished">קובץ</translation>
1692 </message>
1693 <message>
1694 <location filename="../gui/infowidget.cpp" line="30"/>
1695 <location filename="../gui/infowidget.cpp" line="107"/>
1696 <source>Version</source>
1697 <translation type="unfinished">גירסה</translation>
1698 </message>
1699</context>
1700<context>
1701 <name>InfoWidgetFrm</name>
1702 <message>
1703 <location filename="../gui/infowidgetfrm.ui" line="14"/>
1704 <source>Info</source>
1705 <translation type="unfinished">מידע</translation>
1706 </message>
1707 <message>
1708 <location filename="../gui/infowidgetfrm.ui" line="20"/>
1709 <source>Currently installed packages.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; if you manually installed packages this might not be correct!</source>
1710 <translation type="unfinished">חבילות מותקנות. &lt;br/&gt;&lt;b&gt;שים לב:&lt;/b&gt; אם התקנת חבילות ידנית, מידע זה עשוי שלא להיות מדויק!</translation>
1711 </message>
1712 <message>
1713 <location filename="../gui/infowidgetfrm.ui" line="34"/>
1714 <source>Package</source>
1715 <translation type="unfinished"></translation>
1716 </message>
1717</context>
1718<context>
1719 <name>InstallTalkFrm</name>
1720 <message>
1721 <location filename="../installtalkfrm.ui" line="17"/>
1722 <source>Install Talk Files</source>
1723 <translation>התקן קבצי הקראת תפריטים</translation>
1724 </message>
1725 <message>
1726 <location filename="../installtalkfrm.ui" line="52"/>
1727 <source>Generate for files</source>
1728 <translation type="unfinished"></translation>
1729 </message>
1730 <message>
1731 <location filename="../installtalkfrm.ui" line="78"/>
1732 <source>TTS profile:</source>
1733 <translation>פרופיל מנוע דיבור:</translation>
1734 </message>
1735 <message>
1736 <location filename="../installtalkfrm.ui" line="85"/>
1737 <source>Generate for folders</source>
1738 <translation type="unfinished"></translation>
1739 </message>
1740 <message>
1741 <location filename="../installtalkfrm.ui" line="95"/>
1742 <source>Recurse into folders</source>
1743 <translation type="unfinished"></translation>
1744 </message>
1745 <message>
1746 <location filename="../installtalkfrm.ui" line="111"/>
1747 <source>Change</source>
1748 <translation>שינוי</translation>
1749 </message>
1750 <message>
1751 <location filename="../installtalkfrm.ui" line="118"/>
1752 <source>Ignore files</source>
1753 <translation type="unfinished"></translation>
1754 </message>
1755 <message>
1756 <location filename="../installtalkfrm.ui" line="128"/>
1757 <source>Skip existing</source>
1758 <translation type="unfinished"></translation>
1759 </message>
1760 <message>
1761 <location filename="../installtalkfrm.ui" line="170"/>
1762 <source>Select folders for Talkfile generation (Ctrl for multiselect)</source>
1763 <translation type="unfinished"></translation>
1764 </message>
1765 <message>
1766 <location filename="../installtalkfrm.ui" line="36"/>
1767 <source>Generation options</source>
1768 <translation>אפשרויות יצירת קבצי הקראת תפריטים</translation>
1769 </message>
1770 <message>
1771 <location filename="../installtalkfrm.ui" line="42"/>
1772 <source>Strip Extensions</source>
1773 <translation>הסר סיומות קבצים</translation>
1774 </message>
1775 <message>
1776 <location filename="../installtalkfrm.ui" line="143"/>
1777 <source>&amp;Install</source>
1778 <translation>&amp;התקנה</translation>
1779 </message>
1780 <message>
1781 <location filename="../installtalkfrm.ui" line="154"/>
1782 <source>&amp;Cancel</source>
1783 <translation>&amp;ביטול</translation>
1784 </message>
1785</context>
1786<context>
1787 <name>InstallTalkWindow</name>
1788 <message>
1789 <location filename="../installtalkwindow.cpp" line="96"/>
1790 <source>Empty selection</source>
1791 <translation type="unfinished"></translation>
1792 </message>
1793 <message>
1794 <location filename="../installtalkwindow.cpp" line="97"/>
1795 <source>No files or folders selected. Please select files or folders first.</source>
1796 <translation type="unfinished"></translation>
1797 </message>
1798 <message>
1799 <location filename="../installtalkwindow.cpp" line="137"/>
1800 <source>TTS error</source>
1801 <translation type="unfinished"></translation>
1802 </message>
1803 <message>
1804 <location filename="../installtalkwindow.cpp" line="138"/>
1805 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1806 <translation type="unfinished"></translation>
1807 </message>
1808</context>
1809<context>
1810 <name>ManualWidget</name>
1811 <message>
1812 <location filename="../gui/manualwidget.cpp" line="44"/>
1813 <source>&lt;a href=&apos;%1&apos;&gt;PDF Manual&lt;/a&gt;</source>
1814 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;מדריך PDF&lt;/a&gt;</translation>
1815 </message>
1816 <message>
1817 <location filename="../gui/manualwidget.cpp" line="46"/>
1818 <source>&lt;a href=&apos;%1&apos;&gt;HTML Manual (opens in browser)&lt;/a&gt;</source>
1819 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;מדריך HTML (נפתח בדפדפן)&lt;/a&gt;</translation>
1820 </message>
1821 <message>
1822 <location filename="../gui/manualwidget.cpp" line="50"/>
1823 <source>Select a device for a link to the correct manual</source>
1824 <translation type="unfinished">בחר בנגן בשביל קישור למדריך המתאים</translation>
1825 </message>
1826 <message>
1827 <location filename="../gui/manualwidget.cpp" line="51"/>
1828 <source>&lt;a href=&apos;%1&apos;&gt;Manual Overview&lt;/a&gt;</source>
1829 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;רשימת כל מדריכי המשתמש&lt;/a&gt;</translation>
1830 </message>
1831 <message>
1832 <location filename="../gui/manualwidget.cpp" line="62"/>
1833 <source>Confirm download</source>
1834 <translation type="unfinished">אשר הורדה</translation>
1835 </message>
1836 <message>
1837 <location filename="../gui/manualwidget.cpp" line="63"/>
1838 <source>Do you really want to download the manual? The manual will be saved to the root folder of your player.</source>
1839 <translation type="unfinished">האם באמת ברצונך להוריד את המדריך למשתמש? המדריך יישמר בספרייה הראשית של הנגן שלך.</translation>
1840 </message>
1841</context>
1842<context>
1843 <name>ManualWidgetFrm</name>
1844 <message>
1845 <location filename="../gui/manualwidgetfrm.ui" line="14"/>
1846 <source>Manual</source>
1847 <translation type="unfinished"></translation>
1848 </message>
1849 <message>
1850 <location filename="../gui/manualwidgetfrm.ui" line="20"/>
1851 <source>Read the manual</source>
1852 <translation type="unfinished">קרא את המדריך למשתמש</translation>
1853 </message>
1854 <message>
1855 <location filename="../gui/manualwidgetfrm.ui" line="26"/>
1856 <source>PDF manual</source>
1857 <translation type="unfinished">PDF מדריך למשתמש מסוג</translation>
1858 </message>
1859 <message>
1860 <location filename="../gui/manualwidgetfrm.ui" line="39"/>
1861 <source>HTML manual</source>
1862 <translation type="unfinished">HTML מדריך למשתמש מסוג</translation>
1863 </message>
1864 <message>
1865 <location filename="../gui/manualwidgetfrm.ui" line="55"/>
1866 <source>Download the manual</source>
1867 <translation type="unfinished">הורד את המדריך למשתמש</translation>
1868 </message>
1869 <message>
1870 <location filename="../gui/manualwidgetfrm.ui" line="63"/>
1871 <source>&amp;PDF version</source>
1872 <translation type="unfinished">&amp;גירסת PDF</translation>
1873 </message>
1874 <message>
1875 <location filename="../gui/manualwidgetfrm.ui" line="70"/>
1876 <source>&amp;HTML version (zip file)</source>
1877 <translation type="unfinished">&amp;גירסת HTML (קובץ מכווץ)</translation>
1878 </message>
1879 <message>
1880 <location filename="../gui/manualwidgetfrm.ui" line="92"/>
1881 <source>Down&amp;load</source>
1882 <translation type="unfinished">&amp;הורדה</translation>
1883 </message>
1884</context>
1885<context>
1886 <name>MsPackUtil</name>
1887 <message>
1888 <location filename="../base/mspackutil.cpp" line="101"/>
1889 <source>Creating output path failed</source>
1890 <translation type="unfinished"></translation>
1891 </message>
1892 <message>
1893 <location filename="../base/mspackutil.cpp" line="109"/>
1894 <source>Error during CAB operation</source>
1895 <translation type="unfinished"></translation>
1896 </message>
1897</context>
1898<context>
1899 <name>PreviewFrm</name>
1900 <message>
1901 <location filename="../previewfrm.ui" line="16"/>
1902 <source>Preview</source>
1903 <translation>תצוגה מקדימה</translation>
1904 </message>
1905</context>
1906<context>
1907 <name>ProgressLoggerFrm</name>
1908 <message>
1909 <location filename="../progressloggerfrm.ui" line="13"/>
1910 <location filename="../progressloggerfrm.ui" line="19"/>
1911 <source>Progress</source>
1912 <translation>התקדמות</translation>
1913 </message>
1914 <message>
1915 <location filename="../progressloggerfrm.ui" line="58"/>
1916 <source>Save Log</source>
1917 <translation>שמור לוג</translation>
1918 </message>
1919 <message>
1920 <location filename="../progressloggerfrm.ui" line="82"/>
1921 <source>&amp;Abort</source>
1922 <translation>&amp;ביטול</translation>
1923 </message>
1924 <message>
1925 <location filename="../progressloggerfrm.ui" line="32"/>
1926 <source>progresswindow</source>
1927 <translation>חלון התקדמות</translation>
1928 </message>
1929</context>
1930<context>
1931 <name>ProgressLoggerGui</name>
1932 <message>
1933 <location filename="../progressloggergui.cpp" line="122"/>
1934 <source>&amp;Ok</source>
1935 <translation>&amp;אישור</translation>
1936 </message>
1937 <message>
1938 <location filename="../progressloggergui.cpp" line="146"/>
1939 <source>Save system trace log</source>
1940 <translation>שמור קובץ יומן מערכת</translation>
1941 </message>
1942 <message>
1943 <location filename="../progressloggergui.cpp" line="104"/>
1944 <source>&amp;Abort</source>
1945 <translation>&amp;ביטול</translation>
1946 </message>
1947</context>
1948<context>
1949 <name>QObject</name>
1950 <message>
1951 <location filename="../configure.cpp" line="625"/>
1952 <location filename="../main.cpp" line="83"/>
1953 <source>LTR</source>
1954 <extracomment>This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.
1955----------
1956This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.</extracomment>
1957 <translation>RTL</translation>
1958 </message>
1959 <message>
1960 <location filename="../base/system.cpp" line="385"/>
1961 <source>(unknown vendor name) </source>
1962 <translation type="unfinished"></translation>
1963 </message>
1964 <message>
1965 <location filename="../base/system.cpp" line="403"/>
1966 <source>(unknown product name)</source>
1967 <translation type="unfinished"></translation>
1968 </message>
1969 <message>
1970 <location filename="../base/bootloaderinstallhelper.cpp" line="80"/>
1971 <source>Bootloader installation is almost complete. Installation &lt;b&gt;requires&lt;/b&gt; you to perform the following steps manually:</source>
1972 <translation type="unfinished">התקנת מנהל האיתחול כמעט הסתיימה. ההתקנה &lt;b&gt;מחייבת&lt;/b&gt; שתבצע את הצעדים הבאים באופן ידני:</translation>
1973 </message>
1974 <message>
1975 <location filename="../base/bootloaderinstallhelper.cpp" line="86"/>
1976 <source>&lt;li&gt;Safely remove your player.&lt;/li&gt;</source>
1977 <translation type="unfinished">&lt;li&gt;נתק את הנגן שלך בזהירות.&lt;/li&gt;</translation>
1978 </message>
1979 <message>
1980 <location filename="../base/bootloaderinstallhelper.cpp" line="91"/>
1981 <source>&lt;li&gt;Reboot your player into the original firmware.&lt;/li&gt;&lt;li&gt;Perform a firmware upgrade using the update functionality of the original firmware. Please refer to your player&apos;s manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before starting the firmware update process.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1982 <translation type="unfinished"></translation>
1983 </message>
1984 <message>
1985 <location filename="../base/bootloaderinstallhelper.cpp" line="102"/>
1986 <source>&lt;li&gt;Remove any previously inserted microSD card&lt;/li&gt;</source>
1987 <translation type="unfinished"></translation>
1988 </message>
1989 <message>
1990 <location filename="../base/bootloaderinstallhelper.cpp" line="103"/>
1991 <source>&lt;li&gt;Disconnect your player. The player will reboot and perform an update of the original firmware. Please refer to your players manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before disconnecting the player.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1992 <translation type="unfinished"></translation>
1993 </message>
1994 <message>
1995 <location filename="../base/bootloaderinstallhelper.cpp" line="114"/>
1996 <source>&lt;li&gt;Turn the player off&lt;/li&gt;&lt;li&gt;Insert the charger&lt;/li&gt;</source>
1997 <translation type="unfinished">&lt;/il&gt;כבה את הנגן&lt;li&gt;&lt;/il&gt;הכנס את המטען&lt;li&gt;</translation>
1998 </message>
1999 <message>
2000 <location filename="../base/bootloaderinstallhelper.cpp" line="119"/>
2001 <source>&lt;li&gt;Unplug USB and power adaptors&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to turn the player off&lt;/li&gt;&lt;li&gt;Toggle the battery switch on the player&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to boot into Rockbox&lt;/li&gt;</source>
2002 <translation type="unfinished">&lt;/il&gt;נתן את ה- USB ואת ספקי הכח&lt;li&gt;לחץ על &lt;i&gt;Power&lt;/i&gt; על מנת לכבות את הנגן&lt;/il&gt;&lt;li&gt;הזז את מתג הסוללה על הנגן&lt;/il&gt;&lt;li&gt;לחץ על &lt;i&gt;Power&lt;/i&gt; כדי לאתחל לתוך רוקבוקס&lt;/il&gt;&lt;li&gt;</translation>
2003 </message>
2004 <message>
2005 <location filename="../base/bootloaderinstallhelper.cpp" line="125"/>
2006 <source>&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You can safely install other parts first, but the above steps are &lt;b&gt;required&lt;/b&gt; to finish the installation!&lt;/p&gt;</source>
2007 <translation type="unfinished">&lt;p&gt;&lt;b&gt;שים לב:&lt;/b&gt; אתה יכול להתקין חלקים אחרים קודם לכן ללא חשש, אבל הצעדים לעיל הינם &lt;b&gt;נדרשים&lt;/b&gt; על מנת לסיים את ההתקנה!&lt;/p&gt;</translation>
2008 </message>
2009</context>
2010<context>
2011 <name>QuaZipFile</name>
2012 <message>
2013 <location filename="../quazip/quazipfile.cpp" line="141"/>
2014 <source>ZIP/UNZIP API error %1</source>
2015 <translation type="unfinished"></translation>
2016 </message>
2017</context>
2018<context>
2019 <name>RbUtilQt</name>
2020 <message>
2021 <location filename="../rbutilqt.cpp" line="224"/>
2022 <source>Downloading build information, please wait ...</source>
2023 <translation>מוריד מידע גירסאות, אנא המתן...</translation>
2024 </message>
2025 <message>
2026 <location filename="../rbutilqt.cpp" line="235"/>
2027 <source>Can&apos;t get version information!</source>
2028 <translation>לא מצליח לקבל את מידע הגירסאות!</translation>
2029 </message>
2030 <message>
2031 <location filename="../rbutilqt.cpp" line="237"/>
2032 <source>Can&apos;t get version information.
2033Network error: %1. Please check your network and proxy settings.</source>
2034 <translation>לא מצליח להשיג מידע גירסה.
2035שגיאת רשת: %1. אנא בדוק את הרשת והגדרות הפרוקסי.</translation>
2036 </message>
2037 <message>
2038 <location filename="../rbutilqt.cpp" line="329"/>
2039 <source>New installation</source>
2040 <translation>התקנה חדשה</translation>
2041 </message>
2042 <message>
2043 <location filename="../rbutilqt.cpp" line="330"/>
2044 <source>This is a new installation of Rockbox Utility, or a new version. The configuration dialog will now open to allow you to setup the program, or review your settings.</source>
2045 <translation>זוהי התקנה חדשה של תוכנת השירות של רוקבוקס, או גירסה חדשה. תיבת השיח של ההגדרות תיפתח כעת על מנת לאפשר לך להגדיר את התוכנית, או לעבור על ההגדרות הקיימות.</translation>
2046 </message>
2047 <message>
2048 <location filename="../rbutilqt.cpp" line="337"/>
2049 <location filename="../rbutilqt.cpp" line="642"/>
2050 <source>Configuration error</source>
2051 <translation>שגיאת הגדרות</translation>
2052 </message>
2053 <message>
2054 <location filename="../rbutilqt.cpp" line="338"/>
2055 <source>Your configuration is invalid. This is most likely due to a changed device path. The configuration dialog will now open to allow you to correct the problem.</source>
2056 <translation>ההגדרות שלך שגויות. לרוב הדבר נובע מכך שהנתיב לנגן השתנה. תיבת השיח של ההגדרות תיפתח כעת, על מנת לאפשר לך לתקן את הבעיה.</translation>
2057 </message>
2058 <message>
2059 <location filename="../rbutilqt.cpp" line="249"/>
2060 <source>Download build information finished.</source>
2061 <translation>הורדת מידע הגירסאות הסתיימה.</translation>
2062 </message>
2063 <message>
2064 <location filename="../rbutilqt.cpp" line="450"/>
2065 <source>Confirm Installation</source>
2066 <translation>אשר התקנה</translation>
2067 </message>
2068 <message>
2069 <location filename="../rbutilqt.cpp" line="582"/>
2070 <source>Mount point is wrong!</source>
2071 <translation>נקודת העגינה הינה שגויה!</translation>
2072 </message>
2073 <message>
2074 <location filename="../rbutilqt.cpp" line="430"/>
2075 <source>No Rockbox installation found</source>
2076 <translation type="unfinished"></translation>
2077 </message>
2078 <message>
2079 <location filename="../rbutilqt.cpp" line="416"/>
2080 <source>Warning</source>
2081 <translation>אזהרה</translation>
2082 </message>
2083 <message>
2084 <location filename="../rbutilqt.cpp" line="417"/>
2085 <source>The Application is still downloading Information about new Builds. Please try again shortly.</source>
2086 <translation>תוכנית השרות עדיין מורידה מידע לגבי גירסאות חדשות. אנא נסה שוב בקרוב.</translation>
2087 </message>
2088 <message>
2089 <location filename="../rbutilqt.cpp" line="431"/>
2090 <source>Could not determine the installed Rockbox version. Please install a Rockbox build before installing voice files.</source>
2091 <translation type="unfinished"></translation>
2092 </message>
2093 <message>
2094 <location filename="../rbutilqt.cpp" line="451"/>
2095 <source>Do you really want to install the voice file?</source>
2096 <translation>האם באמת ברצונך להתקין את קובץ הקראת התפריטים?</translation>
2097 </message>
2098 <message>
2099 <location filename="../rbutilqt.cpp" line="439"/>
2100 <source>No voice file available</source>
2101 <translation type="unfinished"></translation>
2102 </message>
2103 <message>
2104 <location filename="../rbutilqt.cpp" line="440"/>
2105 <source>The installed version of Rockbox is a development version. Pre-built voices are only available for release versions of Rockbox. Please generate a voice yourself using the &quot;Create voice file&quot; functionality.</source>
2106 <translation type="unfinished"></translation>
2107 </message>
2108 <message>
2109 <location filename="../rbutilqt.cpp" line="512"/>
2110 <source>Confirm Uninstallation</source>
2111 <translation>אשר הסרת התקנה</translation>
2112 </message>
2113 <message>
2114 <location filename="../rbutilqt.cpp" line="513"/>
2115 <source>Do you really want to uninstall the Bootloader?</source>
2116 <translation>האם באמת ברצונך להסיר את מנהל האיתחול?</translation>
2117 </message>
2118 <message>
2119 <location filename="../rbutilqt.cpp" line="528"/>
2120 <source>No uninstall method for this target known.</source>
2121 <translation type="unfinished"></translation>
2122 </message>
2123 <message>
2124 <location filename="../rbutilqt.cpp" line="542"/>
2125 <source>Rockbox Utility can not uninstall the bootloader on this target. Try a normal firmware update to remove the booloader.</source>
2126 <translation type="unfinished"></translation>
2127 </message>
2128 <message>
2129 <location filename="../rbutilqt.cpp" line="550"/>
2130 <source>No Rockbox bootloader found.</source>
2131 <translation type="unfinished"></translation>
2132 </message>
2133 <message>
2134 <location filename="../rbutilqt.cpp" line="568"/>
2135 <source>Confirm installation</source>
2136 <translation>אשר התקנה</translation>
2137 </message>
2138 <message>
2139 <location filename="../rbutilqt.cpp" line="569"/>
2140 <source>Do you really want to install Rockbox Utility to your player? After installation you can run it from the players hard drive.</source>
2141 <translation>האם באמת ברצונך להתקין את תוכנית השרות של רוקבוקס לנגן שלך? לאחר ההתקנה תוכל להריץ אותה מהתקן האיחסון של הנגן.</translation>
2142 </message>
2143 <message>
2144 <location filename="../rbutilqt.cpp" line="578"/>
2145 <source>Installing Rockbox Utility</source>
2146 <translation>מתקין את תוכנת השרות של רוקבוקס</translation>
2147 </message>
2148 <message>
2149 <location filename="../rbutilqt.cpp" line="596"/>
2150 <source>Error installing Rockbox Utility</source>
2151 <translation>שגיאה בהתקנת תוכנת השרות של רוקבוקס</translation>
2152 </message>
2153 <message>
2154 <location filename="../rbutilqt.cpp" line="600"/>
2155 <source>Installing user configuration</source>
2156 <translation>מתקין הגדרות משתמש</translation>
2157 </message>
2158 <message>
2159 <location filename="../rbutilqt.cpp" line="604"/>
2160 <source>Error installing user configuration</source>
2161 <translation>שגיאה בהתקנת הגדרות משתמש</translation>
2162 </message>
2163 <message>
2164 <location filename="../rbutilqt.cpp" line="608"/>
2165 <source>Successfully installed Rockbox Utility.</source>
2166 <translation>התקנת תוכנית השרות של רוקבוקס הסתיימה בהצלחה.</translation>
2167 </message>
2168 <message>
2169 <location filename="../rbutilqt.cpp" line="643"/>
2170 <source>Your configuration is invalid. Please go to the configuration dialog and make sure the selected values are correct.</source>
2171 <translation>ההגדרות שלך שגויות. אנא עבור לתיבת השיח של ההגדרות וודא שהערכים הנכונים נבחרו.</translation>
2172 </message>
2173 <message>
2174 <location filename="../rbutilqt.cpp" line="664"/>
2175 <source>Checking for update ...</source>
2176 <translation type="unfinished"></translation>
2177 </message>
2178 <message>
2179 <location filename="../rbutilqt.cpp" line="729"/>
2180 <source>RockboxUtility Update available</source>
2181 <translation>קיים עידכון של תוכנת השירות של רוקבוקס</translation>
2182 </message>
2183 <message>
2184 <location filename="../rbutilqt.cpp" line="730"/>
2185 <source>&lt;b&gt;New RockboxUtility Version available.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Download it from here: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</source>
2186 <translation>&lt;b&gt;קיימת גירסה חדשה של תוכנית השרות&lt;/b&gt; &lt;br&gt;&lt;br&gt;ניתן להורידה מכאן: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</translation>
2187 </message>
2188 <message>
2189 <location filename="../rbutilqt.cpp" line="733"/>
2190 <source>New version of Rockbox Utility available.</source>
2191 <translation type="unfinished"></translation>
2192 </message>
2193 <message>
2194 <location filename="../rbutilqt.cpp" line="736"/>
2195 <source>Rockbox Utility is up to date.</source>
2196 <translation type="unfinished"></translation>
2197 </message>
2198 <message>
2199 <location filename="../rbutilqt.cpp" line="759"/>
2200 <source>Device ejected</source>
2201 <translation type="unfinished"></translation>
2202 </message>
2203 <message>
2204 <location filename="../rbutilqt.cpp" line="760"/>
2205 <source>Device successfully ejected. You may now disconnect the player from the PC.</source>
2206 <translation type="unfinished"></translation>
2207 </message>
2208 <message>
2209 <location filename="../rbutilqt.cpp" line="764"/>
2210 <source>Ejecting failed</source>
2211 <translation type="unfinished"></translation>
2212 </message>
2213 <message>
2214 <location filename="../rbutilqt.cpp" line="765"/>
2215 <source>Ejecting the device failed. Please make sure no programs are accessing files on the device. If ejecting still fails please use your computers eject funtionality.</source>
2216 <translation type="unfinished"></translation>
2217 </message>
2218 <message>
2219 <location filename="../rbutilqt.cpp" line="236"/>
2220 <source>Network error</source>
2221 <translation>שגיאת רשת</translation>
2222 </message>
2223 <message>
2224 <location filename="../rbutilqt.cpp" line="110"/>
2225 <source>Wine detected!</source>
2226 <translation>Wine זוהתה!</translation>
2227 </message>
2228 <message>
2229 <location filename="../rbutilqt.cpp" line="111"/>
2230 <source>It seems you are trying to run this program under Wine. Please don&apos;t do this, running under Wine will fail. Use the native Linux binary instead.</source>
2231 <translation>נראה שאתה מנסה להריץ את תוכנה זו תחת Wine. אנא הימנע מכך, כיוון שהריצה תיכשל. השתמש בקבצים הבינאריים של לינוקס במקום.</translation>
2232 </message>
2233</context>
2234<context>
2235 <name>RbUtilQtFrm</name>
2236 <message>
2237 <location filename="../rbutilqtfrm.ui" line="14"/>
2238 <source>Rockbox Utility</source>
2239 <translation>תוכנת השרות של רוקבוקס</translation>
2240 </message>
2241 <message>
2242 <location filename="../rbutilqtfrm.ui" line="31"/>
2243 <source>Device</source>
2244 <translation>נגן</translation>
2245 </message>
2246 <message>
2247 <location filename="../rbutilqtfrm.ui" line="92"/>
2248 <source>&amp;Change</source>
2249 <translation>&amp;שינוי</translation>
2250 </message>
2251 <message>
2252 <location filename="../rbutilqtfrm.ui" line="163"/>
2253 <source>Welcome</source>
2254 <translation>ברוכים הבאים</translation>
2255 </message>
2256 <message>
2257 <location filename="../rbutilqtfrm.ui" line="160"/>
2258 <location filename="../rbutilqtfrm.ui" line="658"/>
2259 <source>&amp;Installation</source>
2260 <translation>&amp;התקנה</translation>
2261 </message>
2262 <message>
2263 <location filename="../rbutilqtfrm.ui" line="168"/>
2264 <location filename="../rbutilqtfrm.ui" line="450"/>
2265 <source>&amp;Accessibility</source>
2266 <translation>&amp;נגישות</translation>
2267 </message>
2268 <message>
2269 <location filename="../rbutilqtfrm.ui" line="171"/>
2270 <source>Install accessibility add-ons</source>
2271 <translation>התקנת תוסף נגישות</translation>
2272 </message>
2273 <message>
2274 <location filename="../rbutilqtfrm.ui" line="177"/>
2275 <source>Install Voice files</source>
2276 <translation>התקנת קבצי הקראת תפריטים</translation>
2277 </message>
2278 <message>
2279 <location filename="../rbutilqtfrm.ui" line="194"/>
2280 <source>&lt;b&gt;Install Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so if you installed the voice file Rockbox will speak.</source>
2281 <translation>&lt;b&gt;התקנת קבצי הקראת תפריטים&lt;/b&gt;&lt;br/&gt;קבצי הקראת תפריטים נחוצים על מנת להקריא את ממשק המשתמש. הקראה מופעלת כברירת מחדל, כך שאם התקנת את קבצי הקראת התפריטים, רוקבוקס תקריא אותם.</translation>
2282 </message>
2283 <message>
2284 <location filename="../rbutilqtfrm.ui" line="204"/>
2285 <source>Install Talk files</source>
2286 <translation>התקנת קבצי דיבור</translation>
2287 </message>
2288 <message>
2289 <location filename="../rbutilqtfrm.ui" line="221"/>
2290 <source>&lt;b&gt;Create Talk Files&lt;/b&gt;&lt;br/&gt;Talkfiles are needed to let Rockbox speak File and Foldernames</source>
2291 <translation>&lt;b&gt;יצירת קבצי דיבור&lt;/b&gt;&lt;br/&gt;קבצי דיבור נחוצים על מנת לתת לרוקבוקס להקריא שמות קבצים וספריות</translation>
2292 </message>
2293 <message>
2294 <location filename="../rbutilqtfrm.ui" line="254"/>
2295 <source>Create Voice files</source>
2296 <translation>יצירת קבצי קול</translation>
2297 </message>
2298 <message>
2299 <location filename="../rbutilqtfrm.ui" line="271"/>
2300 <source>&lt;b&gt;Create Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so
2301 if you installed the voice file Rockbox will speak.</source>
2302 <translation>&lt;b&gt;יצירת קבצי הקראת התפריטים&lt;/b&gt;&lt;br/&gt;קבצי קול נחוצים על מנת לגרום לרוקבוקס להקריא את ממשק המשתמש. הקראה מאופשרת כברירת מחדל, כך שאם התקנת את קבצי הקראת התפריטים, רוקבוקס תקריא אותם.</translation>
2303 </message>
2304 <message>
2305 <location filename="../rbutilqtfrm.ui" line="458"/>
2306 <source>&amp;Uninstallation</source>
2307 <translation>ה&amp;סרת התקנה</translation>
2308 </message>
2309 <message>
2310 <location filename="../rbutilqtfrm.ui" line="286"/>
2311 <location filename="../rbutilqtfrm.ui" line="319"/>
2312 <source>Uninstall Rockbox</source>
2313 <translation>הסרת התקנת רוקבוקס</translation>
2314 </message>
2315 <message>
2316 <location filename="../rbutilqtfrm.ui" line="121"/>
2317 <source>mountpoint unknown or invalid</source>
2318 <translation type="unfinished"></translation>
2319 </message>
2320 <message>
2321 <location filename="../rbutilqtfrm.ui" line="114"/>
2322 <source>Mountpoint:</source>
2323 <translation type="unfinished"></translation>
2324 </message>
2325 <message>
2326 <location filename="../rbutilqtfrm.ui" line="72"/>
2327 <source>device unknown or invalid</source>
2328 <translation type="unfinished"></translation>
2329 </message>
2330 <message>
2331 <location filename="../rbutilqtfrm.ui" line="65"/>
2332 <source>Device:</source>
2333 <translation type="unfinished"></translation>
2334 </message>
2335 <message>
2336 <location filename="../rbutilqtfrm.ui" line="103"/>
2337 <source>&amp;Eject</source>
2338 <translation type="unfinished"></translation>
2339 </message>
2340 <message>
2341 <location filename="../rbutilqtfrm.ui" line="283"/>
2342 <source>Backup &amp;&amp; &amp;Uninstallation</source>
2343 <translation type="unfinished"></translation>
2344 </message>
2345 <message>
2346 <location filename="../rbutilqtfrm.ui" line="292"/>
2347 <source>Uninstall Bootloader</source>
2348 <translation>הסרת מנהל האיתחול</translation>
2349 </message>
2350 <message>
2351 <location filename="../rbutilqtfrm.ui" line="309"/>
2352 <source>&lt;b&gt;Remove the bootloader&lt;/b&gt;&lt;br/&gt;After removing the bootloader you won&apos;t be able to start Rockbox.</source>
2353 <translation>&lt;b&gt;הסרת מנהל האיתחול&lt;/b&gt;&lt;br/&gt;לאחר הסרת מנהל האיתחול לא תוכל להפעיל את רוקבוקס.</translation>
2354 </message>
2355 <message>
2356 <location filename="../rbutilqtfrm.ui" line="336"/>
2357 <source>&lt;b&gt;Uninstall Rockbox from your audio player.&lt;/b&gt;&lt;br/&gt;This will leave the bootloader in place (you need to remove it manually).</source>
2358 <translation>&lt;b&gt;הסרת רוקבוקס מהנגן שלך&lt;/b&gt;&lt;br/&gt;מנהל האתחול ישאר במקומו (יהיה עליך להסירו ידנית).</translation>
2359 </message>
2360 <message>
2361 <location filename="../rbutilqtfrm.ui" line="349"/>
2362 <source>Backup</source>
2363 <translation type="unfinished">גיבוי</translation>
2364 </message>
2365 <message>
2366 <location filename="../rbutilqtfrm.ui" line="366"/>
2367 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup current installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Create a backup by archiving the contents of the Rockbox installation folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2368 <translation type="unfinished"></translation>
2369 </message>
2370 <message>
2371 <location filename="../rbutilqtfrm.ui" line="393"/>
2372 <source>&amp;Manual</source>
2373 <translation>מ&amp;דריך למשתמש</translation>
2374 </message>
2375 <message>
2376 <location filename="../rbutilqtfrm.ui" line="396"/>
2377 <source>View and download the manual</source>
2378 <translation>צפה והורד את המדריך למשתמש</translation>
2379 </message>
2380 <message>
2381 <location filename="../rbutilqtfrm.ui" line="401"/>
2382 <source>Inf&amp;o</source>
2383 <translation>&amp;מידע</translation>
2384 </message>
2385 <message>
2386 <location filename="../rbutilqtfrm.ui" line="419"/>
2387 <source>&amp;File</source>
2388 <translation>&amp;קובץ</translation>
2389 </message>
2390 <message>
2391 <location filename="../rbutilqtfrm.ui" line="432"/>
2392 <source>&amp;Troubleshoot</source>
2393 <translation>תפעול ת&amp;קלות</translation>
2394 </message>
2395 <message>
2396 <location filename="../rbutilqtfrm.ui" line="446"/>
2397 <source>Action&amp;s</source>
2398 <translation>&amp;פעולות</translation>
2399 </message>
2400 <message>
2401 <location filename="../rbutilqtfrm.ui" line="474"/>
2402 <source>Empty local download cache</source>
2403 <translation>ריקון מטמון הורדות מקומי</translation>
2404 </message>
2405 <message>
2406 <location filename="../rbutilqtfrm.ui" line="479"/>
2407 <source>Install Rockbox Utility on player</source>
2408 <translation>התקנת תוכנית השירות של רוקבוקס על הנגן</translation>
2409 </message>
2410 <message>
2411 <location filename="../rbutilqtfrm.ui" line="484"/>
2412 <source>&amp;Configure</source>
2413 <translation>&amp;הגדרות</translation>
2414 </message>
2415 <message>
2416 <location filename="../rbutilqtfrm.ui" line="489"/>
2417 <source>E&amp;xit</source>
2418 <translation>&amp;יציאה</translation>
2419 </message>
2420 <message>
2421 <location filename="../rbutilqtfrm.ui" line="492"/>
2422 <source>Ctrl+Q</source>
2423 <translation>Ctrl+Q</translation>
2424 </message>
2425 <message>
2426 <location filename="../rbutilqtfrm.ui" line="497"/>
2427 <source>&amp;About</source>
2428 <translation>&amp;אודות</translation>
2429 </message>
2430 <message>
2431 <location filename="../rbutilqtfrm.ui" line="502"/>
2432 <source>About &amp;Qt</source>
2433 <translation>Qt או&amp;דות</translation>
2434 </message>
2435 <message>
2436 <location filename="../rbutilqtfrm.ui" line="663"/>
2437 <source>Show &amp;Changelog</source>
2438 <translation type="unfinished"></translation>
2439 </message>
2440 <message>
2441 <location filename="../rbutilqtfrm.ui" line="428"/>
2442 <location filename="../rbutilqtfrm.ui" line="507"/>
2443 <source>&amp;Help</source>
2444 <translation>&amp;עזרה</translation>
2445 </message>
2446 <message>
2447 <location filename="../rbutilqtfrm.ui" line="512"/>
2448 <source>Info</source>
2449 <translation>מידע</translation>
2450 </message>
2451 <message>
2452 <location filename="../rbutilqtfrm.ui" line="521"/>
2453 <source>&amp;Complete Installation</source>
2454 <translation>התקנה &amp;מלאה</translation>
2455 </message>
2456 <message>
2457 <location filename="../rbutilqtfrm.ui" line="539"/>
2458 <source>Install &amp;Bootloader</source>
2459 <translation>התקנת מנהל ה&amp;איתחול</translation>
2460 </message>
2461 <message>
2462 <location filename="../rbutilqtfrm.ui" line="548"/>
2463 <source>Install &amp;Rockbox</source>
2464 <translation>התקנת &amp;רוקבוקס</translation>
2465 </message>
2466 <message>
2467 <location filename="../rbutilqtfrm.ui" line="557"/>
2468 <source>Install &amp;Fonts Package</source>
2469 <translation>התקנת חבילת &amp;גופנים</translation>
2470 </message>
2471 <message>
2472 <location filename="../rbutilqtfrm.ui" line="566"/>
2473 <source>Install &amp;Themes</source>
2474 <translation>התקנת &amp;ערכות נושא</translation>
2475 </message>
2476 <message>
2477 <location filename="../rbutilqtfrm.ui" line="575"/>
2478 <source>Install &amp;Game Files</source>
2479 <translation>התקנת קבצי &amp;משחק</translation>
2480 </message>
2481 <message>
2482 <location filename="../rbutilqtfrm.ui" line="584"/>
2483 <source>&amp;Install Voice File</source>
2484 <translation>התקנת קבצי הקראת &amp;תפריטים</translation>
2485 </message>
2486 <message>
2487 <location filename="../rbutilqtfrm.ui" line="593"/>
2488 <source>Create &amp;Talk Files</source>
2489 <translation>יצירת קבצי &amp;דיבור</translation>
2490 </message>
2491 <message>
2492 <location filename="../rbutilqtfrm.ui" line="602"/>
2493 <source>Remove &amp;bootloader</source>
2494 <translation>הסרת &amp;מנהל האיתחול</translation>
2495 </message>
2496 <message>
2497 <location filename="../rbutilqtfrm.ui" line="611"/>
2498 <source>Uninstall &amp;Rockbox</source>
2499 <translation>הסרת &amp;רוקבוקס</translation>
2500 </message>
2501 <message>
2502 <location filename="../rbutilqtfrm.ui" line="616"/>
2503 <source>Read PDF manual</source>
2504 <translation>קריאת מדריך למשתמש מסוג PDF</translation>
2505 </message>
2506 <message>
2507 <location filename="../rbutilqtfrm.ui" line="621"/>
2508 <source>Read HTML manual</source>
2509 <translation>קריאת מדריך למשתמש מסוג HTML</translation>
2510 </message>
2511 <message>
2512 <location filename="../rbutilqtfrm.ui" line="626"/>
2513 <source>Download PDF manual</source>
2514 <translation>הורדת מדריך למשתמש מסוג PDF</translation>
2515 </message>
2516 <message>
2517 <location filename="../rbutilqtfrm.ui" line="631"/>
2518 <source>Download HTML manual (zip)</source>
2519 <translation>הורדת מדריך למשתמש מסוג HTML (קובץ zip)</translation>
2520 </message>
2521 <message>
2522 <location filename="../rbutilqtfrm.ui" line="640"/>
2523 <source>Create &amp;Voice File</source>
2524 <translation>יצירת קובץ &amp;הקראת תפריטים</translation>
2525 </message>
2526 <message>
2527 <location filename="../rbutilqtfrm.ui" line="643"/>
2528 <source>Create Voice File</source>
2529 <translation>יצירת קובץ הקראת תפריטים</translation>
2530 </message>
2531 <message>
2532 <location filename="../rbutilqtfrm.ui" line="648"/>
2533 <source>&amp;System Info</source>
2534 <translation>&amp;מידע מערכת</translation>
2535 </message>
2536 <message>
2537 <location filename="../rbutilqtfrm.ui" line="653"/>
2538 <source>System &amp;Trace</source>
2539 <translation>יומן רי&amp;צת מערכת</translation>
2540 </message>
2541 <message>
2542 <location filename="../rbutilqtfrm.ui" line="530"/>
2543 <source>&amp;Minimal Installation</source>
2544 <translation>התקנה מינימא&amp;לית</translation>
2545 </message>
2546</context>
2547<context>
2548 <name>SelectiveInstallWidget</name>
2549 <message>
2550 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="20"/>
2551 <source>Selective Installation</source>
2552 <translation type="unfinished"></translation>
2553 </message>
2554 <message>
2555 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="26"/>
2556 <source>Rockbox version to install</source>
2557 <translation type="unfinished"></translation>
2558 </message>
2559 <message>
2560 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="35"/>
2561 <source>Version information not available yet.</source>
2562 <translation type="unfinished"></translation>
2563 </message>
2564 <message>
2565 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="54"/>
2566 <source>Rockbox components to install</source>
2567 <translation type="unfinished"></translation>
2568 </message>
2569 <message>
2570 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="60"/>
2571 <source>&amp;Bootloader</source>
2572 <translation type="unfinished"></translation>
2573 </message>
2574 <message>
2575 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="80"/>
2576 <source>The main Rockbox firmware.</source>
2577 <translation type="unfinished"></translation>
2578 </message>
2579 <message>
2580 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="90"/>
2581 <source>Fonts</source>
2582 <translation type="unfinished"></translation>
2583 </message>
2584 <message>
2585 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="104"/>
2586 <source>&amp;Rockbox</source>
2587 <translation type="unfinished"></translation>
2588 </message>
2589 <message>
2590 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="124"/>
2591 <source>Some game plugins require additional files.</source>
2592 <translation type="unfinished"></translation>
2593 </message>
2594 <message>
2595 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="140"/>
2596 <source>Additional fonts for the User Interface.</source>
2597 <translation type="unfinished"></translation>
2598 </message>
2599 <message>
2600 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="156"/>
2601 <source>The bootloader is required for starting Rockbox. Only necessary for first time install.</source>
2602 <translation type="unfinished"></translation>
2603 </message>
2604 <message>
2605 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="166"/>
2606 <source>Game Files</source>
2607 <translation type="unfinished"></translation>
2608 </message>
2609 <message>
2610 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="177"/>
2611 <source>Customize</source>
2612 <translation type="unfinished"></translation>
2613 </message>
2614 <message>
2615 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="188"/>
2616 <source>Themes</source>
2617 <translation type="unfinished"></translation>
2618 </message>
2619 <message>
2620 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="205"/>
2621 <source>Themes allow adjusting the user interface of Rockbox. Use &quot;Customize&quot; to select themes.</source>
2622 <translation type="unfinished"></translation>
2623 </message>
2624 <message>
2625 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="250"/>
2626 <source>&amp;Install</source>
2627 <translation type="unfinished">&amp;התקנה</translation>
2628 </message>
2629 <message>
2630 <location filename="../gui/selectiveinstallwidget.cpp" line="67"/>
2631 <source>This is the latest stable release available.</source>
2632 <translation type="unfinished"></translation>
2633 </message>
2634 <message>
2635 <location filename="../gui/selectiveinstallwidget.cpp" line="70"/>
2636 <source>The development version is updated on every code change. Last update was on %1</source>
2637 <translation type="unfinished"></translation>
2638 </message>
2639 <message>
2640 <location filename="../gui/selectiveinstallwidget.cpp" line="74"/>
2641 <source>This will eventually become the next Rockbox version. Install it to help testing.</source>
2642 <translation type="unfinished"></translation>
2643 </message>
2644 <message>
2645 <location filename="../gui/selectiveinstallwidget.cpp" line="100"/>
2646 <source>Stable Release (Version %1)</source>
2647 <translation type="unfinished"></translation>
2648 </message>
2649 <message>
2650 <location filename="../gui/selectiveinstallwidget.cpp" line="104"/>
2651 <source>Development Version (Revison %1)</source>
2652 <translation type="unfinished"></translation>
2653 </message>
2654 <message>
2655 <location filename="../gui/selectiveinstallwidget.cpp" line="108"/>
2656 <source>Release Candidate (Revison %1)</source>
2657 <translation type="unfinished"></translation>
2658 </message>
2659 <message>
2660 <location filename="../gui/selectiveinstallwidget.cpp" line="131"/>
2661 <source>The selected player doesn&apos;t need a bootloader.</source>
2662 <translation type="unfinished"></translation>
2663 </message>
2664 <message>
2665 <location filename="../gui/selectiveinstallwidget.cpp" line="136"/>
2666 <source>The bootloader is required for starting Rockbox. Installation of the bootloader is only necessary on first time installation.</source>
2667 <translation type="unfinished"></translation>
2668 </message>
2669 <message>
2670 <location filename="../gui/selectiveinstallwidget.cpp" line="183"/>
2671 <source>Mountpoint is wrong</source>
2672 <translation type="unfinished"></translation>
2673 </message>
2674 <message>
2675 <location filename="../gui/selectiveinstallwidget.cpp" line="239"/>
2676 <source>No install method known.</source>
2677 <translation type="unfinished">אין שיטת התקנה ידועה.</translation>
2678 </message>
2679 <message>
2680 <location filename="../gui/selectiveinstallwidget.cpp" line="266"/>
2681 <source>Bootloader detected</source>
2682 <translation type="unfinished">מנהל האיתחול זוהה</translation>
2683 </message>
2684 <message>
2685 <location filename="../gui/selectiveinstallwidget.cpp" line="267"/>
2686 <source>Bootloader already installed. Do you want to reinstall the bootloader?</source>
2687 <translation type="unfinished">מנהל האיתחול כבר מותקן. האם אתה באמת רוצה להתקין מחדש את מנהל האיתחול?</translation>
2688 </message>
2689 <message>
2690 <location filename="../gui/selectiveinstallwidget.cpp" line="271"/>
2691 <source>Bootloader installation skipped</source>
2692 <translation type="unfinished">התקנת מנהל האיתחול לא בוצעה</translation>
2693 </message>
2694 <message>
2695 <location filename="../gui/selectiveinstallwidget.cpp" line="284"/>
2696 <source>Create Bootloader backup</source>
2697 <translation type="unfinished">יוצר גיבוי מנהל האיתחול</translation>
2698 </message>
2699 <message>
2700 <location filename="../gui/selectiveinstallwidget.cpp" line="285"/>
2701 <source>You can create a backup of the original bootloader file. Press &quot;Yes&quot; to select an output folder on your computer to save the file to. The file will get placed in a new folder &quot;%1&quot; created below the selected folder.
2702Press &quot;No&quot; to skip this step.</source>
2703 <translation type="unfinished">ביכולתך ליצור גיבוי של קובץ מנהל האיתחול המקורי. לחץ &quot;כן&quot; על מנת לבחור ספריית פלט על המחשב שלך אליה יישמר הקובץ, אשר יימצא תחת ספרייה חדשה בשם &quot;%1&quot; מתחת לספרייה שנבחרה.
2704לחץ &quot;לא&quot; כדי לדלג על שלב זה.</translation>
2705 </message>
2706 <message>
2707 <location filename="../gui/selectiveinstallwidget.cpp" line="292"/>
2708 <source>Browse backup folder</source>
2709 <translation type="unfinished">עיין בספריית הגיבוי</translation>
2710 </message>
2711 <message>
2712 <location filename="../gui/selectiveinstallwidget.cpp" line="304"/>
2713 <source>Prerequisites</source>
2714 <translation type="unfinished">דרישות מוקדמות</translation>
2715 </message>
2716 <message>
2717 <location filename="../gui/selectiveinstallwidget.cpp" line="309"/>
2718 <source>Bootloader installation aborted</source>
2719 <translation type="unfinished">התקנת מנהל האיתחול בוטלה</translation>
2720 </message>
2721 <message>
2722 <location filename="../gui/selectiveinstallwidget.cpp" line="319"/>
2723 <source>Bootloader files (%1)</source>
2724 <translation type="unfinished"></translation>
2725 </message>
2726 <message>
2727 <location filename="../gui/selectiveinstallwidget.cpp" line="321"/>
2728 <source>All files (*)</source>
2729 <translation type="unfinished"></translation>
2730 </message>
2731 <message>
2732 <location filename="../gui/selectiveinstallwidget.cpp" line="323"/>
2733 <source>Select firmware file</source>
2734 <translation type="unfinished">בחר קובץ קושחה</translation>
2735 </message>
2736 <message>
2737 <location filename="../gui/selectiveinstallwidget.cpp" line="325"/>
2738 <source>Error opening firmware file</source>
2739 <translation type="unfinished">שגיאה בפתיחת קובץ קושחה</translation>
2740 </message>
2741 <message>
2742 <location filename="../gui/selectiveinstallwidget.cpp" line="331"/>
2743 <source>Error reading firmware file</source>
2744 <translation type="unfinished"></translation>
2745 </message>
2746 <message>
2747 <location filename="../gui/selectiveinstallwidget.cpp" line="341"/>
2748 <source>Backup error</source>
2749 <translation type="unfinished">שגיאת גיבוי</translation>
2750 </message>
2751 <message>
2752 <location filename="../gui/selectiveinstallwidget.cpp" line="342"/>
2753 <source>Could not create backup file. Continue?</source>
2754 <translation type="unfinished">לא מצליח ליצור קובץ גיבוי. להמשיך?</translation>
2755 </message>
2756 <message>
2757 <location filename="../gui/selectiveinstallwidget.cpp" line="366"/>
2758 <source>Manual steps required</source>
2759 <translation type="unfinished">צעדים ידניים נדרשים</translation>
2760 </message>
2761 <message>
2762 <location filename="../gui/selectiveinstallwidget.cpp" line="171"/>
2763 <source>Continue with installation?</source>
2764 <translation type="unfinished"></translation>
2765 </message>
2766 <message>
2767 <location filename="../gui/selectiveinstallwidget.cpp" line="172"/>
2768 <source>Really continue?</source>
2769 <translation type="unfinished">באמת להמשיך?</translation>
2770 </message>
2771 <message>
2772 <source>Aborted!</source>
2773 <translation type="obsolete">בוטל!</translation>
2774 </message>
2775 <message>
2776 <location filename="../gui/selectiveinstallwidget.cpp" line="490"/>
2777 <source>Your installation doesn&apos;t require game files, skipping.</source>
2778 <translation type="unfinished"></translation>
2779 </message>
2780</context>
2781<context>
2782 <name>ServerInfo</name>
2783 <message>
2784 <location filename="../base/serverinfo.cpp" line="117"/>
2785 <source>Unknown</source>
2786 <translation>לא ידוע</translation>
2787 </message>
2788 <message>
2789 <location filename="../base/serverinfo.cpp" line="121"/>
2790 <source>Unusable</source>
2791 <translation>לא שמיש</translation>
2792 </message>
2793 <message>
2794 <location filename="../base/serverinfo.cpp" line="124"/>
2795 <source>Unstable</source>
2796 <translation>לא יציב</translation>
2797 </message>
2798 <message>
2799 <location filename="../base/serverinfo.cpp" line="127"/>
2800 <source>Stable</source>
2801 <translation>יציב</translation>
2802 </message>
2803</context>
2804<context>
2805 <name>SysTrace</name>
2806 <message>
2807 <location filename="../systrace.cpp" line="98"/>
2808 <location filename="../systrace.cpp" line="107"/>
2809 <source>Save system trace log</source>
2810 <translation>שמור יומן ריצת מערכת</translation>
2811 </message>
2812</context>
2813<context>
2814 <name>SysTraceFrm</name>
2815 <message>
2816 <location filename="../systracefrm.ui" line="14"/>
2817 <source>System Trace</source>
2818 <translation>יומן ריצת מערכת</translation>
2819 </message>
2820 <message>
2821 <location filename="../systracefrm.ui" line="20"/>
2822 <source>System State trace</source>
2823 <translation>יומן ריצת מערכת</translation>
2824 </message>
2825 <message>
2826 <location filename="../systracefrm.ui" line="46"/>
2827 <source>&amp;Close</source>
2828 <translation>&amp;סגור</translation>
2829 </message>
2830 <message>
2831 <location filename="../systracefrm.ui" line="57"/>
2832 <source>&amp;Save</source>
2833 <translation>&amp;שמור</translation>
2834 </message>
2835 <message>
2836 <location filename="../systracefrm.ui" line="68"/>
2837 <source>&amp;Refresh</source>
2838 <translation>&amp;רענן</translation>
2839 </message>
2840 <message>
2841 <location filename="../systracefrm.ui" line="79"/>
2842 <source>Save &amp;previous</source>
2843 <translation>שמור &amp;קודם</translation>
2844 </message>
2845</context>
2846<context>
2847 <name>Sysinfo</name>
2848 <message>
2849 <location filename="../sysinfo.cpp" line="45"/>
2850 <source>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</source>
2851 <translation>&lt;b&gt;מערכת הפעלה&lt;/b&gt;&lt;br/&gt;</translation>
2852 </message>
2853 <message>
2854 <location filename="../sysinfo.cpp" line="46"/>
2855 <source>&lt;b&gt;Username&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2856 <translation>&lt;b&gt;שם משתמש&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2857 </message>
2858 <message>
2859 <location filename="../sysinfo.cpp" line="48"/>
2860 <source>&lt;b&gt;Permissions&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2861 <translation>&lt;b&gt;הרשאות&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2862 </message>
2863 <message>
2864 <location filename="../sysinfo.cpp" line="50"/>
2865 <source>&lt;b&gt;Attached USB devices&lt;/b&gt;&lt;br/&gt;</source>
2866 <translation>&lt;b&gt;התקני USB מחוברים&lt;/b&gt;&lt;br/&gt;</translation>
2867 </message>
2868 <message>
2869 <location filename="../sysinfo.cpp" line="54"/>
2870 <source>VID: %1 PID: %2, %3</source>
2871 <translation></translation>
2872 </message>
2873 <message>
2874 <location filename="../sysinfo.cpp" line="63"/>
2875 <source>Filesystem</source>
2876 <translation>מערכת קבצים</translation>
2877 </message>
2878 <message>
2879 <location filename="../sysinfo.cpp" line="66"/>
2880 <source>Mountpoint</source>
2881 <translation type="unfinished"></translation>
2882 </message>
2883 <message>
2884 <location filename="../sysinfo.cpp" line="66"/>
2885 <source>Label</source>
2886 <translation type="unfinished"></translation>
2887 </message>
2888 <message>
2889 <location filename="../sysinfo.cpp" line="67"/>
2890 <source>Free</source>
2891 <translation type="unfinished"></translation>
2892 </message>
2893 <message>
2894 <location filename="../sysinfo.cpp" line="67"/>
2895 <source>Total</source>
2896 <translation type="unfinished"></translation>
2897 </message>
2898 <message>
2899 <location filename="../sysinfo.cpp" line="68"/>
2900 <source>Cluster Size</source>
2901 <translation type="unfinished"></translation>
2902 </message>
2903 <message>
2904 <location filename="../sysinfo.cpp" line="70"/>
2905 <source>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</source>
2906 <translation type="unfinished"></translation>
2907 </message>
2908</context>
2909<context>
2910 <name>SysinfoFrm</name>
2911 <message>
2912 <location filename="../sysinfofrm.ui" line="13"/>
2913 <source>System Info</source>
2914 <translation>מידע מערכת</translation>
2915 </message>
2916 <message>
2917 <location filename="../sysinfofrm.ui" line="22"/>
2918 <source>&amp;Refresh</source>
2919 <translation>&amp;רענן</translation>
2920 </message>
2921 <message>
2922 <location filename="../sysinfofrm.ui" line="45"/>
2923 <source>&amp;OK</source>
2924 <translation>&amp;אישור</translation>
2925 </message>
2926</context>
2927<context>
2928 <name>System</name>
2929 <message>
2930 <location filename="../base/system.cpp" line="121"/>
2931 <source>Guest</source>
2932 <translation type="unfinished">אורח</translation>
2933 </message>
2934 <message>
2935 <location filename="../base/system.cpp" line="124"/>
2936 <source>Admin</source>
2937 <translation type="unfinished">מנהל</translation>
2938 </message>
2939 <message>
2940 <location filename="../base/system.cpp" line="127"/>
2941 <source>User</source>
2942 <translation type="unfinished">משתמש</translation>
2943 </message>
2944 <message>
2945 <location filename="../base/system.cpp" line="130"/>
2946 <source>Error</source>
2947 <translation type="unfinished">שגיאה</translation>
2948 </message>
2949 <message>
2950 <location filename="../base/system.cpp" line="278"/>
2951 <location filename="../base/system.cpp" line="323"/>
2952 <source>(no description available)</source>
2953 <translation type="unfinished">(אין תיאור זמין)</translation>
2954 </message>
2955</context>
2956<context>
2957 <name>TTSBase</name>
2958 <message>
2959 <location filename="../base/ttsbase.cpp" line="45"/>
2960 <source>Espeak TTS Engine</source>
2961 <translation type="unfinished"></translation>
2962 </message>
2963 <message>
2964 <location filename="../base/ttsbase.cpp" line="47"/>
2965 <source>Flite TTS Engine</source>
2966 <translation type="unfinished"></translation>
2967 </message>
2968 <message>
2969 <location filename="../base/ttsbase.cpp" line="48"/>
2970 <source>Swift TTS Engine</source>
2971 <translation type="unfinished"></translation>
2972 </message>
2973 <message>
2974 <location filename="../base/ttsbase.cpp" line="51"/>
2975 <source>SAPI4 TTS Engine</source>
2976 <translation type="unfinished"></translation>
2977 </message>
2978 <message>
2979 <location filename="../base/ttsbase.cpp" line="53"/>
2980 <source>SAPI5 TTS Engine</source>
2981 <translation type="unfinished"></translation>
2982 </message>
2983 <message>
2984 <location filename="../base/ttsbase.cpp" line="54"/>
2985 <source>MS Speech Platform</source>
2986 <translation type="unfinished"></translation>
2987 </message>
2988 <message>
2989 <location filename="../base/ttsbase.cpp" line="57"/>
2990 <source>Festival TTS Engine</source>
2991 <translation type="unfinished"></translation>
2992 </message>
2993 <message>
2994 <location filename="../base/ttsbase.cpp" line="60"/>
2995 <source>OS X System Engine</source>
2996 <translation type="unfinished"></translation>
2997 </message>
2998</context>
2999<context>
3000 <name>TTSCarbon</name>
3001 <message>
3002 <location filename="../base/ttscarbon.cpp" line="139"/>
3003 <source>Voice:</source>
3004 <translation>קול:</translation>
3005 </message>
3006 <message>
3007 <location filename="../base/ttscarbon.cpp" line="145"/>
3008 <source>Speed (words/min):</source>
3009 <translation>מהירות (מילים/דקה):</translation>
3010 </message>
3011 <message>
3012 <location filename="../base/ttscarbon.cpp" line="152"/>
3013 <source>Pitch (0 for default):</source>
3014 <translation type="unfinished"></translation>
3015 </message>
3016 <message>
3017 <location filename="../base/ttscarbon.cpp" line="222"/>
3018 <source>Could not voice string</source>
3019 <translation>לא מצליח להקריא את המחרוזת</translation>
3020 </message>
3021 <message>
3022 <location filename="../base/ttscarbon.cpp" line="232"/>
3023 <source>Could not convert intermediate file</source>
3024 <translation>לא מצליח להמיר קובץ ביניים</translation>
3025 </message>
3026</context>
3027<context>
3028 <name>TTSExes</name>
3029 <message>
3030 <location filename="../base/ttsexes.cpp" line="78"/>
3031 <source>TTS executable not found</source>
3032 <translation>קובץ הפעלה של הדיבור לא נמצא</translation>
3033 </message>
3034 <message>
3035 <location filename="../base/ttsexes.cpp" line="44"/>
3036 <source>Path to TTS engine:</source>
3037 <translation>נתיב למנוע הדיבור:</translation>
3038 </message>
3039 <message>
3040 <location filename="../base/ttsexes.cpp" line="46"/>
3041 <source>TTS engine options:</source>
3042 <translation>אפשרויות מנוע דיבור:</translation>
3043 </message>
3044</context>
3045<context>
3046 <name>TTSFestival</name>
3047 <message>
3048 <location filename="../base/ttsfestival.cpp" line="207"/>
3049 <source>engine could not voice string</source>
3050 <translation>המנוע אינו יכול להקריא את המחרוזת</translation>
3051 </message>
3052 <message>
3053 <location filename="../base/ttsfestival.cpp" line="290"/>
3054 <source>No description available</source>
3055 <translation>אין תיאור זמין</translation>
3056 </message>
3057 <message>
3058 <location filename="../base/ttsfestival.cpp" line="53"/>
3059 <source>Path to Festival client:</source>
3060 <translation>נתיב ללקוח Festival:</translation>
3061 </message>
3062 <message>
3063 <location filename="../base/ttsfestival.cpp" line="58"/>
3064 <source>Voice:</source>
3065 <translation>קול:</translation>
3066 </message>
3067 <message>
3068 <location filename="../base/ttsfestival.cpp" line="67"/>
3069 <source>Voice description:</source>
3070 <translation>תיאור קול:</translation>
3071 </message>
3072</context>
3073<context>
3074 <name>TTSSapi</name>
3075 <message>
3076 <location filename="../base/ttssapi.cpp" line="49"/>
3077 <source>Language:</source>
3078 <translation>שפה:</translation>
3079 </message>
3080 <message>
3081 <location filename="../base/ttssapi.cpp" line="56"/>
3082 <source>Voice:</source>
3083 <translation>קול:</translation>
3084 </message>
3085 <message>
3086 <location filename="../base/ttssapi.cpp" line="68"/>
3087 <source>Speed:</source>
3088 <translation>מהירות:</translation>
3089 </message>
3090 <message>
3091 <location filename="../base/ttssapi.cpp" line="71"/>
3092 <source>Options:</source>
3093 <translation>אפשרויות:</translation>
3094 </message>
3095 <message>
3096 <location filename="../base/ttssapi.cpp" line="115"/>
3097 <source>Could not copy the SAPI script</source>
3098 <translation type="unfinished"></translation>
3099 </message>
3100 <message>
3101 <location filename="../base/ttssapi.cpp" line="133"/>
3102 <source>Could not start SAPI process</source>
3103 <translation type="unfinished"></translation>
3104 </message>
3105</context>
3106<context>
3107 <name>TalkFileCreator</name>
3108 <message>
3109 <location filename="../base/talkfile.cpp" line="42"/>
3110 <source>Reading Filelist...</source>
3111 <translation>קורא רשימת קבצים...</translation>
3112 </message>
3113 <message>
3114 <location filename="../base/talkfile.cpp" line="45"/>
3115 <source>Talk file creation aborted</source>
3116 <translation>יצירת קובץ הקראת התפריטים בוטלה</translation>
3117 </message>
3118 <message>
3119 <location filename="../base/talkfile.cpp" line="68"/>
3120 <source>Copying Talkfiles...</source>
3121 <translation>מעתיק קבצי הקראת התפריטים...</translation>
3122 </message>
3123 <message>
3124 <location filename="../base/talkfile.cpp" line="240"/>
3125 <source>File copy aborted</source>
3126 <translation>העתקת קובץ בוטלה</translation>
3127 </message>
3128 <message>
3129 <location filename="../base/talkfile.cpp" line="280"/>
3130 <source>Cleaning up...</source>
3131 <translation>מנקה...</translation>
3132 </message>
3133 <message>
3134 <location filename="../base/talkfile.cpp" line="291"/>
3135 <source>Finished</source>
3136 <translation>הסתיים</translation>
3137 </message>
3138 <message>
3139 <location filename="../base/talkfile.cpp" line="80"/>
3140 <source>Finished creating Talk files</source>
3141 <translation>יצירת קבצי הקראה הסתיימה</translation>
3142 </message>
3143 <message>
3144 <location filename="../base/talkfile.cpp" line="36"/>
3145 <source>Starting Talk file generation for folder %1</source>
3146 <translation type="unfinished"></translation>
3147 </message>
3148 <message>
3149 <location filename="../base/talkfile.cpp" line="259"/>
3150 <source>Copying of %1 to %2 failed</source>
3151 <translation>העתקת %1 ל- %2 נכשלה</translation>
3152 </message>
3153</context>
3154<context>
3155 <name>TalkGenerator</name>
3156 <message>
3157 <location filename="../base/talkgenerator.cpp" line="39"/>
3158 <source>Starting TTS Engine</source>
3159 <translation>מתחיל מנוע דיבור</translation>
3160 </message>
3161 <message>
3162 <location filename="../base/talkgenerator.cpp" line="44"/>
3163 <location filename="../base/talkgenerator.cpp" line="51"/>
3164 <source>Init of TTS engine failed</source>
3165 <translation>איתחול מנוע הדיבור נכשל</translation>
3166 </message>
3167 <message>
3168 <location filename="../base/talkgenerator.cpp" line="58"/>
3169 <source>Starting Encoder Engine</source>
3170 <translation>מתחיל מנוע קידוד</translation>
3171 </message>
3172 <message>
3173 <location filename="../base/talkgenerator.cpp" line="62"/>
3174 <source>Init of Encoder engine failed</source>
3175 <translation>איתחול מנוע הקידוד נכשל</translation>
3176 </message>
3177 <message>
3178 <location filename="../base/talkgenerator.cpp" line="72"/>
3179 <source>Voicing entries...</source>
3180 <translation>מקריא רשומות...</translation>
3181 </message>
3182 <message>
3183 <location filename="../base/talkgenerator.cpp" line="87"/>
3184 <source>Encoding files...</source>
3185 <translation>מקודד קבצים...</translation>
3186 </message>
3187 <message>
3188 <location filename="../base/talkgenerator.cpp" line="126"/>
3189 <source>Voicing aborted</source>
3190 <translation>הקראה בוטלה</translation>
3191 </message>
3192 <message>
3193 <location filename="../base/talkgenerator.cpp" line="162"/>
3194 <location filename="../base/talkgenerator.cpp" line="167"/>
3195 <source>Voicing of %1 failed: %2</source>
3196 <translation>הקראת %1 בוטלה: %2</translation>
3197 </message>
3198 <message>
3199 <location filename="../base/talkgenerator.cpp" line="211"/>
3200 <source>Encoding aborted</source>
3201 <translation>הקידוד בוטל</translation>
3202 </message>
3203 <message>
3204 <location filename="../base/talkgenerator.cpp" line="239"/>
3205 <source>Encoding of %1 failed</source>
3206 <translation>הקידוד של %1 נכשל</translation>
3207 </message>
3208</context>
3209<context>
3210 <name>ThemeInstallFrm</name>
3211 <message>
3212 <location filename="../themesinstallfrm.ui" line="13"/>
3213 <source>Theme Installation</source>
3214 <translation>התקנת ערכת נושא</translation>
3215 </message>
3216 <message>
3217 <location filename="../themesinstallfrm.ui" line="48"/>
3218 <source>Selected Theme</source>
3219 <translation>ערכת הנושא שנבחרה</translation>
3220 </message>
3221 <message>
3222 <location filename="../themesinstallfrm.ui" line="73"/>
3223 <source>Description</source>
3224 <translation>תיאור</translation>
3225 </message>
3226 <message>
3227 <location filename="../themesinstallfrm.ui" line="83"/>
3228 <source>Download size:</source>
3229 <translation>גודל הורדה:</translation>
3230 </message>
3231 <message>
3232 <location filename="../themesinstallfrm.ui" line="115"/>
3233 <source>&amp;Install</source>
3234 <translation>&amp;התקנה</translation>
3235 </message>
3236 <message>
3237 <location filename="../themesinstallfrm.ui" line="125"/>
3238 <source>&amp;Cancel</source>
3239 <translation>&amp;ביטול</translation>
3240 </message>
3241 <message>
3242 <location filename="../themesinstallfrm.ui" line="93"/>
3243 <source>Hold Ctrl to select multiple item, Shift for a range</source>
3244 <translatorcomment>בשביל לבחור טווח Shift ,בשביל לבחור מספר פריטים Ctrl לחץ על</translatorcomment>
3245 <translation>לחץ על Ctrl בשביל לבחור מספר פריטים, או על Shift בשביל לבחור טווח</translation>
3246 </message>
3247</context>
3248<context>
3249 <name>ThemesInstallWindow</name>
3250 <message>
3251 <location filename="../themesinstallwindow.cpp" line="40"/>
3252 <source>no theme selected</source>
3253 <translation>לא נבחרה ערכת נושא</translation>
3254 </message>
3255 <message>
3256 <location filename="../themesinstallwindow.cpp" line="125"/>
3257 <source>Network error: %1.
3258Please check your network and proxy settings.</source>
3259 <translation>תקלת רשת: %1.
3260אנא בדוק את הגדרות הרשת והפרוקסי שלך.</translation>
3261 </message>
3262 <message>
3263 <location filename="../themesinstallwindow.cpp" line="138"/>
3264 <source>the following error occured:
3265%1</source>
3266 <translation>השגיאה הבאה התרחשה:
3267%1</translation>
3268 </message>
3269 <message>
3270 <location filename="../themesinstallwindow.cpp" line="144"/>
3271 <source>done.</source>
3272 <translation>הסתיים.</translation>
3273 </message>
3274 <message>
3275 <location filename="../themesinstallwindow.cpp" line="211"/>
3276 <source>fetching details for %1</source>
3277 <translation>טוען פרטים עבור %1</translation>
3278 </message>
3279 <message>
3280 <location filename="../themesinstallwindow.cpp" line="214"/>
3281 <source>fetching preview ...</source>
3282 <translation>טוען תצוגה מקדימה...</translation>
3283 </message>
3284 <message>
3285 <location filename="../themesinstallwindow.cpp" line="227"/>
3286 <source>&lt;b&gt;Author:&lt;/b&gt; %1&lt;hr/&gt;</source>
3287 <translatorcomment>Keep in English</translatorcomment>
3288 <translation>&lt;b&gt;Author:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3289 </message>
3290 <message>
3291 <location filename="../themesinstallwindow.cpp" line="228"/>
3292 <location filename="../themesinstallwindow.cpp" line="230"/>
3293 <source>unknown</source>
3294 <translation>לא ידוע</translation>
3295 </message>
3296 <message>
3297 <location filename="../themesinstallwindow.cpp" line="229"/>
3298 <source>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</source>
3299 <translatorcomment>Keep in English</translatorcomment>
3300 <translation>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3301 </message>
3302 <message>
3303 <location filename="../themesinstallwindow.cpp" line="231"/>
3304 <source>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</source>
3305 <translatorcomment>Keep in English</translatorcomment>
3306 <translation>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3307 </message>
3308 <message>
3309 <location filename="../themesinstallwindow.cpp" line="232"/>
3310 <source>no description</source>
3311 <translation>אין תיאור</translation>
3312 </message>
3313 <message>
3314 <location filename="../themesinstallwindow.cpp" line="260"/>
3315 <source>no theme preview</source>
3316 <translation>אין תצוגה מקדימה של ערכת נושא</translation>
3317 </message>
3318 <message>
3319 <location filename="../themesinstallwindow.cpp" line="289"/>
3320 <source>Select</source>
3321 <translation type="unfinished"></translation>
3322 </message>
3323 <message>
3324 <location filename="../themesinstallwindow.cpp" line="296"/>
3325 <source>getting themes information ...</source>
3326 <translation>מוריד מידע על ערכות הנושא...</translation>
3327 </message>
3328 <message>
3329 <location filename="../themesinstallwindow.cpp" line="326"/>
3330 <source>No themes selected, skipping</source>
3331 <translation type="unfinished"></translation>
3332 </message>
3333 <message>
3334 <location filename="../themesinstallwindow.cpp" line="356"/>
3335 <source>Mount point is wrong!</source>
3336 <translation>נקודת העגינה הינה שגויה!</translation>
3337 </message>
3338 <message>
3339 <location filename="../themesinstallwindow.cpp" line="41"/>
3340 <source>no selection</source>
3341 <translation>אין בחירה</translation>
3342 </message>
3343 <message>
3344 <location filename="../themesinstallwindow.cpp" line="181"/>
3345 <source>Information</source>
3346 <translation>מידע</translation>
3347 </message>
3348 <message numerus="yes">
3349 <location filename="../themesinstallwindow.cpp" line="198"/>
3350 <source>Download size %L1 kiB (%n item(s))</source>
3351 <translation>
3352 <numerusform>גודל הורדה kiB %L1 (פריט אחד)</numerusform>
3353 <numerusform>גודל הורדה kiB %L1 (%n פריטים)</numerusform>
3354 </translation>
3355 </message>
3356 <message>
3357 <location filename="../themesinstallwindow.cpp" line="248"/>
3358 <source>Retrieving theme preview failed.
3359HTTP response code: %1</source>
3360 <translation>נכשלה תצורגה מקדימה של ערכת נושא.
3361HTTP response code: %1</translation>
3362 </message>
3363</context>
3364<context>
3365 <name>UninstallFrm</name>
3366 <message>
3367 <location filename="../uninstallfrm.ui" line="16"/>
3368 <source>Uninstall Rockbox</source>
3369 <translation>הסרת התקנת רוקבוקס</translation>
3370 </message>
3371 <message>
3372 <location filename="../uninstallfrm.ui" line="35"/>
3373 <source>Please select the Uninstallation Method</source>
3374 <translation>אנא בחר שיטת הסרת התקנה</translation>
3375 </message>
3376 <message>
3377 <location filename="../uninstallfrm.ui" line="45"/>
3378 <source>Uninstallation Method</source>
3379 <translation>שיטת הסרת התקנה</translation>
3380 </message>
3381 <message>
3382 <location filename="../uninstallfrm.ui" line="51"/>
3383 <source>Complete Uninstallation</source>
3384 <translation>הסרת התקנה מלאה</translation>
3385 </message>
3386 <message>
3387 <location filename="../uninstallfrm.ui" line="58"/>
3388 <source>Smart Uninstallation</source>
3389 <translation>הסרת התקנה חכמה</translation>
3390 </message>
3391 <message>
3392 <location filename="../uninstallfrm.ui" line="68"/>
3393 <source>Please select what you want to uninstall</source>
3394 <translation>אנא בחר מה ברצונך להסיר</translation>
3395 </message>
3396 <message>
3397 <location filename="../uninstallfrm.ui" line="78"/>
3398 <source>Installed Parts</source>
3399 <translation>רכיבים מותקנים</translation>
3400 </message>
3401 <message>
3402 <location filename="../uninstallfrm.ui" line="128"/>
3403 <source>&amp;Uninstall</source>
3404 <translation>&amp;הסרת התקנה</translation>
3405 </message>
3406 <message>
3407 <location filename="../uninstallfrm.ui" line="138"/>
3408 <source>&amp;Cancel</source>
3409 <translation>&amp;ביטול</translation>
3410 </message>
3411</context>
3412<context>
3413 <name>Uninstaller</name>
3414 <message>
3415 <location filename="../base/uninstall.cpp" line="32"/>
3416 <location filename="../base/uninstall.cpp" line="43"/>
3417 <source>Starting Uninstallation</source>
3418 <translation>מתחיל להסיר התקנה</translation>
3419 </message>
3420 <message>
3421 <location filename="../base/uninstall.cpp" line="36"/>
3422 <source>Finished Uninstallation</source>
3423 <translation>הסרת התקנה הושלמה</translation>
3424 </message>
3425 <message>
3426 <location filename="../base/uninstall.cpp" line="49"/>
3427 <source>Uninstalling %1...</source>
3428 <translation>מסיר %1...</translation>
3429 </message>
3430 <message>
3431 <location filename="../base/uninstall.cpp" line="80"/>
3432 <source>Could not delete %1</source>
3433 <translation>לא הצלחתי למחוק את %1</translation>
3434 </message>
3435 <message>
3436 <location filename="../base/uninstall.cpp" line="109"/>
3437 <source>Uninstallation finished</source>
3438 <translation>הסרת התקנה הסתיימה</translation>
3439 </message>
3440</context>
3441<context>
3442 <name>Utils</name>
3443 <message>
3444 <location filename="../base/utils.cpp" line="312"/>
3445 <source>&lt;li&gt;Permissions insufficient for bootloader installation.
3446Administrator priviledges are necessary.&lt;/li&gt;</source>
3447 <translation type="unfinished">&lt;li&gt;הרשאות אינן מספיקות להתקנת מנהל איתחול.
3448הרשאות מנהל הינן הכרחיות&lt;/li&gt;</translation>
3449 </message>
3450 <message>
3451 <location filename="../base/utils.cpp" line="324"/>
3452 <source>&lt;li&gt;Target mismatch detected.&lt;br/&gt;Installed target: %1&lt;br/&gt;Selected target: %2.&lt;/li&gt;</source>
3453 <translation type="unfinished"></translation>
3454 </message>
3455 <message>
3456 <location filename="../base/utils.cpp" line="331"/>
3457 <source>Problem detected:</source>
3458 <translation type="unfinished">זוהתה בעיה:</translation>
3459 </message>
3460</context>
3461<context>
3462 <name>VoiceFileCreator</name>
3463 <message>
3464 <location filename="../base/voicefile.cpp" line="43"/>
3465 <source>Starting Voicefile generation</source>
3466 <translation>מתחיל ביצירת קבצי הקראה</translation>
3467 </message>
3468 <message>
3469 <location filename="../base/voicefile.cpp" line="90"/>
3470 <source>Extracted voice strings from installation</source>
3471 <translation type="unfinished"></translation>
3472 </message>
3473 <message>
3474 <location filename="../base/voicefile.cpp" line="100"/>
3475 <source>Extracted voice strings incompatible</source>
3476 <translation type="unfinished"></translation>
3477 </message>
3478 <message>
3479 <location filename="../base/voicefile.cpp" line="145"/>
3480 <source>Could not retrieve strings from installation, downloading</source>
3481 <translation type="unfinished"></translation>
3482 </message>
3483 <message>
3484 <location filename="../base/voicefile.cpp" line="171"/>
3485 <source>Downloading voice info...</source>
3486 <translation>מוריד מידע קול...</translation>
3487 </message>
3488 <message>
3489 <location filename="../base/voicefile.cpp" line="184"/>
3490 <source>Download error: received HTTP error %1.</source>
3491 <translation>כשלון בהורדה: התקבלה שגיאת HTTP %1.</translation>
3492 </message>
3493 <message>
3494 <location filename="../base/voicefile.cpp" line="191"/>
3495 <source>Cached file used.</source>
3496 <translation>נעשה שימוש בקובץ הנמצא במטמון.</translation>
3497 </message>
3498 <message>
3499 <location filename="../base/voicefile.cpp" line="194"/>
3500 <source>Download error: %1</source>
3501 <translation>שגיאת הורדה: %1</translation>
3502 </message>
3503 <message>
3504 <location filename="../base/voicefile.cpp" line="199"/>
3505 <source>Download finished.</source>
3506 <translation>הורדה הסתיימה.</translation>
3507 </message>
3508 <message>
3509 <location filename="../base/voicefile.cpp" line="212"/>
3510 <source>failed to open downloaded file</source>
3511 <translation>פתיחת הקובץ שירד נכשלה</translation>
3512 </message>
3513 <message>
3514 <location filename="../base/voicefile.cpp" line="218"/>
3515 <source>Reading strings...</source>
3516 <translation>קורא מחרוזות...</translation>
3517 </message>
3518 <message>
3519 <location filename="../base/voicefile.cpp" line="297"/>
3520 <source>Creating voicefiles...</source>
3521 <translation>יוצר קבצי הקראה...</translation>
3522 </message>
3523 <message>
3524 <location filename="../base/voicefile.cpp" line="342"/>
3525 <source>Cleaning up...</source>
3526 <translation>מנקה...</translation>
3527 </message>
3528 <message>
3529 <location filename="../base/voicefile.cpp" line="353"/>
3530 <source>Finished</source>
3531 <translation>הסתיים</translation>
3532 </message>
3533 <message>
3534 <location filename="../base/voicefile.cpp" line="271"/>
3535 <source>The downloaded file was empty!</source>
3536 <translation>הקובץ שירד היה ריק!</translation>
3537 </message>
3538 <message>
3539 <location filename="../base/voicefile.cpp" line="302"/>
3540 <source>Error opening downloaded file</source>
3541 <translation>שגיאה בפתיחת הקובץ שירד</translation>
3542 </message>
3543 <message>
3544 <location filename="../base/voicefile.cpp" line="313"/>
3545 <source>Error opening output file</source>
3546 <translation>שגיאה בפתיחת קובץ הפלט</translation>
3547 </message>
3548 <message>
3549 <location filename="../base/voicefile.cpp" line="333"/>
3550 <source>successfully created.</source>
3551 <translation>נוצר בהצלחה.</translation>
3552 </message>
3553 <message>
3554 <location filename="../base/voicefile.cpp" line="56"/>
3555 <source>could not find rockbox-info.txt</source>
3556 <translation>לא מוצא rockbox-info.txt</translation>
3557 </message>
3558</context>
3559<context>
3560 <name>ZipInstaller</name>
3561 <message>
3562 <location filename="../base/zipinstaller.cpp" line="60"/>
3563 <source>done.</source>
3564 <translation>הסתיים.</translation>
3565 </message>
3566 <message>
3567 <location filename="../base/zipinstaller.cpp" line="68"/>
3568 <source>Package installation finished successfully.</source>
3569 <translation type="unfinished"></translation>
3570 </message>
3571 <message>
3572 <location filename="../base/zipinstaller.cpp" line="80"/>
3573 <source>Downloading file %1.%2</source>
3574 <translation>מוריד קובץ %1.%2</translation>
3575 </message>
3576 <message>
3577 <location filename="../base/zipinstaller.cpp" line="115"/>
3578 <source>Download error: received HTTP error %1.</source>
3579 <translation>שגיאת הורדה: התקבלה שגיאת %1 HTTP.</translation>
3580 </message>
3581 <message>
3582 <location filename="../base/zipinstaller.cpp" line="121"/>
3583 <source>Cached file used.</source>
3584 <translation>נעשה שימוש בקובץ מהמטמון.</translation>
3585 </message>
3586 <message>
3587 <location filename="../base/zipinstaller.cpp" line="123"/>
3588 <source>Download error: %1</source>
3589 <translation>שגיאת הורדה: %1</translation>
3590 </message>
3591 <message>
3592 <location filename="../base/zipinstaller.cpp" line="127"/>
3593 <source>Download finished.</source>
3594 <translation>הורדה הסתיימה.</translation>
3595 </message>
3596 <message>
3597 <location filename="../base/zipinstaller.cpp" line="133"/>
3598 <source>Extracting file.</source>
3599 <translation>פורס קובץ.</translation>
3600 </message>
3601 <message>
3602 <location filename="../base/zipinstaller.cpp" line="153"/>
3603 <source>Extraction failed!</source>
3604 <translation type="unfinished"></translation>
3605 </message>
3606 <message>
3607 <location filename="../base/zipinstaller.cpp" line="162"/>
3608 <source>Installing file.</source>
3609 <translation>מתקין קובץ.</translation>
3610 </message>
3611 <message>
3612 <location filename="../base/zipinstaller.cpp" line="173"/>
3613 <source>Installing file failed.</source>
3614 <translation>התקנת קובץ נכשלה.</translation>
3615 </message>
3616 <message>
3617 <location filename="../base/zipinstaller.cpp" line="186"/>
3618 <source>Creating installation log</source>
3619 <translation>יוצר קובץ רישום של ההתקנה</translation>
3620 </message>
3621 <message>
3622 <location filename="../base/zipinstaller.cpp" line="146"/>
3623 <source>Not enough disk space! Aborting.</source>
3624 <translation>אין מספיק מקום בדיסק! מבטל.</translation>
3625 </message>
3626</context>
3627<context>
3628 <name>ZipUtil</name>
3629 <message>
3630 <location filename="../base/ziputil.cpp" line="125"/>
3631 <source>Creating output path failed</source>
3632 <translation type="unfinished"></translation>
3633 </message>
3634 <message>
3635 <location filename="../base/ziputil.cpp" line="132"/>
3636 <source>Creating output file failed</source>
3637 <translation type="unfinished"></translation>
3638 </message>
3639 <message>
3640 <location filename="../base/ziputil.cpp" line="141"/>
3641 <source>Error during Zip operation</source>
3642 <translation type="unfinished"></translation>
3643 </message>
3644</context>
3645<context>
3646 <name>aboutBox</name>
3647 <message>
3648 <location filename="../aboutbox.ui" line="14"/>
3649 <source>About Rockbox Utility</source>
3650 <translation>אודות תוכנת השרות של רוקבוקס</translation>
3651 </message>
3652 <message>
3653 <location filename="../aboutbox.ui" line="32"/>
3654 <source>The Rockbox Utility</source>
3655 <translation>תוכנת השרות של רוקבוקס</translation>
3656 </message>
3657 <message utf8="true">
3658 <location filename="../aboutbox.ui" line="54"/>
3659 <source>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</source>
3660 <translation></translation>
3661 </message>
3662 <message>
3663 <location filename="../aboutbox.ui" line="74"/>
3664 <source>&amp;Credits</source>
3665 <translation>&amp;תודות</translation>
3666 </message>
3667 <message>
3668 <location filename="../aboutbox.ui" line="106"/>
3669 <source>&amp;License</source>
3670 <translation>&amp;רישיון</translation>
3671 </message>
3672 <message>
3673 <location filename="../aboutbox.ui" line="132"/>
3674 <source>&amp;Speex License</source>
3675 <translation type="unfinished"></translation>
3676 </message>
3677 <message>
3678 <location filename="../aboutbox.ui" line="158"/>
3679 <source>&amp;Ok</source>
3680 <translation>&amp;אישור</translation>
3681 </message>
3682</context>
3683</TS>
diff --git a/utils/rbutilqt/lang/rbutil_it.ts b/utils/rbutilqt/lang/rbutil_it.ts
new file mode 100644
index 0000000000..259df81d0d
--- /dev/null
+++ b/utils/rbutilqt/lang/rbutil_it.ts
@@ -0,0 +1,3655 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE TS>
3<TS version="2.0" language="it_IT">
4<context>
5 <name>BackupDialog</name>
6 <message>
7 <location filename="../gui/backupdialogfrm.ui" line="17"/>
8 <location filename="../gui/backupdialogfrm.ui" line="43"/>
9 <source>Backup</source>
10 <translation type="unfinished">Backup</translation>
11 </message>
12 <message>
13 <location filename="../gui/backupdialogfrm.ui" line="33"/>
14 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This dialog will create a backup by archiving the contents of the Rockbox installation on the player into a zip file. This will include installed themes and settings stored below the .rockbox folder on the player.&lt;/p&gt;&lt;p&gt;The backup filename will be created based on the installed version. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
15 <translation type="unfinished"></translation>
16 </message>
17 <message>
18 <location filename="../gui/backupdialogfrm.ui" line="49"/>
19 <source>Size: unknown</source>
20 <translation type="unfinished"></translation>
21 </message>
22 <message>
23 <location filename="../gui/backupdialogfrm.ui" line="56"/>
24 <source>Backup to: unknown</source>
25 <translation type="unfinished"></translation>
26 </message>
27 <message>
28 <location filename="../gui/backupdialogfrm.ui" line="76"/>
29 <source>&amp;Change</source>
30 <translation type="unfinished">&amp;Cambia</translation>
31 </message>
32 <message>
33 <location filename="../gui/backupdialogfrm.ui" line="116"/>
34 <source>&amp;Backup</source>
35 <translation type="unfinished"></translation>
36 </message>
37 <message>
38 <location filename="../gui/backupdialogfrm.ui" line="127"/>
39 <source>&amp;Cancel</source>
40 <translation type="unfinished"></translation>
41 </message>
42 <message>
43 <location filename="../gui/backupdialog.cpp" line="70"/>
44 <source>Installation size: calculating ...</source>
45 <translation type="unfinished"></translation>
46 </message>
47 <message>
48 <location filename="../gui/backupdialog.cpp" line="89"/>
49 <source>Select Backup Filename</source>
50 <translation type="unfinished">Scegliere un nome per il file di backup</translation>
51 </message>
52 <message>
53 <location filename="../gui/backupdialog.cpp" line="109"/>
54 <source>Installation size: %L1 %2</source>
55 <translation type="unfinished"></translation>
56 </message>
57 <message>
58 <location filename="../gui/backupdialog.cpp" line="116"/>
59 <source>File exists</source>
60 <translation type="unfinished"></translation>
61 </message>
62 <message>
63 <location filename="../gui/backupdialog.cpp" line="117"/>
64 <source>The selected backup file already exists. Overwrite?</source>
65 <translation type="unfinished"></translation>
66 </message>
67 <message>
68 <location filename="../gui/backupdialog.cpp" line="125"/>
69 <source>Starting backup ...</source>
70 <translation type="unfinished"></translation>
71 </message>
72 <message>
73 <location filename="../gui/backupdialog.cpp" line="144"/>
74 <source>Backup successful.</source>
75 <translation type="unfinished"></translation>
76 </message>
77 <message>
78 <location filename="../gui/backupdialog.cpp" line="147"/>
79 <source>Backup failed!</source>
80 <translation type="unfinished">Backup fallito!</translation>
81 </message>
82</context>
83<context>
84 <name>BootloaderInstallAms</name>
85 <message>
86 <location filename="../base/bootloaderinstallams.cpp" line="33"/>
87 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; This file is not present on your player and will disappear automatically after installing it.&lt;br/&gt;&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
88 <translation type="unfinished"></translation>
89 </message>
90 <message>
91 <location filename="../base/bootloaderinstallams.cpp" line="58"/>
92 <source>Downloading bootloader file</source>
93 <translation type="unfinished"></translation>
94 </message>
95 <message>
96 <location filename="../base/bootloaderinstallams.cpp" line="100"/>
97 <location filename="../base/bootloaderinstallams.cpp" line="113"/>
98 <source>Could not load %1</source>
99 <translation type="unfinished"></translation>
100 </message>
101 <message>
102 <location filename="../base/bootloaderinstallams.cpp" line="127"/>
103 <source>No room to insert bootloader, try another firmware version</source>
104 <translation type="unfinished"></translation>
105 </message>
106 <message>
107 <location filename="../base/bootloaderinstallams.cpp" line="137"/>
108 <source>Patching Firmware...</source>
109 <translation type="unfinished"></translation>
110 </message>
111 <message>
112 <location filename="../base/bootloaderinstallams.cpp" line="148"/>
113 <source>Could not open %1 for writing</source>
114 <translation type="unfinished"></translation>
115 </message>
116 <message>
117 <location filename="../base/bootloaderinstallams.cpp" line="161"/>
118 <source>Could not write firmware file</source>
119 <translation type="unfinished"></translation>
120 </message>
121 <message>
122 <location filename="../base/bootloaderinstallams.cpp" line="177"/>
123 <source>Success: modified firmware file created</source>
124 <translation type="unfinished">Firmware modificato creato con successo</translation>
125 </message>
126 <message>
127 <location filename="../base/bootloaderinstallams.cpp" line="185"/>
128 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
129 <translation type="unfinished"></translation>
130 </message>
131</context>
132<context>
133 <name>BootloaderInstallBase</name>
134 <message>
135 <location filename="../base/bootloaderinstallbase.cpp" line="78"/>
136 <source>Download error: received HTTP error %1.</source>
137 <translation>Errore durante il download: errore HTTP %1.</translation>
138 </message>
139 <message>
140 <location filename="../base/bootloaderinstallbase.cpp" line="84"/>
141 <source>Download error: %1</source>
142 <translation>Errore durante il Download: %1</translation>
143 </message>
144 <message>
145 <location filename="../base/bootloaderinstallbase.cpp" line="90"/>
146 <source>Download finished (cache used).</source>
147 <translation>Download concluso (cache usata).</translation>
148 </message>
149 <message>
150 <location filename="../base/bootloaderinstallbase.cpp" line="92"/>
151 <source>Download finished.</source>
152 <translation>Download concluso.</translation>
153 </message>
154 <message>
155 <location filename="../base/bootloaderinstallbase.cpp" line="113"/>
156 <source>Creating backup of original firmware file.</source>
157 <translation>Creazione di una copia del firmware originale.</translation>
158 </message>
159 <message>
160 <location filename="../base/bootloaderinstallbase.cpp" line="115"/>
161 <source>Creating backup folder failed</source>
162 <translation>Creazione della cartella per la copia di backup fallita</translation>
163 </message>
164 <message>
165 <location filename="../base/bootloaderinstallbase.cpp" line="121"/>
166 <source>Creating backup copy failed.</source>
167 <translation>Creazione della copia di backup fallita.</translation>
168 </message>
169 <message>
170 <location filename="../base/bootloaderinstallbase.cpp" line="124"/>
171 <source>Backup created.</source>
172 <translation>Copia di backup salvata.</translation>
173 </message>
174 <message>
175 <location filename="../base/bootloaderinstallbase.cpp" line="137"/>
176 <source>Creating installation log</source>
177 <translation>Creazione del log dell&apos;installazione</translation>
178 </message>
179 <message>
180 <location filename="../base/bootloaderinstallbase.cpp" line="149"/>
181 <source>Installation log created</source>
182 <translation>File di log creato</translation>
183 </message>
184 <message>
185 <location filename="../base/bootloaderinstallbase.cpp" line="226"/>
186 <source>Zip file format detected</source>
187 <translation type="unfinished"></translation>
188 </message>
189 <message>
190 <location filename="../base/bootloaderinstallbase.cpp" line="238"/>
191 <source>CAB file format detected</source>
192 <translation type="unfinished"></translation>
193 </message>
194 <message>
195 <location filename="../base/bootloaderinstallbase.cpp" line="259"/>
196 <source>Extracting firmware %1 from archive</source>
197 <translation type="unfinished"></translation>
198 </message>
199 <message>
200 <location filename="../base/bootloaderinstallbase.cpp" line="266"/>
201 <source>Error extracting firmware from archive</source>
202 <translation type="unfinished"></translation>
203 </message>
204 <message>
205 <location filename="../base/bootloaderinstallbase.cpp" line="275"/>
206 <source>Could not find firmware in archive</source>
207 <translation type="unfinished"></translation>
208 </message>
209 <message>
210 <location filename="../base/bootloaderinstallbase.cpp" line="159"/>
211 <source>Waiting for system to remount player</source>
212 <translation type="unfinished"></translation>
213 </message>
214 <message>
215 <location filename="../base/bootloaderinstallbase.cpp" line="189"/>
216 <source>Player remounted</source>
217 <translation type="unfinished"></translation>
218 </message>
219 <message>
220 <location filename="../base/bootloaderinstallbase.cpp" line="194"/>
221 <source>Timeout on remount</source>
222 <translation type="unfinished"></translation>
223 </message>
224</context>
225<context>
226 <name>BootloaderInstallChinaChip</name>
227 <message>
228 <location filename="../base/bootloaderinstallchinachip.cpp" line="33"/>
229 <source>Bootloader installation requires you to provide a firmware file of the original firmware (HXF file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
230 <translation type="unfinished"></translation>
231 </message>
232 <message>
233 <location filename="../base/bootloaderinstallchinachip.cpp" line="50"/>
234 <source>Downloading bootloader file</source>
235 <translation type="unfinished"></translation>
236 </message>
237 <message>
238 <location filename="../base/bootloaderinstallchinachip.cpp" line="75"/>
239 <source>Could not open firmware file</source>
240 <translation type="unfinished"></translation>
241 </message>
242 <message>
243 <location filename="../base/bootloaderinstallchinachip.cpp" line="78"/>
244 <source>Could not open bootloader file</source>
245 <translation type="unfinished"></translation>
246 </message>
247 <message>
248 <location filename="../base/bootloaderinstallchinachip.cpp" line="81"/>
249 <source>Could not allocate memory</source>
250 <translation type="unfinished"></translation>
251 </message>
252 <message>
253 <location filename="../base/bootloaderinstallchinachip.cpp" line="84"/>
254 <source>Could not load firmware file</source>
255 <translation type="unfinished"></translation>
256 </message>
257 <message>
258 <location filename="../base/bootloaderinstallchinachip.cpp" line="87"/>
259 <source>File is not a valid ChinaChip firmware</source>
260 <translation type="unfinished"></translation>
261 </message>
262 <message>
263 <location filename="../base/bootloaderinstallchinachip.cpp" line="90"/>
264 <source>Could not find ccpmp.bin in input file</source>
265 <translation type="unfinished"></translation>
266 </message>
267 <message>
268 <location filename="../base/bootloaderinstallchinachip.cpp" line="93"/>
269 <source>Could not open backup file for ccpmp.bin</source>
270 <translation type="unfinished"></translation>
271 </message>
272 <message>
273 <location filename="../base/bootloaderinstallchinachip.cpp" line="96"/>
274 <source>Could not write backup file for ccpmp.bin</source>
275 <translation type="unfinished"></translation>
276 </message>
277 <message>
278 <location filename="../base/bootloaderinstallchinachip.cpp" line="99"/>
279 <source>Could not load bootloader file</source>
280 <translation type="unfinished"></translation>
281 </message>
282 <message>
283 <location filename="../base/bootloaderinstallchinachip.cpp" line="102"/>
284 <source>Could not get current time</source>
285 <translation type="unfinished"></translation>
286 </message>
287 <message>
288 <location filename="../base/bootloaderinstallchinachip.cpp" line="105"/>
289 <source>Could not open output file</source>
290 <translation type="unfinished"></translation>
291 </message>
292 <message>
293 <location filename="../base/bootloaderinstallchinachip.cpp" line="108"/>
294 <source>Could not write output file</source>
295 <translation type="unfinished"></translation>
296 </message>
297 <message>
298 <location filename="../base/bootloaderinstallchinachip.cpp" line="111"/>
299 <source>Unexpected error from chinachippatcher</source>
300 <translation type="unfinished"></translation>
301 </message>
302</context>
303<context>
304 <name>BootloaderInstallFile</name>
305 <message>
306 <location filename="../base/bootloaderinstallfile.cpp" line="34"/>
307 <source>Downloading bootloader</source>
308 <translation>Download del bootloader in corso</translation>
309 </message>
310 <message>
311 <location filename="../base/bootloaderinstallfile.cpp" line="43"/>
312 <source>Installing Rockbox bootloader</source>
313 <translation>installazione del bootloader Rockbox in corso</translation>
314 </message>
315 <message>
316 <location filename="../base/bootloaderinstallfile.cpp" line="75"/>
317 <source>Error accessing output folder</source>
318 <translation>Errore nell&apos;accedere alla cartella di destinazione</translation>
319 </message>
320 <message>
321 <location filename="../base/bootloaderinstallfile.cpp" line="89"/>
322 <source>A firmware file is already present on player</source>
323 <translation type="unfinished"></translation>
324 </message>
325 <message>
326 <location filename="../base/bootloaderinstallfile.cpp" line="94"/>
327 <source>Bootloader successful installed</source>
328 <translation>Bootloader installato con successo</translation>
329 </message>
330 <message>
331 <location filename="../base/bootloaderinstallfile.cpp" line="97"/>
332 <source>Copying modified firmware file failed</source>
333 <translation type="unfinished"></translation>
334 </message>
335 <message>
336 <location filename="../base/bootloaderinstallfile.cpp" line="111"/>
337 <source>Removing Rockbox bootloader</source>
338 <translation>Rimozione dell bootloader Rockbox in corso</translation>
339 </message>
340 <message>
341 <location filename="../base/bootloaderinstallfile.cpp" line="115"/>
342 <source>No original firmware file found.</source>
343 <translation>Nessun file contenente il firmware originale trovato.</translation>
344 </message>
345 <message>
346 <location filename="../base/bootloaderinstallfile.cpp" line="121"/>
347 <source>Can&apos;t remove Rockbox bootloader file.</source>
348 <translation>Impossibile rimuovere il file contenete il bootloader Rockbox.</translation>
349 </message>
350 <message>
351 <location filename="../base/bootloaderinstallfile.cpp" line="126"/>
352 <source>Can&apos;t restore bootloader file.</source>
353 <translation>Impossibile ripristinare il bootloader.</translation>
354 </message>
355 <message>
356 <location filename="../base/bootloaderinstallfile.cpp" line="130"/>
357 <source>Original bootloader restored successfully.</source>
358 <translation>Bootloader originale ripristinato con successo.</translation>
359 </message>
360</context>
361<context>
362 <name>BootloaderInstallHex</name>
363 <message>
364 <location filename="../base/bootloaderinstallhex.cpp" line="50"/>
365 <source>Bootloader installation requires you to provide a firmware file of the original firmware (hex file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
366 <translation>L&apos;installazione del bootloader richiede di fornire il file del firmware originale(hex file). Occorre scaricarlo a parte a causa di problemi legali. Fate riferimento al &lt;ahref=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manuale&lt;/a&gt; e al &lt;ahref=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;wiki IriverBoot&lt;/a&gt;per ottenere il file.&lt;br/&gt;Premere Ok per continuare e sfogliare le cartelle per cercare il file del firmware.</translation>
367 </message>
368 <message>
369 <location filename="../base/bootloaderinstallhex.cpp" line="69"/>
370 <source>checking MD5 hash of input file ...</source>
371 <translation>Controllo MD5 hash del file in corso...</translation>
372 </message>
373 <message>
374 <location filename="../base/bootloaderinstallhex.cpp" line="80"/>
375 <source>Could not verify original firmware file</source>
376 <translation>Impossibile verificare il file del firmware originale</translation>
377 </message>
378 <message>
379 <location filename="../base/bootloaderinstallhex.cpp" line="95"/>
380 <source>Firmware file not recognized.</source>
381 <translation>Firmware non riconosciuto.</translation>
382 </message>
383 <message>
384 <location filename="../base/bootloaderinstallhex.cpp" line="99"/>
385 <source>MD5 hash ok</source>
386 <translation>Hash MD5 ok</translation>
387 </message>
388 <message>
389 <location filename="../base/bootloaderinstallhex.cpp" line="106"/>
390 <source>Firmware file doesn&apos;t match selected player.</source>
391 <translation>Il firmware non è compatibile col player selezionato.</translation>
392 </message>
393 <message>
394 <location filename="../base/bootloaderinstallhex.cpp" line="111"/>
395 <source>Descrambling file</source>
396 <translation>Decodifica del file</translation>
397 </message>
398 <message>
399 <location filename="../base/bootloaderinstallhex.cpp" line="119"/>
400 <source>Error in descramble: %1</source>
401 <translation>Errore durante la decodifica: %1</translation>
402 </message>
403 <message>
404 <location filename="../base/bootloaderinstallhex.cpp" line="124"/>
405 <source>Downloading bootloader file</source>
406 <translation>Download del file del bootloader</translation>
407 </message>
408 <message>
409 <location filename="../base/bootloaderinstallhex.cpp" line="134"/>
410 <source>Adding bootloader to firmware file</source>
411 <translation>Aggiunta del bootloader al firmware in corso</translation>
412 </message>
413 <message>
414 <location filename="../base/bootloaderinstallhex.cpp" line="172"/>
415 <source>could not open input file</source>
416 <translation>Impossibile aprire il file</translation>
417 </message>
418 <message>
419 <location filename="../base/bootloaderinstallhex.cpp" line="173"/>
420 <source>reading header failed</source>
421 <translation>Lettura del header fallita</translation>
422 </message>
423 <message>
424 <location filename="../base/bootloaderinstallhex.cpp" line="174"/>
425 <source>reading firmware failed</source>
426 <translation>Lettura del firmware fallita</translation>
427 </message>
428 <message>
429 <location filename="../base/bootloaderinstallhex.cpp" line="175"/>
430 <source>can&apos;t open bootloader file</source>
431 <translation>Impossibile aprire il file del bootloader</translation>
432 </message>
433 <message>
434 <location filename="../base/bootloaderinstallhex.cpp" line="176"/>
435 <source>reading bootloader file failed</source>
436 <translation>Lettura del file del bootloader fallita</translation>
437 </message>
438 <message>
439 <location filename="../base/bootloaderinstallhex.cpp" line="177"/>
440 <source>can&apos;t open output file</source>
441 <translation>Impossibile aprire file in uscita</translation>
442 </message>
443 <message>
444 <location filename="../base/bootloaderinstallhex.cpp" line="178"/>
445 <source>writing output file failed</source>
446 <translation>Scrittura file in uscita fallita</translation>
447 </message>
448 <message>
449 <location filename="../base/bootloaderinstallhex.cpp" line="180"/>
450 <source>Error in patching: %1</source>
451 <translation>Errore durante l&apos;applicazione di patch: %1</translation>
452 </message>
453 <message>
454 <location filename="../base/bootloaderinstallhex.cpp" line="191"/>
455 <source>Error in scramble: %1</source>
456 <translation>Errore nella codifica: %1</translation>
457 </message>
458 <message>
459 <location filename="../base/bootloaderinstallhex.cpp" line="206"/>
460 <source>Checking modified firmware file</source>
461 <translation>Controllo del firmware modificato in corso</translation>
462 </message>
463 <message>
464 <location filename="../base/bootloaderinstallhex.cpp" line="208"/>
465 <source>Error: modified file checksum wrong</source>
466 <translation>Errore: checksum del firmware modificato errato</translation>
467 </message>
468 <message>
469 <location filename="../base/bootloaderinstallhex.cpp" line="215"/>
470 <source>A firmware file is already present on player</source>
471 <translation type="unfinished"></translation>
472 </message>
473 <message>
474 <location filename="../base/bootloaderinstallhex.cpp" line="220"/>
475 <source>Success: modified firmware file created</source>
476 <translation>Firmware modificato creato con successo</translation>
477 </message>
478 <message>
479 <location filename="../base/bootloaderinstallhex.cpp" line="223"/>
480 <source>Copying modified firmware file failed</source>
481 <translation type="unfinished"></translation>
482 </message>
483 <message>
484 <location filename="../base/bootloaderinstallhex.cpp" line="237"/>
485 <source>Uninstallation not possible, only installation info removed</source>
486 <translation type="unfinished"></translation>
487 </message>
488 <message>
489 <location filename="../base/bootloaderinstallhex.cpp" line="258"/>
490 <source>Can&apos;t open input file</source>
491 <translation>Impossibile aprire file in entrata</translation>
492 </message>
493 <message>
494 <location filename="../base/bootloaderinstallhex.cpp" line="259"/>
495 <source>Can&apos;t open output file</source>
496 <translation>Impossibile aprire file in uscita</translation>
497 </message>
498 <message>
499 <location filename="../base/bootloaderinstallhex.cpp" line="260"/>
500 <source>invalid file: header length wrong</source>
501 <translation>File non valido: lunghezza del header errata</translation>
502 </message>
503 <message>
504 <location filename="../base/bootloaderinstallhex.cpp" line="261"/>
505 <source>invalid file: unrecognized header</source>
506 <translation>File non valido: header non riconosciuto</translation>
507 </message>
508 <message>
509 <location filename="../base/bootloaderinstallhex.cpp" line="262"/>
510 <source>invalid file: &quot;length&quot; field wrong</source>
511 <translation>File non valido: campo &quot;lenght&quot; errato</translation>
512 </message>
513 <message>
514 <location filename="../base/bootloaderinstallhex.cpp" line="263"/>
515 <source>invalid file: &quot;length2&quot; field wrong</source>
516 <translation>File non valido: campo &quot;lenght2&quot; non valido</translation>
517 </message>
518 <message>
519 <location filename="../base/bootloaderinstallhex.cpp" line="264"/>
520 <source>invalid file: internal checksum error</source>
521 <translation>File non valido: checksum errato</translation>
522 </message>
523 <message>
524 <location filename="../base/bootloaderinstallhex.cpp" line="265"/>
525 <source>invalid file: &quot;length3&quot; field wrong</source>
526 <translation>File non valido: campo &quot;lenght3&quot; errato</translation>
527 </message>
528 <message>
529 <location filename="../base/bootloaderinstallhex.cpp" line="266"/>
530 <source>unknown</source>
531 <translation>sconosciuto</translation>
532 </message>
533</context>
534<context>
535 <name>BootloaderInstallImx</name>
536 <message>
537 <location filename="../base/bootloaderinstallimx.cpp" line="72"/>
538 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (firmware.sb file). This file will be patched with the Rockbox bootloader and installed to your player. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
539 <translation type="unfinished"></translation>
540 </message>
541 <message>
542 <location filename="../base/bootloaderinstallimx.cpp" line="94"/>
543 <source>Could not read original firmware file</source>
544 <translation type="unfinished"></translation>
545 </message>
546 <message>
547 <location filename="../base/bootloaderinstallimx.cpp" line="100"/>
548 <source>Downloading bootloader file</source>
549 <translation type="unfinished"></translation>
550 </message>
551 <message>
552 <location filename="../base/bootloaderinstallimx.cpp" line="110"/>
553 <source>Patching file...</source>
554 <translation type="unfinished"></translation>
555 </message>
556 <message>
557 <location filename="../base/bootloaderinstallimx.cpp" line="137"/>
558 <source>Patching the original firmware failed</source>
559 <translation type="unfinished"></translation>
560 </message>
561 <message>
562 <location filename="../base/bootloaderinstallimx.cpp" line="143"/>
563 <source>Succesfully patched firmware file</source>
564 <translation type="unfinished"></translation>
565 </message>
566 <message>
567 <location filename="../base/bootloaderinstallimx.cpp" line="158"/>
568 <source>Bootloader successful installed</source>
569 <translation type="unfinished">Bootloader installato con successo</translation>
570 </message>
571 <message>
572 <location filename="../base/bootloaderinstallimx.cpp" line="164"/>
573 <source>Patched bootloader could not be installed</source>
574 <translation type="unfinished"></translation>
575 </message>
576 <message>
577 <location filename="../base/bootloaderinstallimx.cpp" line="175"/>
578 <source>To uninstall, perform a normal upgrade with an unmodified original firmware.</source>
579 <translation type="unfinished"></translation>
580 </message>
581</context>
582<context>
583 <name>BootloaderInstallIpod</name>
584 <message>
585 <location filename="../base/bootloaderinstallipod.cpp" line="49"/>
586 <source>Error: can&apos;t allocate buffer memory!</source>
587 <translation>Errore: impossibile allocare memoria buffer!</translation>
588 </message>
589 <message>
590 <location filename="../base/bootloaderinstallipod.cpp" line="80"/>
591 <source>Downloading bootloader file</source>
592 <translation>Download del bootloader in corso</translation>
593 </message>
594 <message>
595 <location filename="../base/bootloaderinstallipod.cpp" line="90"/>
596 <source>Installing Rockbox bootloader</source>
597 <translation>Installazione del file del bootloader in corso</translation>
598 </message>
599 <message>
600 <location filename="../base/bootloaderinstallipod.cpp" line="64"/>
601 <location filename="../base/bootloaderinstallipod.cpp" line="151"/>
602 <source>Failed to read firmware directory</source>
603 <translation>Impossibile leggere la directory del firmware</translation>
604 </message>
605 <message>
606 <location filename="../base/bootloaderinstallipod.cpp" line="69"/>
607 <location filename="../base/bootloaderinstallipod.cpp" line="156"/>
608 <source>Unknown version number in firmware (%1)</source>
609 <translation>Numero di versione del firmware sconosciuto (%1)</translation>
610 </message>
611 <message>
612 <location filename="../base/bootloaderinstallipod.cpp" line="75"/>
613 <source>Warning: This is a MacPod, Rockbox only runs on WinPods.
614See http://www.rockbox.org/wiki/IpodConversionToFAT32</source>
615 <translation type="unfinished"></translation>
616 </message>
617 <message>
618 <location filename="../base/bootloaderinstallipod.cpp" line="94"/>
619 <location filename="../base/bootloaderinstallipod.cpp" line="163"/>
620 <source>Could not open Ipod in R/W mode</source>
621 <translation>Impossibile accedere all&apos;Ipod in R/W</translation>
622 </message>
623 <message>
624 <location filename="../base/bootloaderinstallipod.cpp" line="104"/>
625 <source>Successfull added bootloader</source>
626 <translation>Bootloader installato con successo</translation>
627 </message>
628 <message>
629 <location filename="../base/bootloaderinstallipod.cpp" line="115"/>
630 <source>Failed to add bootloader</source>
631 <translation>Errore nell&apos;installazione del bootloader</translation>
632 </message>
633 <message>
634 <location filename="../base/bootloaderinstallipod.cpp" line="127"/>
635 <source>Bootloader Installation complete.</source>
636 <translation type="unfinished"></translation>
637 </message>
638 <message>
639 <location filename="../base/bootloaderinstallipod.cpp" line="132"/>
640 <source>Writing log aborted</source>
641 <translation type="unfinished"></translation>
642 </message>
643 <message>
644 <location filename="../base/bootloaderinstallipod.cpp" line="142"/>
645 <source>Uninstalling bootloader</source>
646 <translation>Disinstallazione bootloader in corso</translation>
647 </message>
648 <message>
649 <location filename="../base/bootloaderinstallipod.cpp" line="169"/>
650 <source>No bootloader detected.</source>
651 <translation>Nessun bootloader trovato.</translation>
652 </message>
653 <message>
654 <location filename="../base/bootloaderinstallipod.cpp" line="175"/>
655 <source>Successfully removed bootloader</source>
656 <translation>Bootloader rimosso con successo</translation>
657 </message>
658 <message>
659 <location filename="../base/bootloaderinstallipod.cpp" line="182"/>
660 <source>Removing bootloader failed.</source>
661 <translation>Rimozione del bootloader fallita.</translation>
662 </message>
663 <message>
664 <location filename="../base/bootloaderinstallipod.cpp" line="228"/>
665 <source>Error: could not retrieve device name</source>
666 <translation type="unfinished"></translation>
667 </message>
668 <message>
669 <location filename="../base/bootloaderinstallipod.cpp" line="244"/>
670 <source>Error: no mountpoint specified!</source>
671 <translation type="unfinished"></translation>
672 </message>
673 <message>
674 <location filename="../base/bootloaderinstallipod.cpp" line="249"/>
675 <source>Could not open Ipod: permission denied</source>
676 <translation type="unfinished"></translation>
677 </message>
678 <message>
679 <location filename="../base/bootloaderinstallipod.cpp" line="253"/>
680 <source>Could not open Ipod</source>
681 <translation>impossibile accedere all&apos;Ipod</translation>
682 </message>
683 <message>
684 <location filename="../base/bootloaderinstallipod.cpp" line="258"/>
685 <source>Error reading partition table - possibly not an Ipod</source>
686 <translation>Errore nel leggere la tabelle delle partizioni - è possibile che non sia un Ipod</translation>
687 </message>
688 <message>
689 <location filename="../base/bootloaderinstallipod.cpp" line="264"/>
690 <source>No firmware partition on disk</source>
691 <translation>Nessuna partizione per il firmware presente su disco</translation>
692 </message>
693</context>
694<context>
695 <name>BootloaderInstallMi4</name>
696 <message>
697 <location filename="../base/bootloaderinstallmi4.cpp" line="34"/>
698 <source>Downloading bootloader</source>
699 <translation>Download del bootloader in corso</translation>
700 </message>
701 <message>
702 <location filename="../base/bootloaderinstallmi4.cpp" line="43"/>
703 <source>Installing Rockbox bootloader</source>
704 <translation>installazione del bootloader Rockbox in corso</translation>
705 </message>
706 <message>
707 <location filename="../base/bootloaderinstallmi4.cpp" line="66"/>
708 <source>A firmware file is already present on player</source>
709 <translation type="unfinished"></translation>
710 </message>
711 <message>
712 <location filename="../base/bootloaderinstallmi4.cpp" line="71"/>
713 <location filename="../base/bootloaderinstallmi4.cpp" line="79"/>
714 <source>Bootloader successful installed</source>
715 <translation>Bootloader installato con successo</translation>
716 </message>
717 <message>
718 <location filename="../base/bootloaderinstallmi4.cpp" line="74"/>
719 <source>Copying modified firmware file failed</source>
720 <translation type="unfinished"></translation>
721 </message>
722 <message>
723 <location filename="../base/bootloaderinstallmi4.cpp" line="91"/>
724 <source>Checking for Rockbox bootloader</source>
725 <translation>Ricerca del bootloader Rockbox in corso</translation>
726 </message>
727 <message>
728 <location filename="../base/bootloaderinstallmi4.cpp" line="93"/>
729 <source>No Rockbox bootloader found</source>
730 <translation>Nessun Bootloader Rockbox trovato</translation>
731 </message>
732 <message>
733 <location filename="../base/bootloaderinstallmi4.cpp" line="98"/>
734 <source>Checking for original firmware file</source>
735 <translation>Ricerca del file del firmware originale in corso</translation>
736 </message>
737 <message>
738 <location filename="../base/bootloaderinstallmi4.cpp" line="103"/>
739 <source>Error finding original firmware file</source>
740 <translation>Errore nel cercare il firmware originale</translation>
741 </message>
742 <message>
743 <location filename="../base/bootloaderinstallmi4.cpp" line="113"/>
744 <source>Rockbox bootloader successful removed</source>
745 <translation>Bootloader Rockbox rimosso con successo</translation>
746 </message>
747</context>
748<context>
749 <name>BootloaderInstallMpio</name>
750 <message>
751 <location filename="../base/bootloaderinstallmpio.cpp" line="34"/>
752 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
753 <translation type="unfinished"></translation>
754 </message>
755 <message>
756 <location filename="../base/bootloaderinstallmpio.cpp" line="53"/>
757 <source>Downloading bootloader file</source>
758 <translation type="unfinished"></translation>
759 </message>
760 <message>
761 <location filename="../base/bootloaderinstallmpio.cpp" line="80"/>
762 <source>Could not open the original firmware.</source>
763 <translation type="unfinished"></translation>
764 </message>
765 <message>
766 <location filename="../base/bootloaderinstallmpio.cpp" line="83"/>
767 <source>Could not read the original firmware.</source>
768 <translation type="unfinished"></translation>
769 </message>
770 <message>
771 <location filename="../base/bootloaderinstallmpio.cpp" line="86"/>
772 <source>Loaded firmware file does not look like MPIO original firmware file.</source>
773 <translation type="unfinished"></translation>
774 </message>
775 <message>
776 <location filename="../base/bootloaderinstallmpio.cpp" line="101"/>
777 <source>Could not open output file.</source>
778 <translation type="unfinished"></translation>
779 </message>
780 <message>
781 <location filename="../base/bootloaderinstallmpio.cpp" line="104"/>
782 <source>Could not write output file.</source>
783 <translation type="unfinished"></translation>
784 </message>
785 <message>
786 <location filename="../base/bootloaderinstallmpio.cpp" line="107"/>
787 <source>Unknown error number: %1</source>
788 <translation type="unfinished"></translation>
789 </message>
790 <message>
791 <location filename="../base/bootloaderinstallmpio.cpp" line="89"/>
792 <source>Could not open downloaded bootloader.</source>
793 <translation type="unfinished"></translation>
794 </message>
795 <message>
796 <location filename="../base/bootloaderinstallmpio.cpp" line="92"/>
797 <source>Place for bootloader in OF file not empty.</source>
798 <translation type="unfinished"></translation>
799 </message>
800 <message>
801 <location filename="../base/bootloaderinstallmpio.cpp" line="95"/>
802 <source>Could not read the downloaded bootloader.</source>
803 <translation type="unfinished"></translation>
804 </message>
805 <message>
806 <location filename="../base/bootloaderinstallmpio.cpp" line="98"/>
807 <source>Bootloader checksum error.</source>
808 <translation type="unfinished"></translation>
809 </message>
810 <message>
811 <location filename="../base/bootloaderinstallmpio.cpp" line="112"/>
812 <source>Patching original firmware failed: %1</source>
813 <translation type="unfinished"></translation>
814 </message>
815 <message>
816 <location filename="../base/bootloaderinstallmpio.cpp" line="119"/>
817 <source>Success: modified firmware file created</source>
818 <translation type="unfinished">Firmware modificato creato con successo</translation>
819 </message>
820 <message>
821 <location filename="../base/bootloaderinstallmpio.cpp" line="127"/>
822 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
823 <translation type="unfinished"></translation>
824 </message>
825</context>
826<context>
827 <name>BootloaderInstallSansa</name>
828 <message>
829 <location filename="../base/bootloaderinstallsansa.cpp" line="50"/>
830 <source>Error: can&apos;t allocate buffer memory!</source>
831 <translation>Errore: impossibile allocare memoria buffer!</translation>
832 </message>
833 <message>
834 <location filename="../base/bootloaderinstallsansa.cpp" line="55"/>
835 <source>Searching for Sansa</source>
836 <translation>Ricerca del Sansa in corso</translation>
837 </message>
838 <message>
839 <location filename="../base/bootloaderinstallsansa.cpp" line="59"/>
840 <source>Permission for disc access denied!
841This is required to install the bootloader</source>
842 <translation>Permesso di accesso al disco negato!
843Questo occorre per installare il bootloader</translation>
844 </message>
845 <message>
846 <location filename="../base/bootloaderinstallsansa.cpp" line="66"/>
847 <source>No Sansa detected!</source>
848 <translation>Nessun Sansa individuato!</translation>
849 </message>
850 <message>
851 <location filename="../base/bootloaderinstallsansa.cpp" line="79"/>
852 <source>Downloading bootloader file</source>
853 <translation>Download del bootloader in corso</translation>
854 </message>
855 <message>
856 <location filename="../base/bootloaderinstallsansa.cpp" line="94"/>
857 <source>Installing Rockbox bootloader</source>
858 <translation>Installazione del bootloader in corso</translation>
859 </message>
860 <message>
861 <location filename="../base/bootloaderinstallsansa.cpp" line="71"/>
862 <location filename="../base/bootloaderinstallsansa.cpp" line="179"/>
863 <source>OLD ROCKBOX INSTALLATION DETECTED, ABORTING.
864You must reinstall the original Sansa firmware before running
865sansapatcher for the first time.
866See http://www.rockbox.org/wiki/SansaE200Install
867</source>
868 <translation>TROVATA UNA VECCHIA INSTALLAZIONE DI ROCKBOX, INTERRUZIONE IN CORSO.
869Si deve reinstallare il firmware originale Sansa prima di avviare sansapatcher per la prima volta.
870Vedi http://www.rockbox.org/wiki/SansaE200Install
871</translation>
872 </message>
873 <message>
874 <location filename="../base/bootloaderinstallsansa.cpp" line="102"/>
875 <location filename="../base/bootloaderinstallsansa.cpp" line="189"/>
876 <source>Could not open Sansa in R/W mode</source>
877 <translation>impossibile acceder al Sansa in modo R/W</translation>
878 </message>
879 <message>
880 <location filename="../base/bootloaderinstallsansa.cpp" line="111"/>
881 <source>Checking downloaded bootloader</source>
882 <translation>Controllo del bootloader scaricato in corso</translation>
883 </message>
884 <message>
885 <location filename="../base/bootloaderinstallsansa.cpp" line="119"/>
886 <source>Bootloader mismatch! Aborting.</source>
887 <translation>Bootloader non corrispondente! Interruzione in corso.</translation>
888 </message>
889 <message>
890 <location filename="../base/bootloaderinstallsansa.cpp" line="129"/>
891 <source>Successfully installed bootloader</source>
892 <translation>Bootloader installato con successo</translation>
893 </message>
894 <message>
895 <location filename="../base/bootloaderinstallsansa.cpp" line="140"/>
896 <source>Failed to install bootloader</source>
897 <translation>Installazione bootloader fallita</translation>
898 </message>
899 <message>
900 <location filename="../base/bootloaderinstallsansa.cpp" line="153"/>
901 <source>Bootloader Installation complete.</source>
902 <translation type="unfinished"></translation>
903 </message>
904 <message>
905 <location filename="../base/bootloaderinstallsansa.cpp" line="158"/>
906 <source>Writing log aborted</source>
907 <translation type="unfinished"></translation>
908 </message>
909 <message>
910 <location filename="../base/bootloaderinstallsansa.cpp" line="170"/>
911 <source>Uninstalling bootloader</source>
912 <translation>Disinstallazione bootloader in corso</translation>
913 </message>
914 <message>
915 <location filename="../base/bootloaderinstallsansa.cpp" line="195"/>
916 <source>Successfully removed bootloader</source>
917 <translation>bootloader rimosso con successo</translation>
918 </message>
919 <message>
920 <location filename="../base/bootloaderinstallsansa.cpp" line="202"/>
921 <source>Removing bootloader failed.</source>
922 <translation>Rimozione bootloader fallita.</translation>
923 </message>
924 <message>
925 <location filename="../base/bootloaderinstallsansa.cpp" line="238"/>
926 <source>Error: could not retrieve device name</source>
927 <translation type="unfinished"></translation>
928 </message>
929 <message>
930 <location filename="../base/bootloaderinstallsansa.cpp" line="254"/>
931 <source>Can&apos;t find Sansa</source>
932 <translation>Impossibile trovare il Sansa</translation>
933 </message>
934 <message>
935 <location filename="../base/bootloaderinstallsansa.cpp" line="259"/>
936 <source>Could not open Sansa</source>
937 <translation>impossibile accedere al Sansa</translation>
938 </message>
939 <message>
940 <location filename="../base/bootloaderinstallsansa.cpp" line="264"/>
941 <source>Could not read partition table</source>
942 <translation>Impossibile leggere la tabella delle partizioni</translation>
943 </message>
944 <message>
945 <location filename="../base/bootloaderinstallsansa.cpp" line="271"/>
946 <source>Disk is not a Sansa (Error %1), aborting.</source>
947 <translation>Il disco non è di un Sansa (Errore %1), interruzione in corso.</translation>
948 </message>
949</context>
950<context>
951 <name>BootloaderInstallTcc</name>
952 <message>
953 <location filename="../base/bootloaderinstalltcc.cpp" line="33"/>
954 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wiki page on how to obtain the file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
955 <translation type="unfinished"></translation>
956 </message>
957 <message>
958 <location filename="../base/bootloaderinstalltcc.cpp" line="50"/>
959 <source>Downloading bootloader file</source>
960 <translation type="unfinished"></translation>
961 </message>
962 <message>
963 <location filename="../base/bootloaderinstalltcc.cpp" line="82"/>
964 <location filename="../base/bootloaderinstalltcc.cpp" line="99"/>
965 <source>Could not load %1</source>
966 <translation type="unfinished"></translation>
967 </message>
968 <message>
969 <location filename="../base/bootloaderinstalltcc.cpp" line="90"/>
970 <source>Unknown OF file used: %1</source>
971 <translation type="unfinished"></translation>
972 </message>
973 <message>
974 <location filename="../base/bootloaderinstalltcc.cpp" line="104"/>
975 <source>Patching Firmware...</source>
976 <translation type="unfinished"></translation>
977 </message>
978 <message>
979 <location filename="../base/bootloaderinstalltcc.cpp" line="111"/>
980 <source>Could not patch firmware</source>
981 <translation type="unfinished"></translation>
982 </message>
983 <message>
984 <location filename="../base/bootloaderinstalltcc.cpp" line="117"/>
985 <source>Could not open %1 for writing</source>
986 <translation type="unfinished"></translation>
987 </message>
988 <message>
989 <location filename="../base/bootloaderinstalltcc.cpp" line="126"/>
990 <source>Could not write firmware file</source>
991 <translation type="unfinished"></translation>
992 </message>
993 <message>
994 <location filename="../base/bootloaderinstalltcc.cpp" line="131"/>
995 <source>Success: modified firmware file created</source>
996 <translation type="unfinished">Firmware modificato creato con successo</translation>
997 </message>
998 <message>
999 <location filename="../base/bootloaderinstalltcc.cpp" line="151"/>
1000 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
1001 <translation type="unfinished"></translation>
1002 </message>
1003</context>
1004<context>
1005 <name>Changelog</name>
1006 <message>
1007 <location filename="../gui/changelogfrm.ui" line="17"/>
1008 <source>Changelog</source>
1009 <translation type="unfinished"></translation>
1010 </message>
1011 <message>
1012 <location filename="../gui/changelogfrm.ui" line="39"/>
1013 <source>Show on startup</source>
1014 <translation type="unfinished"></translation>
1015 </message>
1016 <message>
1017 <location filename="../gui/changelogfrm.ui" line="46"/>
1018 <source>&amp;Ok</source>
1019 <translation type="unfinished">&amp;Ok</translation>
1020 </message>
1021</context>
1022<context>
1023 <name>Config</name>
1024 <message>
1025 <location filename="../configure.cpp" line="130"/>
1026 <source>The following errors occurred:</source>
1027 <translation>Si è presentato il seguente errore:</translation>
1028 </message>
1029 <message>
1030 <location filename="../configure.cpp" line="175"/>
1031 <source>No mountpoint given</source>
1032 <translation>Nessun mountpoint scelto</translation>
1033 </message>
1034 <message>
1035 <location filename="../configure.cpp" line="179"/>
1036 <source>Mountpoint does not exist</source>
1037 <translation>Mountpoint inesistente</translation>
1038 </message>
1039 <message>
1040 <location filename="../configure.cpp" line="183"/>
1041 <source>Mountpoint is not a directory.</source>
1042 <translation>Il Mountpoint non è una cartella.</translation>
1043 </message>
1044 <message>
1045 <location filename="../configure.cpp" line="187"/>
1046 <source>Mountpoint is not writeable</source>
1047 <translation>Il Mountpoint non è scrivibile</translation>
1048 </message>
1049 <message>
1050 <location filename="../configure.cpp" line="202"/>
1051 <source>No player selected</source>
1052 <translation>Nessun player selezionato</translation>
1053 </message>
1054 <message>
1055 <location filename="../configure.cpp" line="209"/>
1056 <source>Cache path not writeable. Leave path empty to default to systems temporary path.</source>
1057 <translation>Percorso cache non scrivibile.Lasciare in bianco per usare il percorso temporaneo di default.</translation>
1058 </message>
1059 <message>
1060 <location filename="../configure.cpp" line="228"/>
1061 <source>You need to fix the above errors before you can continue.</source>
1062 <translation>Occorre correggere gli errori sopraelencati prima di continuare.</translation>
1063 </message>
1064 <message>
1065 <location filename="../configure.cpp" line="231"/>
1066 <source>Configuration error</source>
1067 <translation>errore nella configurazione</translation>
1068 </message>
1069 <message>
1070 <location filename="../configure.cpp" line="322"/>
1071 <source>Current cache size is %L1 kiB.</source>
1072 <translation>La dimensione corrente della cache è %L1 kiB.</translation>
1073 </message>
1074 <message>
1075 <location filename="../configure.cpp" line="340"/>
1076 <source>Showing disabled targets</source>
1077 <translation type="unfinished"></translation>
1078 </message>
1079 <message>
1080 <location filename="../configure.cpp" line="341"/>
1081 <source>You just enabled showing targets that are marked disabled. Disabled targets are not recommended to end users. Please use this option only if you know what you are doing.</source>
1082 <translation type="unfinished"></translation>
1083 </message>
1084 <message>
1085 <location filename="../configure.cpp" line="448"/>
1086 <location filename="../configure.cpp" line="914"/>
1087 <source>TTS error</source>
1088 <translation type="unfinished"></translation>
1089 </message>
1090 <message>
1091 <location filename="../configure.cpp" line="449"/>
1092 <location filename="../configure.cpp" line="915"/>
1093 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1094 <translation type="unfinished"></translation>
1095 </message>
1096 <message>
1097 <location filename="../configure.cpp" line="455"/>
1098 <location filename="../configure.cpp" line="485"/>
1099 <source>Configuration OK</source>
1100 <translation>Configurazione OK</translation>
1101 </message>
1102 <message>
1103 <location filename="../configure.cpp" line="461"/>
1104 <location filename="../configure.cpp" line="490"/>
1105 <source>Configuration INVALID</source>
1106 <translation>Configurazione NON VALIDA</translation>
1107 </message>
1108 <message>
1109 <location filename="../configure.cpp" line="529"/>
1110 <source>Proxy Detection</source>
1111 <translation type="unfinished"></translation>
1112 </message>
1113 <message>
1114 <location filename="../configure.cpp" line="530"/>
1115 <source>The System Proxy settings are invalid!
1116Rockbox Utility can&apos;t work with this proxy settings. Make sure the system proxy is set correctly. Note that &quot;proxy auto-config (PAC)&quot; scripts are not supported by Rockbox Utility. If your system uses this you need to use manual proxy settings.</source>
1117 <translation type="unfinished"></translation>
1118 </message>
1119 <message>
1120 <location filename="../configure.cpp" line="643"/>
1121 <source>Set Cache Path</source>
1122 <translation type="unfinished"></translation>
1123 </message>
1124 <message>
1125 <location filename="../configure.cpp" line="665"/>
1126 <source>%1 (%2 GiB of %3 GiB free)</source>
1127 <translation type="unfinished"></translation>
1128 </message>
1129 <message>
1130 <location filename="../configure.cpp" line="739"/>
1131 <source>Multiple devices have been detected. Please disconnect all players but one and try again.</source>
1132 <translation type="unfinished"></translation>
1133 </message>
1134 <message>
1135 <location filename="../configure.cpp" line="742"/>
1136 <source>Detected devices:</source>
1137 <translation type="unfinished"></translation>
1138 </message>
1139 <message>
1140 <location filename="../configure.cpp" line="747"/>
1141 <source>(unknown)</source>
1142 <translation type="unfinished"></translation>
1143 </message>
1144 <message>
1145 <location filename="../configure.cpp" line="749"/>
1146 <source>%1 at %2</source>
1147 <translation type="unfinished"></translation>
1148 </message>
1149 <message>
1150 <location filename="../configure.cpp" line="755"/>
1151 <source>Note: detecting connected devices might be ambiguous. You might have less devices connected than listed. In this case it might not be possible to detect your player unambiguously.</source>
1152 <translation type="unfinished"></translation>
1153 </message>
1154 <message>
1155 <location filename="../configure.cpp" line="759"/>
1156 <location filename="../configure.cpp" line="763"/>
1157 <location filename="../configure.cpp" line="805"/>
1158 <source>Device Detection</source>
1159 <translation type="unfinished"></translation>
1160 </message>
1161 <message>
1162 <location filename="../configure.cpp" line="788"/>
1163 <source>%1 &quot;MacPod&quot; found!
1164Rockbox needs a FAT formatted Ipod (so-called &quot;WinPod&quot;) to run. </source>
1165 <translation type="unfinished"></translation>
1166 </message>
1167 <message>
1168 <source>Fatal error</source>
1169 <translation type="obsolete">Errore fatale</translation>
1170 </message>
1171 <message>
1172 <location filename="../configure.cpp" line="774"/>
1173 <source>Detected an unsupported player:
1174%1
1175Sorry, Rockbox doesn&apos;t run on your player.</source>
1176 <translation type="unfinished"></translation>
1177 </message>
1178 <message>
1179 <location filename="../configure.cpp" line="921"/>
1180 <source>TTS configuration invalid</source>
1181 <translation type="unfinished"></translation>
1182 </message>
1183 <message>
1184 <location filename="../configure.cpp" line="922"/>
1185 <source>TTS configuration invalid.
1186 Please configure TTS engine.</source>
1187 <translation type="unfinished"></translation>
1188 </message>
1189 <message>
1190 <location filename="../configure.cpp" line="927"/>
1191 <source>Could not start TTS engine.</source>
1192 <translation type="unfinished"></translation>
1193 </message>
1194 <message>
1195 <location filename="../configure.cpp" line="928"/>
1196 <source>Could not start TTS engine.
1197</source>
1198 <translation type="unfinished"></translation>
1199 </message>
1200 <message>
1201 <location filename="../configure.cpp" line="929"/>
1202 <location filename="../configure.cpp" line="948"/>
1203 <source>
1204Please configure TTS engine.</source>
1205 <translation type="unfinished"></translation>
1206 </message>
1207 <message>
1208 <location filename="../configure.cpp" line="943"/>
1209 <source>Rockbox Utility Voice Test</source>
1210 <translation type="unfinished"></translation>
1211 </message>
1212 <message>
1213 <location filename="../configure.cpp" line="946"/>
1214 <source>Could not voice test string.</source>
1215 <translation type="unfinished"></translation>
1216 </message>
1217 <message>
1218 <location filename="../configure.cpp" line="947"/>
1219 <source>Could not voice test string.
1220</source>
1221 <translation type="unfinished"></translation>
1222 </message>
1223 <message>
1224 <location filename="../configure.cpp" line="858"/>
1225 <source>Autodetection</source>
1226 <translation>Riconoscimento automatico</translation>
1227 </message>
1228 <message>
1229 <location filename="../configure.cpp" line="780"/>
1230 <source>%1 in MTP mode found!
1231You need to change your player to MSC mode for installation. </source>
1232 <translation type="unfinished"></translation>
1233 </message>
1234 <message>
1235 <location filename="../configure.cpp" line="859"/>
1236 <source>Could not detect a Mountpoint.
1237Select your Mountpoint manually.</source>
1238 <translation>Impossibile individuare un Mountpoint.Selezionare un Mountpoint manualmente.</translation>
1239 </message>
1240 <message>
1241 <location filename="../configure.cpp" line="764"/>
1242 <source>Could not detect a device.
1243Select your device and Mountpoint manually.</source>
1244 <translation>Impossibile individuare il dispositivo.Selezionare il dispositivo e il Mountpoint manualmente.</translation>
1245 </message>
1246 <message>
1247 <location filename="../configure.cpp" line="794"/>
1248 <source>The player contains an incompatible filesystem.
1249Make sure you selected the correct mountpoint and the player is set up to use a filesystem compatible with Rockbox.</source>
1250 <translation type="unfinished"></translation>
1251 </message>
1252 <message>
1253 <location filename="../configure.cpp" line="802"/>
1254 <source>An unknown error occured during player detection.</source>
1255 <translation type="unfinished"></translation>
1256 </message>
1257 <message>
1258 <location filename="../configure.cpp" line="869"/>
1259 <source>Really delete cache?</source>
1260 <translation>Cancellare veramente la cache?</translation>
1261 </message>
1262 <message>
1263 <location filename="../configure.cpp" line="870"/>
1264 <source>Do you really want to delete the cache? Make absolutely sure this setting is correct as it will remove &lt;b&gt;all&lt;/b&gt; files in this folder!</source>
1265 <translation>Si vuole cancellare veramente la cache? Assicurarsi che questa impostazione sia corretta poichè cancellarà&lt;b&gt;tutti&lt;/b&gt;i files in questa cartella!</translation>
1266 </message>
1267 <message>
1268 <location filename="../configure.cpp" line="878"/>
1269 <source>Path wrong!</source>
1270 <translation>Percorso nonvalido!</translation>
1271 </message>
1272 <message>
1273 <location filename="../configure.cpp" line="879"/>
1274 <source>The cache path is invalid. Aborting.</source>
1275 <translation>Il percorso per la cache non è valido.Interruzione in corso.</translation>
1276 </message>
1277</context>
1278<context>
1279 <name>ConfigForm</name>
1280 <message>
1281 <location filename="../configurefrm.ui" line="14"/>
1282 <source>Configuration</source>
1283 <translation>Configurazione</translation>
1284 </message>
1285 <message>
1286 <location filename="../configurefrm.ui" line="20"/>
1287 <source>Configure Rockbox Utility</source>
1288 <translation>Configurazione Rockbox Utility</translation>
1289 </message>
1290 <message>
1291 <location filename="../configurefrm.ui" line="35"/>
1292 <source>&amp;Device</source>
1293 <translation>&amp;Dispositivo</translation>
1294 </message>
1295 <message>
1296 <location filename="../configurefrm.ui" line="41"/>
1297 <source>Select your device in the &amp;filesystem</source>
1298 <translation>&amp;Seleziona il tuo dispositivo dal filesystem</translation>
1299 </message>
1300 <message>
1301 <location filename="../configurefrm.ui" line="319"/>
1302 <source>&amp;Browse</source>
1303 <translation>&amp;Sfoglia</translation>
1304 </message>
1305 <message>
1306 <location filename="../configurefrm.ui" line="72"/>
1307 <source>&amp;Select your audio player</source>
1308 <translation>&amp;Seleziona il tuo player audio</translation>
1309 </message>
1310 <message>
1311 <location filename="../configurefrm.ui" line="58"/>
1312 <source>&amp;Refresh</source>
1313 <translation type="unfinished">&amp;Aggiorna</translation>
1314 </message>
1315 <message>
1316 <location filename="../configurefrm.ui" line="95"/>
1317 <source>Show disabled targets</source>
1318 <translation type="unfinished"></translation>
1319 </message>
1320 <message>
1321 <location filename="../configurefrm.ui" line="114"/>
1322 <source>&amp;Autodetect</source>
1323 <translation>&amp;Individuazione automatica</translation>
1324 </message>
1325 <message>
1326 <location filename="../configurefrm.ui" line="136"/>
1327 <source>&amp;Proxy</source>
1328 <translation>&amp;Proxy</translation>
1329 </message>
1330 <message>
1331 <location filename="../configurefrm.ui" line="142"/>
1332 <source>&amp;No Proxy</source>
1333 <translation>&amp;Nessun Proxy</translation>
1334 </message>
1335 <message>
1336 <location filename="../configurefrm.ui" line="152"/>
1337 <source>Use S&amp;ystem values</source>
1338 <translation>&amp;Usa impostazioni di sistema</translation>
1339 </message>
1340 <message>
1341 <location filename="../configurefrm.ui" line="159"/>
1342 <source>&amp;Manual Proxy settings</source>
1343 <translation>&amp;Impostazioe manuale proxy</translation>
1344 </message>
1345 <message>
1346 <location filename="../configurefrm.ui" line="166"/>
1347 <source>Proxy Values</source>
1348 <translation>Valori Proxy</translation>
1349 </message>
1350 <message>
1351 <location filename="../configurefrm.ui" line="172"/>
1352 <source>&amp;Host:</source>
1353 <translation>&amp;Host:</translation>
1354 </message>
1355 <message>
1356 <location filename="../configurefrm.ui" line="182"/>
1357 <source>&amp;Port:</source>
1358 <translation>&amp;Port:</translation>
1359 </message>
1360 <message>
1361 <location filename="../configurefrm.ui" line="199"/>
1362 <source>&amp;Username</source>
1363 <translation>&amp;Nome Utente</translation>
1364 </message>
1365 <message>
1366 <location filename="../configurefrm.ui" line="209"/>
1367 <source>Pass&amp;word</source>
1368 <translation>&amp;Password</translation>
1369 </message>
1370 <message>
1371 <location filename="../configurefrm.ui" line="219"/>
1372 <source>Show</source>
1373 <translation type="unfinished"></translation>
1374 </message>
1375 <message>
1376 <location filename="../configurefrm.ui" line="260"/>
1377 <source>&amp;Language</source>
1378 <translation>&amp;Lingua</translation>
1379 </message>
1380 <message>
1381 <location filename="../configurefrm.ui" line="274"/>
1382 <source>Cac&amp;he</source>
1383 <translation>&amp;Cache</translation>
1384 </message>
1385 <message>
1386 <location filename="../configurefrm.ui" line="277"/>
1387 <source>Download cache settings</source>
1388 <translation>Impostazioni cartella/cache per il download</translation>
1389 </message>
1390 <message>
1391 <location filename="../configurefrm.ui" line="283"/>
1392 <source>Rockbox Utility uses a local download cache to save network traffic. You can change the path to the cache and use it as local repository by enabling Offline mode.</source>
1393 <translation>l&apos;Utility Rockbox usa una cartella/cache locale per il download per i file scaricati. Puoi cambiare il percorso della cache e usarla come repository locale abilitando la modalità Offline.</translation>
1394 </message>
1395 <message>
1396 <location filename="../configurefrm.ui" line="293"/>
1397 <source>Current cache size is %1</source>
1398 <translation>La dimensione corrente della cache è %1</translation>
1399 </message>
1400 <message>
1401 <location filename="../configurefrm.ui" line="302"/>
1402 <source>P&amp;ath</source>
1403 <translation>&amp;Percorso</translation>
1404 </message>
1405 <message>
1406 <location filename="../configurefrm.ui" line="312"/>
1407 <source>Entering an invalid folder will reset the path to the systems temporary path.</source>
1408 <translation>Inserire un percorso ad una cartella non valido reimposta il percorso temporaneo di sistema.</translation>
1409 </message>
1410 <message>
1411 <location filename="../configurefrm.ui" line="334"/>
1412 <source>Disable local &amp;download cache</source>
1413 <translation>&amp;Disabilita la cache locale per il download</translation>
1414 </message>
1415 <message>
1416 <source>O&amp;ffline mode</source>
1417 <translation type="obsolete">&amp;Offline mode</translation>
1418 </message>
1419 <message>
1420 <location filename="../configurefrm.ui" line="369"/>
1421 <source>Clean cache &amp;now</source>
1422 <translation>&amp;Libera la cache ora</translation>
1423 </message>
1424 <message>
1425 <location filename="../configurefrm.ui" line="385"/>
1426 <source>&amp;TTS &amp;&amp; Encoder</source>
1427 <translation>&amp;TTS &amp;&amp;Encoder</translation>
1428 </message>
1429 <message>
1430 <location filename="../configurefrm.ui" line="391"/>
1431 <source>TTS Engine</source>
1432 <translation>TTS Engine</translation>
1433 </message>
1434 <message>
1435 <location filename="../configurefrm.ui" line="397"/>
1436 <source>&amp;Select TTS Engine</source>
1437 <translation>&amp;Scegli engine TTS</translation>
1438 </message>
1439 <message>
1440 <location filename="../configurefrm.ui" line="410"/>
1441 <source>Configure TTS Engine</source>
1442 <translation>Configura engine TTS</translation>
1443 </message>
1444 <message>
1445 <location filename="../configurefrm.ui" line="417"/>
1446 <location filename="../configurefrm.ui" line="468"/>
1447 <source>Configuration invalid!</source>
1448 <translation>Configurazione non valida!</translation>
1449 </message>
1450 <message>
1451 <location filename="../configurefrm.ui" line="434"/>
1452 <source>Configure &amp;TTS</source>
1453 <translation>Configura &amp;TTS</translation>
1454 </message>
1455 <message>
1456 <location filename="../configurefrm.ui" line="445"/>
1457 <source>Test TTS</source>
1458 <translation type="unfinished"></translation>
1459 </message>
1460 <message>
1461 <location filename="../configurefrm.ui" line="452"/>
1462 <source>&amp;Use string corrections for TTS</source>
1463 <translation type="unfinished"></translation>
1464 </message>
1465 <message>
1466 <location filename="../configurefrm.ui" line="462"/>
1467 <source>Encoder Engine</source>
1468 <translation>Engine encoder</translation>
1469 </message>
1470 <message>
1471 <location filename="../configurefrm.ui" line="485"/>
1472 <source>Configure &amp;Enc</source>
1473 <translation>Configura &amp;Enc</translation>
1474 </message>
1475 <message>
1476 <location filename="../configurefrm.ui" line="496"/>
1477 <source>encoder name</source>
1478 <translation>nome encoder</translation>
1479 </message>
1480 <message>
1481 <location filename="../configurefrm.ui" line="536"/>
1482 <source>&amp;Ok</source>
1483 <translation>&amp;Ok</translation>
1484 </message>
1485 <message>
1486 <location filename="../configurefrm.ui" line="547"/>
1487 <source>&amp;Cancel</source>
1488 <translation>&amp;Cancel</translation>
1489 </message>
1490</context>
1491<context>
1492 <name>Configure</name>
1493 <message>
1494 <location filename="../configure.cpp" line="589"/>
1495 <source>English</source>
1496 <comment>This is the localized language name, i.e. your language.</comment>
1497 <translation>Italiano</translation>
1498 </message>
1499</context>
1500<context>
1501 <name>CreateVoiceFrm</name>
1502 <message>
1503 <location filename="../createvoicefrm.ui" line="17"/>
1504 <source>Create Voice File</source>
1505 <translation>Crea file voce</translation>
1506 </message>
1507 <message>
1508 <location filename="../createvoicefrm.ui" line="42"/>
1509 <source>Select the Language you want to generate a voicefile for:</source>
1510 <translation>seleziona la lingua per la quale vuoi generare un file voce:</translation>
1511 </message>
1512 <message>
1513 <location filename="../createvoicefrm.ui" line="55"/>
1514 <source>TTS:</source>
1515 <translation type="unfinished"></translation>
1516 </message>
1517 <message>
1518 <location filename="../createvoicefrm.ui" line="101"/>
1519 <source>Silence threshold</source>
1520 <translation type="unfinished"></translation>
1521 </message>
1522 <message>
1523 <location filename="../createvoicefrm.ui" line="163"/>
1524 <source>Language</source>
1525 <translation>lingua</translation>
1526 </message>
1527 <message>
1528 <location filename="../createvoicefrm.ui" line="49"/>
1529 <source>Generation settings</source>
1530 <translation>Impostazioni generatore</translation>
1531 </message>
1532 <message>
1533 <location filename="../createvoicefrm.ui" line="68"/>
1534 <source>Change</source>
1535 <translation>Cambia</translation>
1536 </message>
1537 <message>
1538 <location filename="../createvoicefrm.ui" line="139"/>
1539 <source>&amp;Install</source>
1540 <translation>&amp;Installa</translation>
1541 </message>
1542 <message>
1543 <location filename="../createvoicefrm.ui" line="150"/>
1544 <source>&amp;Cancel</source>
1545 <translation>&amp;Annulla</translation>
1546 </message>
1547 <message>
1548 <location filename="../createvoicefrm.ui" line="88"/>
1549 <source>Wavtrim Threshold</source>
1550 <translation>Soglia Wavtrim</translation>
1551 </message>
1552</context>
1553<context>
1554 <name>CreateVoiceWindow</name>
1555 <message>
1556 <location filename="../createvoicewindow.cpp" line="100"/>
1557 <source>TTS error</source>
1558 <translation type="unfinished"></translation>
1559 </message>
1560 <message>
1561 <location filename="../createvoicewindow.cpp" line="101"/>
1562 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1563 <translation type="unfinished"></translation>
1564 </message>
1565 <message>
1566 <location filename="../createvoicewindow.cpp" line="105"/>
1567 <location filename="../createvoicewindow.cpp" line="108"/>
1568 <source>Engine: &lt;b&gt;%1&lt;/b&gt;</source>
1569 <translation type="unfinished"></translation>
1570 </message>
1571</context>
1572<context>
1573 <name>EncTtsCfgGui</name>
1574 <message>
1575 <location filename="../encttscfggui.cpp" line="45"/>
1576 <source>Waiting for engine...</source>
1577 <translation>In attesa di un motore...</translation>
1578 </message>
1579 <message>
1580 <location filename="../encttscfggui.cpp" line="95"/>
1581 <source>Ok</source>
1582 <translation>Ok</translation>
1583 </message>
1584 <message>
1585 <location filename="../encttscfggui.cpp" line="98"/>
1586 <source>Cancel</source>
1587 <translation>Annulla</translation>
1588 </message>
1589 <message>
1590 <location filename="../encttscfggui.cpp" line="197"/>
1591 <source>Browse</source>
1592 <translation>Esplora</translation>
1593 </message>
1594 <message>
1595 <location filename="../encttscfggui.cpp" line="205"/>
1596 <source>Refresh</source>
1597 <translation>Aggiorna</translation>
1598 </message>
1599 <message>
1600 <location filename="../encttscfggui.cpp" line="377"/>
1601 <source>Select executable</source>
1602 <translation type="unfinished"></translation>
1603 </message>
1604</context>
1605<context>
1606 <name>EncoderExe</name>
1607 <message>
1608 <location filename="../base/encoderexe.cpp" line="41"/>
1609 <source>Path to Encoder:</source>
1610 <translation type="unfinished">Percorso dell&apos;Encoder:</translation>
1611 </message>
1612 <message>
1613 <location filename="../base/encoderexe.cpp" line="43"/>
1614 <source>Encoder options:</source>
1615 <translation type="unfinished">Opzioni per l&apos;Encoder:</translation>
1616 </message>
1617</context>
1618<context>
1619 <name>EncoderLame</name>
1620 <message>
1621 <location filename="../base/encoderlame.cpp" line="73"/>
1622 <location filename="../base/encoderlame.cpp" line="83"/>
1623 <source>LAME</source>
1624 <translation type="unfinished"></translation>
1625 </message>
1626 <message>
1627 <location filename="../base/encoderlame.cpp" line="75"/>
1628 <source>Volume</source>
1629 <translation type="unfinished"></translation>
1630 </message>
1631 <message>
1632 <location filename="../base/encoderlame.cpp" line="79"/>
1633 <source>Quality</source>
1634 <translation type="unfinished"></translation>
1635 </message>
1636 <message>
1637 <location filename="../base/encoderlame.cpp" line="83"/>
1638 <source>Could not find libmp3lame!</source>
1639 <translation type="unfinished"></translation>
1640 </message>
1641</context>
1642<context>
1643 <name>EncoderRbSpeex</name>
1644 <message>
1645 <location filename="../base/encoderrbspeex.cpp" line="34"/>
1646 <source>Volume:</source>
1647 <translation type="unfinished">Volume:</translation>
1648 </message>
1649 <message>
1650 <location filename="../base/encoderrbspeex.cpp" line="36"/>
1651 <source>Quality:</source>
1652 <translation type="unfinished">Qualità:</translation>
1653 </message>
1654 <message>
1655 <location filename="../base/encoderrbspeex.cpp" line="38"/>
1656 <source>Complexity:</source>
1657 <translation type="unfinished">Complessità:</translation>
1658 </message>
1659 <message>
1660 <location filename="../base/encoderrbspeex.cpp" line="40"/>
1661 <source>Use Narrowband:</source>
1662 <translation type="unfinished">Usa Narrowband:</translation>
1663 </message>
1664</context>
1665<context>
1666 <name>InfoWidget</name>
1667 <message>
1668 <location filename="../gui/infowidget.cpp" line="30"/>
1669 <location filename="../gui/infowidget.cpp" line="107"/>
1670 <source>File</source>
1671 <translation type="unfinished">File</translation>
1672 </message>
1673 <message>
1674 <location filename="../gui/infowidget.cpp" line="30"/>
1675 <location filename="../gui/infowidget.cpp" line="107"/>
1676 <source>Version</source>
1677 <translation type="unfinished">Versione</translation>
1678 </message>
1679</context>
1680<context>
1681 <name>InfoWidgetFrm</name>
1682 <message>
1683 <location filename="../gui/infowidgetfrm.ui" line="14"/>
1684 <source>Info</source>
1685 <translation type="unfinished">info</translation>
1686 </message>
1687 <message>
1688 <location filename="../gui/infowidgetfrm.ui" line="20"/>
1689 <source>Currently installed packages.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; if you manually installed packages this might not be correct!</source>
1690 <translation type="unfinished">Pacchetti correntemente installati.&lt;br/&gt;&lt;b&gt;Nota:&lt;/b&gt;se si sono installati dei pacchetti manualmente potrebbero non essere visti!</translation>
1691 </message>
1692 <message>
1693 <location filename="../gui/infowidgetfrm.ui" line="34"/>
1694 <source>Package</source>
1695 <translation type="unfinished"></translation>
1696 </message>
1697</context>
1698<context>
1699 <name>InstallTalkFrm</name>
1700 <message>
1701 <location filename="../installtalkfrm.ui" line="17"/>
1702 <source>Install Talk Files</source>
1703 <translation>Installa files Talk</translation>
1704 </message>
1705 <message>
1706 <location filename="../installtalkfrm.ui" line="52"/>
1707 <source>Generate for files</source>
1708 <translation type="unfinished"></translation>
1709 </message>
1710 <message>
1711 <location filename="../installtalkfrm.ui" line="78"/>
1712 <source>TTS profile:</source>
1713 <translation>Profilo TTS:</translation>
1714 </message>
1715 <message>
1716 <location filename="../installtalkfrm.ui" line="85"/>
1717 <source>Generate for folders</source>
1718 <translation type="unfinished"></translation>
1719 </message>
1720 <message>
1721 <location filename="../installtalkfrm.ui" line="95"/>
1722 <source>Recurse into folders</source>
1723 <translation type="unfinished"></translation>
1724 </message>
1725 <message>
1726 <location filename="../installtalkfrm.ui" line="111"/>
1727 <source>Change</source>
1728 <translation>Cambia</translation>
1729 </message>
1730 <message>
1731 <location filename="../installtalkfrm.ui" line="118"/>
1732 <source>Ignore files</source>
1733 <translation type="unfinished"></translation>
1734 </message>
1735 <message>
1736 <location filename="../installtalkfrm.ui" line="128"/>
1737 <source>Skip existing</source>
1738 <translation type="unfinished"></translation>
1739 </message>
1740 <message>
1741 <location filename="../installtalkfrm.ui" line="170"/>
1742 <source>Select folders for Talkfile generation (Ctrl for multiselect)</source>
1743 <translation type="unfinished"></translation>
1744 </message>
1745 <message>
1746 <location filename="../installtalkfrm.ui" line="36"/>
1747 <source>Generation options</source>
1748 <translation>Opzione creazione</translation>
1749 </message>
1750 <message>
1751 <location filename="../installtalkfrm.ui" line="42"/>
1752 <source>Strip Extensions</source>
1753 <translation type="unfinished"></translation>
1754 </message>
1755 <message>
1756 <location filename="../installtalkfrm.ui" line="143"/>
1757 <source>&amp;Install</source>
1758 <translation>&amp;Installa</translation>
1759 </message>
1760 <message>
1761 <location filename="../installtalkfrm.ui" line="154"/>
1762 <source>&amp;Cancel</source>
1763 <translation>&amp;Cancella</translation>
1764 </message>
1765</context>
1766<context>
1767 <name>InstallTalkWindow</name>
1768 <message>
1769 <location filename="../installtalkwindow.cpp" line="96"/>
1770 <source>Empty selection</source>
1771 <translation type="unfinished"></translation>
1772 </message>
1773 <message>
1774 <location filename="../installtalkwindow.cpp" line="97"/>
1775 <source>No files or folders selected. Please select files or folders first.</source>
1776 <translation type="unfinished"></translation>
1777 </message>
1778 <message>
1779 <location filename="../installtalkwindow.cpp" line="137"/>
1780 <source>TTS error</source>
1781 <translation type="unfinished"></translation>
1782 </message>
1783 <message>
1784 <location filename="../installtalkwindow.cpp" line="138"/>
1785 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1786 <translation type="unfinished"></translation>
1787 </message>
1788</context>
1789<context>
1790 <name>ManualWidget</name>
1791 <message>
1792 <location filename="../gui/manualwidget.cpp" line="44"/>
1793 <source>&lt;a href=&apos;%1&apos;&gt;PDF Manual&lt;/a&gt;</source>
1794 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Manuale PDF&lt;/a&gt;</translation>
1795 </message>
1796 <message>
1797 <location filename="../gui/manualwidget.cpp" line="46"/>
1798 <source>&lt;a href=&apos;%1&apos;&gt;HTML Manual (opens in browser)&lt;/a&gt;</source>
1799 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Manuale HTML (si apre nel browser)&lt;/a&gt;</translation>
1800 </message>
1801 <message>
1802 <location filename="../gui/manualwidget.cpp" line="50"/>
1803 <source>Select a device for a link to the correct manual</source>
1804 <translation type="unfinished">Selezionare un dispositivo per trovare il manuale corretto</translation>
1805 </message>
1806 <message>
1807 <location filename="../gui/manualwidget.cpp" line="51"/>
1808 <source>&lt;a href=&apos;%1&apos;&gt;Manual Overview&lt;/a&gt;</source>
1809 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Anteprima manuale&lt;/a&gt;</translation>
1810 </message>
1811 <message>
1812 <location filename="../gui/manualwidget.cpp" line="62"/>
1813 <source>Confirm download</source>
1814 <translation type="unfinished">Conferma download</translation>
1815 </message>
1816 <message>
1817 <location filename="../gui/manualwidget.cpp" line="63"/>
1818 <source>Do you really want to download the manual? The manual will be saved to the root folder of your player.</source>
1819 <translation type="unfinished">Vuoi scaricare il manuale? Il manuale verrà salvato nella cartella root del tuo player.</translation>
1820 </message>
1821</context>
1822<context>
1823 <name>ManualWidgetFrm</name>
1824 <message>
1825 <location filename="../gui/manualwidgetfrm.ui" line="14"/>
1826 <source>Manual</source>
1827 <translation type="unfinished"></translation>
1828 </message>
1829 <message>
1830 <location filename="../gui/manualwidgetfrm.ui" line="20"/>
1831 <source>Read the manual</source>
1832 <translation type="unfinished">Leggi il manuale</translation>
1833 </message>
1834 <message>
1835 <location filename="../gui/manualwidgetfrm.ui" line="26"/>
1836 <source>PDF manual</source>
1837 <translation type="unfinished">Manuale in PDF</translation>
1838 </message>
1839 <message>
1840 <location filename="../gui/manualwidgetfrm.ui" line="39"/>
1841 <source>HTML manual</source>
1842 <translation type="unfinished">Manuale in HTML</translation>
1843 </message>
1844 <message>
1845 <location filename="../gui/manualwidgetfrm.ui" line="55"/>
1846 <source>Download the manual</source>
1847 <translation type="unfinished">Scarica il manuale</translation>
1848 </message>
1849 <message>
1850 <location filename="../gui/manualwidgetfrm.ui" line="63"/>
1851 <source>&amp;PDF version</source>
1852 <translation type="unfinished">&amp;Versione PDF</translation>
1853 </message>
1854 <message>
1855 <location filename="../gui/manualwidgetfrm.ui" line="70"/>
1856 <source>&amp;HTML version (zip file)</source>
1857 <translation type="unfinished">&amp;Versione in HTML (file zip)</translation>
1858 </message>
1859 <message>
1860 <location filename="../gui/manualwidgetfrm.ui" line="92"/>
1861 <source>Down&amp;load</source>
1862 <translation type="unfinished">Down&amp;load</translation>
1863 </message>
1864</context>
1865<context>
1866 <name>MsPackUtil</name>
1867 <message>
1868 <location filename="../base/mspackutil.cpp" line="101"/>
1869 <source>Creating output path failed</source>
1870 <translation type="unfinished"></translation>
1871 </message>
1872 <message>
1873 <location filename="../base/mspackutil.cpp" line="109"/>
1874 <source>Error during CAB operation</source>
1875 <translation type="unfinished"></translation>
1876 </message>
1877</context>
1878<context>
1879 <name>PreviewFrm</name>
1880 <message>
1881 <location filename="../previewfrm.ui" line="16"/>
1882 <source>Preview</source>
1883 <translation>Anteprima</translation>
1884 </message>
1885</context>
1886<context>
1887 <name>ProgressLoggerFrm</name>
1888 <message>
1889 <location filename="../progressloggerfrm.ui" line="13"/>
1890 <location filename="../progressloggerfrm.ui" line="19"/>
1891 <source>Progress</source>
1892 <translation>Avanzamento</translation>
1893 </message>
1894 <message>
1895 <location filename="../progressloggerfrm.ui" line="32"/>
1896 <source>progresswindow</source>
1897 <translation>finestra di avanzamento</translation>
1898 </message>
1899 <message>
1900 <location filename="../progressloggerfrm.ui" line="58"/>
1901 <source>Save Log</source>
1902 <translation type="unfinished"></translation>
1903 </message>
1904 <message>
1905 <location filename="../progressloggerfrm.ui" line="82"/>
1906 <source>&amp;Abort</source>
1907 <translation>&amp;Interrompi</translation>
1908 </message>
1909</context>
1910<context>
1911 <name>ProgressLoggerGui</name>
1912 <message>
1913 <location filename="../progressloggergui.cpp" line="104"/>
1914 <source>&amp;Abort</source>
1915 <translation>&amp;Annulla</translation>
1916 </message>
1917 <message>
1918 <location filename="../progressloggergui.cpp" line="122"/>
1919 <source>&amp;Ok</source>
1920 <translation></translation>
1921 </message>
1922 <message>
1923 <location filename="../progressloggergui.cpp" line="146"/>
1924 <source>Save system trace log</source>
1925 <translation type="unfinished"></translation>
1926 </message>
1927</context>
1928<context>
1929 <name>QObject</name>
1930 <message>
1931 <location filename="../configure.cpp" line="625"/>
1932 <location filename="../main.cpp" line="83"/>
1933 <source>LTR</source>
1934 <extracomment>This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.
1935----------
1936This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.</extracomment>
1937 <translation type="unfinished"></translation>
1938 </message>
1939 <message>
1940 <location filename="../base/system.cpp" line="385"/>
1941 <source>(unknown vendor name) </source>
1942 <translation type="unfinished"></translation>
1943 </message>
1944 <message>
1945 <location filename="../base/system.cpp" line="403"/>
1946 <source>(unknown product name)</source>
1947 <translation type="unfinished"></translation>
1948 </message>
1949 <message>
1950 <location filename="../base/bootloaderinstallhelper.cpp" line="80"/>
1951 <source>Bootloader installation is almost complete. Installation &lt;b&gt;requires&lt;/b&gt; you to perform the following steps manually:</source>
1952 <translation type="unfinished">l&apos;installazione del bootloader è quasi completa. Per continuare &lt;b&gt;occorre&lt;/b&gt; che tu faccia le seguenti operazioni manualmente:</translation>
1953 </message>
1954 <message>
1955 <location filename="../base/bootloaderinstallhelper.cpp" line="86"/>
1956 <source>&lt;li&gt;Safely remove your player.&lt;/li&gt;</source>
1957 <translation type="unfinished">&lt;li&gt;Rimuovi il tuo player in maniera sicura.&lt;/li&gt;</translation>
1958 </message>
1959 <message>
1960 <location filename="../base/bootloaderinstallhelper.cpp" line="91"/>
1961 <source>&lt;li&gt;Reboot your player into the original firmware.&lt;/li&gt;&lt;li&gt;Perform a firmware upgrade using the update functionality of the original firmware. Please refer to your player&apos;s manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before starting the firmware update process.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1962 <translation type="unfinished"></translation>
1963 </message>
1964 <message>
1965 <location filename="../base/bootloaderinstallhelper.cpp" line="102"/>
1966 <source>&lt;li&gt;Remove any previously inserted microSD card&lt;/li&gt;</source>
1967 <translation type="unfinished"></translation>
1968 </message>
1969 <message>
1970 <location filename="../base/bootloaderinstallhelper.cpp" line="103"/>
1971 <source>&lt;li&gt;Disconnect your player. The player will reboot and perform an update of the original firmware. Please refer to your players manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before disconnecting the player.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1972 <translation type="unfinished"></translation>
1973 </message>
1974 <message>
1975 <location filename="../base/bootloaderinstallhelper.cpp" line="114"/>
1976 <source>&lt;li&gt;Turn the player off&lt;/li&gt;&lt;li&gt;Insert the charger&lt;/li&gt;</source>
1977 <translation type="unfinished">&lt;li&gt;Spegni il player&lt;/li&gt;&lt;li&gt;Inserisci il caricabatterie&lt;/li&gt;</translation>
1978 </message>
1979 <message>
1980 <location filename="../base/bootloaderinstallhelper.cpp" line="119"/>
1981 <source>&lt;li&gt;Unplug USB and power adaptors&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to turn the player off&lt;/li&gt;&lt;li&gt;Toggle the battery switch on the player&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to boot into Rockbox&lt;/li&gt;</source>
1982 <translation type="unfinished">&lt;li&gt;Stacca il cavo USB&lt;/li&gt;&lt;li&gt;Tieni premuto il tasto&lt;i&gt;Power&lt;/i&gt;per spegnere il player&lt;/li&gt;&lt;li&gt;Sposta l&apos;interruttore della batteria sul player&lt;/li&gt;&lt;li&gt;Tieni premuto &lt;i&gt;Power&lt;/i&gt; per avviare Rockbox&lt;/li&gt;</translation>
1983 </message>
1984 <message>
1985 <location filename="../base/bootloaderinstallhelper.cpp" line="125"/>
1986 <source>&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You can safely install other parts first, but the above steps are &lt;b&gt;required&lt;/b&gt; to finish the installation!&lt;/p&gt;</source>
1987 <translation type="unfinished">&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt;Puoi installare in tutta sicurezza prima le altre componenti, ma i passi precedenti &lt;b&gt;sono indispensabili&lt;/b&gt;per concludere l&apos;installazione!&lt;/p&gt;</translation>
1988 </message>
1989</context>
1990<context>
1991 <name>QuaZipFile</name>
1992 <message>
1993 <location filename="../quazip/quazipfile.cpp" line="141"/>
1994 <source>ZIP/UNZIP API error %1</source>
1995 <translation type="unfinished"></translation>
1996 </message>
1997</context>
1998<context>
1999 <name>RbUtilQt</name>
2000 <message>
2001 <location filename="../rbutilqt.cpp" line="236"/>
2002 <source>Network error</source>
2003 <translation>Errore Rete</translation>
2004 </message>
2005 <message>
2006 <location filename="../rbutilqt.cpp" line="329"/>
2007 <source>New installation</source>
2008 <translation>Nuova installazione</translation>
2009 </message>
2010 <message>
2011 <location filename="../rbutilqt.cpp" line="330"/>
2012 <source>This is a new installation of Rockbox Utility, or a new version. The configuration dialog will now open to allow you to setup the program, or review your settings.</source>
2013 <translation>Questa è una nuova installazione di Rockbox, o una nuova versione. Si aprirà una finestra che permetterà di impostare il programma o rivedere le tue impostazioni.</translation>
2014 </message>
2015 <message>
2016 <location filename="../rbutilqt.cpp" line="337"/>
2017 <location filename="../rbutilqt.cpp" line="642"/>
2018 <source>Configuration error</source>
2019 <translation>Errore nella configurazione</translation>
2020 </message>
2021 <message>
2022 <location filename="../rbutilqt.cpp" line="338"/>
2023 <source>Your configuration is invalid. This is most likely due to a changed device path. The configuration dialog will now open to allow you to correct the problem.</source>
2024 <translation>La tua configurazione non è valida. Questo spesso è causato da un cambiamento nel percorso del dispositivo. Si aprirà una finestra che permetterà di correggere il problema.</translation>
2025 </message>
2026 <message>
2027 <location filename="../rbutilqt.cpp" line="110"/>
2028 <source>Wine detected!</source>
2029 <translation type="unfinished"></translation>
2030 </message>
2031 <message>
2032 <location filename="../rbutilqt.cpp" line="111"/>
2033 <source>It seems you are trying to run this program under Wine. Please don&apos;t do this, running under Wine will fail. Use the native Linux binary instead.</source>
2034 <translation type="unfinished"></translation>
2035 </message>
2036 <message>
2037 <location filename="../rbutilqt.cpp" line="224"/>
2038 <source>Downloading build information, please wait ...</source>
2039 <translation type="unfinished"></translation>
2040 </message>
2041 <message>
2042 <location filename="../rbutilqt.cpp" line="235"/>
2043 <source>Can&apos;t get version information!</source>
2044 <translation type="unfinished"></translation>
2045 </message>
2046 <message>
2047 <location filename="../rbutilqt.cpp" line="237"/>
2048 <source>Can&apos;t get version information.
2049Network error: %1. Please check your network and proxy settings.</source>
2050 <translation type="unfinished"></translation>
2051 </message>
2052 <message>
2053 <location filename="../rbutilqt.cpp" line="249"/>
2054 <source>Download build information finished.</source>
2055 <translation type="unfinished"></translation>
2056 </message>
2057 <message>
2058 <location filename="../rbutilqt.cpp" line="450"/>
2059 <source>Confirm Installation</source>
2060 <translation>Conferma installazione</translation>
2061 </message>
2062 <message>
2063 <location filename="../rbutilqt.cpp" line="582"/>
2064 <source>Mount point is wrong!</source>
2065 <translation>Punto di Mount errato!</translation>
2066 </message>
2067 <message>
2068 <location filename="../rbutilqt.cpp" line="430"/>
2069 <source>No Rockbox installation found</source>
2070 <translation type="unfinished"></translation>
2071 </message>
2072 <message>
2073 <location filename="../rbutilqt.cpp" line="416"/>
2074 <source>Warning</source>
2075 <translation>Attenzione</translation>
2076 </message>
2077 <message>
2078 <location filename="../rbutilqt.cpp" line="417"/>
2079 <source>The Application is still downloading Information about new Builds. Please try again shortly.</source>
2080 <translation>L&apos;applicazione sta ancora scaricando le informazioni riguardo la nuova build. Per favore riprova fra poco.</translation>
2081 </message>
2082 <message>
2083 <location filename="../rbutilqt.cpp" line="431"/>
2084 <source>Could not determine the installed Rockbox version. Please install a Rockbox build before installing voice files.</source>
2085 <translation type="unfinished"></translation>
2086 </message>
2087 <message>
2088 <location filename="../rbutilqt.cpp" line="451"/>
2089 <source>Do you really want to install the voice file?</source>
2090 <translation>Vuoi installare il file voce?</translation>
2091 </message>
2092 <message>
2093 <location filename="../rbutilqt.cpp" line="512"/>
2094 <source>Confirm Uninstallation</source>
2095 <translation>Conferma disinstallazione</translation>
2096 </message>
2097 <message>
2098 <location filename="../rbutilqt.cpp" line="513"/>
2099 <source>Do you really want to uninstall the Bootloader?</source>
2100 <translation>Vuoi realmente disinstallare il bootloader?</translation>
2101 </message>
2102 <message>
2103 <location filename="../rbutilqt.cpp" line="528"/>
2104 <source>No uninstall method for this target known.</source>
2105 <translation type="unfinished"></translation>
2106 </message>
2107 <message>
2108 <location filename="../rbutilqt.cpp" line="542"/>
2109 <source>Rockbox Utility can not uninstall the bootloader on this target. Try a normal firmware update to remove the booloader.</source>
2110 <translation type="unfinished"></translation>
2111 </message>
2112 <message>
2113 <location filename="../rbutilqt.cpp" line="733"/>
2114 <source>New version of Rockbox Utility available.</source>
2115 <translation type="unfinished"></translation>
2116 </message>
2117 <message>
2118 <location filename="../rbutilqt.cpp" line="736"/>
2119 <source>Rockbox Utility is up to date.</source>
2120 <translation type="unfinished"></translation>
2121 </message>
2122 <message>
2123 <location filename="../rbutilqt.cpp" line="568"/>
2124 <source>Confirm installation</source>
2125 <translation>Conferma installazione</translation>
2126 </message>
2127 <message>
2128 <location filename="../rbutilqt.cpp" line="439"/>
2129 <source>No voice file available</source>
2130 <translation type="unfinished"></translation>
2131 </message>
2132 <message>
2133 <location filename="../rbutilqt.cpp" line="440"/>
2134 <source>The installed version of Rockbox is a development version. Pre-built voices are only available for release versions of Rockbox. Please generate a voice yourself using the &quot;Create voice file&quot; functionality.</source>
2135 <translation type="unfinished"></translation>
2136 </message>
2137 <message>
2138 <location filename="../rbutilqt.cpp" line="550"/>
2139 <source>No Rockbox bootloader found.</source>
2140 <translation type="unfinished"></translation>
2141 </message>
2142 <message>
2143 <location filename="../rbutilqt.cpp" line="569"/>
2144 <source>Do you really want to install Rockbox Utility to your player? After installation you can run it from the players hard drive.</source>
2145 <translation>Vuoi installare la Rockbox utility nel tuo player ? Dopo l&apos;installazione potrai avviarla dal disco del tuo player.</translation>
2146 </message>
2147 <message>
2148 <location filename="../rbutilqt.cpp" line="578"/>
2149 <source>Installing Rockbox Utility</source>
2150 <translation>Installazione Rockbox Utility in corso</translation>
2151 </message>
2152 <message>
2153 <location filename="../rbutilqt.cpp" line="596"/>
2154 <source>Error installing Rockbox Utility</source>
2155 <translation>Errore nell&apos;installare l&apos;utility Rockbox</translation>
2156 </message>
2157 <message>
2158 <location filename="../rbutilqt.cpp" line="600"/>
2159 <source>Installing user configuration</source>
2160 <translation>Installazione configurazione utente in corso</translation>
2161 </message>
2162 <message>
2163 <location filename="../rbutilqt.cpp" line="604"/>
2164 <source>Error installing user configuration</source>
2165 <translation>Errore nell&apos;installare la configurazione utente</translation>
2166 </message>
2167 <message>
2168 <location filename="../rbutilqt.cpp" line="608"/>
2169 <source>Successfully installed Rockbox Utility.</source>
2170 <translation>Rockbox Utility installata con successo.</translation>
2171 </message>
2172 <message>
2173 <location filename="../rbutilqt.cpp" line="643"/>
2174 <source>Your configuration is invalid. Please go to the configuration dialog and make sure the selected values are correct.</source>
2175 <translation>La tua configurazione non è valida. Per favore torna alla finestra per la configurazione e assicurati che i valori corretti siano selezionati.</translation>
2176 </message>
2177 <message>
2178 <location filename="../rbutilqt.cpp" line="664"/>
2179 <source>Checking for update ...</source>
2180 <translation type="unfinished"></translation>
2181 </message>
2182 <message>
2183 <location filename="../rbutilqt.cpp" line="729"/>
2184 <source>RockboxUtility Update available</source>
2185 <translation type="unfinished"></translation>
2186 </message>
2187 <message>
2188 <location filename="../rbutilqt.cpp" line="730"/>
2189 <source>&lt;b&gt;New RockboxUtility Version available.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Download it from here: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</source>
2190 <translation type="unfinished"></translation>
2191 </message>
2192 <message>
2193 <location filename="../rbutilqt.cpp" line="759"/>
2194 <source>Device ejected</source>
2195 <translation type="unfinished"></translation>
2196 </message>
2197 <message>
2198 <location filename="../rbutilqt.cpp" line="760"/>
2199 <source>Device successfully ejected. You may now disconnect the player from the PC.</source>
2200 <translation type="unfinished"></translation>
2201 </message>
2202 <message>
2203 <location filename="../rbutilqt.cpp" line="764"/>
2204 <source>Ejecting failed</source>
2205 <translation type="unfinished"></translation>
2206 </message>
2207 <message>
2208 <location filename="../rbutilqt.cpp" line="765"/>
2209 <source>Ejecting the device failed. Please make sure no programs are accessing files on the device. If ejecting still fails please use your computers eject funtionality.</source>
2210 <translation type="unfinished"></translation>
2211 </message>
2212</context>
2213<context>
2214 <name>RbUtilQtFrm</name>
2215 <message>
2216 <location filename="../rbutilqtfrm.ui" line="14"/>
2217 <source>Rockbox Utility</source>
2218 <translation>Rockbox Utility</translation>
2219 </message>
2220 <message>
2221 <location filename="../rbutilqtfrm.ui" line="31"/>
2222 <source>Device</source>
2223 <translation>Dispositivo</translation>
2224 </message>
2225 <message>
2226 <location filename="../rbutilqtfrm.ui" line="92"/>
2227 <source>&amp;Change</source>
2228 <translation>&amp;Cambia</translation>
2229 </message>
2230 <message>
2231 <location filename="../rbutilqtfrm.ui" line="163"/>
2232 <source>Welcome</source>
2233 <translation>Benvenuto</translation>
2234 </message>
2235 <message>
2236 <location filename="../rbutilqtfrm.ui" line="160"/>
2237 <location filename="../rbutilqtfrm.ui" line="658"/>
2238 <source>&amp;Installation</source>
2239 <translation>&amp;Installazione</translation>
2240 </message>
2241 <message>
2242 <location filename="../rbutilqtfrm.ui" line="168"/>
2243 <location filename="../rbutilqtfrm.ui" line="450"/>
2244 <source>&amp;Accessibility</source>
2245 <translation>&amp;Accessibilità</translation>
2246 </message>
2247 <message>
2248 <location filename="../rbutilqtfrm.ui" line="171"/>
2249 <source>Install accessibility add-ons</source>
2250 <translation>Installa gli add-ons per l&apos;accessibilità</translation>
2251 </message>
2252 <message>
2253 <location filename="../rbutilqtfrm.ui" line="177"/>
2254 <source>Install Voice files</source>
2255 <translation>Installa file Voce</translation>
2256 </message>
2257 <message>
2258 <location filename="../rbutilqtfrm.ui" line="194"/>
2259 <source>&lt;b&gt;Install Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so if you installed the voice file Rockbox will speak.</source>
2260 <translation>&lt;b&gt;Installa file Voce&lt;/b&gt;&lt;br/&gt;Occorrono i file Voce affinche Rockbox descriva l&apos;interfaccia utente. La sintesi vocale è attiva di default, così dopo aver installato un file Voce, Rockbox parlerà.</translation>
2261 </message>
2262 <message>
2263 <location filename="../rbutilqtfrm.ui" line="204"/>
2264 <source>Install Talk files</source>
2265 <translation>Installa file Talk</translation>
2266 </message>
2267 <message>
2268 <location filename="../rbutilqtfrm.ui" line="221"/>
2269 <source>&lt;b&gt;Create Talk Files&lt;/b&gt;&lt;br/&gt;Talkfiles are needed to let Rockbox speak File and Foldernames</source>
2270 <translation type="unfinished"></translation>
2271 </message>
2272 <message>
2273 <location filename="../rbutilqtfrm.ui" line="254"/>
2274 <source>Create Voice files</source>
2275 <translation>Crea file Voice</translation>
2276 </message>
2277 <message>
2278 <location filename="../rbutilqtfrm.ui" line="271"/>
2279 <source>&lt;b&gt;Create Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so
2280 if you installed the voice file Rockbox will speak.</source>
2281 <translation type="unfinished"></translation>
2282 </message>
2283 <message>
2284 <location filename="../rbutilqtfrm.ui" line="458"/>
2285 <source>&amp;Uninstallation</source>
2286 <translation>&amp;Disinstallazione</translation>
2287 </message>
2288 <message>
2289 <location filename="../rbutilqtfrm.ui" line="286"/>
2290 <location filename="../rbutilqtfrm.ui" line="319"/>
2291 <source>Uninstall Rockbox</source>
2292 <translation>Disinstalla Rockbox</translation>
2293 </message>
2294 <message>
2295 <location filename="../rbutilqtfrm.ui" line="121"/>
2296 <source>mountpoint unknown or invalid</source>
2297 <translation type="unfinished"></translation>
2298 </message>
2299 <message>
2300 <location filename="../rbutilqtfrm.ui" line="114"/>
2301 <source>Mountpoint:</source>
2302 <translation type="unfinished"></translation>
2303 </message>
2304 <message>
2305 <location filename="../rbutilqtfrm.ui" line="72"/>
2306 <source>device unknown or invalid</source>
2307 <translation type="unfinished"></translation>
2308 </message>
2309 <message>
2310 <location filename="../rbutilqtfrm.ui" line="65"/>
2311 <source>Device:</source>
2312 <translation type="unfinished"></translation>
2313 </message>
2314 <message>
2315 <location filename="../rbutilqtfrm.ui" line="283"/>
2316 <source>Backup &amp;&amp; &amp;Uninstallation</source>
2317 <translation type="unfinished"></translation>
2318 </message>
2319 <message>
2320 <location filename="../rbutilqtfrm.ui" line="292"/>
2321 <source>Uninstall Bootloader</source>
2322 <translation>Disinstalla il bootloader</translation>
2323 </message>
2324 <message>
2325 <location filename="../rbutilqtfrm.ui" line="309"/>
2326 <source>&lt;b&gt;Remove the bootloader&lt;/b&gt;&lt;br/&gt;After removing the bootloader you won&apos;t be able to start Rockbox.</source>
2327 <translation>&lt;b&gt;Rimuovere il bootloader&lt;/B&gt;&lt;br/&gt;Dopo aver rimosso il bootloader sarà impossibile avviare Rockbox.</translation>
2328 </message>
2329 <message>
2330 <location filename="../rbutilqtfrm.ui" line="336"/>
2331 <source>&lt;b&gt;Uninstall Rockbox from your audio player.&lt;/b&gt;&lt;br/&gt;This will leave the bootloader in place (you need to remove it manually).</source>
2332 <translation>&lt;b&gt;Disinstallare Rockbox dal player audio.&lt;/b&gt;&lt;br/&gt;Questo lascerà il bootloader al suo posto (si dovrà rimuoverlo manualmente).</translation>
2333 </message>
2334 <message>
2335 <location filename="../rbutilqtfrm.ui" line="349"/>
2336 <source>Backup</source>
2337 <translation type="unfinished">Backup</translation>
2338 </message>
2339 <message>
2340 <location filename="../rbutilqtfrm.ui" line="366"/>
2341 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup current installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Create a backup by archiving the contents of the Rockbox installation folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2342 <translation type="unfinished"></translation>
2343 </message>
2344 <message>
2345 <location filename="../rbutilqtfrm.ui" line="393"/>
2346 <source>&amp;Manual</source>
2347 <translation>&amp;Manuale</translation>
2348 </message>
2349 <message>
2350 <location filename="../rbutilqtfrm.ui" line="396"/>
2351 <source>View and download the manual</source>
2352 <translation>Leggi e scarica il manuale</translation>
2353 </message>
2354 <message>
2355 <location filename="../rbutilqtfrm.ui" line="401"/>
2356 <source>Inf&amp;o</source>
2357 <translation>Inf&amp;o</translation>
2358 </message>
2359 <message>
2360 <location filename="../rbutilqtfrm.ui" line="419"/>
2361 <source>&amp;File</source>
2362 <translation>&amp;File</translation>
2363 </message>
2364 <message>
2365 <location filename="../rbutilqtfrm.ui" line="653"/>
2366 <source>System &amp;Trace</source>
2367 <translation type="unfinished"></translation>
2368 </message>
2369 <message>
2370 <location filename="../rbutilqtfrm.ui" line="446"/>
2371 <source>Action&amp;s</source>
2372 <translation>&amp;Azioni</translation>
2373 </message>
2374 <message>
2375 <location filename="../rbutilqtfrm.ui" line="474"/>
2376 <source>Empty local download cache</source>
2377 <translation>Svuota la cache dei download</translation>
2378 </message>
2379 <message>
2380 <location filename="../rbutilqtfrm.ui" line="479"/>
2381 <source>Install Rockbox Utility on player</source>
2382 <translation>Installa l&apos;utility Rockbox sul tuo player</translation>
2383 </message>
2384 <message>
2385 <location filename="../rbutilqtfrm.ui" line="484"/>
2386 <source>&amp;Configure</source>
2387 <translation>&amp;Configura</translation>
2388 </message>
2389 <message>
2390 <location filename="../rbutilqtfrm.ui" line="489"/>
2391 <source>E&amp;xit</source>
2392 <translation>&amp;Esci</translation>
2393 </message>
2394 <message>
2395 <location filename="../rbutilqtfrm.ui" line="492"/>
2396 <source>Ctrl+Q</source>
2397 <translation>Ctrl+Q</translation>
2398 </message>
2399 <message>
2400 <location filename="../rbutilqtfrm.ui" line="497"/>
2401 <source>&amp;About</source>
2402 <translation>&amp;A riguardo</translation>
2403 </message>
2404 <message>
2405 <location filename="../rbutilqtfrm.ui" line="502"/>
2406 <source>About &amp;Qt</source>
2407 <translation>&amp;Sulle Qt</translation>
2408 </message>
2409 <message>
2410 <location filename="../rbutilqtfrm.ui" line="428"/>
2411 <location filename="../rbutilqtfrm.ui" line="507"/>
2412 <source>&amp;Help</source>
2413 <translation>&amp;Aiuto</translation>
2414 </message>
2415 <message>
2416 <location filename="../rbutilqtfrm.ui" line="103"/>
2417 <source>&amp;Eject</source>
2418 <translation type="unfinished"></translation>
2419 </message>
2420 <message>
2421 <location filename="../rbutilqtfrm.ui" line="432"/>
2422 <source>&amp;Troubleshoot</source>
2423 <translation type="unfinished"></translation>
2424 </message>
2425 <message>
2426 <location filename="../rbutilqtfrm.ui" line="512"/>
2427 <source>Info</source>
2428 <translation>info</translation>
2429 </message>
2430 <message>
2431 <location filename="../rbutilqtfrm.ui" line="521"/>
2432 <source>&amp;Complete Installation</source>
2433 <translation>&amp;Installazione completa</translation>
2434 </message>
2435 <message>
2436 <location filename="../rbutilqtfrm.ui" line="530"/>
2437 <source>&amp;Minimal Installation</source>
2438 <translation>&amp;Installazione minima</translation>
2439 </message>
2440 <message>
2441 <location filename="../rbutilqtfrm.ui" line="539"/>
2442 <source>Install &amp;Bootloader</source>
2443 <translation>Installa &amp;Bootloader</translation>
2444 </message>
2445 <message>
2446 <location filename="../rbutilqtfrm.ui" line="548"/>
2447 <source>Install &amp;Rockbox</source>
2448 <translation>Installa &amp;Rockbox</translation>
2449 </message>
2450 <message>
2451 <location filename="../rbutilqtfrm.ui" line="557"/>
2452 <source>Install &amp;Fonts Package</source>
2453 <translation>Installa &amp;Pacchetto Fonts</translation>
2454 </message>
2455 <message>
2456 <location filename="../rbutilqtfrm.ui" line="566"/>
2457 <source>Install &amp;Themes</source>
2458 <translation>Installa &amp;Tema</translation>
2459 </message>
2460 <message>
2461 <location filename="../rbutilqtfrm.ui" line="575"/>
2462 <source>Install &amp;Game Files</source>
2463 <translation>Installa &amp;Game files</translation>
2464 </message>
2465 <message>
2466 <location filename="../rbutilqtfrm.ui" line="584"/>
2467 <source>&amp;Install Voice File</source>
2468 <translation>&amp;Installa file Voice</translation>
2469 </message>
2470 <message>
2471 <location filename="../rbutilqtfrm.ui" line="593"/>
2472 <source>Create &amp;Talk Files</source>
2473 <translation>&amp;Crea file Talk</translation>
2474 </message>
2475 <message>
2476 <location filename="../rbutilqtfrm.ui" line="602"/>
2477 <source>Remove &amp;bootloader</source>
2478 <translation>Rimuovi &amp;Bootloader</translation>
2479 </message>
2480 <message>
2481 <location filename="../rbutilqtfrm.ui" line="611"/>
2482 <source>Uninstall &amp;Rockbox</source>
2483 <translation>Disinstalla &amp;Rockbox</translation>
2484 </message>
2485 <message>
2486 <location filename="../rbutilqtfrm.ui" line="616"/>
2487 <source>Read PDF manual</source>
2488 <translation>Leggi il manuale in PDF</translation>
2489 </message>
2490 <message>
2491 <location filename="../rbutilqtfrm.ui" line="621"/>
2492 <source>Read HTML manual</source>
2493 <translation>Leggi il manuale in HTML</translation>
2494 </message>
2495 <message>
2496 <location filename="../rbutilqtfrm.ui" line="626"/>
2497 <source>Download PDF manual</source>
2498 <translation>Scarica il manuale in PDF</translation>
2499 </message>
2500 <message>
2501 <location filename="../rbutilqtfrm.ui" line="631"/>
2502 <source>Download HTML manual (zip)</source>
2503 <translation>Scarica il manuale in HTML</translation>
2504 </message>
2505 <message>
2506 <location filename="../rbutilqtfrm.ui" line="640"/>
2507 <source>Create &amp;Voice File</source>
2508 <translation>Crea &amp;file Voce</translation>
2509 </message>
2510 <message>
2511 <location filename="../rbutilqtfrm.ui" line="643"/>
2512 <source>Create Voice File</source>
2513 <translation>Crea file Voce</translation>
2514 </message>
2515 <message>
2516 <location filename="../rbutilqtfrm.ui" line="648"/>
2517 <source>&amp;System Info</source>
2518 <translation>&amp;Info Sistema</translation>
2519 </message>
2520 <message>
2521 <location filename="../rbutilqtfrm.ui" line="663"/>
2522 <source>Show &amp;Changelog</source>
2523 <translation type="unfinished"></translation>
2524 </message>
2525</context>
2526<context>
2527 <name>SelectiveInstallWidget</name>
2528 <message>
2529 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="20"/>
2530 <source>Selective Installation</source>
2531 <translation type="unfinished"></translation>
2532 </message>
2533 <message>
2534 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="26"/>
2535 <source>Rockbox version to install</source>
2536 <translation type="unfinished"></translation>
2537 </message>
2538 <message>
2539 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="35"/>
2540 <source>Version information not available yet.</source>
2541 <translation type="unfinished"></translation>
2542 </message>
2543 <message>
2544 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="54"/>
2545 <source>Rockbox components to install</source>
2546 <translation type="unfinished"></translation>
2547 </message>
2548 <message>
2549 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="60"/>
2550 <source>&amp;Bootloader</source>
2551 <translation type="unfinished"></translation>
2552 </message>
2553 <message>
2554 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="80"/>
2555 <source>The main Rockbox firmware.</source>
2556 <translation type="unfinished"></translation>
2557 </message>
2558 <message>
2559 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="90"/>
2560 <source>Fonts</source>
2561 <translation type="unfinished"></translation>
2562 </message>
2563 <message>
2564 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="104"/>
2565 <source>&amp;Rockbox</source>
2566 <translation type="unfinished"></translation>
2567 </message>
2568 <message>
2569 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="124"/>
2570 <source>Some game plugins require additional files.</source>
2571 <translation type="unfinished"></translation>
2572 </message>
2573 <message>
2574 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="140"/>
2575 <source>Additional fonts for the User Interface.</source>
2576 <translation type="unfinished"></translation>
2577 </message>
2578 <message>
2579 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="156"/>
2580 <source>The bootloader is required for starting Rockbox. Only necessary for first time install.</source>
2581 <translation type="unfinished"></translation>
2582 </message>
2583 <message>
2584 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="166"/>
2585 <source>Game Files</source>
2586 <translation type="unfinished"></translation>
2587 </message>
2588 <message>
2589 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="177"/>
2590 <source>Customize</source>
2591 <translation type="unfinished"></translation>
2592 </message>
2593 <message>
2594 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="188"/>
2595 <source>Themes</source>
2596 <translation type="unfinished"></translation>
2597 </message>
2598 <message>
2599 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="205"/>
2600 <source>Themes allow adjusting the user interface of Rockbox. Use &quot;Customize&quot; to select themes.</source>
2601 <translation type="unfinished"></translation>
2602 </message>
2603 <message>
2604 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="250"/>
2605 <source>&amp;Install</source>
2606 <translation type="unfinished">&amp;Installa</translation>
2607 </message>
2608 <message>
2609 <location filename="../gui/selectiveinstallwidget.cpp" line="67"/>
2610 <source>This is the latest stable release available.</source>
2611 <translation type="unfinished"></translation>
2612 </message>
2613 <message>
2614 <location filename="../gui/selectiveinstallwidget.cpp" line="70"/>
2615 <source>The development version is updated on every code change. Last update was on %1</source>
2616 <translation type="unfinished"></translation>
2617 </message>
2618 <message>
2619 <location filename="../gui/selectiveinstallwidget.cpp" line="74"/>
2620 <source>This will eventually become the next Rockbox version. Install it to help testing.</source>
2621 <translation type="unfinished"></translation>
2622 </message>
2623 <message>
2624 <location filename="../gui/selectiveinstallwidget.cpp" line="100"/>
2625 <source>Stable Release (Version %1)</source>
2626 <translation type="unfinished"></translation>
2627 </message>
2628 <message>
2629 <location filename="../gui/selectiveinstallwidget.cpp" line="104"/>
2630 <source>Development Version (Revison %1)</source>
2631 <translation type="unfinished"></translation>
2632 </message>
2633 <message>
2634 <location filename="../gui/selectiveinstallwidget.cpp" line="108"/>
2635 <source>Release Candidate (Revison %1)</source>
2636 <translation type="unfinished"></translation>
2637 </message>
2638 <message>
2639 <location filename="../gui/selectiveinstallwidget.cpp" line="131"/>
2640 <source>The selected player doesn&apos;t need a bootloader.</source>
2641 <translation type="unfinished"></translation>
2642 </message>
2643 <message>
2644 <location filename="../gui/selectiveinstallwidget.cpp" line="136"/>
2645 <source>The bootloader is required for starting Rockbox. Installation of the bootloader is only necessary on first time installation.</source>
2646 <translation type="unfinished"></translation>
2647 </message>
2648 <message>
2649 <location filename="../gui/selectiveinstallwidget.cpp" line="183"/>
2650 <source>Mountpoint is wrong</source>
2651 <translation type="unfinished"></translation>
2652 </message>
2653 <message>
2654 <location filename="../gui/selectiveinstallwidget.cpp" line="239"/>
2655 <source>No install method known.</source>
2656 <translation type="unfinished">Nessun metodo di installazione conosciuto.</translation>
2657 </message>
2658 <message>
2659 <location filename="../gui/selectiveinstallwidget.cpp" line="266"/>
2660 <source>Bootloader detected</source>
2661 <translation type="unfinished">Trovato bootloader</translation>
2662 </message>
2663 <message>
2664 <location filename="../gui/selectiveinstallwidget.cpp" line="267"/>
2665 <source>Bootloader already installed. Do you want to reinstall the bootloader?</source>
2666 <translation type="unfinished">Bootloader già installato. Vuoi reinstallarlo?</translation>
2667 </message>
2668 <message>
2669 <location filename="../gui/selectiveinstallwidget.cpp" line="271"/>
2670 <source>Bootloader installation skipped</source>
2671 <translation type="unfinished">Installazione bootloader saltata</translation>
2672 </message>
2673 <message>
2674 <location filename="../gui/selectiveinstallwidget.cpp" line="284"/>
2675 <source>Create Bootloader backup</source>
2676 <translation type="unfinished">Crea un backup del bootloader</translation>
2677 </message>
2678 <message>
2679 <location filename="../gui/selectiveinstallwidget.cpp" line="285"/>
2680 <source>You can create a backup of the original bootloader file. Press &quot;Yes&quot; to select an output folder on your computer to save the file to. The file will get placed in a new folder &quot;%1&quot; created below the selected folder.
2681Press &quot;No&quot; to skip this step.</source>
2682 <translation type="unfinished">Puoi creare un backup del bootloader originale. Premi &quot;Si&quot; e seleziona una cartella sul tuo pc dove salvare il file. Il file verrà salvato in una nuova cartella &quot;%1&quot; all&apos;interno della cartella selezionata.
2683Premi &quot;No&quot; per saltare questo passo.</translation>
2684 </message>
2685 <message>
2686 <location filename="../gui/selectiveinstallwidget.cpp" line="292"/>
2687 <source>Browse backup folder</source>
2688 <translation type="unfinished">Scegli la cartella per il backup</translation>
2689 </message>
2690 <message>
2691 <location filename="../gui/selectiveinstallwidget.cpp" line="304"/>
2692 <source>Prerequisites</source>
2693 <translation type="unfinished">Prerequisiti</translation>
2694 </message>
2695 <message>
2696 <location filename="../gui/selectiveinstallwidget.cpp" line="309"/>
2697 <source>Bootloader installation aborted</source>
2698 <translation type="unfinished">Installazione bootloader interrotta</translation>
2699 </message>
2700 <message>
2701 <location filename="../gui/selectiveinstallwidget.cpp" line="319"/>
2702 <source>Bootloader files (%1)</source>
2703 <translation type="unfinished"></translation>
2704 </message>
2705 <message>
2706 <location filename="../gui/selectiveinstallwidget.cpp" line="321"/>
2707 <source>All files (*)</source>
2708 <translation type="unfinished"></translation>
2709 </message>
2710 <message>
2711 <location filename="../gui/selectiveinstallwidget.cpp" line="323"/>
2712 <source>Select firmware file</source>
2713 <translation type="unfinished">Selezionare il file del firmware</translation>
2714 </message>
2715 <message>
2716 <location filename="../gui/selectiveinstallwidget.cpp" line="325"/>
2717 <source>Error opening firmware file</source>
2718 <translation type="unfinished">Errore nell&apos;aprire il file del firmware</translation>
2719 </message>
2720 <message>
2721 <location filename="../gui/selectiveinstallwidget.cpp" line="331"/>
2722 <source>Error reading firmware file</source>
2723 <translation type="unfinished"></translation>
2724 </message>
2725 <message>
2726 <location filename="../gui/selectiveinstallwidget.cpp" line="341"/>
2727 <source>Backup error</source>
2728 <translation type="unfinished">Errore durante il backup</translation>
2729 </message>
2730 <message>
2731 <location filename="../gui/selectiveinstallwidget.cpp" line="342"/>
2732 <source>Could not create backup file. Continue?</source>
2733 <translation type="unfinished">Impossibile creare un backup. Continuare comunque?</translation>
2734 </message>
2735 <message>
2736 <location filename="../gui/selectiveinstallwidget.cpp" line="366"/>
2737 <source>Manual steps required</source>
2738 <translation type="unfinished">Richiesto intervento manuale</translation>
2739 </message>
2740 <message>
2741 <location filename="../gui/selectiveinstallwidget.cpp" line="171"/>
2742 <source>Continue with installation?</source>
2743 <translation type="unfinished"></translation>
2744 </message>
2745 <message>
2746 <location filename="../gui/selectiveinstallwidget.cpp" line="172"/>
2747 <source>Really continue?</source>
2748 <translation type="unfinished">Vuoi continuare veramente?</translation>
2749 </message>
2750 <message>
2751 <source>Aborted!</source>
2752 <translation type="obsolete">Annullato!</translation>
2753 </message>
2754 <message>
2755 <location filename="../gui/selectiveinstallwidget.cpp" line="490"/>
2756 <source>Your installation doesn&apos;t require game files, skipping.</source>
2757 <translation type="unfinished"></translation>
2758 </message>
2759</context>
2760<context>
2761 <name>ServerInfo</name>
2762 <message>
2763 <location filename="../base/serverinfo.cpp" line="117"/>
2764 <source>Unknown</source>
2765 <translation type="unfinished"></translation>
2766 </message>
2767 <message>
2768 <location filename="../base/serverinfo.cpp" line="121"/>
2769 <source>Unusable</source>
2770 <translation type="unfinished"></translation>
2771 </message>
2772 <message>
2773 <location filename="../base/serverinfo.cpp" line="124"/>
2774 <source>Unstable</source>
2775 <translation type="unfinished"></translation>
2776 </message>
2777 <message>
2778 <location filename="../base/serverinfo.cpp" line="127"/>
2779 <source>Stable</source>
2780 <translation type="unfinished"></translation>
2781 </message>
2782</context>
2783<context>
2784 <name>SysTrace</name>
2785 <message>
2786 <location filename="../systrace.cpp" line="98"/>
2787 <location filename="../systrace.cpp" line="107"/>
2788 <source>Save system trace log</source>
2789 <translation type="unfinished"></translation>
2790 </message>
2791</context>
2792<context>
2793 <name>SysTraceFrm</name>
2794 <message>
2795 <location filename="../systracefrm.ui" line="14"/>
2796 <source>System Trace</source>
2797 <translation type="unfinished"></translation>
2798 </message>
2799 <message>
2800 <location filename="../systracefrm.ui" line="20"/>
2801 <source>System State trace</source>
2802 <translation type="unfinished"></translation>
2803 </message>
2804 <message>
2805 <location filename="../systracefrm.ui" line="46"/>
2806 <source>&amp;Close</source>
2807 <translation type="unfinished"></translation>
2808 </message>
2809 <message>
2810 <location filename="../systracefrm.ui" line="57"/>
2811 <source>&amp;Save</source>
2812 <translation type="unfinished"></translation>
2813 </message>
2814 <message>
2815 <location filename="../systracefrm.ui" line="68"/>
2816 <source>&amp;Refresh</source>
2817 <translation type="unfinished">&amp;Aggiorna</translation>
2818 </message>
2819 <message>
2820 <location filename="../systracefrm.ui" line="79"/>
2821 <source>Save &amp;previous</source>
2822 <translation type="unfinished"></translation>
2823 </message>
2824</context>
2825<context>
2826 <name>Sysinfo</name>
2827 <message>
2828 <location filename="../sysinfo.cpp" line="45"/>
2829 <source>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</source>
2830 <translation>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</translation>
2831 </message>
2832 <message>
2833 <location filename="../sysinfo.cpp" line="46"/>
2834 <source>&lt;b&gt;Username&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2835 <translation>&lt;b&gt;Nome utente&lt;7b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2836 </message>
2837 <message>
2838 <location filename="../sysinfo.cpp" line="48"/>
2839 <source>&lt;b&gt;Permissions&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2840 <translation>&lt;b&gt;Permessi&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2841 </message>
2842 <message>
2843 <location filename="../sysinfo.cpp" line="50"/>
2844 <source>&lt;b&gt;Attached USB devices&lt;/b&gt;&lt;br/&gt;</source>
2845 <translation>&lt;b&gt;Dispositivo USB connesso&lt;/b&gt;&lt;br/&gt;</translation>
2846 </message>
2847 <message>
2848 <location filename="../sysinfo.cpp" line="54"/>
2849 <source>VID: %1 PID: %2, %3</source>
2850 <translation>VID: %1 PID: %2, %3</translation>
2851 </message>
2852 <message>
2853 <location filename="../sysinfo.cpp" line="63"/>
2854 <source>Filesystem</source>
2855 <translation>Filesystem</translation>
2856 </message>
2857 <message>
2858 <location filename="../sysinfo.cpp" line="66"/>
2859 <source>Mountpoint</source>
2860 <translation type="unfinished"></translation>
2861 </message>
2862 <message>
2863 <location filename="../sysinfo.cpp" line="66"/>
2864 <source>Label</source>
2865 <translation type="unfinished"></translation>
2866 </message>
2867 <message>
2868 <location filename="../sysinfo.cpp" line="67"/>
2869 <source>Free</source>
2870 <translation type="unfinished"></translation>
2871 </message>
2872 <message>
2873 <location filename="../sysinfo.cpp" line="67"/>
2874 <source>Total</source>
2875 <translation type="unfinished"></translation>
2876 </message>
2877 <message>
2878 <location filename="../sysinfo.cpp" line="68"/>
2879 <source>Cluster Size</source>
2880 <translation type="unfinished"></translation>
2881 </message>
2882 <message>
2883 <location filename="../sysinfo.cpp" line="70"/>
2884 <source>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</source>
2885 <translation type="unfinished"></translation>
2886 </message>
2887</context>
2888<context>
2889 <name>SysinfoFrm</name>
2890 <message>
2891 <location filename="../sysinfofrm.ui" line="13"/>
2892 <source>System Info</source>
2893 <translation>Info sul sistema</translation>
2894 </message>
2895 <message>
2896 <location filename="../sysinfofrm.ui" line="22"/>
2897 <source>&amp;Refresh</source>
2898 <translation>&amp;Aggiorna</translation>
2899 </message>
2900 <message>
2901 <location filename="../sysinfofrm.ui" line="45"/>
2902 <source>&amp;OK</source>
2903 <translation>&amp;Ok</translation>
2904 </message>
2905</context>
2906<context>
2907 <name>System</name>
2908 <message>
2909 <location filename="../base/system.cpp" line="121"/>
2910 <source>Guest</source>
2911 <translation type="unfinished">Ospite</translation>
2912 </message>
2913 <message>
2914 <location filename="../base/system.cpp" line="124"/>
2915 <source>Admin</source>
2916 <translation type="unfinished">Amministratore</translation>
2917 </message>
2918 <message>
2919 <location filename="../base/system.cpp" line="127"/>
2920 <source>User</source>
2921 <translation type="unfinished">Utente</translation>
2922 </message>
2923 <message>
2924 <location filename="../base/system.cpp" line="130"/>
2925 <source>Error</source>
2926 <translation type="unfinished">Errore</translation>
2927 </message>
2928 <message>
2929 <location filename="../base/system.cpp" line="278"/>
2930 <location filename="../base/system.cpp" line="323"/>
2931 <source>(no description available)</source>
2932 <translation type="unfinished">(nessuna descrizione disponibile)</translation>
2933 </message>
2934</context>
2935<context>
2936 <name>TTSBase</name>
2937 <message>
2938 <location filename="../base/ttsbase.cpp" line="45"/>
2939 <source>Espeak TTS Engine</source>
2940 <translation type="unfinished"></translation>
2941 </message>
2942 <message>
2943 <location filename="../base/ttsbase.cpp" line="47"/>
2944 <source>Flite TTS Engine</source>
2945 <translation type="unfinished"></translation>
2946 </message>
2947 <message>
2948 <location filename="../base/ttsbase.cpp" line="48"/>
2949 <source>Swift TTS Engine</source>
2950 <translation type="unfinished"></translation>
2951 </message>
2952 <message>
2953 <location filename="../base/ttsbase.cpp" line="51"/>
2954 <source>SAPI4 TTS Engine</source>
2955 <translation type="unfinished"></translation>
2956 </message>
2957 <message>
2958 <location filename="../base/ttsbase.cpp" line="53"/>
2959 <source>SAPI5 TTS Engine</source>
2960 <translation type="unfinished"></translation>
2961 </message>
2962 <message>
2963 <location filename="../base/ttsbase.cpp" line="54"/>
2964 <source>MS Speech Platform</source>
2965 <translation type="unfinished"></translation>
2966 </message>
2967 <message>
2968 <location filename="../base/ttsbase.cpp" line="57"/>
2969 <source>Festival TTS Engine</source>
2970 <translation type="unfinished"></translation>
2971 </message>
2972 <message>
2973 <location filename="../base/ttsbase.cpp" line="60"/>
2974 <source>OS X System Engine</source>
2975 <translation type="unfinished"></translation>
2976 </message>
2977</context>
2978<context>
2979 <name>TTSCarbon</name>
2980 <message>
2981 <location filename="../base/ttscarbon.cpp" line="139"/>
2982 <source>Voice:</source>
2983 <translation type="unfinished">Voce:</translation>
2984 </message>
2985 <message>
2986 <location filename="../base/ttscarbon.cpp" line="145"/>
2987 <source>Speed (words/min):</source>
2988 <translation type="unfinished"></translation>
2989 </message>
2990 <message>
2991 <location filename="../base/ttscarbon.cpp" line="152"/>
2992 <source>Pitch (0 for default):</source>
2993 <translation type="unfinished"></translation>
2994 </message>
2995 <message>
2996 <location filename="../base/ttscarbon.cpp" line="222"/>
2997 <source>Could not voice string</source>
2998 <translation type="unfinished"></translation>
2999 </message>
3000 <message>
3001 <location filename="../base/ttscarbon.cpp" line="232"/>
3002 <source>Could not convert intermediate file</source>
3003 <translation type="unfinished"></translation>
3004 </message>
3005</context>
3006<context>
3007 <name>TTSExes</name>
3008 <message>
3009 <location filename="../base/ttsexes.cpp" line="44"/>
3010 <source>Path to TTS engine:</source>
3011 <translation>Percorso del motore TTS:</translation>
3012 </message>
3013 <message>
3014 <location filename="../base/ttsexes.cpp" line="46"/>
3015 <source>TTS engine options:</source>
3016 <translation>Opzioni per il motore TTS:</translation>
3017 </message>
3018 <message>
3019 <location filename="../base/ttsexes.cpp" line="78"/>
3020 <source>TTS executable not found</source>
3021 <translation>Impossibile trovare eseguibile TTS</translation>
3022 </message>
3023</context>
3024<context>
3025 <name>TTSFestival</name>
3026 <message>
3027 <location filename="../base/ttsfestival.cpp" line="53"/>
3028 <source>Path to Festival client:</source>
3029 <translation>Percorso del client Festival:</translation>
3030 </message>
3031 <message>
3032 <location filename="../base/ttsfestival.cpp" line="58"/>
3033 <source>Voice:</source>
3034 <translation>Voce:</translation>
3035 </message>
3036 <message>
3037 <location filename="../base/ttsfestival.cpp" line="67"/>
3038 <source>Voice description:</source>
3039 <translation>Descrizione del file della voce:</translation>
3040 </message>
3041 <message>
3042 <location filename="../base/ttsfestival.cpp" line="207"/>
3043 <source>engine could not voice string</source>
3044 <translation>Il motore non riesce a leggere la stringa</translation>
3045 </message>
3046 <message>
3047 <location filename="../base/ttsfestival.cpp" line="290"/>
3048 <source>No description available</source>
3049 <translation>Nessuna descrizione disponibile</translation>
3050 </message>
3051</context>
3052<context>
3053 <name>TTSSapi</name>
3054 <message>
3055 <location filename="../base/ttssapi.cpp" line="49"/>
3056 <source>Language:</source>
3057 <translation>Lingua:</translation>
3058 </message>
3059 <message>
3060 <location filename="../base/ttssapi.cpp" line="56"/>
3061 <source>Voice:</source>
3062 <translation>Voce:</translation>
3063 </message>
3064 <message>
3065 <location filename="../base/ttssapi.cpp" line="68"/>
3066 <source>Speed:</source>
3067 <translation>Velocità:</translation>
3068 </message>
3069 <message>
3070 <location filename="../base/ttssapi.cpp" line="71"/>
3071 <source>Options:</source>
3072 <translation>Opzioni:</translation>
3073 </message>
3074 <message>
3075 <location filename="../base/ttssapi.cpp" line="115"/>
3076 <source>Could not copy the SAPI script</source>
3077 <translation type="unfinished"></translation>
3078 </message>
3079 <message>
3080 <location filename="../base/ttssapi.cpp" line="133"/>
3081 <source>Could not start SAPI process</source>
3082 <translation type="unfinished"></translation>
3083 </message>
3084</context>
3085<context>
3086 <name>TalkFileCreator</name>
3087 <message>
3088 <location filename="../base/talkfile.cpp" line="42"/>
3089 <source>Reading Filelist...</source>
3090 <translation>Lettura della lista dei file in corso...</translation>
3091 </message>
3092 <message>
3093 <location filename="../base/talkfile.cpp" line="45"/>
3094 <source>Talk file creation aborted</source>
3095 <translation>Creazione del TalkFile interrotta</translation>
3096 </message>
3097 <message>
3098 <location filename="../base/talkfile.cpp" line="68"/>
3099 <source>Copying Talkfiles...</source>
3100 <translation type="unfinished"></translation>
3101 </message>
3102 <message>
3103 <location filename="../base/talkfile.cpp" line="240"/>
3104 <source>File copy aborted</source>
3105 <translation type="unfinished"></translation>
3106 </message>
3107 <message>
3108 <location filename="../base/talkfile.cpp" line="280"/>
3109 <source>Cleaning up...</source>
3110 <translation type="unfinished"></translation>
3111 </message>
3112 <message>
3113 <location filename="../base/talkfile.cpp" line="291"/>
3114 <source>Finished</source>
3115 <translation type="unfinished"></translation>
3116 </message>
3117 <message>
3118 <location filename="../base/talkfile.cpp" line="80"/>
3119 <source>Finished creating Talk files</source>
3120 <translation>Creazione Talkfile conclusa</translation>
3121 </message>
3122 <message>
3123 <location filename="../base/talkfile.cpp" line="36"/>
3124 <source>Starting Talk file generation for folder %1</source>
3125 <translation type="unfinished"></translation>
3126 </message>
3127 <message>
3128 <location filename="../base/talkfile.cpp" line="259"/>
3129 <source>Copying of %1 to %2 failed</source>
3130 <translation>Copia di %1 in %2 fallita</translation>
3131 </message>
3132</context>
3133<context>
3134 <name>TalkGenerator</name>
3135 <message>
3136 <location filename="../base/talkgenerator.cpp" line="39"/>
3137 <source>Starting TTS Engine</source>
3138 <translation type="unfinished"></translation>
3139 </message>
3140 <message>
3141 <location filename="../base/talkgenerator.cpp" line="44"/>
3142 <location filename="../base/talkgenerator.cpp" line="51"/>
3143 <source>Init of TTS engine failed</source>
3144 <translation type="unfinished"></translation>
3145 </message>
3146 <message>
3147 <location filename="../base/talkgenerator.cpp" line="58"/>
3148 <source>Starting Encoder Engine</source>
3149 <translation type="unfinished"></translation>
3150 </message>
3151 <message>
3152 <location filename="../base/talkgenerator.cpp" line="62"/>
3153 <source>Init of Encoder engine failed</source>
3154 <translation type="unfinished"></translation>
3155 </message>
3156 <message>
3157 <location filename="../base/talkgenerator.cpp" line="72"/>
3158 <source>Voicing entries...</source>
3159 <translation type="unfinished"></translation>
3160 </message>
3161 <message>
3162 <location filename="../base/talkgenerator.cpp" line="87"/>
3163 <source>Encoding files...</source>
3164 <translation type="unfinished">Codififca file in corso...</translation>
3165 </message>
3166 <message>
3167 <location filename="../base/talkgenerator.cpp" line="126"/>
3168 <source>Voicing aborted</source>
3169 <translation type="unfinished"></translation>
3170 </message>
3171 <message>
3172 <location filename="../base/talkgenerator.cpp" line="162"/>
3173 <location filename="../base/talkgenerator.cpp" line="167"/>
3174 <source>Voicing of %1 failed: %2</source>
3175 <translation type="unfinished">Sintesi vocale di %1 fallita: %2</translation>
3176 </message>
3177 <message>
3178 <location filename="../base/talkgenerator.cpp" line="211"/>
3179 <source>Encoding aborted</source>
3180 <translation type="unfinished"></translation>
3181 </message>
3182 <message>
3183 <location filename="../base/talkgenerator.cpp" line="239"/>
3184 <source>Encoding of %1 failed</source>
3185 <translation type="unfinished">Codifica di %1 fallita</translation>
3186 </message>
3187</context>
3188<context>
3189 <name>ThemeInstallFrm</name>
3190 <message>
3191 <location filename="../themesinstallfrm.ui" line="13"/>
3192 <source>Theme Installation</source>
3193 <translation>Installazione Tema</translation>
3194 </message>
3195 <message>
3196 <location filename="../themesinstallfrm.ui" line="48"/>
3197 <source>Selected Theme</source>
3198 <translation>Tema selezionato</translation>
3199 </message>
3200 <message>
3201 <location filename="../themesinstallfrm.ui" line="73"/>
3202 <source>Description</source>
3203 <translation>Descrizione</translation>
3204 </message>
3205 <message>
3206 <location filename="../themesinstallfrm.ui" line="83"/>
3207 <source>Download size:</source>
3208 <translation>Dimensione download:</translation>
3209 </message>
3210 <message>
3211 <location filename="../themesinstallfrm.ui" line="93"/>
3212 <source>Hold Ctrl to select multiple item, Shift for a range</source>
3213 <translation>Premere Ctrl per selezionare più temi, Shift per un gruppo</translation>
3214 </message>
3215 <message>
3216 <location filename="../themesinstallfrm.ui" line="115"/>
3217 <source>&amp;Install</source>
3218 <translation>&amp;Installa</translation>
3219 </message>
3220 <message>
3221 <location filename="../themesinstallfrm.ui" line="125"/>
3222 <source>&amp;Cancel</source>
3223 <translation>&amp;annulla</translation>
3224 </message>
3225</context>
3226<context>
3227 <name>ThemesInstallWindow</name>
3228 <message>
3229 <location filename="../themesinstallwindow.cpp" line="40"/>
3230 <source>no theme selected</source>
3231 <translation>Nessun tema selezionato</translation>
3232 </message>
3233 <message>
3234 <location filename="../themesinstallwindow.cpp" line="41"/>
3235 <source>no selection</source>
3236 <translation>Nessuna scelta</translation>
3237 </message>
3238 <message>
3239 <location filename="../themesinstallwindow.cpp" line="125"/>
3240 <source>Network error: %1.
3241Please check your network and proxy settings.</source>
3242 <translation>Errore rete: %1. Per favore controlla le impostazioni di rete e del proxy.</translation>
3243 </message>
3244 <message>
3245 <location filename="../themesinstallwindow.cpp" line="138"/>
3246 <source>the following error occured:
3247%1</source>
3248 <translation>E&apos; sorto il seguente errore: %1</translation>
3249 </message>
3250 <message>
3251 <location filename="../themesinstallwindow.cpp" line="144"/>
3252 <source>done.</source>
3253 <translation>fatto.</translation>
3254 </message>
3255 <message>
3256 <location filename="../themesinstallwindow.cpp" line="181"/>
3257 <source>Information</source>
3258 <translation>Informazioni</translation>
3259 </message>
3260 <message numerus="yes">
3261 <location filename="../themesinstallwindow.cpp" line="198"/>
3262 <source>Download size %L1 kiB (%n item(s))</source>
3263 <translation>
3264 <numerusform>Grandezza download %L1 kiB (%n oggetti)</numerusform>
3265 <numerusform></numerusform>
3266 </translation>
3267 </message>
3268 <message>
3269 <location filename="../themesinstallwindow.cpp" line="211"/>
3270 <source>fetching details for %1</source>
3271 <translation>download dettagli per %1 in corso</translation>
3272 </message>
3273 <message>
3274 <location filename="../themesinstallwindow.cpp" line="214"/>
3275 <source>fetching preview ...</source>
3276 <translation>download anteprima in corso...</translation>
3277 </message>
3278 <message>
3279 <location filename="../themesinstallwindow.cpp" line="227"/>
3280 <source>&lt;b&gt;Author:&lt;/b&gt; %1&lt;hr/&gt;</source>
3281 <translation>&lt;b&gt;Autore:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3282 </message>
3283 <message>
3284 <location filename="../themesinstallwindow.cpp" line="228"/>
3285 <location filename="../themesinstallwindow.cpp" line="230"/>
3286 <source>unknown</source>
3287 <translation>Sconosciuto</translation>
3288 </message>
3289 <message>
3290 <location filename="../themesinstallwindow.cpp" line="229"/>
3291 <source>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</source>
3292 <translation>&lt;b&gt;Versione:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3293 </message>
3294 <message>
3295 <location filename="../themesinstallwindow.cpp" line="231"/>
3296 <source>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</source>
3297 <translation>&lt;b&gt;Descrizione:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3298 </message>
3299 <message>
3300 <location filename="../themesinstallwindow.cpp" line="232"/>
3301 <source>no description</source>
3302 <translation>nessuna descrizione</translation>
3303 </message>
3304 <message>
3305 <location filename="../themesinstallwindow.cpp" line="248"/>
3306 <source>Retrieving theme preview failed.
3307HTTP response code: %1</source>
3308 <translation>Download anteprima tema fallita. Codice di risposta HTTP: %1</translation>
3309 </message>
3310 <message>
3311 <location filename="../themesinstallwindow.cpp" line="260"/>
3312 <source>no theme preview</source>
3313 <translation>nessuna anteprima disponibile</translation>
3314 </message>
3315 <message>
3316 <location filename="../themesinstallwindow.cpp" line="289"/>
3317 <source>Select</source>
3318 <translation type="unfinished"></translation>
3319 </message>
3320 <message>
3321 <location filename="../themesinstallwindow.cpp" line="296"/>
3322 <source>getting themes information ...</source>
3323 <translation>download info sul tema in corso...</translation>
3324 </message>
3325 <message>
3326 <location filename="../themesinstallwindow.cpp" line="326"/>
3327 <source>No themes selected, skipping</source>
3328 <translation type="unfinished"></translation>
3329 </message>
3330 <message>
3331 <location filename="../themesinstallwindow.cpp" line="356"/>
3332 <source>Mount point is wrong!</source>
3333 <translation>Mount point errato!</translation>
3334 </message>
3335</context>
3336<context>
3337 <name>UninstallFrm</name>
3338 <message>
3339 <location filename="../uninstallfrm.ui" line="16"/>
3340 <source>Uninstall Rockbox</source>
3341 <translation>Disinstalla Rockbox</translation>
3342 </message>
3343 <message>
3344 <location filename="../uninstallfrm.ui" line="35"/>
3345 <source>Please select the Uninstallation Method</source>
3346 <translation>Per favore scegli il metodo di disinstallazione</translation>
3347 </message>
3348 <message>
3349 <location filename="../uninstallfrm.ui" line="45"/>
3350 <source>Uninstallation Method</source>
3351 <translation>Metodo di disinstallazione</translation>
3352 </message>
3353 <message>
3354 <location filename="../uninstallfrm.ui" line="51"/>
3355 <source>Complete Uninstallation</source>
3356 <translation>Disinstallazione completa</translation>
3357 </message>
3358 <message>
3359 <location filename="../uninstallfrm.ui" line="58"/>
3360 <source>Smart Uninstallation</source>
3361 <translation>Disinstallazione intelligente</translation>
3362 </message>
3363 <message>
3364 <location filename="../uninstallfrm.ui" line="68"/>
3365 <source>Please select what you want to uninstall</source>
3366 <translation>Per favore scegli ciò che vuoi disinstallare</translation>
3367 </message>
3368 <message>
3369 <location filename="../uninstallfrm.ui" line="78"/>
3370 <source>Installed Parts</source>
3371 <translation>Componenti installati</translation>
3372 </message>
3373 <message>
3374 <location filename="../uninstallfrm.ui" line="128"/>
3375 <source>&amp;Uninstall</source>
3376 <translation>&amp;Disinstalla</translation>
3377 </message>
3378 <message>
3379 <location filename="../uninstallfrm.ui" line="138"/>
3380 <source>&amp;Cancel</source>
3381 <translation>&amp;Annulla</translation>
3382 </message>
3383</context>
3384<context>
3385 <name>Uninstaller</name>
3386 <message>
3387 <location filename="../base/uninstall.cpp" line="32"/>
3388 <location filename="../base/uninstall.cpp" line="43"/>
3389 <source>Starting Uninstallation</source>
3390 <translation>Disinstallazione iniziata</translation>
3391 </message>
3392 <message>
3393 <location filename="../base/uninstall.cpp" line="36"/>
3394 <source>Finished Uninstallation</source>
3395 <translation>Disinstallazione finita</translation>
3396 </message>
3397 <message>
3398 <location filename="../base/uninstall.cpp" line="49"/>
3399 <source>Uninstalling %1...</source>
3400 <translation type="unfinished"></translation>
3401 </message>
3402 <message>
3403 <location filename="../base/uninstall.cpp" line="80"/>
3404 <source>Could not delete %1</source>
3405 <translation type="unfinished"></translation>
3406 </message>
3407 <message>
3408 <location filename="../base/uninstall.cpp" line="109"/>
3409 <source>Uninstallation finished</source>
3410 <translation>Disinstallazione finita</translation>
3411 </message>
3412</context>
3413<context>
3414 <name>Utils</name>
3415 <message>
3416 <location filename="../base/utils.cpp" line="312"/>
3417 <source>&lt;li&gt;Permissions insufficient for bootloader installation.
3418Administrator priviledges are necessary.&lt;/li&gt;</source>
3419 <translation type="unfinished">&lt;li&gt;Permessi insufficenti per installare il bootloader.
3420Sono necessari i privilegi di amministratore.&lt;/li&gt;</translation>
3421 </message>
3422 <message>
3423 <location filename="../base/utils.cpp" line="324"/>
3424 <source>&lt;li&gt;Target mismatch detected.&lt;br/&gt;Installed target: %1&lt;br/&gt;Selected target: %2.&lt;/li&gt;</source>
3425 <translation type="unfinished"></translation>
3426 </message>
3427 <message>
3428 <location filename="../base/utils.cpp" line="331"/>
3429 <source>Problem detected:</source>
3430 <translation type="unfinished">Problema individuato:</translation>
3431 </message>
3432</context>
3433<context>
3434 <name>VoiceFileCreator</name>
3435 <message>
3436 <location filename="../base/voicefile.cpp" line="43"/>
3437 <source>Starting Voicefile generation</source>
3438 <translation>Generazione del Voicefile in corso</translation>
3439 </message>
3440 <message>
3441 <location filename="../base/voicefile.cpp" line="56"/>
3442 <source>could not find rockbox-info.txt</source>
3443 <translation>Impossibile trovare rockbox-info.txt</translation>
3444 </message>
3445 <message>
3446 <location filename="../base/voicefile.cpp" line="90"/>
3447 <source>Extracted voice strings from installation</source>
3448 <translation type="unfinished"></translation>
3449 </message>
3450 <message>
3451 <location filename="../base/voicefile.cpp" line="100"/>
3452 <source>Extracted voice strings incompatible</source>
3453 <translation type="unfinished"></translation>
3454 </message>
3455 <message>
3456 <location filename="../base/voicefile.cpp" line="145"/>
3457 <source>Could not retrieve strings from installation, downloading</source>
3458 <translation type="unfinished"></translation>
3459 </message>
3460 <message>
3461 <location filename="../base/voicefile.cpp" line="171"/>
3462 <source>Downloading voice info...</source>
3463 <translation type="unfinished"></translation>
3464 </message>
3465 <message>
3466 <location filename="../base/voicefile.cpp" line="184"/>
3467 <source>Download error: received HTTP error %1.</source>
3468 <translation>Errore nel download: errore HTTP %1.</translation>
3469 </message>
3470 <message>
3471 <location filename="../base/voicefile.cpp" line="191"/>
3472 <source>Cached file used.</source>
3473 <translation>Usato file in cache.</translation>
3474 </message>
3475 <message>
3476 <location filename="../base/voicefile.cpp" line="194"/>
3477 <source>Download error: %1</source>
3478 <translation>Errore nel download: %1</translation>
3479 </message>
3480 <message>
3481 <location filename="../base/voicefile.cpp" line="199"/>
3482 <source>Download finished.</source>
3483 <translation>Download concluso.</translation>
3484 </message>
3485 <message>
3486 <location filename="../base/voicefile.cpp" line="212"/>
3487 <source>failed to open downloaded file</source>
3488 <translation>Impossibile aprire il file scaricato</translation>
3489 </message>
3490 <message>
3491 <location filename="../base/voicefile.cpp" line="218"/>
3492 <source>Reading strings...</source>
3493 <translation type="unfinished"></translation>
3494 </message>
3495 <message>
3496 <location filename="../base/voicefile.cpp" line="297"/>
3497 <source>Creating voicefiles...</source>
3498 <translation type="unfinished"></translation>
3499 </message>
3500 <message>
3501 <location filename="../base/voicefile.cpp" line="342"/>
3502 <source>Cleaning up...</source>
3503 <translation type="unfinished"></translation>
3504 </message>
3505 <message>
3506 <location filename="../base/voicefile.cpp" line="353"/>
3507 <source>Finished</source>
3508 <translation type="unfinished"></translation>
3509 </message>
3510 <message>
3511 <location filename="../base/voicefile.cpp" line="271"/>
3512 <source>The downloaded file was empty!</source>
3513 <translation>Il file scaricato era vuoto!</translation>
3514 </message>
3515 <message>
3516 <location filename="../base/voicefile.cpp" line="302"/>
3517 <source>Error opening downloaded file</source>
3518 <translation>Errore nell&apos;apertura del file scaricato</translation>
3519 </message>
3520 <message>
3521 <location filename="../base/voicefile.cpp" line="313"/>
3522 <source>Error opening output file</source>
3523 <translation>Errore nell&apos;apertura del file in outpt</translation>
3524 </message>
3525 <message>
3526 <location filename="../base/voicefile.cpp" line="333"/>
3527 <source>successfully created.</source>
3528 <translation>Creato con successo.</translation>
3529 </message>
3530</context>
3531<context>
3532 <name>ZipInstaller</name>
3533 <message>
3534 <location filename="../base/zipinstaller.cpp" line="60"/>
3535 <source>done.</source>
3536 <translation>Fatto.</translation>
3537 </message>
3538 <message>
3539 <location filename="../base/zipinstaller.cpp" line="80"/>
3540 <source>Downloading file %1.%2</source>
3541 <translation>Download file in corso %1.%2</translation>
3542 </message>
3543 <message>
3544 <location filename="../base/zipinstaller.cpp" line="115"/>
3545 <source>Download error: received HTTP error %1.</source>
3546 <translation>Errore durante il download: errore HTTP %1.</translation>
3547 </message>
3548 <message>
3549 <location filename="../base/zipinstaller.cpp" line="121"/>
3550 <source>Cached file used.</source>
3551 <translation>Usato file in cache.</translation>
3552 </message>
3553 <message>
3554 <location filename="../base/zipinstaller.cpp" line="123"/>
3555 <source>Download error: %1</source>
3556 <translation>Errore Download: %1</translation>
3557 </message>
3558 <message>
3559 <location filename="../base/zipinstaller.cpp" line="127"/>
3560 <source>Download finished.</source>
3561 <translation>Download concluso.</translation>
3562 </message>
3563 <message>
3564 <location filename="../base/zipinstaller.cpp" line="133"/>
3565 <source>Extracting file.</source>
3566 <translation>Estrazione file in corso.</translation>
3567 </message>
3568 <message>
3569 <location filename="../base/zipinstaller.cpp" line="153"/>
3570 <source>Extraction failed!</source>
3571 <translation type="unfinished"></translation>
3572 </message>
3573 <message>
3574 <location filename="../base/zipinstaller.cpp" line="146"/>
3575 <source>Not enough disk space! Aborting.</source>
3576 <translation>Spazio du disco insufficente! Interruzione in corso.</translation>
3577 </message>
3578 <message>
3579 <location filename="../base/zipinstaller.cpp" line="68"/>
3580 <source>Package installation finished successfully.</source>
3581 <translation type="unfinished"></translation>
3582 </message>
3583 <message>
3584 <location filename="../base/zipinstaller.cpp" line="162"/>
3585 <source>Installing file.</source>
3586 <translation>Installazione file in corso.</translation>
3587 </message>
3588 <message>
3589 <location filename="../base/zipinstaller.cpp" line="173"/>
3590 <source>Installing file failed.</source>
3591 <translation>Installazione file fallita.</translation>
3592 </message>
3593 <message>
3594 <location filename="../base/zipinstaller.cpp" line="186"/>
3595 <source>Creating installation log</source>
3596 <translation>Creazione log dell&apos;installazione in corso</translation>
3597 </message>
3598</context>
3599<context>
3600 <name>ZipUtil</name>
3601 <message>
3602 <location filename="../base/ziputil.cpp" line="125"/>
3603 <source>Creating output path failed</source>
3604 <translation type="unfinished"></translation>
3605 </message>
3606 <message>
3607 <location filename="../base/ziputil.cpp" line="132"/>
3608 <source>Creating output file failed</source>
3609 <translation type="unfinished"></translation>
3610 </message>
3611 <message>
3612 <location filename="../base/ziputil.cpp" line="141"/>
3613 <source>Error during Zip operation</source>
3614 <translation type="unfinished"></translation>
3615 </message>
3616</context>
3617<context>
3618 <name>aboutBox</name>
3619 <message>
3620 <location filename="../aboutbox.ui" line="14"/>
3621 <source>About Rockbox Utility</source>
3622 <translation>A proposito di Rockbox Utility</translation>
3623 </message>
3624 <message>
3625 <location filename="../aboutbox.ui" line="32"/>
3626 <source>The Rockbox Utility</source>
3627 <translation>Rockbox Utility</translation>
3628 </message>
3629 <message utf8="true">
3630 <location filename="../aboutbox.ui" line="54"/>
3631 <source>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</source>
3632 <translation type="unfinished"></translation>
3633 </message>
3634 <message>
3635 <location filename="../aboutbox.ui" line="74"/>
3636 <source>&amp;Credits</source>
3637 <translation>&amp;Riconoscimenti</translation>
3638 </message>
3639 <message>
3640 <location filename="../aboutbox.ui" line="106"/>
3641 <source>&amp;License</source>
3642 <translation>&amp;Licenza</translation>
3643 </message>
3644 <message>
3645 <location filename="../aboutbox.ui" line="132"/>
3646 <source>&amp;Speex License</source>
3647 <translation type="unfinished"></translation>
3648 </message>
3649 <message>
3650 <location filename="../aboutbox.ui" line="158"/>
3651 <source>&amp;Ok</source>
3652 <translation>&amp;Ok</translation>
3653 </message>
3654</context>
3655</TS>
diff --git a/utils/rbutilqt/lang/rbutil_ja.ts b/utils/rbutilqt/lang/rbutil_ja.ts
new file mode 100644
index 0000000000..11a52c8754
--- /dev/null
+++ b/utils/rbutilqt/lang/rbutil_ja.ts
@@ -0,0 +1,3678 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE TS>
3<TS version="2.0" language="ja_JP">
4<context>
5 <name>BackupDialog</name>
6 <message>
7 <location filename="../gui/backupdialogfrm.ui" line="17"/>
8 <location filename="../gui/backupdialogfrm.ui" line="43"/>
9 <source>Backup</source>
10 <translation type="unfinished">バックアップ</translation>
11 </message>
12 <message>
13 <location filename="../gui/backupdialogfrm.ui" line="33"/>
14 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This dialog will create a backup by archiving the contents of the Rockbox installation on the player into a zip file. This will include installed themes and settings stored below the .rockbox folder on the player.&lt;/p&gt;&lt;p&gt;The backup filename will be created based on the installed version. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
15 <translation type="unfinished"></translation>
16 </message>
17 <message>
18 <location filename="../gui/backupdialogfrm.ui" line="49"/>
19 <source>Size: unknown</source>
20 <translation type="unfinished"></translation>
21 </message>
22 <message>
23 <location filename="../gui/backupdialogfrm.ui" line="56"/>
24 <source>Backup to: unknown</source>
25 <translation type="unfinished"></translation>
26 </message>
27 <message>
28 <location filename="../gui/backupdialogfrm.ui" line="76"/>
29 <source>&amp;Change</source>
30 <translation type="unfinished">変更(&amp;C)</translation>
31 </message>
32 <message>
33 <location filename="../gui/backupdialogfrm.ui" line="116"/>
34 <source>&amp;Backup</source>
35 <translation type="unfinished"></translation>
36 </message>
37 <message>
38 <location filename="../gui/backupdialogfrm.ui" line="127"/>
39 <source>&amp;Cancel</source>
40 <translation type="unfinished">キャンセル(&amp;C)</translation>
41 </message>
42 <message>
43 <location filename="../gui/backupdialog.cpp" line="70"/>
44 <source>Installation size: calculating ...</source>
45 <translation type="unfinished"></translation>
46 </message>
47 <message>
48 <location filename="../gui/backupdialog.cpp" line="89"/>
49 <source>Select Backup Filename</source>
50 <translation type="unfinished">バックアップファイルの選択</translation>
51 </message>
52 <message>
53 <location filename="../gui/backupdialog.cpp" line="109"/>
54 <source>Installation size: %L1 %2</source>
55 <translation type="unfinished"></translation>
56 </message>
57 <message>
58 <location filename="../gui/backupdialog.cpp" line="116"/>
59 <source>File exists</source>
60 <translation type="unfinished"></translation>
61 </message>
62 <message>
63 <location filename="../gui/backupdialog.cpp" line="117"/>
64 <source>The selected backup file already exists. Overwrite?</source>
65 <translation type="unfinished"></translation>
66 </message>
67 <message>
68 <location filename="../gui/backupdialog.cpp" line="125"/>
69 <source>Starting backup ...</source>
70 <translation type="unfinished"></translation>
71 </message>
72 <message>
73 <location filename="../gui/backupdialog.cpp" line="144"/>
74 <source>Backup successful.</source>
75 <translation type="unfinished"></translation>
76 </message>
77 <message>
78 <location filename="../gui/backupdialog.cpp" line="147"/>
79 <source>Backup failed!</source>
80 <translation type="unfinished">バックアップが失敗しました!</translation>
81 </message>
82</context>
83<context>
84 <name>BootloaderInstallAms</name>
85 <message>
86 <location filename="../base/bootloaderinstallams.cpp" line="33"/>
87 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; This file is not present on your player and will disappear automatically after installing it.&lt;br/&gt;&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
88 <translation type="unfinished"></translation>
89 </message>
90 <message>
91 <location filename="../base/bootloaderinstallams.cpp" line="58"/>
92 <source>Downloading bootloader file</source>
93 <translation>ブートローダをダウンロードしています</translation>
94 </message>
95 <message>
96 <location filename="../base/bootloaderinstallams.cpp" line="100"/>
97 <location filename="../base/bootloaderinstallams.cpp" line="113"/>
98 <source>Could not load %1</source>
99 <translation>%1 をロードすることができませんでした</translation>
100 </message>
101 <message>
102 <location filename="../base/bootloaderinstallams.cpp" line="127"/>
103 <source>No room to insert bootloader, try another firmware version</source>
104 <translation>ブートローダに挿入する余裕がありません。他のバージョンのファームウェアで試して下さい</translation>
105 </message>
106 <message>
107 <location filename="../base/bootloaderinstallams.cpp" line="137"/>
108 <source>Patching Firmware...</source>
109 <translation>ファームウェアにパッチをあてています...</translation>
110 </message>
111 <message>
112 <location filename="../base/bootloaderinstallams.cpp" line="148"/>
113 <source>Could not open %1 for writing</source>
114 <translation>書き込めるように %1 を開くことができませんでした</translation>
115 </message>
116 <message>
117 <location filename="../base/bootloaderinstallams.cpp" line="161"/>
118 <source>Could not write firmware file</source>
119 <translation>ファームウェアを書き込むことができませんでした</translation>
120 </message>
121 <message>
122 <location filename="../base/bootloaderinstallams.cpp" line="177"/>
123 <source>Success: modified firmware file created</source>
124 <translation>成功: 変更されたファームウェアが作成されました</translation>
125 </message>
126 <message>
127 <location filename="../base/bootloaderinstallams.cpp" line="185"/>
128 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
129 <translation>アンインストールは、改変されていないオリジナルのファームウェアを用いて通常の方法でファームウェアの更新を行って下さい</translation>
130 </message>
131</context>
132<context>
133 <name>BootloaderInstallBase</name>
134 <message>
135 <location filename="../base/bootloaderinstallbase.cpp" line="78"/>
136 <source>Download error: received HTTP error %1.</source>
137 <translation>ダウンロードエラー: HTTP 受信のエラー %1.</translation>
138 </message>
139 <message>
140 <location filename="../base/bootloaderinstallbase.cpp" line="84"/>
141 <source>Download error: %1</source>
142 <translation>ダウンロードエラー: %1</translation>
143 </message>
144 <message>
145 <location filename="../base/bootloaderinstallbase.cpp" line="90"/>
146 <source>Download finished (cache used).</source>
147 <translation>ダウンロードが終了しました (キャッシュの使用)。</translation>
148 </message>
149 <message>
150 <location filename="../base/bootloaderinstallbase.cpp" line="92"/>
151 <source>Download finished.</source>
152 <translation>ダウンロードが終了しました。</translation>
153 </message>
154 <message>
155 <location filename="../base/bootloaderinstallbase.cpp" line="113"/>
156 <source>Creating backup of original firmware file.</source>
157 <translation>オリジナルのファームウェアのバックアップを行っています。</translation>
158 </message>
159 <message>
160 <location filename="../base/bootloaderinstallbase.cpp" line="115"/>
161 <source>Creating backup folder failed</source>
162 <translation>バックアップフォルダの作成に失敗しました</translation>
163 </message>
164 <message>
165 <location filename="../base/bootloaderinstallbase.cpp" line="121"/>
166 <source>Creating backup copy failed.</source>
167 <translation>バックアップに失敗しました。</translation>
168 </message>
169 <message>
170 <location filename="../base/bootloaderinstallbase.cpp" line="124"/>
171 <source>Backup created.</source>
172 <translation>バックアップが作成されました。</translation>
173 </message>
174 <message>
175 <location filename="../base/bootloaderinstallbase.cpp" line="137"/>
176 <source>Creating installation log</source>
177 <translation>インストール時のログを作成しています</translation>
178 </message>
179 <message>
180 <location filename="../base/bootloaderinstallbase.cpp" line="226"/>
181 <source>Zip file format detected</source>
182 <translation type="unfinished"></translation>
183 </message>
184 <message>
185 <location filename="../base/bootloaderinstallbase.cpp" line="238"/>
186 <source>CAB file format detected</source>
187 <translation type="unfinished"></translation>
188 </message>
189 <message>
190 <location filename="../base/bootloaderinstallbase.cpp" line="259"/>
191 <source>Extracting firmware %1 from archive</source>
192 <translation type="unfinished"></translation>
193 </message>
194 <message>
195 <location filename="../base/bootloaderinstallbase.cpp" line="266"/>
196 <source>Error extracting firmware from archive</source>
197 <translation type="unfinished"></translation>
198 </message>
199 <message>
200 <location filename="../base/bootloaderinstallbase.cpp" line="275"/>
201 <source>Could not find firmware in archive</source>
202 <translation type="unfinished"></translation>
203 </message>
204 <message>
205 <location filename="../base/bootloaderinstallbase.cpp" line="159"/>
206 <source>Waiting for system to remount player</source>
207 <translation>プレイヤーが再びマウントされるのを待っています</translation>
208 </message>
209 <message>
210 <location filename="../base/bootloaderinstallbase.cpp" line="189"/>
211 <source>Player remounted</source>
212 <translation>プレイヤーが再びマウントしました</translation>
213 </message>
214 <message>
215 <location filename="../base/bootloaderinstallbase.cpp" line="194"/>
216 <source>Timeout on remount</source>
217 <translation>プレイヤーの再マウント処理がタイムアウトしました</translation>
218 </message>
219 <message>
220 <location filename="../base/bootloaderinstallbase.cpp" line="149"/>
221 <source>Installation log created</source>
222 <translation>インストール時のログを作成しました</translation>
223 </message>
224</context>
225<context>
226 <name>BootloaderInstallChinaChip</name>
227 <message>
228 <location filename="../base/bootloaderinstallchinachip.cpp" line="33"/>
229 <source>Bootloader installation requires you to provide a firmware file of the original firmware (HXF file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
230 <translation>ブートローダのインストールには、オリジナルのファームウェア(HXF 形式のファイル)を用意する必要があります。法律上の理由により、ファームウェアはあなた自身でダウンロードする必要があります。&lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;マニュアル&lt;/a&gt; および、ファームウェアを取得する方法が書かれた &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; の Wiki ページを参考にして下さい。&lt;br/&gt;ファームウェアが用意できましたら、OKボタンを押して下さい。</translation>
231 </message>
232 <message>
233 <location filename="../base/bootloaderinstallchinachip.cpp" line="50"/>
234 <source>Downloading bootloader file</source>
235 <translation>ブートローダをダウンロードしています</translation>
236 </message>
237 <message>
238 <location filename="../base/bootloaderinstallchinachip.cpp" line="75"/>
239 <source>Could not open firmware file</source>
240 <translation type="unfinished"></translation>
241 </message>
242 <message>
243 <location filename="../base/bootloaderinstallchinachip.cpp" line="78"/>
244 <source>Could not open bootloader file</source>
245 <translation type="unfinished"></translation>
246 </message>
247 <message>
248 <location filename="../base/bootloaderinstallchinachip.cpp" line="81"/>
249 <source>Could not allocate memory</source>
250 <translation type="unfinished"></translation>
251 </message>
252 <message>
253 <location filename="../base/bootloaderinstallchinachip.cpp" line="84"/>
254 <source>Could not load firmware file</source>
255 <translation type="unfinished"></translation>
256 </message>
257 <message>
258 <location filename="../base/bootloaderinstallchinachip.cpp" line="87"/>
259 <source>File is not a valid ChinaChip firmware</source>
260 <translation type="unfinished"></translation>
261 </message>
262 <message>
263 <location filename="../base/bootloaderinstallchinachip.cpp" line="90"/>
264 <source>Could not find ccpmp.bin in input file</source>
265 <translation type="unfinished"></translation>
266 </message>
267 <message>
268 <location filename="../base/bootloaderinstallchinachip.cpp" line="93"/>
269 <source>Could not open backup file for ccpmp.bin</source>
270 <translation type="unfinished"></translation>
271 </message>
272 <message>
273 <location filename="../base/bootloaderinstallchinachip.cpp" line="96"/>
274 <source>Could not write backup file for ccpmp.bin</source>
275 <translation type="unfinished"></translation>
276 </message>
277 <message>
278 <location filename="../base/bootloaderinstallchinachip.cpp" line="99"/>
279 <source>Could not load bootloader file</source>
280 <translation type="unfinished"></translation>
281 </message>
282 <message>
283 <location filename="../base/bootloaderinstallchinachip.cpp" line="102"/>
284 <source>Could not get current time</source>
285 <translation type="unfinished"></translation>
286 </message>
287 <message>
288 <location filename="../base/bootloaderinstallchinachip.cpp" line="105"/>
289 <source>Could not open output file</source>
290 <translation type="unfinished"></translation>
291 </message>
292 <message>
293 <location filename="../base/bootloaderinstallchinachip.cpp" line="108"/>
294 <source>Could not write output file</source>
295 <translation type="unfinished"></translation>
296 </message>
297 <message>
298 <location filename="../base/bootloaderinstallchinachip.cpp" line="111"/>
299 <source>Unexpected error from chinachippatcher</source>
300 <translation type="unfinished"></translation>
301 </message>
302</context>
303<context>
304 <name>BootloaderInstallFile</name>
305 <message>
306 <location filename="../base/bootloaderinstallfile.cpp" line="34"/>
307 <source>Downloading bootloader</source>
308 <translation>ブートローダをダウンロードしています</translation>
309 </message>
310 <message>
311 <location filename="../base/bootloaderinstallfile.cpp" line="43"/>
312 <source>Installing Rockbox bootloader</source>
313 <translation>Rockboxのブートローダをインストールしています</translation>
314 </message>
315 <message>
316 <location filename="../base/bootloaderinstallfile.cpp" line="75"/>
317 <source>Error accessing output folder</source>
318 <translation>出力フォルダへのアクセスエラー</translation>
319 </message>
320 <message>
321 <location filename="../base/bootloaderinstallfile.cpp" line="89"/>
322 <source>A firmware file is already present on player</source>
323 <translation type="unfinished"></translation>
324 </message>
325 <message>
326 <location filename="../base/bootloaderinstallfile.cpp" line="94"/>
327 <source>Bootloader successful installed</source>
328 <translation>ブートローダのインストールが成功しました</translation>
329 </message>
330 <message>
331 <location filename="../base/bootloaderinstallfile.cpp" line="97"/>
332 <source>Copying modified firmware file failed</source>
333 <translation type="unfinished"></translation>
334 </message>
335 <message>
336 <location filename="../base/bootloaderinstallfile.cpp" line="111"/>
337 <source>Removing Rockbox bootloader</source>
338 <translation>Rockboxのブートローダを削除しています</translation>
339 </message>
340 <message>
341 <location filename="../base/bootloaderinstallfile.cpp" line="115"/>
342 <source>No original firmware file found.</source>
343 <translation>オリジナルのファームウェアが見つかりませんでした。</translation>
344 </message>
345 <message>
346 <location filename="../base/bootloaderinstallfile.cpp" line="121"/>
347 <source>Can&apos;t remove Rockbox bootloader file.</source>
348 <translation>Rockboxのブートローダの削除ができません。</translation>
349 </message>
350 <message>
351 <location filename="../base/bootloaderinstallfile.cpp" line="126"/>
352 <source>Can&apos;t restore bootloader file.</source>
353 <translation>ブートローダファイルの復旧ができません。</translation>
354 </message>
355 <message>
356 <location filename="../base/bootloaderinstallfile.cpp" line="130"/>
357 <source>Original bootloader restored successfully.</source>
358 <translation>オリジナルのブートローダの復旧が成功しました。</translation>
359 </message>
360</context>
361<context>
362 <name>BootloaderInstallHex</name>
363 <message>
364 <location filename="../base/bootloaderinstallhex.cpp" line="69"/>
365 <source>checking MD5 hash of input file ...</source>
366 <translation>入力ファイルのMD5ハッシュ値をチェックしています...</translation>
367 </message>
368 <message>
369 <location filename="../base/bootloaderinstallhex.cpp" line="80"/>
370 <source>Could not verify original firmware file</source>
371 <translation>オリジナルのファームウェアファイルの確認ができませんでした</translation>
372 </message>
373 <message>
374 <location filename="../base/bootloaderinstallhex.cpp" line="95"/>
375 <source>Firmware file not recognized.</source>
376 <translation>ファームウェアファイルが認識されません。</translation>
377 </message>
378 <message>
379 <location filename="../base/bootloaderinstallhex.cpp" line="99"/>
380 <source>MD5 hash ok</source>
381 <translation>MD5ハッシュ値ok</translation>
382 </message>
383 <message>
384 <location filename="../base/bootloaderinstallhex.cpp" line="106"/>
385 <source>Firmware file doesn&apos;t match selected player.</source>
386 <translation>ファームウェアファイルは、選択されたプレイヤーに適合しません。</translation>
387 </message>
388 <message>
389 <location filename="../base/bootloaderinstallhex.cpp" line="111"/>
390 <source>Descrambling file</source>
391 <translation>ファームウェアを復号しています</translation>
392 </message>
393 <message>
394 <location filename="../base/bootloaderinstallhex.cpp" line="119"/>
395 <source>Error in descramble: %1</source>
396 <translation>ファームウェアの復号処理時にエラーが発生しました: %1</translation>
397 </message>
398 <message>
399 <location filename="../base/bootloaderinstallhex.cpp" line="124"/>
400 <source>Downloading bootloader file</source>
401 <translation>ブートローダをダウンロードしています</translation>
402 </message>
403 <message>
404 <location filename="../base/bootloaderinstallhex.cpp" line="134"/>
405 <source>Adding bootloader to firmware file</source>
406 <translation>ファームウェアファイルにブートローダを追加しています</translation>
407 </message>
408 <message>
409 <location filename="../base/bootloaderinstallhex.cpp" line="172"/>
410 <source>could not open input file</source>
411 <translation>入力ファイルを開くことができませんでした</translation>
412 </message>
413 <message>
414 <location filename="../base/bootloaderinstallhex.cpp" line="173"/>
415 <source>reading header failed</source>
416 <translation>ヘッダの読み込みに失敗しました</translation>
417 </message>
418 <message>
419 <location filename="../base/bootloaderinstallhex.cpp" line="174"/>
420 <source>reading firmware failed</source>
421 <translation>ファームウェアの読み込みに失敗しました</translation>
422 </message>
423 <message>
424 <location filename="../base/bootloaderinstallhex.cpp" line="175"/>
425 <source>can&apos;t open bootloader file</source>
426 <translation>ブートローダが読み込めません</translation>
427 </message>
428 <message>
429 <location filename="../base/bootloaderinstallhex.cpp" line="176"/>
430 <source>reading bootloader file failed</source>
431 <translation>ブートローダの読み込みに失敗しました</translation>
432 </message>
433 <message>
434 <location filename="../base/bootloaderinstallhex.cpp" line="177"/>
435 <source>can&apos;t open output file</source>
436 <translation>出力ファイルが読み込めません</translation>
437 </message>
438 <message>
439 <location filename="../base/bootloaderinstallhex.cpp" line="178"/>
440 <source>writing output file failed</source>
441 <translation>出力ファイルの出力に失敗しました</translation>
442 </message>
443 <message>
444 <location filename="../base/bootloaderinstallhex.cpp" line="180"/>
445 <source>Error in patching: %1</source>
446 <translation>ファームウェアにパッチをあてる処理でエラーが発生しました: %1</translation>
447 </message>
448 <message>
449 <location filename="../base/bootloaderinstallhex.cpp" line="191"/>
450 <source>Error in scramble: %1</source>
451 <translation>ファームウェアの暗号化処理に失敗しました: %1</translation>
452 </message>
453 <message>
454 <location filename="../base/bootloaderinstallhex.cpp" line="206"/>
455 <source>Checking modified firmware file</source>
456 <translation>変更されたファームウェアをチェックしています</translation>
457 </message>
458 <message>
459 <location filename="../base/bootloaderinstallhex.cpp" line="208"/>
460 <source>Error: modified file checksum wrong</source>
461 <translation>エラー: 変更されたファームウェアのチェックサムの値が間違っています</translation>
462 </message>
463 <message>
464 <location filename="../base/bootloaderinstallhex.cpp" line="215"/>
465 <source>A firmware file is already present on player</source>
466 <translation type="unfinished"></translation>
467 </message>
468 <message>
469 <location filename="../base/bootloaderinstallhex.cpp" line="220"/>
470 <source>Success: modified firmware file created</source>
471 <translation>成功: 変更されたファームウェアが作成されました</translation>
472 </message>
473 <message>
474 <location filename="../base/bootloaderinstallhex.cpp" line="223"/>
475 <source>Copying modified firmware file failed</source>
476 <translation type="unfinished"></translation>
477 </message>
478 <message>
479 <location filename="../base/bootloaderinstallhex.cpp" line="237"/>
480 <source>Uninstallation not possible, only installation info removed</source>
481 <translation>アンインストールはできません。インストール情報を削除するだけです</translation>
482 </message>
483 <message>
484 <location filename="../base/bootloaderinstallhex.cpp" line="258"/>
485 <source>Can&apos;t open input file</source>
486 <translation>入力ファイルをオープンすることができません</translation>
487 </message>
488 <message>
489 <location filename="../base/bootloaderinstallhex.cpp" line="259"/>
490 <source>Can&apos;t open output file</source>
491 <translation>出力ファイルを開くことができません</translation>
492 </message>
493 <message>
494 <location filename="../base/bootloaderinstallhex.cpp" line="260"/>
495 <source>invalid file: header length wrong</source>
496 <translation>不正なファイル: ヘッダの長さが間違っています</translation>
497 </message>
498 <message>
499 <location filename="../base/bootloaderinstallhex.cpp" line="261"/>
500 <source>invalid file: unrecognized header</source>
501 <translation>不正なファイル: ヘッダが正しくありません</translation>
502 </message>
503 <message>
504 <location filename="../base/bootloaderinstallhex.cpp" line="262"/>
505 <source>invalid file: &quot;length&quot; field wrong</source>
506 <translation>不正なファイル: &quot;length&quot; の値が間違っています</translation>
507 </message>
508 <message>
509 <location filename="../base/bootloaderinstallhex.cpp" line="263"/>
510 <source>invalid file: &quot;length2&quot; field wrong</source>
511 <translation>不正なファイル: &quot;length2&quot; の値が間違っています</translation>
512 </message>
513 <message>
514 <location filename="../base/bootloaderinstallhex.cpp" line="264"/>
515 <source>invalid file: internal checksum error</source>
516 <translation>不正なファイル: ファームウェアに書かれたチェックサムの値が間違っています</translation>
517 </message>
518 <message>
519 <location filename="../base/bootloaderinstallhex.cpp" line="265"/>
520 <source>invalid file: &quot;length3&quot; field wrong</source>
521 <translation>不正なファイル: &quot;length3&quot; の値が間違っています</translation>
522 </message>
523 <message>
524 <location filename="../base/bootloaderinstallhex.cpp" line="266"/>
525 <source>unknown</source>
526 <translation>不明</translation>
527 </message>
528 <message>
529 <location filename="../base/bootloaderinstallhex.cpp" line="50"/>
530 <source>Bootloader installation requires you to provide a firmware file of the original firmware (hex file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
531 <translation>ブートローダのインストールには、オリジナルのファームウェア(hex 形式のファイル)を用意する必要があります。法律上の理由により、ファームウェアはあなた自身でダウンロードする必要があります。&lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;マニュアル&lt;/a&gt; および、ファームウェアを取得する方法が書かれた &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; の Wiki ページを参考にして下さい。&lt;br/&gt;ファームウェアが用意できましたら、OKボタンを押して下さい。</translation>
532 </message>
533</context>
534<context>
535 <name>BootloaderInstallImx</name>
536 <message>
537 <location filename="../base/bootloaderinstallimx.cpp" line="72"/>
538 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (firmware.sb file). This file will be patched with the Rockbox bootloader and installed to your player. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
539 <translation type="unfinished"></translation>
540 </message>
541 <message>
542 <location filename="../base/bootloaderinstallimx.cpp" line="94"/>
543 <source>Could not read original firmware file</source>
544 <translation type="unfinished"></translation>
545 </message>
546 <message>
547 <location filename="../base/bootloaderinstallimx.cpp" line="100"/>
548 <source>Downloading bootloader file</source>
549 <translation type="unfinished">ブートローダをダウンロードしています</translation>
550 </message>
551 <message>
552 <location filename="../base/bootloaderinstallimx.cpp" line="110"/>
553 <source>Patching file...</source>
554 <translation type="unfinished"></translation>
555 </message>
556 <message>
557 <location filename="../base/bootloaderinstallimx.cpp" line="137"/>
558 <source>Patching the original firmware failed</source>
559 <translation type="unfinished"></translation>
560 </message>
561 <message>
562 <location filename="../base/bootloaderinstallimx.cpp" line="143"/>
563 <source>Succesfully patched firmware file</source>
564 <translation type="unfinished"></translation>
565 </message>
566 <message>
567 <location filename="../base/bootloaderinstallimx.cpp" line="158"/>
568 <source>Bootloader successful installed</source>
569 <translation type="unfinished">ブートローダのインストールが成功しました</translation>
570 </message>
571 <message>
572 <location filename="../base/bootloaderinstallimx.cpp" line="164"/>
573 <source>Patched bootloader could not be installed</source>
574 <translation type="unfinished"></translation>
575 </message>
576 <message>
577 <location filename="../base/bootloaderinstallimx.cpp" line="175"/>
578 <source>To uninstall, perform a normal upgrade with an unmodified original firmware.</source>
579 <translation type="unfinished"></translation>
580 </message>
581</context>
582<context>
583 <name>BootloaderInstallIpod</name>
584 <message>
585 <location filename="../base/bootloaderinstallipod.cpp" line="49"/>
586 <source>Error: can&apos;t allocate buffer memory!</source>
587 <translation>エラー: メモリの割り当てに失敗しました!</translation>
588 </message>
589 <message>
590 <location filename="../base/bootloaderinstallipod.cpp" line="80"/>
591 <source>Downloading bootloader file</source>
592 <translation>ブートローダをダウンロードしています</translation>
593 </message>
594 <message>
595 <location filename="../base/bootloaderinstallipod.cpp" line="64"/>
596 <location filename="../base/bootloaderinstallipod.cpp" line="151"/>
597 <source>Failed to read firmware directory</source>
598 <translation>ファームウェアのあるディレクトリの読み込みに失敗しました</translation>
599 </message>
600 <message>
601 <location filename="../base/bootloaderinstallipod.cpp" line="69"/>
602 <location filename="../base/bootloaderinstallipod.cpp" line="156"/>
603 <source>Unknown version number in firmware (%1)</source>
604 <translation>ファームウェアのバージョン(%1)が不明です</translation>
605 </message>
606 <message>
607 <location filename="../base/bootloaderinstallipod.cpp" line="75"/>
608 <source>Warning: This is a MacPod, Rockbox only runs on WinPods.
609See http://www.rockbox.org/wiki/IpodConversionToFAT32</source>
610 <translation>注意: Macintosh 専用の iPod です。Rockbox は、Windows で使用できる iPod でしか動作しません。
611 http://www.rockbox.org/wiki/IpodConversionToFAT32 を参照して下さい</translation>
612 </message>
613 <message>
614 <location filename="../base/bootloaderinstallipod.cpp" line="94"/>
615 <location filename="../base/bootloaderinstallipod.cpp" line="163"/>
616 <source>Could not open Ipod in R/W mode</source>
617 <translation>iPod に読み書きできるようにアクセスすることができませんでした</translation>
618 </message>
619 <message>
620 <location filename="../base/bootloaderinstallipod.cpp" line="104"/>
621 <source>Successfull added bootloader</source>
622 <translation>ブートローダの追加が成功しました</translation>
623 </message>
624 <message>
625 <location filename="../base/bootloaderinstallipod.cpp" line="115"/>
626 <source>Failed to add bootloader</source>
627 <translation>ブートローダの追加に失敗しました</translation>
628 </message>
629 <message>
630 <location filename="../base/bootloaderinstallipod.cpp" line="127"/>
631 <source>Bootloader Installation complete.</source>
632 <translation>ブートローダのインストールが完了しました。</translation>
633 </message>
634 <message>
635 <location filename="../base/bootloaderinstallipod.cpp" line="132"/>
636 <source>Writing log aborted</source>
637 <translation>ログの出力が失敗しました</translation>
638 </message>
639 <message>
640 <location filename="../base/bootloaderinstallipod.cpp" line="169"/>
641 <source>No bootloader detected.</source>
642 <translation>ブートローダが検出されませんでした。</translation>
643 </message>
644 <message>
645 <location filename="../base/bootloaderinstallipod.cpp" line="228"/>
646 <source>Error: could not retrieve device name</source>
647 <translation>エラー: デバイス名を得ることができません</translation>
648 </message>
649 <message>
650 <location filename="../base/bootloaderinstallipod.cpp" line="244"/>
651 <source>Error: no mountpoint specified!</source>
652 <translation>エラー: マウントポイントがありません!</translation>
653 </message>
654 <message>
655 <location filename="../base/bootloaderinstallipod.cpp" line="249"/>
656 <source>Could not open Ipod: permission denied</source>
657 <translation>iPod にアクセスすることができませんでした: アクセス権限がありません</translation>
658 </message>
659 <message>
660 <location filename="../base/bootloaderinstallipod.cpp" line="253"/>
661 <source>Could not open Ipod</source>
662 <translation>iPod にアクセスできませんでした</translation>
663 </message>
664 <message>
665 <location filename="../base/bootloaderinstallipod.cpp" line="264"/>
666 <source>No firmware partition on disk</source>
667 <translation>ファームウェアが存在しません</translation>
668 </message>
669 <message>
670 <location filename="../base/bootloaderinstallipod.cpp" line="175"/>
671 <source>Successfully removed bootloader</source>
672 <translation>ブートローダの削除が成功しました</translation>
673 </message>
674 <message>
675 <location filename="../base/bootloaderinstallipod.cpp" line="182"/>
676 <source>Removing bootloader failed.</source>
677 <translation>ブートローダの削除に失敗しました。</translation>
678 </message>
679 <message>
680 <location filename="../base/bootloaderinstallipod.cpp" line="90"/>
681 <source>Installing Rockbox bootloader</source>
682 <translation>Rockbox のブートローダをインストールしています</translation>
683 </message>
684 <message>
685 <location filename="../base/bootloaderinstallipod.cpp" line="142"/>
686 <source>Uninstalling bootloader</source>
687 <translation>ブートローダをアンインストールしています</translation>
688 </message>
689 <message>
690 <location filename="../base/bootloaderinstallipod.cpp" line="258"/>
691 <source>Error reading partition table - possibly not an Ipod</source>
692 <translation>パーティションテーブルの読み込みのエラー - iPod ではない可能性があります</translation>
693 </message>
694</context>
695<context>
696 <name>BootloaderInstallMi4</name>
697 <message>
698 <location filename="../base/bootloaderinstallmi4.cpp" line="34"/>
699 <source>Downloading bootloader</source>
700 <translation>ブートローダをダウンロードしています</translation>
701 </message>
702 <message>
703 <location filename="../base/bootloaderinstallmi4.cpp" line="43"/>
704 <source>Installing Rockbox bootloader</source>
705 <translation>Rockboxのブートローダをインストールしています</translation>
706 </message>
707 <message>
708 <location filename="../base/bootloaderinstallmi4.cpp" line="66"/>
709 <source>A firmware file is already present on player</source>
710 <translation type="unfinished"></translation>
711 </message>
712 <message>
713 <location filename="../base/bootloaderinstallmi4.cpp" line="71"/>
714 <location filename="../base/bootloaderinstallmi4.cpp" line="79"/>
715 <source>Bootloader successful installed</source>
716 <translation>ブートローダのインストールが成功しました</translation>
717 </message>
718 <message>
719 <location filename="../base/bootloaderinstallmi4.cpp" line="74"/>
720 <source>Copying modified firmware file failed</source>
721 <translation type="unfinished"></translation>
722 </message>
723 <message>
724 <location filename="../base/bootloaderinstallmi4.cpp" line="91"/>
725 <source>Checking for Rockbox bootloader</source>
726 <translation>Rockboxのブートローダをチェックしています</translation>
727 </message>
728 <message>
729 <location filename="../base/bootloaderinstallmi4.cpp" line="93"/>
730 <source>No Rockbox bootloader found</source>
731 <translation>Rockboxのブートローダが見つかりませんでした</translation>
732 </message>
733 <message>
734 <location filename="../base/bootloaderinstallmi4.cpp" line="98"/>
735 <source>Checking for original firmware file</source>
736 <translation>オリジナルのファームウェアをチェックしています</translation>
737 </message>
738 <message>
739 <location filename="../base/bootloaderinstallmi4.cpp" line="103"/>
740 <source>Error finding original firmware file</source>
741 <translation>オリジナルのファームウェアの検出エラー</translation>
742 </message>
743 <message>
744 <location filename="../base/bootloaderinstallmi4.cpp" line="113"/>
745 <source>Rockbox bootloader successful removed</source>
746 <translation>Rockboxのブートローダの削除が成功しました</translation>
747 </message>
748</context>
749<context>
750 <name>BootloaderInstallMpio</name>
751 <message>
752 <location filename="../base/bootloaderinstallmpio.cpp" line="34"/>
753 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
754 <translation type="unfinished"></translation>
755 </message>
756 <message>
757 <location filename="../base/bootloaderinstallmpio.cpp" line="53"/>
758 <source>Downloading bootloader file</source>
759 <translation type="unfinished">ブートローダをダウンロードしています</translation>
760 </message>
761 <message>
762 <location filename="../base/bootloaderinstallmpio.cpp" line="80"/>
763 <source>Could not open the original firmware.</source>
764 <translation type="unfinished"></translation>
765 </message>
766 <message>
767 <location filename="../base/bootloaderinstallmpio.cpp" line="83"/>
768 <source>Could not read the original firmware.</source>
769 <translation type="unfinished"></translation>
770 </message>
771 <message>
772 <location filename="../base/bootloaderinstallmpio.cpp" line="86"/>
773 <source>Loaded firmware file does not look like MPIO original firmware file.</source>
774 <translation type="unfinished"></translation>
775 </message>
776 <message>
777 <location filename="../base/bootloaderinstallmpio.cpp" line="101"/>
778 <source>Could not open output file.</source>
779 <translation type="unfinished"></translation>
780 </message>
781 <message>
782 <location filename="../base/bootloaderinstallmpio.cpp" line="104"/>
783 <source>Could not write output file.</source>
784 <translation type="unfinished"></translation>
785 </message>
786 <message>
787 <location filename="../base/bootloaderinstallmpio.cpp" line="107"/>
788 <source>Unknown error number: %1</source>
789 <translation type="unfinished"></translation>
790 </message>
791 <message>
792 <location filename="../base/bootloaderinstallmpio.cpp" line="89"/>
793 <source>Could not open downloaded bootloader.</source>
794 <translation type="unfinished"></translation>
795 </message>
796 <message>
797 <location filename="../base/bootloaderinstallmpio.cpp" line="92"/>
798 <source>Place for bootloader in OF file not empty.</source>
799 <translation type="unfinished"></translation>
800 </message>
801 <message>
802 <location filename="../base/bootloaderinstallmpio.cpp" line="95"/>
803 <source>Could not read the downloaded bootloader.</source>
804 <translation type="unfinished"></translation>
805 </message>
806 <message>
807 <location filename="../base/bootloaderinstallmpio.cpp" line="98"/>
808 <source>Bootloader checksum error.</source>
809 <translation type="unfinished"></translation>
810 </message>
811 <message>
812 <location filename="../base/bootloaderinstallmpio.cpp" line="112"/>
813 <source>Patching original firmware failed: %1</source>
814 <translation type="unfinished"></translation>
815 </message>
816 <message>
817 <location filename="../base/bootloaderinstallmpio.cpp" line="119"/>
818 <source>Success: modified firmware file created</source>
819 <translation type="unfinished">成功: 変更されたファームウェアが作成されました</translation>
820 </message>
821 <message>
822 <location filename="../base/bootloaderinstallmpio.cpp" line="127"/>
823 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
824 <translation type="unfinished">アンインストールは、改変されていないオリジナルのファームウェアを用いて通常の方法でファームウェアの更新を行って下さい</translation>
825 </message>
826</context>
827<context>
828 <name>BootloaderInstallSansa</name>
829 <message>
830 <location filename="../base/bootloaderinstallsansa.cpp" line="50"/>
831 <source>Error: can&apos;t allocate buffer memory!</source>
832 <translation>エラー: メモリの割り当てに失敗しました!</translation>
833 </message>
834 <message>
835 <location filename="../base/bootloaderinstallsansa.cpp" line="55"/>
836 <source>Searching for Sansa</source>
837 <translation>Sansa を探しています</translation>
838 </message>
839 <message>
840 <location filename="../base/bootloaderinstallsansa.cpp" line="59"/>
841 <source>Permission for disc access denied!
842This is required to install the bootloader</source>
843 <translation>このプレイヤーに対するディスクアクセスの権限がありません!
844ブートローダのインストールには、ディスクアクセスの権限が必要です</translation>
845 </message>
846 <message>
847 <location filename="../base/bootloaderinstallsansa.cpp" line="66"/>
848 <source>No Sansa detected!</source>
849 <translation>Sansa が検出されませんでした!</translation>
850 </message>
851 <message>
852 <location filename="../base/bootloaderinstallsansa.cpp" line="79"/>
853 <source>Downloading bootloader file</source>
854 <translation>ブートローダをダウンロードしています</translation>
855 </message>
856 <message>
857 <location filename="../base/bootloaderinstallsansa.cpp" line="71"/>
858 <location filename="../base/bootloaderinstallsansa.cpp" line="179"/>
859 <source>OLD ROCKBOX INSTALLATION DETECTED, ABORTING.
860You must reinstall the original Sansa firmware before running
861sansapatcher for the first time.
862See http://www.rockbox.org/wiki/SansaE200Install
863</source>
864 <translation>&lt;b&gt;古い Rockbox がインストールされていますので、処理を中止します。&lt;/b&gt;
865sansapatcher を最初に実行する前に、Sansa のオリジナル
866ファームウェアをインストールしなければいけません。
867http://www.rockbox.org/wiki/SansaE200Install を参照して下さい
868</translation>
869 </message>
870 <message>
871 <location filename="../base/bootloaderinstallsansa.cpp" line="102"/>
872 <location filename="../base/bootloaderinstallsansa.cpp" line="189"/>
873 <source>Could not open Sansa in R/W mode</source>
874 <translation>Sansa に読み書きできるようにアクセスすることができませんでした</translation>
875 </message>
876 <message>
877 <location filename="../base/bootloaderinstallsansa.cpp" line="129"/>
878 <source>Successfully installed bootloader</source>
879 <translation>ブートローダのインストールに成功しました</translation>
880 </message>
881 <message>
882 <location filename="../base/bootloaderinstallsansa.cpp" line="140"/>
883 <source>Failed to install bootloader</source>
884 <translation>ブートローダのインストールに失敗しました</translation>
885 </message>
886 <message>
887 <location filename="../base/bootloaderinstallsansa.cpp" line="153"/>
888 <source>Bootloader Installation complete.</source>
889 <translation>ブートローダのインストールが完了しました。</translation>
890 </message>
891 <message>
892 <location filename="../base/bootloaderinstallsansa.cpp" line="158"/>
893 <source>Writing log aborted</source>
894 <translation>ログの出力が失敗しました</translation>
895 </message>
896 <message>
897 <location filename="../base/bootloaderinstallsansa.cpp" line="238"/>
898 <source>Error: could not retrieve device name</source>
899 <translation>エラー: デバイス名を得ることができません</translation>
900 </message>
901 <message>
902 <location filename="../base/bootloaderinstallsansa.cpp" line="254"/>
903 <source>Can&apos;t find Sansa</source>
904 <translation>Sansa が見つかりませんでした</translation>
905 </message>
906 <message>
907 <location filename="../base/bootloaderinstallsansa.cpp" line="259"/>
908 <source>Could not open Sansa</source>
909 <translation>Sansa にアクセスできませんでした</translation>
910 </message>
911 <message>
912 <location filename="../base/bootloaderinstallsansa.cpp" line="264"/>
913 <source>Could not read partition table</source>
914 <translation>パーティションテーブルを読み込めませんでした</translation>
915 </message>
916 <message>
917 <location filename="../base/bootloaderinstallsansa.cpp" line="271"/>
918 <source>Disk is not a Sansa (Error %1), aborting.</source>
919 <translation>Sansa にディスクが見つかりませんでした (エラー: %1)。処理を中止します。</translation>
920 </message>
921 <message>
922 <location filename="../base/bootloaderinstallsansa.cpp" line="195"/>
923 <source>Successfully removed bootloader</source>
924 <translation>ブートローダの削除が成功しました</translation>
925 </message>
926 <message>
927 <location filename="../base/bootloaderinstallsansa.cpp" line="202"/>
928 <source>Removing bootloader failed.</source>
929 <translation>ブートローダの削除に失敗しました。</translation>
930 </message>
931 <message>
932 <location filename="../base/bootloaderinstallsansa.cpp" line="94"/>
933 <source>Installing Rockbox bootloader</source>
934 <translation>Rockboxのブートローダをインストールしています</translation>
935 </message>
936 <message>
937 <location filename="../base/bootloaderinstallsansa.cpp" line="170"/>
938 <source>Uninstalling bootloader</source>
939 <translation>ブートローダをアンインストールしています</translation>
940 </message>
941 <message>
942 <location filename="../base/bootloaderinstallsansa.cpp" line="111"/>
943 <source>Checking downloaded bootloader</source>
944 <translation>ダウンロードしたブートローダをチェックしています</translation>
945 </message>
946 <message>
947 <location filename="../base/bootloaderinstallsansa.cpp" line="119"/>
948 <source>Bootloader mismatch! Aborting.</source>
949 <translation>ブートローダが正しくありません! 処理を中止します。</translation>
950 </message>
951</context>
952<context>
953 <name>BootloaderInstallTcc</name>
954 <message>
955 <location filename="../base/bootloaderinstalltcc.cpp" line="33"/>
956 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wiki page on how to obtain the file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
957 <translation>ブートローダのインストールには、オリジナルのファームウェア(bin 形式のファイル)を用意する必要があります。法律上の理由により、ファームウェアはあなた自身でダウンロードする必要があります。&lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;マニュアル&lt;/a&gt; および、ファームウェアを取得する方法が書かれた &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2&lt;/a&gt; の Wiki ページを参考にして下さい。&lt;br/&gt;ファームウェアが用意できましたら、OKボタンを押して下さい。</translation>
958 </message>
959 <message>
960 <location filename="../base/bootloaderinstalltcc.cpp" line="50"/>
961 <source>Downloading bootloader file</source>
962 <translation>ブートローダをダウンロードしています</translation>
963 </message>
964 <message>
965 <location filename="../base/bootloaderinstalltcc.cpp" line="82"/>
966 <location filename="../base/bootloaderinstalltcc.cpp" line="99"/>
967 <source>Could not load %1</source>
968 <translation>%1 をロードすることができませんでした</translation>
969 </message>
970 <message>
971 <location filename="../base/bootloaderinstalltcc.cpp" line="90"/>
972 <source>Unknown OF file used: %1</source>
973 <translation>不明なオリジナルファームウェアが使用されています: %1</translation>
974 </message>
975 <message>
976 <location filename="../base/bootloaderinstalltcc.cpp" line="104"/>
977 <source>Patching Firmware...</source>
978 <translation>ファームウェアにパッチをあてています...</translation>
979 </message>
980 <message>
981 <location filename="../base/bootloaderinstalltcc.cpp" line="111"/>
982 <source>Could not patch firmware</source>
983 <translation>ファームウェアにパッチをあてることができませんでした</translation>
984 </message>
985 <message>
986 <location filename="../base/bootloaderinstalltcc.cpp" line="117"/>
987 <source>Could not open %1 for writing</source>
988 <translation>書き込めるように %1 を開くことができませんでした</translation>
989 </message>
990 <message>
991 <location filename="../base/bootloaderinstalltcc.cpp" line="126"/>
992 <source>Could not write firmware file</source>
993 <translation>ファームウェアを書き込むことができませんでした</translation>
994 </message>
995 <message>
996 <location filename="../base/bootloaderinstalltcc.cpp" line="131"/>
997 <source>Success: modified firmware file created</source>
998 <translation>成功: 変更されたファームウェアが作成されました</translation>
999 </message>
1000 <message>
1001 <location filename="../base/bootloaderinstalltcc.cpp" line="151"/>
1002 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
1003 <translation>アンインストールは、改変されていないオリジナルのファームウェアを用いて通常の方法でファームウェアの更新を行って下さい</translation>
1004 </message>
1005</context>
1006<context>
1007 <name>Changelog</name>
1008 <message>
1009 <location filename="../gui/changelogfrm.ui" line="17"/>
1010 <source>Changelog</source>
1011 <translation type="unfinished"></translation>
1012 </message>
1013 <message>
1014 <location filename="../gui/changelogfrm.ui" line="39"/>
1015 <source>Show on startup</source>
1016 <translation type="unfinished"></translation>
1017 </message>
1018 <message>
1019 <location filename="../gui/changelogfrm.ui" line="46"/>
1020 <source>&amp;Ok</source>
1021 <translation type="unfinished">Ok(&amp;O)</translation>
1022 </message>
1023</context>
1024<context>
1025 <name>Config</name>
1026 <message>
1027 <location filename="../configure.cpp" line="858"/>
1028 <source>Autodetection</source>
1029 <translation>自動検出</translation>
1030 </message>
1031 <message>
1032 <location filename="../configure.cpp" line="859"/>
1033 <source>Could not detect a Mountpoint.
1034Select your Mountpoint manually.</source>
1035 <translation>マウントポイントが検出できませんでした。
1036マウントポイントを手動で選択して下さい。</translation>
1037 </message>
1038 <message>
1039 <location filename="../configure.cpp" line="764"/>
1040 <source>Could not detect a device.
1041Select your device and Mountpoint manually.</source>
1042 <translation>デバイスが検出できませんでした。
1043デバイスおよびマウントポイントを手動で選択して下さい。</translation>
1044 </message>
1045 <message>
1046 <location filename="../configure.cpp" line="794"/>
1047 <source>The player contains an incompatible filesystem.
1048Make sure you selected the correct mountpoint and the player is set up to use a filesystem compatible with Rockbox.</source>
1049 <translation type="unfinished"></translation>
1050 </message>
1051 <message>
1052 <location filename="../configure.cpp" line="802"/>
1053 <source>An unknown error occured during player detection.</source>
1054 <translation type="unfinished"></translation>
1055 </message>
1056 <message>
1057 <location filename="../configure.cpp" line="869"/>
1058 <source>Really delete cache?</source>
1059 <translation>本当にキャッシュを削除していいですか?</translation>
1060 </message>
1061 <message>
1062 <location filename="../configure.cpp" line="870"/>
1063 <source>Do you really want to delete the cache? Make absolutely sure this setting is correct as it will remove &lt;b&gt;all&lt;/b&gt; files in this folder!</source>
1064 <translation>本当にキャッシュを削除しますか? このフォルダに含まれる&lt;b&gt;全ての&lt;/b&gt;ファイルを削除しますので、絶対に正しい値を設定して下さい!</translation>
1065 </message>
1066 <message>
1067 <location filename="../configure.cpp" line="878"/>
1068 <source>Path wrong!</source>
1069 <translation>パスが間違っています!</translation>
1070 </message>
1071 <message>
1072 <location filename="../configure.cpp" line="879"/>
1073 <source>The cache path is invalid. Aborting.</source>
1074 <translation>キャッシュのパスが不正です。処理を中止します。</translation>
1075 </message>
1076 <message>
1077 <location filename="../configure.cpp" line="322"/>
1078 <source>Current cache size is %L1 kiB.</source>
1079 <translation>現在のキャッシュサイズは、%L1 kiB です。</translation>
1080 </message>
1081 <message>
1082 <source>Fatal error</source>
1083 <translation type="obsolete">致命的なエラー</translation>
1084 </message>
1085 <message>
1086 <location filename="../configure.cpp" line="455"/>
1087 <location filename="../configure.cpp" line="485"/>
1088 <source>Configuration OK</source>
1089 <translation>設定OK</translation>
1090 </message>
1091 <message>
1092 <location filename="../configure.cpp" line="461"/>
1093 <location filename="../configure.cpp" line="490"/>
1094 <source>Configuration INVALID</source>
1095 <translation>不正な設定</translation>
1096 </message>
1097 <message>
1098 <location filename="../configure.cpp" line="130"/>
1099 <source>The following errors occurred:</source>
1100 <translation>以下のエラーが発生しました:</translation>
1101 </message>
1102 <message>
1103 <location filename="../configure.cpp" line="175"/>
1104 <source>No mountpoint given</source>
1105 <translation>マウントポイントが入力されていません</translation>
1106 </message>
1107 <message>
1108 <location filename="../configure.cpp" line="179"/>
1109 <source>Mountpoint does not exist</source>
1110 <translation>マウントポイントが存在しません</translation>
1111 </message>
1112 <message>
1113 <location filename="../configure.cpp" line="183"/>
1114 <source>Mountpoint is not a directory.</source>
1115 <translation>マウントポイントがフォルダではありません。</translation>
1116 </message>
1117 <message>
1118 <location filename="../configure.cpp" line="187"/>
1119 <source>Mountpoint is not writeable</source>
1120 <translation>マウントポイントが書き込み禁止です</translation>
1121 </message>
1122 <message>
1123 <location filename="../configure.cpp" line="202"/>
1124 <source>No player selected</source>
1125 <translation>プレイヤーが選択されていません</translation>
1126 </message>
1127 <message>
1128 <location filename="../configure.cpp" line="209"/>
1129 <source>Cache path not writeable. Leave path empty to default to systems temporary path.</source>
1130 <translation>キャッシュのパスが書き込み禁止です。デフォルトのシステムテンポラリパスを空にします。</translation>
1131 </message>
1132 <message>
1133 <location filename="../configure.cpp" line="228"/>
1134 <source>You need to fix the above errors before you can continue.</source>
1135 <translation>処理を続行する前に、上記のエラーを修正する必要があります。</translation>
1136 </message>
1137 <message>
1138 <location filename="../configure.cpp" line="231"/>
1139 <source>Configuration error</source>
1140 <translation>設定エラー</translation>
1141 </message>
1142 <message>
1143 <location filename="../configure.cpp" line="340"/>
1144 <source>Showing disabled targets</source>
1145 <translation>推奨されないプレイヤーの表示</translation>
1146 </message>
1147 <message>
1148 <location filename="../configure.cpp" line="341"/>
1149 <source>You just enabled showing targets that are marked disabled. Disabled targets are not recommended to end users. Please use this option only if you know what you are doing.</source>
1150 <translation>あなたは推奨されないプレイヤーを表示するように変更しました。推奨外のプレイヤーは、一般的なユーザにはお勧めできません。どんなことがおきても、あなたが対処できる場合に限りこのオプションを有効にして下さい。</translation>
1151 </message>
1152 <message>
1153 <location filename="../configure.cpp" line="448"/>
1154 <location filename="../configure.cpp" line="914"/>
1155 <source>TTS error</source>
1156 <translation type="unfinished"></translation>
1157 </message>
1158 <message>
1159 <location filename="../configure.cpp" line="449"/>
1160 <location filename="../configure.cpp" line="915"/>
1161 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1162 <translation type="unfinished"></translation>
1163 </message>
1164 <message>
1165 <location filename="../configure.cpp" line="529"/>
1166 <source>Proxy Detection</source>
1167 <translation>プロキシの検出</translation>
1168 </message>
1169 <message>
1170 <location filename="../configure.cpp" line="530"/>
1171 <source>The System Proxy settings are invalid!
1172Rockbox Utility can&apos;t work with this proxy settings. Make sure the system proxy is set correctly. Note that &quot;proxy auto-config (PAC)&quot; scripts are not supported by Rockbox Utility. If your system uses this you need to use manual proxy settings.</source>
1173 <translation>システムのプロキシ設定は正しくありません
1174Rockbox Utility は、このプロキシの設定では動作できません。システムのプロキシ設定を正しく設定して下さい。注意 &quot;proxy auto-config (PAC)&quot; スクリプトは、 Rockbox Utility ではサポートされていません。もし、あなたが使用しているシステムがこれを使用しているならば、手動でプロキシの設定を行う必要があります。</translation>
1175 </message>
1176 <message>
1177 <location filename="../configure.cpp" line="643"/>
1178 <source>Set Cache Path</source>
1179 <translation>キャッシュのパスを設定して下さい</translation>
1180 </message>
1181 <message>
1182 <location filename="../configure.cpp" line="665"/>
1183 <source>%1 (%2 GiB of %3 GiB free)</source>
1184 <translation type="unfinished"></translation>
1185 </message>
1186 <message>
1187 <location filename="../configure.cpp" line="739"/>
1188 <source>Multiple devices have been detected. Please disconnect all players but one and try again.</source>
1189 <translation type="unfinished"></translation>
1190 </message>
1191 <message>
1192 <location filename="../configure.cpp" line="742"/>
1193 <source>Detected devices:</source>
1194 <translation type="unfinished"></translation>
1195 </message>
1196 <message>
1197 <location filename="../configure.cpp" line="747"/>
1198 <source>(unknown)</source>
1199 <translation type="unfinished"></translation>
1200 </message>
1201 <message>
1202 <location filename="../configure.cpp" line="749"/>
1203 <source>%1 at %2</source>
1204 <translation type="unfinished"></translation>
1205 </message>
1206 <message>
1207 <location filename="../configure.cpp" line="755"/>
1208 <source>Note: detecting connected devices might be ambiguous. You might have less devices connected than listed. In this case it might not be possible to detect your player unambiguously.</source>
1209 <translation type="unfinished"></translation>
1210 </message>
1211 <message>
1212 <location filename="../configure.cpp" line="759"/>
1213 <location filename="../configure.cpp" line="763"/>
1214 <location filename="../configure.cpp" line="805"/>
1215 <source>Device Detection</source>
1216 <translation type="unfinished"></translation>
1217 </message>
1218 <message>
1219 <location filename="../configure.cpp" line="788"/>
1220 <source>%1 &quot;MacPod&quot; found!
1221Rockbox needs a FAT formatted Ipod (so-called &quot;WinPod&quot;) to run. </source>
1222 <translation>%1 Macintosh 専用の iPod が見つかりました。
1223Rockbox を実行するには、FAT 形式でフォーマットされた iPod (&quot;WinMad&quot;)が必要です。</translation>
1224 </message>
1225 <message>
1226 <location filename="../configure.cpp" line="780"/>
1227 <source>%1 in MTP mode found!
1228You need to change your player to MSC mode for installation. </source>
1229 <translation type="unfinished"></translation>
1230 </message>
1231 <message>
1232 <location filename="../configure.cpp" line="774"/>
1233 <source>Detected an unsupported player:
1234%1
1235Sorry, Rockbox doesn&apos;t run on your player.</source>
1236 <translation>サポートされていないプレイヤーが見つかりました。:
1237%1
1238残念ながら、Rockbox はこのプレイヤーでは動きません。</translation>
1239 </message>
1240 <message>
1241 <source>Fatal: player incompatible</source>
1242 <translation type="obsolete">致命的なエラー: 互換性のないプレイヤーです</translation>
1243 </message>
1244 <message>
1245 <location filename="../configure.cpp" line="921"/>
1246 <source>TTS configuration invalid</source>
1247 <translation>TTS の設定が不正です</translation>
1248 </message>
1249 <message>
1250 <location filename="../configure.cpp" line="922"/>
1251 <source>TTS configuration invalid.
1252 Please configure TTS engine.</source>
1253 <translation>TTS の設定が不正です
1254TTSエンジンの設定を行って下さい。</translation>
1255 </message>
1256 <message>
1257 <location filename="../configure.cpp" line="927"/>
1258 <source>Could not start TTS engine.</source>
1259 <translation>TTS エンジンが実行できませんでした。</translation>
1260 </message>
1261 <message>
1262 <location filename="../configure.cpp" line="928"/>
1263 <source>Could not start TTS engine.
1264</source>
1265 <translation>TTS エンジンが実行できませんでした。
1266</translation>
1267 </message>
1268 <message>
1269 <location filename="../configure.cpp" line="929"/>
1270 <location filename="../configure.cpp" line="948"/>
1271 <source>
1272Please configure TTS engine.</source>
1273 <translation>
1274TTSエンジンの設定を行って下さい。</translation>
1275 </message>
1276 <message>
1277 <location filename="../configure.cpp" line="943"/>
1278 <source>Rockbox Utility Voice Test</source>
1279 <translation>Rockbox Utility Voice Test</translation>
1280 </message>
1281 <message>
1282 <location filename="../configure.cpp" line="946"/>
1283 <source>Could not voice test string.</source>
1284 <translation>ボイスのテストができませんでした。</translation>
1285 </message>
1286 <message>
1287 <location filename="../configure.cpp" line="947"/>
1288 <source>Could not voice test string.
1289</source>
1290 <translation>ボイスのテストができませんでした。
1291</translation>
1292 </message>
1293</context>
1294<context>
1295 <name>ConfigForm</name>
1296 <message>
1297 <location filename="../configurefrm.ui" line="14"/>
1298 <source>Configuration</source>
1299 <translation>設定</translation>
1300 </message>
1301 <message>
1302 <location filename="../configurefrm.ui" line="20"/>
1303 <source>Configure Rockbox Utility</source>
1304 <translation>Rockbox Utilityの設定</translation>
1305 </message>
1306 <message>
1307 <location filename="../configurefrm.ui" line="536"/>
1308 <source>&amp;Ok</source>
1309 <translation>Ok(&amp;O)</translation>
1310 </message>
1311 <message>
1312 <location filename="../configurefrm.ui" line="547"/>
1313 <source>&amp;Cancel</source>
1314 <translation>キャンセル(&amp;C)</translation>
1315 </message>
1316 <message>
1317 <location filename="../configurefrm.ui" line="136"/>
1318 <source>&amp;Proxy</source>
1319 <translation>プロキシーを使用(&amp;P)</translation>
1320 </message>
1321 <message>
1322 <location filename="../configurefrm.ui" line="95"/>
1323 <source>Show disabled targets</source>
1324 <translation>推奨外のプレイヤーを表示</translation>
1325 </message>
1326 <message>
1327 <location filename="../configurefrm.ui" line="142"/>
1328 <source>&amp;No Proxy</source>
1329 <translation>プロキシーの不使用(&amp;N)</translation>
1330 </message>
1331 <message>
1332 <location filename="../configurefrm.ui" line="159"/>
1333 <source>&amp;Manual Proxy settings</source>
1334 <translation>プロキシーの手動設定(&amp;M)</translation>
1335 </message>
1336 <message>
1337 <location filename="../configurefrm.ui" line="166"/>
1338 <source>Proxy Values</source>
1339 <translation>プロキシーの値</translation>
1340 </message>
1341 <message>
1342 <location filename="../configurefrm.ui" line="172"/>
1343 <source>&amp;Host:</source>
1344 <translation>ホスト(&amp;H):</translation>
1345 </message>
1346 <message>
1347 <location filename="../configurefrm.ui" line="182"/>
1348 <source>&amp;Port:</source>
1349 <translation>ポート(&amp;P):</translation>
1350 </message>
1351 <message>
1352 <location filename="../configurefrm.ui" line="199"/>
1353 <source>&amp;Username</source>
1354 <translation>ユーザ名(&amp;U)</translation>
1355 </message>
1356 <message>
1357 <location filename="../configurefrm.ui" line="260"/>
1358 <source>&amp;Language</source>
1359 <translation>表示言語(&amp;L)</translation>
1360 </message>
1361 <message>
1362 <location filename="../configurefrm.ui" line="35"/>
1363 <source>&amp;Device</source>
1364 <translation>デバイス(&amp;D)</translation>
1365 </message>
1366 <message>
1367 <location filename="../configurefrm.ui" line="41"/>
1368 <source>Select your device in the &amp;filesystem</source>
1369 <translation>ファイルシステムを選択して下さい(&amp;F)</translation>
1370 </message>
1371 <message>
1372 <location filename="../configurefrm.ui" line="319"/>
1373 <source>&amp;Browse</source>
1374 <translation>参照(&amp;B)</translation>
1375 </message>
1376 <message>
1377 <location filename="../configurefrm.ui" line="72"/>
1378 <source>&amp;Select your audio player</source>
1379 <translation>オーディオプレイヤーを選択して下さい(&amp;S)</translation>
1380 </message>
1381 <message>
1382 <location filename="../configurefrm.ui" line="58"/>
1383 <source>&amp;Refresh</source>
1384 <translation type="unfinished">更新(&amp;R)</translation>
1385 </message>
1386 <message>
1387 <location filename="../configurefrm.ui" line="114"/>
1388 <source>&amp;Autodetect</source>
1389 <translation>自動検出(&amp;A)</translation>
1390 </message>
1391 <message>
1392 <location filename="../configurefrm.ui" line="152"/>
1393 <source>Use S&amp;ystem values</source>
1394 <translation>システム設定値を使用(&amp;Y)</translation>
1395 </message>
1396 <message>
1397 <location filename="../configurefrm.ui" line="209"/>
1398 <source>Pass&amp;word</source>
1399 <translation>パスワード(&amp;W)</translation>
1400 </message>
1401 <message>
1402 <location filename="../configurefrm.ui" line="219"/>
1403 <source>Show</source>
1404 <translation type="unfinished"></translation>
1405 </message>
1406 <message>
1407 <location filename="../configurefrm.ui" line="274"/>
1408 <source>Cac&amp;he</source>
1409 <translation>キャッシュ(&amp;H)</translation>
1410 </message>
1411 <message>
1412 <location filename="../configurefrm.ui" line="277"/>
1413 <source>Download cache settings</source>
1414 <translation>ダウンロードキャッシュの設定</translation>
1415 </message>
1416 <message>
1417 <location filename="../configurefrm.ui" line="283"/>
1418 <source>Rockbox Utility uses a local download cache to save network traffic. You can change the path to the cache and use it as local repository by enabling Offline mode.</source>
1419 <translation>Rockbox Utilityは、ネットワークのトラフィックを節約するために、ダウンロードしたファイルをローカルにキャッシュします。キャッシュフォルダは変更することができます。オフラインモードが有効であれば、選択されたキャッシュフォルダを使用します。</translation>
1420 </message>
1421 <message>
1422 <location filename="../configurefrm.ui" line="293"/>
1423 <source>Current cache size is %1</source>
1424 <translation>現在のキャッシュサイズは、%1 です</translation>
1425 </message>
1426 <message>
1427 <location filename="../configurefrm.ui" line="302"/>
1428 <source>P&amp;ath</source>
1429 <translation>パス(&amp;P)</translation>
1430 </message>
1431 <message>
1432 <location filename="../configurefrm.ui" line="334"/>
1433 <source>Disable local &amp;download cache</source>
1434 <translation>ローカルのダウンロードキャッシュを無効にします(&amp;D)</translation>
1435 </message>
1436 <message>
1437 <source>O&amp;ffline mode</source>
1438 <translation type="obsolete">オフラインモード(&amp;F)</translation>
1439 </message>
1440 <message>
1441 <location filename="../configurefrm.ui" line="369"/>
1442 <source>Clean cache &amp;now</source>
1443 <translation>キャッシュのクリア(&amp;N)</translation>
1444 </message>
1445 <message>
1446 <location filename="../configurefrm.ui" line="312"/>
1447 <source>Entering an invalid folder will reset the path to the systems temporary path.</source>
1448 <translation>無効なフォルダを入力しますと、パスの値はシステムのテンポラリパスに設定されます。</translation>
1449 </message>
1450 <message>
1451 <source>&lt;p&gt;This will try to use all information from the cache, even information about updates. Only use this option if you want to install without network connection. Note: you need to do the same install you want to perform later with network access first to download all required files to the cache.&lt;/p&gt;</source>
1452 <translation type="obsolete">&lt;p&gt;これはキャッシュから、全ての情報、アップデート情報さえ使用するでしょう。 ネットワークに接続しないでインストールしたいのであれば、このオプションを使用して下さい。 注意: 後で実行されるインストールに必要なファイル全てをキャッシュにダウンロードするために、最初は、ネットワークがつながる環境で実行する必要があります。&lt;/p&gt;</translation>
1453 </message>
1454 <message>
1455 <location filename="../configurefrm.ui" line="385"/>
1456 <source>&amp;TTS &amp;&amp; Encoder</source>
1457 <translation>TTS およびエンコーダ(&amp;T)</translation>
1458 </message>
1459 <message>
1460 <location filename="../configurefrm.ui" line="391"/>
1461 <source>TTS Engine</source>
1462 <translation>TTS エンジン</translation>
1463 </message>
1464 <message>
1465 <location filename="../configurefrm.ui" line="462"/>
1466 <source>Encoder Engine</source>
1467 <translation>エンコーダエンジン</translation>
1468 </message>
1469 <message>
1470 <location filename="../configurefrm.ui" line="397"/>
1471 <source>&amp;Select TTS Engine</source>
1472 <translation>TTS エンジンの選択(&amp;S)</translation>
1473 </message>
1474 <message>
1475 <location filename="../configurefrm.ui" line="410"/>
1476 <source>Configure TTS Engine</source>
1477 <translation>TTS エンジンの設定</translation>
1478 </message>
1479 <message>
1480 <location filename="../configurefrm.ui" line="417"/>
1481 <location filename="../configurefrm.ui" line="468"/>
1482 <source>Configuration invalid!</source>
1483 <translation>不正な設定!</translation>
1484 </message>
1485 <message>
1486 <location filename="../configurefrm.ui" line="434"/>
1487 <source>Configure &amp;TTS</source>
1488 <translation>TTS の設定(&amp;T)</translation>
1489 </message>
1490 <message>
1491 <location filename="../configurefrm.ui" line="452"/>
1492 <source>&amp;Use string corrections for TTS</source>
1493 <translation type="unfinished"></translation>
1494 </message>
1495 <message>
1496 <location filename="../configurefrm.ui" line="485"/>
1497 <source>Configure &amp;Enc</source>
1498 <translation>エンコーダの設定(&amp;E)</translation>
1499 </message>
1500 <message>
1501 <location filename="../configurefrm.ui" line="496"/>
1502 <source>encoder name</source>
1503 <translation>エンコーダ名</translation>
1504 </message>
1505 <message>
1506 <location filename="../configurefrm.ui" line="445"/>
1507 <source>Test TTS</source>
1508 <translation>TTS のテスト</translation>
1509 </message>
1510</context>
1511<context>
1512 <name>Configure</name>
1513 <message>
1514 <location filename="../configure.cpp" line="589"/>
1515 <source>English</source>
1516 <comment>This is the localized language name, i.e. your language.</comment>
1517 <translation>日本語</translation>
1518 </message>
1519</context>
1520<context>
1521 <name>CreateVoiceFrm</name>
1522 <message>
1523 <location filename="../createvoicefrm.ui" line="17"/>
1524 <source>Create Voice File</source>
1525 <translation>ボイスファイルの作成</translation>
1526 </message>
1527 <message>
1528 <location filename="../createvoicefrm.ui" line="42"/>
1529 <source>Select the Language you want to generate a voicefile for:</source>
1530 <translation>作成するボイスファイルの言語を選択して下さい:</translation>
1531 </message>
1532 <message>
1533 <location filename="../createvoicefrm.ui" line="49"/>
1534 <source>Generation settings</source>
1535 <translation>ボイスファイル作成の設定</translation>
1536 </message>
1537 <message>
1538 <location filename="../createvoicefrm.ui" line="68"/>
1539 <source>Change</source>
1540 <translation>変更</translation>
1541 </message>
1542 <message>
1543 <location filename="../createvoicefrm.ui" line="101"/>
1544 <source>Silence threshold</source>
1545 <translation type="unfinished"></translation>
1546 </message>
1547 <message>
1548 <location filename="../createvoicefrm.ui" line="139"/>
1549 <source>&amp;Install</source>
1550 <translation>インストール(&amp;I)</translation>
1551 </message>
1552 <message>
1553 <location filename="../createvoicefrm.ui" line="150"/>
1554 <source>&amp;Cancel</source>
1555 <translation>キャンセル(&amp;C)</translation>
1556 </message>
1557 <message>
1558 <location filename="../createvoicefrm.ui" line="88"/>
1559 <source>Wavtrim Threshold</source>
1560 <translation>Wavtrim の閾値</translation>
1561 </message>
1562 <message>
1563 <location filename="../createvoicefrm.ui" line="55"/>
1564 <source>TTS:</source>
1565 <translation type="unfinished"></translation>
1566 </message>
1567 <message>
1568 <location filename="../createvoicefrm.ui" line="163"/>
1569 <source>Language</source>
1570 <translation>言語</translation>
1571 </message>
1572</context>
1573<context>
1574 <name>CreateVoiceWindow</name>
1575 <message>
1576 <location filename="../createvoicewindow.cpp" line="100"/>
1577 <source>TTS error</source>
1578 <translation type="unfinished"></translation>
1579 </message>
1580 <message>
1581 <location filename="../createvoicewindow.cpp" line="101"/>
1582 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1583 <translation type="unfinished"></translation>
1584 </message>
1585 <message>
1586 <location filename="../createvoicewindow.cpp" line="105"/>
1587 <location filename="../createvoicewindow.cpp" line="108"/>
1588 <source>Engine: &lt;b&gt;%1&lt;/b&gt;</source>
1589 <translation type="unfinished"></translation>
1590 </message>
1591</context>
1592<context>
1593 <name>EncTtsCfgGui</name>
1594 <message>
1595 <location filename="../encttscfggui.cpp" line="45"/>
1596 <source>Waiting for engine...</source>
1597 <translation>エンコードエンジンを待っています...</translation>
1598 </message>
1599 <message>
1600 <location filename="../encttscfggui.cpp" line="95"/>
1601 <source>Ok</source>
1602 <translation>Ok</translation>
1603 </message>
1604 <message>
1605 <location filename="../encttscfggui.cpp" line="98"/>
1606 <source>Cancel</source>
1607 <translation>キャンセル</translation>
1608 </message>
1609 <message>
1610 <location filename="../encttscfggui.cpp" line="197"/>
1611 <source>Browse</source>
1612 <translation>参照</translation>
1613 </message>
1614 <message>
1615 <location filename="../encttscfggui.cpp" line="205"/>
1616 <source>Refresh</source>
1617 <translation>更新</translation>
1618 </message>
1619 <message>
1620 <location filename="../encttscfggui.cpp" line="377"/>
1621 <source>Select executable</source>
1622 <translation type="unfinished"></translation>
1623 </message>
1624</context>
1625<context>
1626 <name>EncoderExe</name>
1627 <message>
1628 <location filename="../base/encoderexe.cpp" line="41"/>
1629 <source>Path to Encoder:</source>
1630 <translation type="unfinished">エンコーダのパス:</translation>
1631 </message>
1632 <message>
1633 <location filename="../base/encoderexe.cpp" line="43"/>
1634 <source>Encoder options:</source>
1635 <translation type="unfinished">エンコーダ・オプション:</translation>
1636 </message>
1637</context>
1638<context>
1639 <name>EncoderLame</name>
1640 <message>
1641 <location filename="../base/encoderlame.cpp" line="73"/>
1642 <location filename="../base/encoderlame.cpp" line="83"/>
1643 <source>LAME</source>
1644 <translation type="unfinished"></translation>
1645 </message>
1646 <message>
1647 <location filename="../base/encoderlame.cpp" line="75"/>
1648 <source>Volume</source>
1649 <translation type="unfinished"></translation>
1650 </message>
1651 <message>
1652 <location filename="../base/encoderlame.cpp" line="79"/>
1653 <source>Quality</source>
1654 <translation type="unfinished"></translation>
1655 </message>
1656 <message>
1657 <location filename="../base/encoderlame.cpp" line="83"/>
1658 <source>Could not find libmp3lame!</source>
1659 <translation type="unfinished"></translation>
1660 </message>
1661</context>
1662<context>
1663 <name>EncoderRbSpeex</name>
1664 <message>
1665 <location filename="../base/encoderrbspeex.cpp" line="34"/>
1666 <source>Volume:</source>
1667 <translation type="unfinished">ボリューム:</translation>
1668 </message>
1669 <message>
1670 <location filename="../base/encoderrbspeex.cpp" line="36"/>
1671 <source>Quality:</source>
1672 <translation type="unfinished">品質:</translation>
1673 </message>
1674 <message>
1675 <location filename="../base/encoderrbspeex.cpp" line="38"/>
1676 <source>Complexity:</source>
1677 <translation type="unfinished">複雑さ:</translation>
1678 </message>
1679 <message>
1680 <location filename="../base/encoderrbspeex.cpp" line="40"/>
1681 <source>Use Narrowband:</source>
1682 <translation type="unfinished">ナローバンド版:</translation>
1683 </message>
1684</context>
1685<context>
1686 <name>InfoWidget</name>
1687 <message>
1688 <location filename="../gui/infowidget.cpp" line="30"/>
1689 <location filename="../gui/infowidget.cpp" line="107"/>
1690 <source>File</source>
1691 <translation type="unfinished">ファイル</translation>
1692 </message>
1693 <message>
1694 <location filename="../gui/infowidget.cpp" line="30"/>
1695 <location filename="../gui/infowidget.cpp" line="107"/>
1696 <source>Version</source>
1697 <translation type="unfinished">バージョン</translation>
1698 </message>
1699</context>
1700<context>
1701 <name>InfoWidgetFrm</name>
1702 <message>
1703 <location filename="../gui/infowidgetfrm.ui" line="14"/>
1704 <source>Info</source>
1705 <translation type="unfinished">情報</translation>
1706 </message>
1707 <message>
1708 <location filename="../gui/infowidgetfrm.ui" line="20"/>
1709 <source>Currently installed packages.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; if you manually installed packages this might not be correct!</source>
1710 <translation type="unfinished">現在インストールされているパッケージ&lt;br/&gt;&lt;b&gt;注意:&lt;/b&gt; もし、パッケージを手動でインストールした場合、正しくない可能性があります!</translation>
1711 </message>
1712 <message>
1713 <location filename="../gui/infowidgetfrm.ui" line="34"/>
1714 <source>Package</source>
1715 <translation type="unfinished"></translation>
1716 </message>
1717</context>
1718<context>
1719 <name>InstallTalkFrm</name>
1720 <message>
1721 <location filename="../installtalkfrm.ui" line="17"/>
1722 <source>Install Talk Files</source>
1723 <translation>トークファイルのインストール</translation>
1724 </message>
1725 <message>
1726 <location filename="../installtalkfrm.ui" line="42"/>
1727 <source>Strip Extensions</source>
1728 <translation>拡張子を削除します</translation>
1729 </message>
1730 <message>
1731 <location filename="../installtalkfrm.ui" line="52"/>
1732 <source>Generate for files</source>
1733 <translation type="unfinished"></translation>
1734 </message>
1735 <message>
1736 <location filename="../installtalkfrm.ui" line="85"/>
1737 <source>Generate for folders</source>
1738 <translation type="unfinished"></translation>
1739 </message>
1740 <message>
1741 <location filename="../installtalkfrm.ui" line="95"/>
1742 <source>Recurse into folders</source>
1743 <translation type="unfinished"></translation>
1744 </message>
1745 <message>
1746 <location filename="../installtalkfrm.ui" line="118"/>
1747 <source>Ignore files</source>
1748 <translation type="unfinished"></translation>
1749 </message>
1750 <message>
1751 <location filename="../installtalkfrm.ui" line="128"/>
1752 <source>Skip existing</source>
1753 <translation type="unfinished"></translation>
1754 </message>
1755 <message>
1756 <location filename="../installtalkfrm.ui" line="154"/>
1757 <source>&amp;Cancel</source>
1758 <translation>キャンセル(&amp;C)</translation>
1759 </message>
1760 <message>
1761 <location filename="../installtalkfrm.ui" line="170"/>
1762 <source>Select folders for Talkfile generation (Ctrl for multiselect)</source>
1763 <translation type="unfinished"></translation>
1764 </message>
1765 <message>
1766 <location filename="../installtalkfrm.ui" line="78"/>
1767 <source>TTS profile:</source>
1768 <translation>TTSのプロファイル:</translation>
1769 </message>
1770 <message>
1771 <location filename="../installtalkfrm.ui" line="36"/>
1772 <source>Generation options</source>
1773 <translation>オプション</translation>
1774 </message>
1775 <message>
1776 <location filename="../installtalkfrm.ui" line="111"/>
1777 <source>Change</source>
1778 <translation>変更</translation>
1779 </message>
1780 <message>
1781 <location filename="../installtalkfrm.ui" line="143"/>
1782 <source>&amp;Install</source>
1783 <translation>インストール(&amp;I)</translation>
1784 </message>
1785</context>
1786<context>
1787 <name>InstallTalkWindow</name>
1788 <message>
1789 <location filename="../installtalkwindow.cpp" line="96"/>
1790 <source>Empty selection</source>
1791 <translation type="unfinished"></translation>
1792 </message>
1793 <message>
1794 <location filename="../installtalkwindow.cpp" line="97"/>
1795 <source>No files or folders selected. Please select files or folders first.</source>
1796 <translation type="unfinished"></translation>
1797 </message>
1798 <message>
1799 <location filename="../installtalkwindow.cpp" line="137"/>
1800 <source>TTS error</source>
1801 <translation type="unfinished"></translation>
1802 </message>
1803 <message>
1804 <location filename="../installtalkwindow.cpp" line="138"/>
1805 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1806 <translation type="unfinished"></translation>
1807 </message>
1808</context>
1809<context>
1810 <name>ManualWidget</name>
1811 <message>
1812 <location filename="../gui/manualwidget.cpp" line="44"/>
1813 <source>&lt;a href=&apos;%1&apos;&gt;PDF Manual&lt;/a&gt;</source>
1814 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;PDF 形式のマニュアル&lt;/a&gt;</translation>
1815 </message>
1816 <message>
1817 <location filename="../gui/manualwidget.cpp" line="46"/>
1818 <source>&lt;a href=&apos;%1&apos;&gt;HTML Manual (opens in browser)&lt;/a&gt;</source>
1819 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;HTML 形式のマニュアル (ブラウザで開きます)&lt;/a&gt;</translation>
1820 </message>
1821 <message>
1822 <location filename="../gui/manualwidget.cpp" line="50"/>
1823 <source>Select a device for a link to the correct manual</source>
1824 <translation type="unfinished">正しいマニュアルへのリンクを指定するため、デバイスを選択して下さい</translation>
1825 </message>
1826 <message>
1827 <location filename="../gui/manualwidget.cpp" line="51"/>
1828 <source>&lt;a href=&apos;%1&apos;&gt;Manual Overview&lt;/a&gt;</source>
1829 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Manual の概要&lt;/a&gt;</translation>
1830 </message>
1831 <message>
1832 <location filename="../gui/manualwidget.cpp" line="62"/>
1833 <source>Confirm download</source>
1834 <translation type="unfinished">ダウンロードの確認</translation>
1835 </message>
1836 <message>
1837 <location filename="../gui/manualwidget.cpp" line="63"/>
1838 <source>Do you really want to download the manual? The manual will be saved to the root folder of your player.</source>
1839 <translation type="unfinished">マニュアルのダウンロードを本当に行いますか? マニュアルは、プレイヤーのルートフォルダに保存されます。</translation>
1840 </message>
1841</context>
1842<context>
1843 <name>ManualWidgetFrm</name>
1844 <message>
1845 <location filename="../gui/manualwidgetfrm.ui" line="14"/>
1846 <source>Manual</source>
1847 <translation type="unfinished"></translation>
1848 </message>
1849 <message>
1850 <location filename="../gui/manualwidgetfrm.ui" line="20"/>
1851 <source>Read the manual</source>
1852 <translation type="unfinished">マニュアルを読む</translation>
1853 </message>
1854 <message>
1855 <location filename="../gui/manualwidgetfrm.ui" line="26"/>
1856 <source>PDF manual</source>
1857 <translation type="unfinished">PDF 形式のマニュアル</translation>
1858 </message>
1859 <message>
1860 <location filename="../gui/manualwidgetfrm.ui" line="39"/>
1861 <source>HTML manual</source>
1862 <translation type="unfinished">HTML 形式のマニュアル</translation>
1863 </message>
1864 <message>
1865 <location filename="../gui/manualwidgetfrm.ui" line="55"/>
1866 <source>Download the manual</source>
1867 <translation type="unfinished">マニュアルのインストール</translation>
1868 </message>
1869 <message>
1870 <location filename="../gui/manualwidgetfrm.ui" line="63"/>
1871 <source>&amp;PDF version</source>
1872 <translation type="unfinished">PDF 形式(&amp;P)</translation>
1873 </message>
1874 <message>
1875 <location filename="../gui/manualwidgetfrm.ui" line="70"/>
1876 <source>&amp;HTML version (zip file)</source>
1877 <translation type="unfinished">HTML 形式 (zip ファイル)(&amp;H)</translation>
1878 </message>
1879 <message>
1880 <location filename="../gui/manualwidgetfrm.ui" line="92"/>
1881 <source>Down&amp;load</source>
1882 <translation type="unfinished">ダウンロード(&amp;L)</translation>
1883 </message>
1884</context>
1885<context>
1886 <name>MsPackUtil</name>
1887 <message>
1888 <location filename="../base/mspackutil.cpp" line="101"/>
1889 <source>Creating output path failed</source>
1890 <translation type="unfinished"></translation>
1891 </message>
1892 <message>
1893 <location filename="../base/mspackutil.cpp" line="109"/>
1894 <source>Error during CAB operation</source>
1895 <translation type="unfinished"></translation>
1896 </message>
1897</context>
1898<context>
1899 <name>PreviewFrm</name>
1900 <message>
1901 <location filename="../previewfrm.ui" line="16"/>
1902 <source>Preview</source>
1903 <translation>プレビュー</translation>
1904 </message>
1905</context>
1906<context>
1907 <name>ProgressLoggerFrm</name>
1908 <message>
1909 <location filename="../progressloggerfrm.ui" line="13"/>
1910 <location filename="../progressloggerfrm.ui" line="19"/>
1911 <source>Progress</source>
1912 <translation>処理中</translation>
1913 </message>
1914 <message>
1915 <location filename="../progressloggerfrm.ui" line="82"/>
1916 <source>&amp;Abort</source>
1917 <translation>中止(&amp;A)</translation>
1918 </message>
1919 <message>
1920 <location filename="../progressloggerfrm.ui" line="32"/>
1921 <source>progresswindow</source>
1922 <translation>進捗画面</translation>
1923 </message>
1924 <message>
1925 <location filename="../progressloggerfrm.ui" line="58"/>
1926 <source>Save Log</source>
1927 <translation>ログの保存</translation>
1928 </message>
1929</context>
1930<context>
1931 <name>ProgressLoggerGui</name>
1932 <message>
1933 <location filename="../progressloggergui.cpp" line="122"/>
1934 <source>&amp;Ok</source>
1935 <translation>Ok(&amp;O)</translation>
1936 </message>
1937 <message>
1938 <location filename="../progressloggergui.cpp" line="104"/>
1939 <source>&amp;Abort</source>
1940 <translation>中止(&amp;A)</translation>
1941 </message>
1942 <message>
1943 <location filename="../progressloggergui.cpp" line="146"/>
1944 <source>Save system trace log</source>
1945 <translation>システムトレースのログを保存します</translation>
1946 </message>
1947</context>
1948<context>
1949 <name>QObject</name>
1950 <message>
1951 <location filename="../configure.cpp" line="625"/>
1952 <location filename="../main.cpp" line="83"/>
1953 <source>LTR</source>
1954 <extracomment>This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.
1955----------
1956This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.</extracomment>
1957 <translation type="unfinished"></translation>
1958 </message>
1959 <message>
1960 <location filename="../base/system.cpp" line="385"/>
1961 <source>(unknown vendor name) </source>
1962 <translation type="unfinished"></translation>
1963 </message>
1964 <message>
1965 <location filename="../base/system.cpp" line="403"/>
1966 <source>(unknown product name)</source>
1967 <translation type="unfinished"></translation>
1968 </message>
1969 <message>
1970 <location filename="../base/bootloaderinstallhelper.cpp" line="80"/>
1971 <source>Bootloader installation is almost complete. Installation &lt;b&gt;requires&lt;/b&gt; you to perform the following steps manually:</source>
1972 <translation type="unfinished">ブートローダのインストールは、ほとんど完了していますが、以下のことを手動で行う&lt;b&gt;必要があります&lt;/b&gt;:</translation>
1973 </message>
1974 <message>
1975 <location filename="../base/bootloaderinstallhelper.cpp" line="86"/>
1976 <source>&lt;li&gt;Safely remove your player.&lt;/li&gt;</source>
1977 <translation type="unfinished">&lt;li&gt;プレイヤーを安全に取り外します。&lt;/li&gt;</translation>
1978 </message>
1979 <message>
1980 <location filename="../base/bootloaderinstallhelper.cpp" line="91"/>
1981 <source>&lt;li&gt;Reboot your player into the original firmware.&lt;/li&gt;&lt;li&gt;Perform a firmware upgrade using the update functionality of the original firmware. Please refer to your player&apos;s manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before starting the firmware update process.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1982 <translation type="unfinished"></translation>
1983 </message>
1984 <message>
1985 <location filename="../base/bootloaderinstallhelper.cpp" line="102"/>
1986 <source>&lt;li&gt;Remove any previously inserted microSD card&lt;/li&gt;</source>
1987 <translation type="unfinished"></translation>
1988 </message>
1989 <message>
1990 <location filename="../base/bootloaderinstallhelper.cpp" line="103"/>
1991 <source>&lt;li&gt;Disconnect your player. The player will reboot and perform an update of the original firmware. Please refer to your players manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before disconnecting the player.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1992 <translation type="unfinished"></translation>
1993 </message>
1994 <message>
1995 <location filename="../base/bootloaderinstallhelper.cpp" line="114"/>
1996 <source>&lt;li&gt;Turn the player off&lt;/li&gt;&lt;li&gt;Insert the charger&lt;/li&gt;</source>
1997 <translation type="unfinished">&lt;li&gt;プレイヤーの電源を落として下さい&lt;/li&gt;&lt;li&gt;充電器に接続して下さい&lt;/li&gt;</translation>
1998 </message>
1999 <message>
2000 <location filename="../base/bootloaderinstallhelper.cpp" line="119"/>
2001 <source>&lt;li&gt;Unplug USB and power adaptors&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to turn the player off&lt;/li&gt;&lt;li&gt;Toggle the battery switch on the player&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to boot into Rockbox&lt;/li&gt;</source>
2002 <translation type="unfinished">&lt;li&gt;USBおよび充電器から取り外して下さい&lt;/li&gt;&lt;li&gt;プレイヤーの電源を落として下さい&lt;/li&gt;&lt;li&gt;電源スイッチを切り替えて下さい&lt;/li&gt;&lt;li&gt;電源スイッチを入れ、Rockboxを起動して下さい&lt;/li&gt;</translation>
2003 </message>
2004 <message>
2005 <location filename="../base/bootloaderinstallhelper.cpp" line="125"/>
2006 <source>&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You can safely install other parts first, but the above steps are &lt;b&gt;required&lt;/b&gt; to finish the installation!&lt;/p&gt;</source>
2007 <translation type="unfinished">&lt;p&gt;&lt;b&gt;注意:&lt;/b&gt; 他のインストールを行うことができますが、インストールを完了させるためには、上記のことを行う&lt;b&gt;必要があります!&lt;/b&gt;&lt;/p&gt;</translation>
2008 </message>
2009</context>
2010<context>
2011 <name>QuaZipFile</name>
2012 <message>
2013 <location filename="../quazip/quazipfile.cpp" line="141"/>
2014 <source>ZIP/UNZIP API error %1</source>
2015 <translation type="unfinished"></translation>
2016 </message>
2017</context>
2018<context>
2019 <name>RbUtilQt</name>
2020 <message>
2021 <location filename="../rbutilqt.cpp" line="450"/>
2022 <source>Confirm Installation</source>
2023 <translation>インストールの確認</translation>
2024 </message>
2025 <message>
2026 <location filename="../rbutilqt.cpp" line="430"/>
2027 <source>No Rockbox installation found</source>
2028 <translation type="unfinished"></translation>
2029 </message>
2030 <message>
2031 <location filename="../rbutilqt.cpp" line="431"/>
2032 <source>Could not determine the installed Rockbox version. Please install a Rockbox build before installing voice files.</source>
2033 <translation type="unfinished"></translation>
2034 </message>
2035 <message>
2036 <location filename="../rbutilqt.cpp" line="451"/>
2037 <source>Do you really want to install the voice file?</source>
2038 <translation>ボイスファイルのインストールを本当に行いますか?</translation>
2039 </message>
2040 <message>
2041 <location filename="../rbutilqt.cpp" line="512"/>
2042 <source>Confirm Uninstallation</source>
2043 <translation>アンインストールの確認</translation>
2044 </message>
2045 <message>
2046 <location filename="../rbutilqt.cpp" line="513"/>
2047 <source>Do you really want to uninstall the Bootloader?</source>
2048 <translation>ブートローダのアンインストールを本当に行いますか?</translation>
2049 </message>
2050 <message>
2051 <location filename="../rbutilqt.cpp" line="528"/>
2052 <source>No uninstall method for this target known.</source>
2053 <translation>このプレイヤーに対するアンインストール方法は不明です。</translation>
2054 </message>
2055 <message>
2056 <location filename="../rbutilqt.cpp" line="542"/>
2057 <source>Rockbox Utility can not uninstall the bootloader on this target. Try a normal firmware update to remove the booloader.</source>
2058 <translation>Rockbox Utility は、このプレイヤーに対して、ブートローダをアンインストールすることができません。通常のファームウェアのアップデート処理を行って、ブートローダを削除して下さい。</translation>
2059 </message>
2060 <message>
2061 <location filename="../rbutilqt.cpp" line="550"/>
2062 <source>No Rockbox bootloader found.</source>
2063 <translation type="unfinished"></translation>
2064 </message>
2065 <message>
2066 <location filename="../rbutilqt.cpp" line="568"/>
2067 <source>Confirm installation</source>
2068 <translation>インストールの確認</translation>
2069 </message>
2070 <message>
2071 <location filename="../rbutilqt.cpp" line="569"/>
2072 <source>Do you really want to install Rockbox Utility to your player? After installation you can run it from the players hard drive.</source>
2073 <translation>Rockbox Utilityをプレイヤーにインストールしてもいいですか? インストール後、プレイヤーのハードディスクから実行して下さい。</translation>
2074 </message>
2075 <message>
2076 <location filename="../rbutilqt.cpp" line="578"/>
2077 <source>Installing Rockbox Utility</source>
2078 <translation>Rockbox Utilityをインストールしています</translation>
2079 </message>
2080 <message>
2081 <location filename="../rbutilqt.cpp" line="733"/>
2082 <source>New version of Rockbox Utility available.</source>
2083 <translation type="unfinished"></translation>
2084 </message>
2085 <message>
2086 <location filename="../rbutilqt.cpp" line="736"/>
2087 <source>Rockbox Utility is up to date.</source>
2088 <translation type="unfinished"></translation>
2089 </message>
2090 <message>
2091 <location filename="../rbutilqt.cpp" line="759"/>
2092 <source>Device ejected</source>
2093 <translation type="unfinished"></translation>
2094 </message>
2095 <message>
2096 <location filename="../rbutilqt.cpp" line="760"/>
2097 <source>Device successfully ejected. You may now disconnect the player from the PC.</source>
2098 <translation type="unfinished"></translation>
2099 </message>
2100 <message>
2101 <location filename="../rbutilqt.cpp" line="764"/>
2102 <source>Ejecting failed</source>
2103 <translation type="unfinished"></translation>
2104 </message>
2105 <message>
2106 <location filename="../rbutilqt.cpp" line="765"/>
2107 <source>Ejecting the device failed. Please make sure no programs are accessing files on the device. If ejecting still fails please use your computers eject funtionality.</source>
2108 <translation type="unfinished"></translation>
2109 </message>
2110 <message>
2111 <location filename="../rbutilqt.cpp" line="582"/>
2112 <source>Mount point is wrong!</source>
2113 <translation>マウントポイントが間違っています!</translation>
2114 </message>
2115 <message>
2116 <location filename="../rbutilqt.cpp" line="439"/>
2117 <source>No voice file available</source>
2118 <translation type="unfinished"></translation>
2119 </message>
2120 <message>
2121 <location filename="../rbutilqt.cpp" line="440"/>
2122 <source>The installed version of Rockbox is a development version. Pre-built voices are only available for release versions of Rockbox. Please generate a voice yourself using the &quot;Create voice file&quot; functionality.</source>
2123 <translation type="unfinished"></translation>
2124 </message>
2125 <message>
2126 <location filename="../rbutilqt.cpp" line="596"/>
2127 <source>Error installing Rockbox Utility</source>
2128 <translation>Rockbox Utilityのインストール中にエラーが発生しました</translation>
2129 </message>
2130 <message>
2131 <location filename="../rbutilqt.cpp" line="600"/>
2132 <source>Installing user configuration</source>
2133 <translation>ユーザ設定をインストールしています</translation>
2134 </message>
2135 <message>
2136 <location filename="../rbutilqt.cpp" line="604"/>
2137 <source>Error installing user configuration</source>
2138 <translation>ユーザ設定のインストール中にエラーが発生しました</translation>
2139 </message>
2140 <message>
2141 <location filename="../rbutilqt.cpp" line="608"/>
2142 <source>Successfully installed Rockbox Utility.</source>
2143 <translation>Rockbox Utilityのインストールが成功しました。</translation>
2144 </message>
2145 <message>
2146 <location filename="../rbutilqt.cpp" line="337"/>
2147 <location filename="../rbutilqt.cpp" line="642"/>
2148 <source>Configuration error</source>
2149 <translation>設定エラー</translation>
2150 </message>
2151 <message>
2152 <location filename="../rbutilqt.cpp" line="643"/>
2153 <source>Your configuration is invalid. Please go to the configuration dialog and make sure the selected values are correct.</source>
2154 <translation>設定が正しくありません。設定ダイアログを表示し、選択された値が正しいか確認して下さい。</translation>
2155 </message>
2156 <message>
2157 <location filename="../rbutilqt.cpp" line="330"/>
2158 <source>This is a new installation of Rockbox Utility, or a new version. The configuration dialog will now open to allow you to setup the program, or review your settings.</source>
2159 <translation>これは、新規にインストール、または、新しいバージョンに更新された Rockbox Utility です。プログラムのセットアップを許可したり、または、設定を見直すために設定ダイアログが表示されることがあります。</translation>
2160 </message>
2161 <message>
2162 <location filename="../rbutilqt.cpp" line="110"/>
2163 <source>Wine detected!</source>
2164 <translation>Wine が検出されました!</translation>
2165 </message>
2166 <message>
2167 <location filename="../rbutilqt.cpp" line="111"/>
2168 <source>It seems you are trying to run this program under Wine. Please don&apos;t do this, running under Wine will fail. Use the native Linux binary instead.</source>
2169 <translation>Wine 上でこのプログラムを動かそうとしている様に思えます。Wine 上では処理が失敗するので、Wine 上で実行しないで下さい。代わりに Linux で動くバイナリを用いて下さい。</translation>
2170 </message>
2171 <message>
2172 <location filename="../rbutilqt.cpp" line="237"/>
2173 <source>Can&apos;t get version information.
2174Network error: %1. Please check your network and proxy settings.</source>
2175 <translation>バージョン情報が取得できません。
2176ネットワークエラー: %1. ネットワークおよびプロキシーの設定を確認して下さい。</translation>
2177 </message>
2178 <message>
2179 <location filename="../rbutilqt.cpp" line="416"/>
2180 <source>Warning</source>
2181 <translation>警告</translation>
2182 </message>
2183 <message>
2184 <location filename="../rbutilqt.cpp" line="417"/>
2185 <source>The Application is still downloading Information about new Builds. Please try again shortly.</source>
2186 <translation>そのアプリケーションは、新規ビルドに対する情報をまだダウンロードしています。もう少し経ちましたら、再度行って下さい。</translation>
2187 </message>
2188 <message>
2189 <location filename="../rbutilqt.cpp" line="329"/>
2190 <source>New installation</source>
2191 <translation>新規インストール</translation>
2192 </message>
2193 <message>
2194 <location filename="../rbutilqt.cpp" line="338"/>
2195 <source>Your configuration is invalid. This is most likely due to a changed device path. The configuration dialog will now open to allow you to correct the problem.</source>
2196 <translation>設定が正しくありません。たぶん、デバイスのパスが変更されているのが原因です。問題を修正できるように、設定ダイアログが表示されます。</translation>
2197 </message>
2198 <message>
2199 <location filename="../rbutilqt.cpp" line="236"/>
2200 <source>Network error</source>
2201 <translation>ネットワークエラー</translation>
2202 </message>
2203 <message>
2204 <location filename="../rbutilqt.cpp" line="224"/>
2205 <source>Downloading build information, please wait ...</source>
2206 <translation>ビルド情報をダウンロードしています。お待ち下さい...</translation>
2207 </message>
2208 <message>
2209 <location filename="../rbutilqt.cpp" line="235"/>
2210 <source>Can&apos;t get version information!</source>
2211 <translation>バージョン情報を取得することができませんでした!</translation>
2212 </message>
2213 <message>
2214 <location filename="../rbutilqt.cpp" line="249"/>
2215 <source>Download build information finished.</source>
2216 <translation>ビルド情報のダウンロードが完了しました。</translation>
2217 </message>
2218 <message>
2219 <location filename="../rbutilqt.cpp" line="664"/>
2220 <source>Checking for update ...</source>
2221 <translation type="unfinished"></translation>
2222 </message>
2223 <message>
2224 <location filename="../rbutilqt.cpp" line="729"/>
2225 <source>RockboxUtility Update available</source>
2226 <translation>より新しい Rockbox Utility が存在しています</translation>
2227 </message>
2228 <message>
2229 <location filename="../rbutilqt.cpp" line="730"/>
2230 <source>&lt;b&gt;New RockboxUtility Version available.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Download it from here: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</source>
2231 <translation>&lt;b&gt;新しい RockboxUtility が存在しています。&lt;/b&gt; &lt;br&gt;&lt;br&gt;ここから最新版をダウンロードします: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</translation>
2232 </message>
2233</context>
2234<context>
2235 <name>RbUtilQtFrm</name>
2236 <message>
2237 <location filename="../rbutilqtfrm.ui" line="14"/>
2238 <source>Rockbox Utility</source>
2239 <translation>Rockbox Utility</translation>
2240 </message>
2241 <message>
2242 <location filename="../rbutilqtfrm.ui" line="160"/>
2243 <location filename="../rbutilqtfrm.ui" line="658"/>
2244 <source>&amp;Installation</source>
2245 <translation>インストール(&amp;I)</translation>
2246 </message>
2247 <message>
2248 <location filename="../rbutilqtfrm.ui" line="458"/>
2249 <source>&amp;Uninstallation</source>
2250 <translation>アンインストール(&amp;U)</translation>
2251 </message>
2252 <message>
2253 <location filename="../rbutilqtfrm.ui" line="393"/>
2254 <source>&amp;Manual</source>
2255 <translation>マニュアル(&amp;M)</translation>
2256 </message>
2257 <message>
2258 <location filename="../rbutilqtfrm.ui" line="419"/>
2259 <source>&amp;File</source>
2260 <translation>ファイル(&amp;F)</translation>
2261 </message>
2262 <message>
2263 <location filename="../rbutilqtfrm.ui" line="497"/>
2264 <source>&amp;About</source>
2265 <translation>Rockbox Utilityについて(&amp;A)</translation>
2266 </message>
2267 <message>
2268 <location filename="../rbutilqtfrm.ui" line="474"/>
2269 <source>Empty local download cache</source>
2270 <translation>ローカルのダウンロードキャッシュを空にします</translation>
2271 </message>
2272 <message>
2273 <location filename="../rbutilqtfrm.ui" line="121"/>
2274 <source>mountpoint unknown or invalid</source>
2275 <translation type="unfinished"></translation>
2276 </message>
2277 <message>
2278 <location filename="../rbutilqtfrm.ui" line="114"/>
2279 <source>Mountpoint:</source>
2280 <translation type="unfinished"></translation>
2281 </message>
2282 <message>
2283 <location filename="../rbutilqtfrm.ui" line="72"/>
2284 <source>device unknown or invalid</source>
2285 <translation type="unfinished"></translation>
2286 </message>
2287 <message>
2288 <location filename="../rbutilqtfrm.ui" line="65"/>
2289 <source>Device:</source>
2290 <translation type="unfinished"></translation>
2291 </message>
2292 <message>
2293 <location filename="../rbutilqtfrm.ui" line="479"/>
2294 <source>Install Rockbox Utility on player</source>
2295 <translation>Rockbox Utilityのインストール</translation>
2296 </message>
2297 <message>
2298 <location filename="../rbutilqtfrm.ui" line="484"/>
2299 <source>&amp;Configure</source>
2300 <translation>設定(&amp;C)</translation>
2301 </message>
2302 <message>
2303 <location filename="../rbutilqtfrm.ui" line="489"/>
2304 <source>E&amp;xit</source>
2305 <translation>終了(&amp;E)</translation>
2306 </message>
2307 <message>
2308 <location filename="../rbutilqtfrm.ui" line="492"/>
2309 <source>Ctrl+Q</source>
2310 <translation>Ctrl+Q</translation>
2311 </message>
2312 <message>
2313 <location filename="../rbutilqtfrm.ui" line="502"/>
2314 <source>About &amp;Qt</source>
2315 <translation>Qt について(&amp;Q)</translation>
2316 </message>
2317 <message>
2318 <location filename="../rbutilqtfrm.ui" line="292"/>
2319 <source>Uninstall Bootloader</source>
2320 <translation>ブートローダのアンインストール</translation>
2321 </message>
2322 <message>
2323 <location filename="../rbutilqtfrm.ui" line="286"/>
2324 <location filename="../rbutilqtfrm.ui" line="319"/>
2325 <source>Uninstall Rockbox</source>
2326 <translation>Rockbox のアンインストール</translation>
2327 </message>
2328 <message>
2329 <location filename="../rbutilqtfrm.ui" line="31"/>
2330 <source>Device</source>
2331 <translation>デバイス</translation>
2332 </message>
2333 <message>
2334 <location filename="../rbutilqtfrm.ui" line="92"/>
2335 <source>&amp;Change</source>
2336 <translation>変更(&amp;C)</translation>
2337 </message>
2338 <message>
2339 <location filename="../rbutilqtfrm.ui" line="163"/>
2340 <source>Welcome</source>
2341 <translation>ようこそ</translation>
2342 </message>
2343 <message>
2344 <location filename="../rbutilqtfrm.ui" line="168"/>
2345 <location filename="../rbutilqtfrm.ui" line="450"/>
2346 <source>&amp;Accessibility</source>
2347 <translation>ユーザ補助(&amp;A)</translation>
2348 </message>
2349 <message>
2350 <location filename="../rbutilqtfrm.ui" line="171"/>
2351 <source>Install accessibility add-ons</source>
2352 <translation>ユーザ補助用のアドオンのインストール</translation>
2353 </message>
2354 <message>
2355 <location filename="../rbutilqtfrm.ui" line="177"/>
2356 <source>Install Voice files</source>
2357 <translation>ボイスファイルのインストール</translation>
2358 </message>
2359 <message>
2360 <location filename="../rbutilqtfrm.ui" line="204"/>
2361 <source>Install Talk files</source>
2362 <translation>トークファイルのインストール</translation>
2363 </message>
2364 <message>
2365 <location filename="../rbutilqtfrm.ui" line="396"/>
2366 <source>View and download the manual</source>
2367 <translation>閲覧およびマニュアルのダウンロード</translation>
2368 </message>
2369 <message>
2370 <location filename="../rbutilqtfrm.ui" line="401"/>
2371 <source>Inf&amp;o</source>
2372 <translation>情報(&amp;I)</translation>
2373 </message>
2374 <message>
2375 <location filename="../rbutilqtfrm.ui" line="428"/>
2376 <location filename="../rbutilqtfrm.ui" line="507"/>
2377 <source>&amp;Help</source>
2378 <translation>ヘルプ(&amp;H)</translation>
2379 </message>
2380 <message>
2381 <location filename="../rbutilqtfrm.ui" line="446"/>
2382 <source>Action&amp;s</source>
2383 <translation>アクション(&amp;S)</translation>
2384 </message>
2385 <message>
2386 <location filename="../rbutilqtfrm.ui" line="512"/>
2387 <source>Info</source>
2388 <translation>情報</translation>
2389 </message>
2390 <message>
2391 <location filename="../rbutilqtfrm.ui" line="616"/>
2392 <source>Read PDF manual</source>
2393 <translation>PDF形式のマニュアルを読む</translation>
2394 </message>
2395 <message>
2396 <location filename="../rbutilqtfrm.ui" line="621"/>
2397 <source>Read HTML manual</source>
2398 <translation>HTML形式のマニュアルを読む</translation>
2399 </message>
2400 <message>
2401 <location filename="../rbutilqtfrm.ui" line="626"/>
2402 <source>Download PDF manual</source>
2403 <translation>PDF形式のマニュアルのダウンロード</translation>
2404 </message>
2405 <message>
2406 <location filename="../rbutilqtfrm.ui" line="631"/>
2407 <source>Download HTML manual (zip)</source>
2408 <translation>HTML形式のマニュアルのダウンロード (zip)</translation>
2409 </message>
2410 <message>
2411 <location filename="../rbutilqtfrm.ui" line="254"/>
2412 <source>Create Voice files</source>
2413 <translation>ボイスファイルの作成</translation>
2414 </message>
2415 <message>
2416 <location filename="../rbutilqtfrm.ui" line="643"/>
2417 <source>Create Voice File</source>
2418 <translation>ボイスファイルの作成</translation>
2419 </message>
2420 <message>
2421 <location filename="../rbutilqtfrm.ui" line="194"/>
2422 <source>&lt;b&gt;Install Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so if you installed the voice file Rockbox will speak.</source>
2423 <translation>&lt;b&gt;ボイスファイルのインストール&lt;/b&gt;&lt;br/&gt;Rockboxにユーザインターフェースを話させるためには、ボイスファイルが必要です。デフォルトで、Rockbox は話すことが可能になっていますので、ボイスファイルをインストールしますと、Rockbox は話すようになります。</translation>
2424 </message>
2425 <message>
2426 <location filename="../rbutilqtfrm.ui" line="103"/>
2427 <source>&amp;Eject</source>
2428 <translation type="unfinished"></translation>
2429 </message>
2430 <message>
2431 <location filename="../rbutilqtfrm.ui" line="221"/>
2432 <source>&lt;b&gt;Create Talk Files&lt;/b&gt;&lt;br/&gt;Talkfiles are needed to let Rockbox speak File and Foldernames</source>
2433 <translation>&lt;b&gt;トークファイルの作成&lt;/b&gt;&lt;br/&gt;Rockbox がファイル名やフォルダ名を話すためには、トークファイルが必要です</translation>
2434 </message>
2435 <message>
2436 <location filename="../rbutilqtfrm.ui" line="271"/>
2437 <source>&lt;b&gt;Create Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so
2438 if you installed the voice file Rockbox will speak.</source>
2439 <translation>&lt;b&gt;ボイスファイルの作成&lt;/b&gt;&lt;br/&gt;Rockboxにユーザインターフェースを話させるためには、ボイスファイルが必要です。デフォルトで、Rockbox は話すことが可能になっていますので、ボイスファイルをインストールしますと、Rockbox は話すようになります。</translation>
2440 </message>
2441 <message>
2442 <location filename="../rbutilqtfrm.ui" line="283"/>
2443 <source>Backup &amp;&amp; &amp;Uninstallation</source>
2444 <translation type="unfinished"></translation>
2445 </message>
2446 <message>
2447 <location filename="../rbutilqtfrm.ui" line="309"/>
2448 <source>&lt;b&gt;Remove the bootloader&lt;/b&gt;&lt;br/&gt;After removing the bootloader you won&apos;t be able to start Rockbox.</source>
2449 <translation>&lt;b&gt;ブートローダの削除&lt;/b&gt;&lt;br/&gt;ブートローダを削除しますと、Rockbox をスタートすることができなくなります。</translation>
2450 </message>
2451 <message>
2452 <location filename="../rbutilqtfrm.ui" line="336"/>
2453 <source>&lt;b&gt;Uninstall Rockbox from your audio player.&lt;/b&gt;&lt;br/&gt;This will leave the bootloader in place (you need to remove it manually).</source>
2454 <translation>&lt;b&gt;Rockbox のアンインストール&lt;/b&gt;&lt;br/&gt;ブートローダは残ります。 (手動で削除する必要があります。).</translation>
2455 </message>
2456 <message>
2457 <location filename="../rbutilqtfrm.ui" line="349"/>
2458 <source>Backup</source>
2459 <translation type="unfinished">バックアップ</translation>
2460 </message>
2461 <message>
2462 <location filename="../rbutilqtfrm.ui" line="366"/>
2463 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup current installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Create a backup by archiving the contents of the Rockbox installation folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2464 <translation type="unfinished"></translation>
2465 </message>
2466 <message>
2467 <location filename="../rbutilqtfrm.ui" line="539"/>
2468 <source>Install &amp;Bootloader</source>
2469 <translation>ブートローダのインストール(&amp;B)</translation>
2470 </message>
2471 <message>
2472 <location filename="../rbutilqtfrm.ui" line="548"/>
2473 <source>Install &amp;Rockbox</source>
2474 <translation>Rockbox のインストール(&amp;R)</translation>
2475 </message>
2476 <message>
2477 <location filename="../rbutilqtfrm.ui" line="557"/>
2478 <source>Install &amp;Fonts Package</source>
2479 <translation>フォントパッケージのインストール(&amp;F)</translation>
2480 </message>
2481 <message>
2482 <location filename="../rbutilqtfrm.ui" line="566"/>
2483 <source>Install &amp;Themes</source>
2484 <translation>テーマのインストール(&amp;T)</translation>
2485 </message>
2486 <message>
2487 <location filename="../rbutilqtfrm.ui" line="575"/>
2488 <source>Install &amp;Game Files</source>
2489 <translation>ゲームのインストール(&amp;G)</translation>
2490 </message>
2491 <message>
2492 <location filename="../rbutilqtfrm.ui" line="584"/>
2493 <source>&amp;Install Voice File</source>
2494 <translation>ボイスファイルのインストール(&amp;I)</translation>
2495 </message>
2496 <message>
2497 <location filename="../rbutilqtfrm.ui" line="593"/>
2498 <source>Create &amp;Talk Files</source>
2499 <translation>トークファイルの作成(&amp;T)</translation>
2500 </message>
2501 <message>
2502 <location filename="../rbutilqtfrm.ui" line="602"/>
2503 <source>Remove &amp;bootloader</source>
2504 <translation>ブートローダのアンインストール(&amp;B)</translation>
2505 </message>
2506 <message>
2507 <location filename="../rbutilqtfrm.ui" line="611"/>
2508 <source>Uninstall &amp;Rockbox</source>
2509 <translation>Rockbox のアンインストール(&amp;R)</translation>
2510 </message>
2511 <message>
2512 <location filename="../rbutilqtfrm.ui" line="640"/>
2513 <source>Create &amp;Voice File</source>
2514 <translation>ボイスファイルの作成(&amp;V)</translation>
2515 </message>
2516 <message>
2517 <location filename="../rbutilqtfrm.ui" line="648"/>
2518 <source>&amp;System Info</source>
2519 <translation>システム情報(&amp;S)</translation>
2520 </message>
2521 <message>
2522 <location filename="../rbutilqtfrm.ui" line="663"/>
2523 <source>Show &amp;Changelog</source>
2524 <translation type="unfinished"></translation>
2525 </message>
2526 <message>
2527 <location filename="../rbutilqtfrm.ui" line="521"/>
2528 <source>&amp;Complete Installation</source>
2529 <translation>完全インストール(&amp;C)</translation>
2530 </message>
2531 <message>
2532 <location filename="../rbutilqtfrm.ui" line="530"/>
2533 <source>&amp;Minimal Installation</source>
2534 <translation>最小インストール(&amp;M)</translation>
2535 </message>
2536 <message>
2537 <location filename="../rbutilqtfrm.ui" line="432"/>
2538 <source>&amp;Troubleshoot</source>
2539 <translation>トラブルシュート(&amp;T)</translation>
2540 </message>
2541 <message>
2542 <location filename="../rbutilqtfrm.ui" line="653"/>
2543 <source>System &amp;Trace</source>
2544 <translation>システムトレース(&amp;T)</translation>
2545 </message>
2546</context>
2547<context>
2548 <name>SelectiveInstallWidget</name>
2549 <message>
2550 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="20"/>
2551 <source>Selective Installation</source>
2552 <translation type="unfinished"></translation>
2553 </message>
2554 <message>
2555 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="26"/>
2556 <source>Rockbox version to install</source>
2557 <translation type="unfinished"></translation>
2558 </message>
2559 <message>
2560 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="35"/>
2561 <source>Version information not available yet.</source>
2562 <translation type="unfinished"></translation>
2563 </message>
2564 <message>
2565 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="54"/>
2566 <source>Rockbox components to install</source>
2567 <translation type="unfinished"></translation>
2568 </message>
2569 <message>
2570 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="60"/>
2571 <source>&amp;Bootloader</source>
2572 <translation type="unfinished"></translation>
2573 </message>
2574 <message>
2575 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="80"/>
2576 <source>The main Rockbox firmware.</source>
2577 <translation type="unfinished"></translation>
2578 </message>
2579 <message>
2580 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="90"/>
2581 <source>Fonts</source>
2582 <translation type="unfinished"></translation>
2583 </message>
2584 <message>
2585 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="104"/>
2586 <source>&amp;Rockbox</source>
2587 <translation type="unfinished"></translation>
2588 </message>
2589 <message>
2590 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="124"/>
2591 <source>Some game plugins require additional files.</source>
2592 <translation type="unfinished"></translation>
2593 </message>
2594 <message>
2595 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="140"/>
2596 <source>Additional fonts for the User Interface.</source>
2597 <translation type="unfinished"></translation>
2598 </message>
2599 <message>
2600 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="156"/>
2601 <source>The bootloader is required for starting Rockbox. Only necessary for first time install.</source>
2602 <translation type="unfinished"></translation>
2603 </message>
2604 <message>
2605 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="166"/>
2606 <source>Game Files</source>
2607 <translation type="unfinished"></translation>
2608 </message>
2609 <message>
2610 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="177"/>
2611 <source>Customize</source>
2612 <translation type="unfinished"></translation>
2613 </message>
2614 <message>
2615 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="188"/>
2616 <source>Themes</source>
2617 <translation type="unfinished"></translation>
2618 </message>
2619 <message>
2620 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="205"/>
2621 <source>Themes allow adjusting the user interface of Rockbox. Use &quot;Customize&quot; to select themes.</source>
2622 <translation type="unfinished"></translation>
2623 </message>
2624 <message>
2625 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="250"/>
2626 <source>&amp;Install</source>
2627 <translation type="unfinished">インストール(&amp;I)</translation>
2628 </message>
2629 <message>
2630 <location filename="../gui/selectiveinstallwidget.cpp" line="67"/>
2631 <source>This is the latest stable release available.</source>
2632 <translation type="unfinished"></translation>
2633 </message>
2634 <message>
2635 <location filename="../gui/selectiveinstallwidget.cpp" line="70"/>
2636 <source>The development version is updated on every code change. Last update was on %1</source>
2637 <translation type="unfinished"></translation>
2638 </message>
2639 <message>
2640 <location filename="../gui/selectiveinstallwidget.cpp" line="74"/>
2641 <source>This will eventually become the next Rockbox version. Install it to help testing.</source>
2642 <translation type="unfinished"></translation>
2643 </message>
2644 <message>
2645 <location filename="../gui/selectiveinstallwidget.cpp" line="100"/>
2646 <source>Stable Release (Version %1)</source>
2647 <translation type="unfinished"></translation>
2648 </message>
2649 <message>
2650 <location filename="../gui/selectiveinstallwidget.cpp" line="104"/>
2651 <source>Development Version (Revison %1)</source>
2652 <translation type="unfinished"></translation>
2653 </message>
2654 <message>
2655 <location filename="../gui/selectiveinstallwidget.cpp" line="108"/>
2656 <source>Release Candidate (Revison %1)</source>
2657 <translation type="unfinished"></translation>
2658 </message>
2659 <message>
2660 <location filename="../gui/selectiveinstallwidget.cpp" line="131"/>
2661 <source>The selected player doesn&apos;t need a bootloader.</source>
2662 <translation type="unfinished"></translation>
2663 </message>
2664 <message>
2665 <location filename="../gui/selectiveinstallwidget.cpp" line="136"/>
2666 <source>The bootloader is required for starting Rockbox. Installation of the bootloader is only necessary on first time installation.</source>
2667 <translation type="unfinished"></translation>
2668 </message>
2669 <message>
2670 <location filename="../gui/selectiveinstallwidget.cpp" line="183"/>
2671 <source>Mountpoint is wrong</source>
2672 <translation type="unfinished"></translation>
2673 </message>
2674 <message>
2675 <location filename="../gui/selectiveinstallwidget.cpp" line="239"/>
2676 <source>No install method known.</source>
2677 <translation type="unfinished">インストール方法が不明です。</translation>
2678 </message>
2679 <message>
2680 <location filename="../gui/selectiveinstallwidget.cpp" line="266"/>
2681 <source>Bootloader detected</source>
2682 <translation type="unfinished">ブートローダが検出されました</translation>
2683 </message>
2684 <message>
2685 <location filename="../gui/selectiveinstallwidget.cpp" line="267"/>
2686 <source>Bootloader already installed. Do you want to reinstall the bootloader?</source>
2687 <translation type="unfinished">ブートローダは既にインストールされています。ブートローダをインストールしますか?</translation>
2688 </message>
2689 <message>
2690 <location filename="../gui/selectiveinstallwidget.cpp" line="271"/>
2691 <source>Bootloader installation skipped</source>
2692 <translation type="unfinished">ブートローダのインストールをスキップしました</translation>
2693 </message>
2694 <message>
2695 <location filename="../gui/selectiveinstallwidget.cpp" line="284"/>
2696 <source>Create Bootloader backup</source>
2697 <translation type="unfinished">ブートローダのバックアップを作成します</translation>
2698 </message>
2699 <message>
2700 <location filename="../gui/selectiveinstallwidget.cpp" line="285"/>
2701 <source>You can create a backup of the original bootloader file. Press &quot;Yes&quot; to select an output folder on your computer to save the file to. The file will get placed in a new folder &quot;%1&quot; created below the selected folder.
2702Press &quot;No&quot; to skip this step.</source>
2703 <translation type="unfinished">オリジナルのブートローダファイルのバックアップファイルを作成することができます。&quot;はい&quot;ボタンを押して、バックアップファイルを保存するためのフォルダを選択して下さい。選択されたフォルダの下に &quot;%1&quot; フォルダを作成し、バックアップファイルを作成します。
2704&quot;いいえ&quot;ボタンを押しますと、バックアップファイルを作成しません。</translation>
2705 </message>
2706 <message>
2707 <location filename="../gui/selectiveinstallwidget.cpp" line="292"/>
2708 <source>Browse backup folder</source>
2709 <translation type="unfinished">バックアップフォルダの表示</translation>
2710 </message>
2711 <message>
2712 <location filename="../gui/selectiveinstallwidget.cpp" line="304"/>
2713 <source>Prerequisites</source>
2714 <translation type="unfinished">前提条件</translation>
2715 </message>
2716 <message>
2717 <location filename="../gui/selectiveinstallwidget.cpp" line="309"/>
2718 <source>Bootloader installation aborted</source>
2719 <translation type="unfinished">ブートローダのインストールが中止しました</translation>
2720 </message>
2721 <message>
2722 <location filename="../gui/selectiveinstallwidget.cpp" line="319"/>
2723 <source>Bootloader files (%1)</source>
2724 <translation type="unfinished"></translation>
2725 </message>
2726 <message>
2727 <location filename="../gui/selectiveinstallwidget.cpp" line="321"/>
2728 <source>All files (*)</source>
2729 <translation type="unfinished"></translation>
2730 </message>
2731 <message>
2732 <location filename="../gui/selectiveinstallwidget.cpp" line="323"/>
2733 <source>Select firmware file</source>
2734 <translation type="unfinished">ファームウェアを選択して下さい</translation>
2735 </message>
2736 <message>
2737 <location filename="../gui/selectiveinstallwidget.cpp" line="325"/>
2738 <source>Error opening firmware file</source>
2739 <translation type="unfinished">ファームウェア読み込み時のエラー</translation>
2740 </message>
2741 <message>
2742 <location filename="../gui/selectiveinstallwidget.cpp" line="331"/>
2743 <source>Error reading firmware file</source>
2744 <translation type="unfinished"></translation>
2745 </message>
2746 <message>
2747 <location filename="../gui/selectiveinstallwidget.cpp" line="341"/>
2748 <source>Backup error</source>
2749 <translation type="unfinished">バックアップエラー</translation>
2750 </message>
2751 <message>
2752 <location filename="../gui/selectiveinstallwidget.cpp" line="342"/>
2753 <source>Could not create backup file. Continue?</source>
2754 <translation type="unfinished">バックアップファイルが作成されませんでした。続行しますか?</translation>
2755 </message>
2756 <message>
2757 <location filename="../gui/selectiveinstallwidget.cpp" line="366"/>
2758 <source>Manual steps required</source>
2759 <translation type="unfinished">手動で行う必要があります</translation>
2760 </message>
2761 <message>
2762 <location filename="../gui/selectiveinstallwidget.cpp" line="171"/>
2763 <source>Continue with installation?</source>
2764 <translation type="unfinished"></translation>
2765 </message>
2766 <message>
2767 <location filename="../gui/selectiveinstallwidget.cpp" line="172"/>
2768 <source>Really continue?</source>
2769 <translation type="unfinished">本当に続行しますか?</translation>
2770 </message>
2771 <message>
2772 <source>Aborted!</source>
2773 <translation type="obsolete">処理を中止します!</translation>
2774 </message>
2775 <message>
2776 <location filename="../gui/selectiveinstallwidget.cpp" line="490"/>
2777 <source>Your installation doesn&apos;t require game files, skipping.</source>
2778 <translation type="unfinished"></translation>
2779 </message>
2780</context>
2781<context>
2782 <name>ServerInfo</name>
2783 <message>
2784 <location filename="../base/serverinfo.cpp" line="117"/>
2785 <source>Unknown</source>
2786 <translation>不明</translation>
2787 </message>
2788 <message>
2789 <location filename="../base/serverinfo.cpp" line="121"/>
2790 <source>Unusable</source>
2791 <translation>使用不可能</translation>
2792 </message>
2793 <message>
2794 <location filename="../base/serverinfo.cpp" line="124"/>
2795 <source>Unstable</source>
2796 <translation>不安定版</translation>
2797 </message>
2798 <message>
2799 <location filename="../base/serverinfo.cpp" line="127"/>
2800 <source>Stable</source>
2801 <translation>安定版</translation>
2802 </message>
2803</context>
2804<context>
2805 <name>SysTrace</name>
2806 <message>
2807 <location filename="../systrace.cpp" line="98"/>
2808 <location filename="../systrace.cpp" line="107"/>
2809 <source>Save system trace log</source>
2810 <translation>システムトレースのログを保存します</translation>
2811 </message>
2812</context>
2813<context>
2814 <name>SysTraceFrm</name>
2815 <message>
2816 <location filename="../systracefrm.ui" line="14"/>
2817 <source>System Trace</source>
2818 <translation>システムトレース</translation>
2819 </message>
2820 <message>
2821 <location filename="../systracefrm.ui" line="20"/>
2822 <source>System State trace</source>
2823 <translation>システム情報のトレース</translation>
2824 </message>
2825 <message>
2826 <location filename="../systracefrm.ui" line="46"/>
2827 <source>&amp;Close</source>
2828 <translation>閉じる(&amp;C)</translation>
2829 </message>
2830 <message>
2831 <location filename="../systracefrm.ui" line="57"/>
2832 <source>&amp;Save</source>
2833 <translation>保存(&amp;S)</translation>
2834 </message>
2835 <message>
2836 <location filename="../systracefrm.ui" line="68"/>
2837 <source>&amp;Refresh</source>
2838 <translation>更新(&amp;R)</translation>
2839 </message>
2840 <message>
2841 <location filename="../systracefrm.ui" line="79"/>
2842 <source>Save &amp;previous</source>
2843 <translation>1つ前を保存(&amp;p)</translation>
2844 </message>
2845</context>
2846<context>
2847 <name>Sysinfo</name>
2848 <message>
2849 <location filename="../sysinfo.cpp" line="45"/>
2850 <source>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</source>
2851 <translation>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</translation>
2852 </message>
2853 <message>
2854 <location filename="../sysinfo.cpp" line="46"/>
2855 <source>&lt;b&gt;Username&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2856 <translation>&lt;b&gt;ユーザ名&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2857 </message>
2858 <message>
2859 <location filename="../sysinfo.cpp" line="48"/>
2860 <source>&lt;b&gt;Permissions&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2861 <translation>&lt;b&gt;権限&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2862 </message>
2863 <message>
2864 <location filename="../sysinfo.cpp" line="50"/>
2865 <source>&lt;b&gt;Attached USB devices&lt;/b&gt;&lt;br/&gt;</source>
2866 <translation>&lt;b&gt;接続された USB デバイス&lt;/b&gt;&lt;br/&gt;</translation>
2867 </message>
2868 <message>
2869 <location filename="../sysinfo.cpp" line="54"/>
2870 <source>VID: %1 PID: %2, %3</source>
2871 <translation>VID: %1 PID: %2, %3</translation>
2872 </message>
2873 <message>
2874 <location filename="../sysinfo.cpp" line="63"/>
2875 <source>Filesystem</source>
2876 <translation>ファイルシステム</translation>
2877 </message>
2878 <message>
2879 <location filename="../sysinfo.cpp" line="66"/>
2880 <source>Mountpoint</source>
2881 <translation type="unfinished"></translation>
2882 </message>
2883 <message>
2884 <location filename="../sysinfo.cpp" line="66"/>
2885 <source>Label</source>
2886 <translation type="unfinished"></translation>
2887 </message>
2888 <message>
2889 <location filename="../sysinfo.cpp" line="67"/>
2890 <source>Free</source>
2891 <translation type="unfinished"></translation>
2892 </message>
2893 <message>
2894 <location filename="../sysinfo.cpp" line="67"/>
2895 <source>Total</source>
2896 <translation type="unfinished"></translation>
2897 </message>
2898 <message>
2899 <location filename="../sysinfo.cpp" line="68"/>
2900 <source>Cluster Size</source>
2901 <translation type="unfinished"></translation>
2902 </message>
2903 <message>
2904 <location filename="../sysinfo.cpp" line="70"/>
2905 <source>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</source>
2906 <translation type="unfinished"></translation>
2907 </message>
2908</context>
2909<context>
2910 <name>SysinfoFrm</name>
2911 <message>
2912 <location filename="../sysinfofrm.ui" line="13"/>
2913 <source>System Info</source>
2914 <translation>システム情報</translation>
2915 </message>
2916 <message>
2917 <location filename="../sysinfofrm.ui" line="22"/>
2918 <source>&amp;Refresh</source>
2919 <translation>更新(&amp;R)</translation>
2920 </message>
2921 <message>
2922 <location filename="../sysinfofrm.ui" line="45"/>
2923 <source>&amp;OK</source>
2924 <translation>Ok(&amp;O)</translation>
2925 </message>
2926</context>
2927<context>
2928 <name>System</name>
2929 <message>
2930 <location filename="../base/system.cpp" line="121"/>
2931 <source>Guest</source>
2932 <translation type="unfinished">ゲスト</translation>
2933 </message>
2934 <message>
2935 <location filename="../base/system.cpp" line="124"/>
2936 <source>Admin</source>
2937 <translation type="unfinished">管理者</translation>
2938 </message>
2939 <message>
2940 <location filename="../base/system.cpp" line="127"/>
2941 <source>User</source>
2942 <translation type="unfinished">ユーザ</translation>
2943 </message>
2944 <message>
2945 <location filename="../base/system.cpp" line="130"/>
2946 <source>Error</source>
2947 <translation type="unfinished">エラー</translation>
2948 </message>
2949 <message>
2950 <location filename="../base/system.cpp" line="278"/>
2951 <location filename="../base/system.cpp" line="323"/>
2952 <source>(no description available)</source>
2953 <translation type="unfinished">(利用可能な記述がありません)</translation>
2954 </message>
2955</context>
2956<context>
2957 <name>TTSBase</name>
2958 <message>
2959 <location filename="../base/ttsbase.cpp" line="45"/>
2960 <source>Espeak TTS Engine</source>
2961 <translation type="unfinished"></translation>
2962 </message>
2963 <message>
2964 <location filename="../base/ttsbase.cpp" line="47"/>
2965 <source>Flite TTS Engine</source>
2966 <translation type="unfinished"></translation>
2967 </message>
2968 <message>
2969 <location filename="../base/ttsbase.cpp" line="48"/>
2970 <source>Swift TTS Engine</source>
2971 <translation type="unfinished"></translation>
2972 </message>
2973 <message>
2974 <location filename="../base/ttsbase.cpp" line="51"/>
2975 <source>SAPI4 TTS Engine</source>
2976 <translation type="unfinished"></translation>
2977 </message>
2978 <message>
2979 <location filename="../base/ttsbase.cpp" line="53"/>
2980 <source>SAPI5 TTS Engine</source>
2981 <translation type="unfinished"></translation>
2982 </message>
2983 <message>
2984 <location filename="../base/ttsbase.cpp" line="54"/>
2985 <source>MS Speech Platform</source>
2986 <translation type="unfinished"></translation>
2987 </message>
2988 <message>
2989 <location filename="../base/ttsbase.cpp" line="57"/>
2990 <source>Festival TTS Engine</source>
2991 <translation type="unfinished"></translation>
2992 </message>
2993 <message>
2994 <location filename="../base/ttsbase.cpp" line="60"/>
2995 <source>OS X System Engine</source>
2996 <translation type="unfinished"></translation>
2997 </message>
2998</context>
2999<context>
3000 <name>TTSCarbon</name>
3001 <message>
3002 <location filename="../base/ttscarbon.cpp" line="139"/>
3003 <source>Voice:</source>
3004 <translation>ボイス:</translation>
3005 </message>
3006 <message>
3007 <location filename="../base/ttscarbon.cpp" line="145"/>
3008 <source>Speed (words/min):</source>
3009 <translation>スピード(語/分):</translation>
3010 </message>
3011 <message>
3012 <location filename="../base/ttscarbon.cpp" line="152"/>
3013 <source>Pitch (0 for default):</source>
3014 <translation type="unfinished"></translation>
3015 </message>
3016 <message>
3017 <location filename="../base/ttscarbon.cpp" line="222"/>
3018 <source>Could not voice string</source>
3019 <translation>ボイス化する文字列が見つかりませんでした</translation>
3020 </message>
3021 <message>
3022 <location filename="../base/ttscarbon.cpp" line="232"/>
3023 <source>Could not convert intermediate file</source>
3024 <translation>中間ファイルへの変換に失敗しました</translation>
3025 </message>
3026</context>
3027<context>
3028 <name>TTSExes</name>
3029 <message>
3030 <location filename="../base/ttsexes.cpp" line="78"/>
3031 <source>TTS executable not found</source>
3032 <translation>実行可能な TTS が見つかりませんでした</translation>
3033 </message>
3034 <message>
3035 <location filename="../base/ttsexes.cpp" line="44"/>
3036 <source>Path to TTS engine:</source>
3037 <translation>TTS エンジンのパス:</translation>
3038 </message>
3039 <message>
3040 <location filename="../base/ttsexes.cpp" line="46"/>
3041 <source>TTS engine options:</source>
3042 <translation>TTS エンジンのオプション:</translation>
3043 </message>
3044</context>
3045<context>
3046 <name>TTSFestival</name>
3047 <message>
3048 <location filename="../base/ttsfestival.cpp" line="207"/>
3049 <source>engine could not voice string</source>
3050 <translation>ボイス化する文字列が見つかりませんでした</translation>
3051 </message>
3052 <message>
3053 <location filename="../base/ttsfestival.cpp" line="290"/>
3054 <source>No description available</source>
3055 <translation>利用可能な記述がありません</translation>
3056 </message>
3057 <message>
3058 <location filename="../base/ttsfestival.cpp" line="53"/>
3059 <source>Path to Festival client:</source>
3060 <translation>Festival クライアントのパス:</translation>
3061 </message>
3062 <message>
3063 <location filename="../base/ttsfestival.cpp" line="58"/>
3064 <source>Voice:</source>
3065 <translation>ボイス:</translation>
3066 </message>
3067 <message>
3068 <location filename="../base/ttsfestival.cpp" line="67"/>
3069 <source>Voice description:</source>
3070 <translation>ボイスの説明:</translation>
3071 </message>
3072</context>
3073<context>
3074 <name>TTSSapi</name>
3075 <message>
3076 <location filename="../base/ttssapi.cpp" line="49"/>
3077 <source>Language:</source>
3078 <translation>言語:</translation>
3079 </message>
3080 <message>
3081 <location filename="../base/ttssapi.cpp" line="56"/>
3082 <source>Voice:</source>
3083 <translation>ボイス:</translation>
3084 </message>
3085 <message>
3086 <location filename="../base/ttssapi.cpp" line="68"/>
3087 <source>Speed:</source>
3088 <translation>スピード:</translation>
3089 </message>
3090 <message>
3091 <location filename="../base/ttssapi.cpp" line="71"/>
3092 <source>Options:</source>
3093 <translation>オプション:</translation>
3094 </message>
3095 <message>
3096 <location filename="../base/ttssapi.cpp" line="115"/>
3097 <source>Could not copy the SAPI script</source>
3098 <translation type="unfinished"></translation>
3099 </message>
3100 <message>
3101 <location filename="../base/ttssapi.cpp" line="133"/>
3102 <source>Could not start SAPI process</source>
3103 <translation type="unfinished"></translation>
3104 </message>
3105</context>
3106<context>
3107 <name>TalkFileCreator</name>
3108 <message>
3109 <location filename="../base/talkfile.cpp" line="45"/>
3110 <source>Talk file creation aborted</source>
3111 <translation>トークファイルの作成を中止しました</translation>
3112 </message>
3113 <message>
3114 <location filename="../base/talkfile.cpp" line="80"/>
3115 <source>Finished creating Talk files</source>
3116 <translation>トークファイルの作成が終了しました</translation>
3117 </message>
3118 <message>
3119 <location filename="../base/talkfile.cpp" line="42"/>
3120 <source>Reading Filelist...</source>
3121 <translation>ファイルリストを読み込んでいます...</translation>
3122 </message>
3123 <message>
3124 <location filename="../base/talkfile.cpp" line="259"/>
3125 <source>Copying of %1 to %2 failed</source>
3126 <translation>%1 から %2 にファイルをコピーすることに失敗しました</translation>
3127 </message>
3128 <message>
3129 <location filename="../base/talkfile.cpp" line="68"/>
3130 <source>Copying Talkfiles...</source>
3131 <translation>トークファイルをコピーしています...</translation>
3132 </message>
3133 <message>
3134 <location filename="../base/talkfile.cpp" line="36"/>
3135 <source>Starting Talk file generation for folder %1</source>
3136 <translation type="unfinished"></translation>
3137 </message>
3138 <message>
3139 <location filename="../base/talkfile.cpp" line="240"/>
3140 <source>File copy aborted</source>
3141 <translation>ファイルのコピーが失敗しました</translation>
3142 </message>
3143 <message>
3144 <location filename="../base/talkfile.cpp" line="280"/>
3145 <source>Cleaning up...</source>
3146 <translation>不要なファイルを削除しています...</translation>
3147 </message>
3148 <message>
3149 <location filename="../base/talkfile.cpp" line="291"/>
3150 <source>Finished</source>
3151 <translation>終了しました</translation>
3152 </message>
3153</context>
3154<context>
3155 <name>TalkGenerator</name>
3156 <message>
3157 <location filename="../base/talkgenerator.cpp" line="39"/>
3158 <source>Starting TTS Engine</source>
3159 <translation>TTS エンジンの開始</translation>
3160 </message>
3161 <message>
3162 <location filename="../base/talkgenerator.cpp" line="44"/>
3163 <location filename="../base/talkgenerator.cpp" line="51"/>
3164 <source>Init of TTS engine failed</source>
3165 <translation>TTS エンジンの初期化に失敗しました</translation>
3166 </message>
3167 <message>
3168 <location filename="../base/talkgenerator.cpp" line="58"/>
3169 <source>Starting Encoder Engine</source>
3170 <translation>エンコーダエンジンの開始</translation>
3171 </message>
3172 <message>
3173 <location filename="../base/talkgenerator.cpp" line="62"/>
3174 <source>Init of Encoder engine failed</source>
3175 <translation>エンコーダエンジンの初期化に失敗しました</translation>
3176 </message>
3177 <message>
3178 <location filename="../base/talkgenerator.cpp" line="72"/>
3179 <source>Voicing entries...</source>
3180 <translation>ボイス化しています...</translation>
3181 </message>
3182 <message>
3183 <location filename="../base/talkgenerator.cpp" line="87"/>
3184 <source>Encoding files...</source>
3185 <translation>エンコードしています...</translation>
3186 </message>
3187 <message>
3188 <location filename="../base/talkgenerator.cpp" line="126"/>
3189 <source>Voicing aborted</source>
3190 <translation>ボイス化に失敗しました</translation>
3191 </message>
3192 <message>
3193 <location filename="../base/talkgenerator.cpp" line="162"/>
3194 <location filename="../base/talkgenerator.cpp" line="167"/>
3195 <source>Voicing of %1 failed: %2</source>
3196 <translation>%1 のボイス化に失敗しました: %2</translation>
3197 </message>
3198 <message>
3199 <location filename="../base/talkgenerator.cpp" line="211"/>
3200 <source>Encoding aborted</source>
3201 <translation>エンコード処理に失敗しました</translation>
3202 </message>
3203 <message>
3204 <location filename="../base/talkgenerator.cpp" line="239"/>
3205 <source>Encoding of %1 failed</source>
3206 <translation>%1 のエンコードに失敗しました</translation>
3207 </message>
3208</context>
3209<context>
3210 <name>ThemeInstallFrm</name>
3211 <message>
3212 <location filename="../themesinstallfrm.ui" line="13"/>
3213 <source>Theme Installation</source>
3214 <translation>テーマのインストール</translation>
3215 </message>
3216 <message>
3217 <location filename="../themesinstallfrm.ui" line="48"/>
3218 <source>Selected Theme</source>
3219 <translation>テーマの選択</translation>
3220 </message>
3221 <message>
3222 <location filename="../themesinstallfrm.ui" line="73"/>
3223 <source>Description</source>
3224 <translation>説明</translation>
3225 </message>
3226 <message>
3227 <location filename="../themesinstallfrm.ui" line="83"/>
3228 <source>Download size:</source>
3229 <translation>ダウンロードサイズ:</translation>
3230 </message>
3231 <message>
3232 <location filename="../themesinstallfrm.ui" line="125"/>
3233 <source>&amp;Cancel</source>
3234 <translation>キャンセル(&amp;C)</translation>
3235 </message>
3236 <message>
3237 <location filename="../themesinstallfrm.ui" line="115"/>
3238 <source>&amp;Install</source>
3239 <translation>インストール(&amp;I)</translation>
3240 </message>
3241 <message>
3242 <location filename="../themesinstallfrm.ui" line="93"/>
3243 <source>Hold Ctrl to select multiple item, Shift for a range</source>
3244 <translation>複数の項目を選択するためには、Ctrlキーを押し続けて下さい。範囲指定を行うには、Shiftキーを押し続けて下さい</translation>
3245 </message>
3246</context>
3247<context>
3248 <name>ThemesInstallWindow</name>
3249 <message>
3250 <location filename="../themesinstallwindow.cpp" line="40"/>
3251 <source>no theme selected</source>
3252 <translation>テーマが選択されていません</translation>
3253 </message>
3254 <message>
3255 <location filename="../themesinstallwindow.cpp" line="125"/>
3256 <source>Network error: %1.
3257Please check your network and proxy settings.</source>
3258 <translation>ネットワークエラー: %1.
3259ネットワークおよびプロキシーの設定を確認して下さい。</translation>
3260 </message>
3261 <message>
3262 <location filename="../themesinstallwindow.cpp" line="138"/>
3263 <source>the following error occured:
3264%1</source>
3265 <translation>以下のエラーが発生しました:
3266%1</translation>
3267 </message>
3268 <message>
3269 <location filename="../themesinstallwindow.cpp" line="144"/>
3270 <source>done.</source>
3271 <translation>終了しました。</translation>
3272 </message>
3273 <message>
3274 <location filename="../themesinstallwindow.cpp" line="211"/>
3275 <source>fetching details for %1</source>
3276 <translation>%1 の説明を取得しています</translation>
3277 </message>
3278 <message>
3279 <location filename="../themesinstallwindow.cpp" line="214"/>
3280 <source>fetching preview ...</source>
3281 <translation>プレビューを取得しています...</translation>
3282 </message>
3283 <message>
3284 <location filename="../themesinstallwindow.cpp" line="227"/>
3285 <source>&lt;b&gt;Author:&lt;/b&gt; %1&lt;hr/&gt;</source>
3286 <translation>&lt;b&gt;制作者:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3287 </message>
3288 <message>
3289 <location filename="../themesinstallwindow.cpp" line="228"/>
3290 <location filename="../themesinstallwindow.cpp" line="230"/>
3291 <source>unknown</source>
3292 <translation>不明</translation>
3293 </message>
3294 <message>
3295 <location filename="../themesinstallwindow.cpp" line="229"/>
3296 <source>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</source>
3297 <translation>&lt;b&gt;バージョン:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3298 </message>
3299 <message>
3300 <location filename="../themesinstallwindow.cpp" line="232"/>
3301 <source>no description</source>
3302 <translation>説明はありません</translation>
3303 </message>
3304 <message>
3305 <location filename="../themesinstallwindow.cpp" line="260"/>
3306 <source>no theme preview</source>
3307 <translation>テーマのプレビューはありません</translation>
3308 </message>
3309 <message>
3310 <location filename="../themesinstallwindow.cpp" line="289"/>
3311 <source>Select</source>
3312 <translation type="unfinished"></translation>
3313 </message>
3314 <message>
3315 <location filename="../themesinstallwindow.cpp" line="296"/>
3316 <source>getting themes information ...</source>
3317 <translation>テーマの情報を取得しています...</translation>
3318 </message>
3319 <message>
3320 <location filename="../themesinstallwindow.cpp" line="326"/>
3321 <source>No themes selected, skipping</source>
3322 <translation type="unfinished"></translation>
3323 </message>
3324 <message>
3325 <location filename="../themesinstallwindow.cpp" line="356"/>
3326 <source>Mount point is wrong!</source>
3327 <translation>マウントポイントが間違っています!</translation>
3328 </message>
3329 <message>
3330 <location filename="../themesinstallwindow.cpp" line="231"/>
3331 <source>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</source>
3332 <translation>&lt;b&gt;説明:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3333 </message>
3334 <message>
3335 <location filename="../themesinstallwindow.cpp" line="41"/>
3336 <source>no selection</source>
3337 <translation>選択されていません</translation>
3338 </message>
3339 <message>
3340 <location filename="../themesinstallwindow.cpp" line="181"/>
3341 <source>Information</source>
3342 <translation>情報</translation>
3343 </message>
3344 <message numerus="yes">
3345 <location filename="../themesinstallwindow.cpp" line="198"/>
3346 <source>Download size %L1 kiB (%n item(s))</source>
3347 <translation>
3348 <numerusform>ダウンロードサイズ %L1 kiB (%n アイテム)</numerusform>
3349 </translation>
3350 </message>
3351 <message>
3352 <location filename="../themesinstallwindow.cpp" line="248"/>
3353 <source>Retrieving theme preview failed.
3354HTTP response code: %1</source>
3355 <translation>テーマのプレビュー画像の取得に失敗しました。
3356HTTP レスポンスコード: %1</translation>
3357 </message>
3358</context>
3359<context>
3360 <name>UninstallFrm</name>
3361 <message>
3362 <location filename="../uninstallfrm.ui" line="16"/>
3363 <source>Uninstall Rockbox</source>
3364 <translation>Rockbox のアンインストール</translation>
3365 </message>
3366 <message>
3367 <location filename="../uninstallfrm.ui" line="35"/>
3368 <source>Please select the Uninstallation Method</source>
3369 <translation>アンインストール方法を選択して下さい</translation>
3370 </message>
3371 <message>
3372 <location filename="../uninstallfrm.ui" line="45"/>
3373 <source>Uninstallation Method</source>
3374 <translation>アンインストール方法</translation>
3375 </message>
3376 <message>
3377 <location filename="../uninstallfrm.ui" line="51"/>
3378 <source>Complete Uninstallation</source>
3379 <translation>完全アンインストール</translation>
3380 </message>
3381 <message>
3382 <location filename="../uninstallfrm.ui" line="58"/>
3383 <source>Smart Uninstallation</source>
3384 <translation>高性能アンインストール</translation>
3385 </message>
3386 <message>
3387 <location filename="../uninstallfrm.ui" line="68"/>
3388 <source>Please select what you want to uninstall</source>
3389 <translation>アンインストール方法を選択して下さい</translation>
3390 </message>
3391 <message>
3392 <location filename="../uninstallfrm.ui" line="78"/>
3393 <source>Installed Parts</source>
3394 <translation>インストールしたもの</translation>
3395 </message>
3396 <message>
3397 <location filename="../uninstallfrm.ui" line="138"/>
3398 <source>&amp;Cancel</source>
3399 <translation>キャンセル(&amp;C)</translation>
3400 </message>
3401 <message>
3402 <location filename="../uninstallfrm.ui" line="128"/>
3403 <source>&amp;Uninstall</source>
3404 <translation>アンインストール(&amp;U)</translation>
3405 </message>
3406</context>
3407<context>
3408 <name>Uninstaller</name>
3409 <message>
3410 <location filename="../base/uninstall.cpp" line="32"/>
3411 <location filename="../base/uninstall.cpp" line="43"/>
3412 <source>Starting Uninstallation</source>
3413 <translation>アンインストールを開始します</translation>
3414 </message>
3415 <message>
3416 <location filename="../base/uninstall.cpp" line="36"/>
3417 <source>Finished Uninstallation</source>
3418 <translation>アンインストールが終了しました</translation>
3419 </message>
3420 <message>
3421 <location filename="../base/uninstall.cpp" line="49"/>
3422 <source>Uninstalling %1...</source>
3423 <translation>%1 をアンインストールしています...</translation>
3424 </message>
3425 <message>
3426 <location filename="../base/uninstall.cpp" line="80"/>
3427 <source>Could not delete %1</source>
3428 <translation>%1 を削除することができませんでした</translation>
3429 </message>
3430 <message>
3431 <location filename="../base/uninstall.cpp" line="109"/>
3432 <source>Uninstallation finished</source>
3433 <translation>アンインストールが終了しました</translation>
3434 </message>
3435</context>
3436<context>
3437 <name>Utils</name>
3438 <message>
3439 <location filename="../base/utils.cpp" line="312"/>
3440 <source>&lt;li&gt;Permissions insufficient for bootloader installation.
3441Administrator priviledges are necessary.&lt;/li&gt;</source>
3442 <translation type="unfinished">&lt;li&gt;ブートローダをインストールするのに、アクセス権限が足りません。
3443管理者権限が必要です。&lt;/li&gt;</translation>
3444 </message>
3445 <message>
3446 <location filename="../base/utils.cpp" line="324"/>
3447 <source>&lt;li&gt;Target mismatch detected.&lt;br/&gt;Installed target: %1&lt;br/&gt;Selected target: %2.&lt;/li&gt;</source>
3448 <translation type="unfinished"></translation>
3449 </message>
3450 <message>
3451 <location filename="../base/utils.cpp" line="331"/>
3452 <source>Problem detected:</source>
3453 <translation type="unfinished">問題が見つかりました:</translation>
3454 </message>
3455</context>
3456<context>
3457 <name>VoiceFileCreator</name>
3458 <message>
3459 <location filename="../base/voicefile.cpp" line="43"/>
3460 <source>Starting Voicefile generation</source>
3461 <translation>ボイスファイルの作成を開始しています</translation>
3462 </message>
3463 <message>
3464 <location filename="../base/voicefile.cpp" line="90"/>
3465 <source>Extracted voice strings from installation</source>
3466 <translation type="unfinished"></translation>
3467 </message>
3468 <message>
3469 <location filename="../base/voicefile.cpp" line="100"/>
3470 <source>Extracted voice strings incompatible</source>
3471 <translation type="unfinished"></translation>
3472 </message>
3473 <message>
3474 <location filename="../base/voicefile.cpp" line="145"/>
3475 <source>Could not retrieve strings from installation, downloading</source>
3476 <translation type="unfinished"></translation>
3477 </message>
3478 <message>
3479 <location filename="../base/voicefile.cpp" line="184"/>
3480 <source>Download error: received HTTP error %1.</source>
3481 <translation>ダウンロードエラー: HTTP 受信のエラー %1.</translation>
3482 </message>
3483 <message>
3484 <location filename="../base/voicefile.cpp" line="191"/>
3485 <source>Cached file used.</source>
3486 <translation>キャッシュファイルを使用しました。</translation>
3487 </message>
3488 <message>
3489 <location filename="../base/voicefile.cpp" line="194"/>
3490 <source>Download error: %1</source>
3491 <translation>ダウンロードエラー: %1</translation>
3492 </message>
3493 <message>
3494 <location filename="../base/voicefile.cpp" line="199"/>
3495 <source>Download finished.</source>
3496 <translation>ダウンロードが終了しました。</translation>
3497 </message>
3498 <message>
3499 <location filename="../base/voicefile.cpp" line="212"/>
3500 <source>failed to open downloaded file</source>
3501 <translation>ダウンロードしたファイルが開けませんでした</translation>
3502 </message>
3503 <message>
3504 <location filename="../base/voicefile.cpp" line="271"/>
3505 <source>The downloaded file was empty!</source>
3506 <translation>ダウンロードしたファイルが空です!</translation>
3507 </message>
3508 <message>
3509 <location filename="../base/voicefile.cpp" line="302"/>
3510 <source>Error opening downloaded file</source>
3511 <translation>ダウンロードしたファイルの読み込みエラー</translation>
3512 </message>
3513 <message>
3514 <location filename="../base/voicefile.cpp" line="313"/>
3515 <source>Error opening output file</source>
3516 <translation>出力ファイルの出力時のエラー</translation>
3517 </message>
3518 <message>
3519 <location filename="../base/voicefile.cpp" line="333"/>
3520 <source>successfully created.</source>
3521 <translation>正常に作成されました。</translation>
3522 </message>
3523 <message>
3524 <location filename="../base/voicefile.cpp" line="56"/>
3525 <source>could not find rockbox-info.txt</source>
3526 <translation>rockbox-info.txt が見つかりませんでした</translation>
3527 </message>
3528 <message>
3529 <location filename="../base/voicefile.cpp" line="171"/>
3530 <source>Downloading voice info...</source>
3531 <translation>ボイス情報をダウンロードしています...</translation>
3532 </message>
3533 <message>
3534 <location filename="../base/voicefile.cpp" line="218"/>
3535 <source>Reading strings...</source>
3536 <translation>文字列を読み込んでいます...</translation>
3537 </message>
3538 <message>
3539 <location filename="../base/voicefile.cpp" line="297"/>
3540 <source>Creating voicefiles...</source>
3541 <translation>ボイスファイルを作成しています...</translation>
3542 </message>
3543 <message>
3544 <location filename="../base/voicefile.cpp" line="342"/>
3545 <source>Cleaning up...</source>
3546 <translation>不要なファイルを削除しています...</translation>
3547 </message>
3548 <message>
3549 <location filename="../base/voicefile.cpp" line="353"/>
3550 <source>Finished</source>
3551 <translation>終了しました</translation>
3552 </message>
3553</context>
3554<context>
3555 <name>ZipInstaller</name>
3556 <message>
3557 <location filename="../base/zipinstaller.cpp" line="60"/>
3558 <source>done.</source>
3559 <translation>終了しました。</translation>
3560 </message>
3561 <message>
3562 <location filename="../base/zipinstaller.cpp" line="80"/>
3563 <source>Downloading file %1.%2</source>
3564 <translation>%1.%2 をダウンロードしています</translation>
3565 </message>
3566 <message>
3567 <location filename="../base/zipinstaller.cpp" line="115"/>
3568 <source>Download error: received HTTP error %1.</source>
3569 <translation>ダウンロードエラー: HTTP 受信のエラー %1.</translation>
3570 </message>
3571 <message>
3572 <location filename="../base/zipinstaller.cpp" line="123"/>
3573 <source>Download error: %1</source>
3574 <translation>ダウンロードエラー: %1</translation>
3575 </message>
3576 <message>
3577 <location filename="../base/zipinstaller.cpp" line="127"/>
3578 <source>Download finished.</source>
3579 <translation>ダウンロードが終了しました。</translation>
3580 </message>
3581 <message>
3582 <location filename="../base/zipinstaller.cpp" line="133"/>
3583 <source>Extracting file.</source>
3584 <translation>解凍しています。</translation>
3585 </message>
3586 <message>
3587 <location filename="../base/zipinstaller.cpp" line="153"/>
3588 <source>Extraction failed!</source>
3589 <translation type="unfinished"></translation>
3590 </message>
3591 <message>
3592 <location filename="../base/zipinstaller.cpp" line="162"/>
3593 <source>Installing file.</source>
3594 <translation>ファイルをインストールしています。</translation>
3595 </message>
3596 <message>
3597 <location filename="../base/zipinstaller.cpp" line="173"/>
3598 <source>Installing file failed.</source>
3599 <translation>ファイルのインストールに失敗しました。</translation>
3600 </message>
3601 <message>
3602 <location filename="../base/zipinstaller.cpp" line="186"/>
3603 <source>Creating installation log</source>
3604 <translation>インストール時のログを作成しています</translation>
3605 </message>
3606 <message>
3607 <location filename="../base/zipinstaller.cpp" line="121"/>
3608 <source>Cached file used.</source>
3609 <translation>キャッシュファイルを使用しました。</translation>
3610 </message>
3611 <message>
3612 <location filename="../base/zipinstaller.cpp" line="68"/>
3613 <source>Package installation finished successfully.</source>
3614 <translation type="unfinished"></translation>
3615 </message>
3616 <message>
3617 <location filename="../base/zipinstaller.cpp" line="146"/>
3618 <source>Not enough disk space! Aborting.</source>
3619 <translation>ディスクの空き領域が足りません! 処理を中止します。</translation>
3620 </message>
3621</context>
3622<context>
3623 <name>ZipUtil</name>
3624 <message>
3625 <location filename="../base/ziputil.cpp" line="125"/>
3626 <source>Creating output path failed</source>
3627 <translation type="unfinished"></translation>
3628 </message>
3629 <message>
3630 <location filename="../base/ziputil.cpp" line="132"/>
3631 <source>Creating output file failed</source>
3632 <translation type="unfinished"></translation>
3633 </message>
3634 <message>
3635 <location filename="../base/ziputil.cpp" line="141"/>
3636 <source>Error during Zip operation</source>
3637 <translation type="unfinished"></translation>
3638 </message>
3639</context>
3640<context>
3641 <name>aboutBox</name>
3642 <message>
3643 <location filename="../aboutbox.ui" line="14"/>
3644 <source>About Rockbox Utility</source>
3645 <translation>Rockbox Utilityについて</translation>
3646 </message>
3647 <message>
3648 <location filename="../aboutbox.ui" line="74"/>
3649 <source>&amp;Credits</source>
3650 <translation>クレジット(&amp;C)</translation>
3651 </message>
3652 <message>
3653 <location filename="../aboutbox.ui" line="106"/>
3654 <source>&amp;License</source>
3655 <translation>ライセンス(&amp;L)</translation>
3656 </message>
3657 <message>
3658 <location filename="../aboutbox.ui" line="132"/>
3659 <source>&amp;Speex License</source>
3660 <translation type="unfinished"></translation>
3661 </message>
3662 <message>
3663 <location filename="../aboutbox.ui" line="158"/>
3664 <source>&amp;Ok</source>
3665 <translation>Ok(&amp;O)</translation>
3666 </message>
3667 <message>
3668 <location filename="../aboutbox.ui" line="32"/>
3669 <source>The Rockbox Utility</source>
3670 <translation>The Rockbox Utility</translation>
3671 </message>
3672 <message utf8="true">
3673 <location filename="../aboutbox.ui" line="54"/>
3674 <source>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</source>
3675 <translation>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team &lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</translation>
3676 </message>
3677</context>
3678</TS>
diff --git a/utils/rbutilqt/lang/rbutil_nl.ts b/utils/rbutilqt/lang/rbutil_nl.ts
new file mode 100644
index 0000000000..19123120f4
--- /dev/null
+++ b/utils/rbutilqt/lang/rbutil_nl.ts
@@ -0,0 +1,3697 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE TS>
3<TS version="2.0" language="nl">
4<context>
5 <name>BackupDialog</name>
6 <message>
7 <location filename="../gui/backupdialogfrm.ui" line="17"/>
8 <location filename="../gui/backupdialogfrm.ui" line="43"/>
9 <source>Backup</source>
10 <translation>Backup</translation>
11 </message>
12 <message>
13 <location filename="../gui/backupdialogfrm.ui" line="33"/>
14 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This dialog will create a backup by archiving the contents of the Rockbox installation on the player into a zip file. This will include installed themes and settings stored below the .rockbox folder on the player.&lt;/p&gt;&lt;p&gt;The backup filename will be created based on the installed version. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
15 <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In dit scherm wordt een backup gemaakt door inhoud van de Rockbox-installatie op de speler naar een zip-bestand te archiveren. Dit omvat de geïnstalleerde themes en instellingen opgeslagen onder de .rockbox folder op de speler.&lt;/p&gt;&lt;p&gt;De bestandsnaam van de backup is gebaseerd op de geïnstalleerde versie.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
16 </message>
17 <message>
18 <location filename="../gui/backupdialogfrm.ui" line="49"/>
19 <source>Size: unknown</source>
20 <translation>Grootte: onbekend</translation>
21 </message>
22 <message>
23 <location filename="../gui/backupdialogfrm.ui" line="56"/>
24 <source>Backup to: unknown</source>
25 <translation>Backup naar: onbekend</translation>
26 </message>
27 <message>
28 <location filename="../gui/backupdialogfrm.ui" line="76"/>
29 <source>&amp;Change</source>
30 <translation>&amp;Veranderen</translation>
31 </message>
32 <message>
33 <location filename="../gui/backupdialogfrm.ui" line="116"/>
34 <source>&amp;Backup</source>
35 <translation>&amp;Backup</translation>
36 </message>
37 <message>
38 <location filename="../gui/backupdialogfrm.ui" line="127"/>
39 <source>&amp;Cancel</source>
40 <translation>&amp;Annuleren</translation>
41 </message>
42 <message>
43 <location filename="../gui/backupdialog.cpp" line="70"/>
44 <source>Installation size: calculating ...</source>
45 <translation>Installatiegrootte: berekenen ...</translation>
46 </message>
47 <message>
48 <location filename="../gui/backupdialog.cpp" line="89"/>
49 <source>Select Backup Filename</source>
50 <translation>Selecteer backup bestandsnaam</translation>
51 </message>
52 <message>
53 <location filename="../gui/backupdialog.cpp" line="109"/>
54 <source>Installation size: %L1 %2</source>
55 <translation>Installatiegrootte: %L1 %2</translation>
56 </message>
57 <message>
58 <location filename="../gui/backupdialog.cpp" line="116"/>
59 <source>File exists</source>
60 <translation>Bestand bestaat</translation>
61 </message>
62 <message>
63 <location filename="../gui/backupdialog.cpp" line="117"/>
64 <source>The selected backup file already exists. Overwrite?</source>
65 <translation>Het geselecteerde backup-bestand bestaat al. Overschrijven?</translation>
66 </message>
67 <message>
68 <location filename="../gui/backupdialog.cpp" line="125"/>
69 <source>Starting backup ...</source>
70 <translation>Starten backup ...</translation>
71 </message>
72 <message>
73 <location filename="../gui/backupdialog.cpp" line="144"/>
74 <source>Backup successful.</source>
75 <translation>Backup succesvol.</translation>
76 </message>
77 <message>
78 <location filename="../gui/backupdialog.cpp" line="147"/>
79 <source>Backup failed!</source>
80 <translation>Backup mislukt!</translation>
81 </message>
82</context>
83<context>
84 <name>BootloaderInstallAms</name>
85 <message>
86 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
87 <translation type="obsolete">Voor installatie van de bootloader is het nodig dat u een kopie van de originele Sandisk firmware (bin bestand) aanlevert. Dit bestand zal aangepast en dan geïnstalleerd worden op uw speler, samen met de rockbox bootloader. U moet dit bestand zelf downloaden om juridische redenen. Kijk op &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; of op &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;handleiding&lt;/a&gt; en de &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wikipagina hoe u dit bestand kan verkrijgen.&lt;br/&gt;Druk Ok om door te gaan en om op uw computer te bladeren naar het firmware bestand.</translation>
88 </message>
89 <message>
90 <location filename="../base/bootloaderinstallams.cpp" line="33"/>
91 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; This file is not present on your player and will disappear automatically after installing it.&lt;br/&gt;&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
92 <translation>Voor installatie van de bootloader is het nodig dat u een kopie van de originele Sandisk firmware (bin bestand) aanlevert. Dit bestand zal aangepast en dan geïnstalleerd worden op uw speler, samen met de rockbox bootloader. U moet dit bestand zelf downloaden om juridische redenen. Kijk op &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; of op &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;handleiding&lt;/a&gt; en de &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wikipagina hoe u dit bestand kan verkrijgen.&lt;br/&gt;Druk Ok om door te gaan en om op uw computer te bladeren naar het firmware bestand.</translation>
93 </message>
94 <message>
95 <location filename="../base/bootloaderinstallams.cpp" line="58"/>
96 <source>Downloading bootloader file</source>
97 <translation>Bezig met downloaden van Bootloader</translation>
98 </message>
99 <message>
100 <location filename="../base/bootloaderinstallams.cpp" line="100"/>
101 <location filename="../base/bootloaderinstallams.cpp" line="113"/>
102 <source>Could not load %1</source>
103 <translation>Kon %1 niet laden</translation>
104 </message>
105 <message>
106 <location filename="../base/bootloaderinstallams.cpp" line="127"/>
107 <source>No room to insert bootloader, try another firmware version</source>
108 <translation>Geen ruimte om de bootloader in te voegen, probeer een andere firmwareversie</translation>
109 </message>
110 <message>
111 <location filename="../base/bootloaderinstallams.cpp" line="137"/>
112 <source>Patching Firmware...</source>
113 <translation>Bezig met pachen van firmware...</translation>
114 </message>
115 <message>
116 <location filename="../base/bootloaderinstallams.cpp" line="148"/>
117 <source>Could not open %1 for writing</source>
118 <translation>Kon %1 niet openen voor schrijven</translation>
119 </message>
120 <message>
121 <location filename="../base/bootloaderinstallams.cpp" line="161"/>
122 <source>Could not write firmware file</source>
123 <translation>Kon het firmware bestand niet beschrijven</translation>
124 </message>
125 <message>
126 <location filename="../base/bootloaderinstallams.cpp" line="177"/>
127 <source>Success: modified firmware file created</source>
128 <translation>Succes: gemodificeerde Firmware aangemaakt</translation>
129 </message>
130 <message>
131 <location filename="../base/bootloaderinstallams.cpp" line="185"/>
132 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
133 <translation>Voer een normale upgrade met een ongewijzigde originele firmware, om the deïnstalleren</translation>
134 </message>
135</context>
136<context>
137 <name>BootloaderInstallBase</name>
138 <message>
139 <location filename="../base/bootloaderinstallbase.cpp" line="78"/>
140 <source>Download error: received HTTP error %1.</source>
141 <translation>Download fout: HTTP fout %1.</translation>
142 </message>
143 <message>
144 <location filename="../base/bootloaderinstallbase.cpp" line="84"/>
145 <source>Download error: %1</source>
146 <translation>Download fout : %1</translation>
147 </message>
148 <message>
149 <location filename="../base/bootloaderinstallbase.cpp" line="90"/>
150 <source>Download finished (cache used).</source>
151 <translation>Download voltooid (cache gebruikt).</translation>
152 </message>
153 <message>
154 <location filename="../base/bootloaderinstallbase.cpp" line="92"/>
155 <source>Download finished.</source>
156 <translation>Download voltooid.</translation>
157 </message>
158 <message>
159 <location filename="../base/bootloaderinstallbase.cpp" line="113"/>
160 <source>Creating backup of original firmware file.</source>
161 <translation>Maak een backup van de Originele Firmware.</translation>
162 </message>
163 <message>
164 <location filename="../base/bootloaderinstallbase.cpp" line="115"/>
165 <source>Creating backup folder failed</source>
166 <translation>Aanmaken van backup map heeft gefaald</translation>
167 </message>
168 <message>
169 <location filename="../base/bootloaderinstallbase.cpp" line="121"/>
170 <source>Creating backup copy failed.</source>
171 <translation>Aanmaken van backup kopie heeft gefaald.</translation>
172 </message>
173 <message>
174 <location filename="../base/bootloaderinstallbase.cpp" line="124"/>
175 <source>Backup created.</source>
176 <translation>Backup aangemaakt.</translation>
177 </message>
178 <message>
179 <location filename="../base/bootloaderinstallbase.cpp" line="137"/>
180 <source>Creating installation log</source>
181 <translation>Bezig met creëren van installatie log</translation>
182 </message>
183 <message>
184 <location filename="../base/bootloaderinstallbase.cpp" line="226"/>
185 <source>Zip file format detected</source>
186 <translation>Zip-formaat gedetecteerd</translation>
187 </message>
188 <message>
189 <location filename="../base/bootloaderinstallbase.cpp" line="238"/>
190 <source>CAB file format detected</source>
191 <translation>CAB bestandsformaat gedetecteerd</translation>
192 </message>
193 <message>
194 <location filename="../base/bootloaderinstallbase.cpp" line="259"/>
195 <source>Extracting firmware %1 from archive</source>
196 <translation>Bezig met uitpakken firmware %1 uit archief</translation>
197 </message>
198 <message>
199 <location filename="../base/bootloaderinstallbase.cpp" line="266"/>
200 <source>Error extracting firmware from archive</source>
201 <translation>Fout bij uitpakken firmware uit archief</translation>
202 </message>
203 <message>
204 <location filename="../base/bootloaderinstallbase.cpp" line="275"/>
205 <source>Could not find firmware in archive</source>
206 <translation>Firmware kon niet gevonden worden in archief</translation>
207 </message>
208 <message>
209 <location filename="../base/bootloaderinstallbase.cpp" line="159"/>
210 <source>Waiting for system to remount player</source>
211 <translation>Wachten op het systeem om de speler opnieuw te koppelen</translation>
212 </message>
213 <message>
214 <location filename="../base/bootloaderinstallbase.cpp" line="189"/>
215 <source>Player remounted</source>
216 <translation>Speler opnieuw gekoppeld</translation>
217 </message>
218 <message>
219 <location filename="../base/bootloaderinstallbase.cpp" line="194"/>
220 <source>Timeout on remount</source>
221 <translation>Time-out bij opnieuw koppelen</translation>
222 </message>
223 <message>
224 <location filename="../base/bootloaderinstallbase.cpp" line="149"/>
225 <source>Installation log created</source>
226 <translation>Installatie log aangemaakt</translation>
227 </message>
228</context>
229<context>
230 <name>BootloaderInstallChinaChip</name>
231 <message>
232 <location filename="../base/bootloaderinstallchinachip.cpp" line="33"/>
233 <source>Bootloader installation requires you to provide a firmware file of the original firmware (HXF file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
234 <translation>De Bootloader installatie vereist u om een firmware bestand van de Originele Firmware te voorzien (HXF bestand). U moet dit bestand zelf downloaden wegens juridische redenen. Wij verwijzen u door naar de &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;handleiding&lt;/a&gt; en de &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki pagina voor meer informatie hoe dit bestand te verkrijgen.&lt;br/&gt;Druk op Ok om verder te gaan en te bladeren op uw computer naar dit bestand.</translation>
235 </message>
236 <message>
237 <location filename="../base/bootloaderinstallchinachip.cpp" line="50"/>
238 <source>Downloading bootloader file</source>
239 <translation>Bezig met downloaden van Bootloader</translation>
240 </message>
241 <message>
242 <location filename="../base/bootloaderinstallchinachip.cpp" line="75"/>
243 <source>Could not open firmware file</source>
244 <translation>Firmware-bestand kon niet geopend worden</translation>
245 </message>
246 <message>
247 <location filename="../base/bootloaderinstallchinachip.cpp" line="78"/>
248 <source>Could not open bootloader file</source>
249 <translation>Bootloader-bestand kon niet geopend worden</translation>
250 </message>
251 <message>
252 <location filename="../base/bootloaderinstallchinachip.cpp" line="81"/>
253 <source>Could not allocate memory</source>
254 <translation>Geheugen kon niet toegewezen worden</translation>
255 </message>
256 <message>
257 <location filename="../base/bootloaderinstallchinachip.cpp" line="84"/>
258 <source>Could not load firmware file</source>
259 <translation>Firmware-bestand kon niet geladen worden</translation>
260 </message>
261 <message>
262 <location filename="../base/bootloaderinstallchinachip.cpp" line="87"/>
263 <source>File is not a valid ChinaChip firmware</source>
264 <translation>Bestand is geen geldige ChinaChip firmware</translation>
265 </message>
266 <message>
267 <location filename="../base/bootloaderinstallchinachip.cpp" line="90"/>
268 <source>Could not find ccpmp.bin in input file</source>
269 <translation>Kon ccpmp.bin niet vinden in bestand</translation>
270 </message>
271 <message>
272 <location filename="../base/bootloaderinstallchinachip.cpp" line="93"/>
273 <source>Could not open backup file for ccpmp.bin</source>
274 <translation>Kon backup-bestand voor ccpmp.bin niet openen</translation>
275 </message>
276 <message>
277 <location filename="../base/bootloaderinstallchinachip.cpp" line="96"/>
278 <source>Could not write backup file for ccpmp.bin</source>
279 <translation>Kon backup-bestand voor ccpmp.bin niet schrijven</translation>
280 </message>
281 <message>
282 <location filename="../base/bootloaderinstallchinachip.cpp" line="99"/>
283 <source>Could not load bootloader file</source>
284 <translation>Kon bootloader-bestand niet laden</translation>
285 </message>
286 <message>
287 <location filename="../base/bootloaderinstallchinachip.cpp" line="102"/>
288 <source>Could not get current time</source>
289 <translation>Kon huidige tijd niet opvragen</translation>
290 </message>
291 <message>
292 <location filename="../base/bootloaderinstallchinachip.cpp" line="105"/>
293 <source>Could not open output file</source>
294 <translation>Uitvoerbestand kon niet geopend worden</translation>
295 </message>
296 <message>
297 <location filename="../base/bootloaderinstallchinachip.cpp" line="108"/>
298 <source>Could not write output file</source>
299 <translation>Uitvoerbestand kon niet geschreven worden</translation>
300 </message>
301 <message>
302 <location filename="../base/bootloaderinstallchinachip.cpp" line="111"/>
303 <source>Unexpected error from chinachippatcher</source>
304 <translation>Onverwachte fout van chinachippatcher</translation>
305 </message>
306</context>
307<context>
308 <name>BootloaderInstallFile</name>
309 <message>
310 <location filename="../base/bootloaderinstallfile.cpp" line="34"/>
311 <source>Downloading bootloader</source>
312 <translation>Bezig met downloaden van Bootloader</translation>
313 </message>
314 <message>
315 <location filename="../base/bootloaderinstallfile.cpp" line="43"/>
316 <source>Installing Rockbox bootloader</source>
317 <translation>Bezig met installeren van Rockbox bootloader</translation>
318 </message>
319 <message>
320 <location filename="../base/bootloaderinstallfile.cpp" line="75"/>
321 <source>Error accessing output folder</source>
322 <translation>Fout bij openen output map</translation>
323 </message>
324 <message>
325 <location filename="../base/bootloaderinstallfile.cpp" line="89"/>
326 <source>A firmware file is already present on player</source>
327 <translation>Een firmware-bestand is al aanwezig op de speler</translation>
328 </message>
329 <message>
330 <location filename="../base/bootloaderinstallfile.cpp" line="94"/>
331 <source>Bootloader successful installed</source>
332 <translation>Bootloader succesvol geïnstalleerd</translation>
333 </message>
334 <message>
335 <location filename="../base/bootloaderinstallfile.cpp" line="97"/>
336 <source>Copying modified firmware file failed</source>
337 <translation>Kopieren van aangepast firmware-bestand is mislukt</translation>
338 </message>
339 <message>
340 <location filename="../base/bootloaderinstallfile.cpp" line="111"/>
341 <source>Removing Rockbox bootloader</source>
342 <translation>Bezig met verwijderen van Rockbox bootloader</translation>
343 </message>
344 <message>
345 <location filename="../base/bootloaderinstallfile.cpp" line="115"/>
346 <source>No original firmware file found.</source>
347 <translation>Geen Originele Firmware gevonden.</translation>
348 </message>
349 <message>
350 <location filename="../base/bootloaderinstallfile.cpp" line="121"/>
351 <source>Can&apos;t remove Rockbox bootloader file.</source>
352 <translation>Kan de Rockbox bootloader niet verwijderen.</translation>
353 </message>
354 <message>
355 <location filename="../base/bootloaderinstallfile.cpp" line="126"/>
356 <source>Can&apos;t restore bootloader file.</source>
357 <translation>Kan de bootloader niet terugplaatsen.</translation>
358 </message>
359 <message>
360 <location filename="../base/bootloaderinstallfile.cpp" line="130"/>
361 <source>Original bootloader restored successfully.</source>
362 <translation>Originele Bootloader succesvol teruggeplaatst.</translation>
363 </message>
364</context>
365<context>
366 <name>BootloaderInstallHex</name>
367 <message>
368 <location filename="../base/bootloaderinstallhex.cpp" line="50"/>
369 <source>Bootloader installation requires you to provide a firmware file of the original firmware (hex file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
370 <translation>De Bootloader installatie vereist een firmware bestand van de Originele Firmware (hex bestand). U moet dit bestand zelf downloaden om legale redenen. Gelieve in de &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;handleiding&lt;/a&gt; en de &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki pagina te kijken hoe u dit bestand moet verkrijgen.&lt;br/&gt;Druk op Ok om verder te gaan en te bladeren naar het firmware bestand.</translation>
371 </message>
372 <message>
373 <location filename="../base/bootloaderinstallhex.cpp" line="69"/>
374 <source>checking MD5 hash of input file ...</source>
375 <translation>bezig met controleren van MD5 hash op input bestand ...</translation>
376 </message>
377 <message>
378 <location filename="../base/bootloaderinstallhex.cpp" line="80"/>
379 <source>Could not verify original firmware file</source>
380 <translation>Kon Originele Firmware niet verifiëren</translation>
381 </message>
382 <message>
383 <location filename="../base/bootloaderinstallhex.cpp" line="95"/>
384 <source>Firmware file not recognized.</source>
385 <translation>Firmware bestand niet herkend.</translation>
386 </message>
387 <message>
388 <location filename="../base/bootloaderinstallhex.cpp" line="99"/>
389 <source>MD5 hash ok</source>
390 <translation>MD5 hash ok</translation>
391 </message>
392 <message>
393 <location filename="../base/bootloaderinstallhex.cpp" line="106"/>
394 <source>Firmware file doesn&apos;t match selected player.</source>
395 <translation>Firmware bestand past niet op de geselecteerd speler.</translation>
396 </message>
397 <message>
398 <location filename="../base/bootloaderinstallhex.cpp" line="111"/>
399 <source>Descrambling file</source>
400 <translation>Bezig met decoderen van bestand</translation>
401 </message>
402 <message>
403 <location filename="../base/bootloaderinstallhex.cpp" line="119"/>
404 <source>Error in descramble: %1</source>
405 <translation>Fout tijdens decoderen: %1</translation>
406 </message>
407 <message>
408 <location filename="../base/bootloaderinstallhex.cpp" line="124"/>
409 <source>Downloading bootloader file</source>
410 <translation>Bezig met downloaden van Bootloader</translation>
411 </message>
412 <message>
413 <location filename="../base/bootloaderinstallhex.cpp" line="134"/>
414 <source>Adding bootloader to firmware file</source>
415 <translation>Bezig met toevoegen van Bootloader aan Firmware</translation>
416 </message>
417 <message>
418 <location filename="../base/bootloaderinstallhex.cpp" line="172"/>
419 <source>could not open input file</source>
420 <translation>kon input bestand niet openen</translation>
421 </message>
422 <message>
423 <location filename="../base/bootloaderinstallhex.cpp" line="173"/>
424 <source>reading header failed</source>
425 <translation>lezen van hoofding mislukt</translation>
426 </message>
427 <message>
428 <location filename="../base/bootloaderinstallhex.cpp" line="174"/>
429 <source>reading firmware failed</source>
430 <translation>lezen van firmware mislukt</translation>
431 </message>
432 <message>
433 <location filename="../base/bootloaderinstallhex.cpp" line="175"/>
434 <source>can&apos;t open bootloader file</source>
435 <translation>kan bootloader bestand niet openen</translation>
436 </message>
437 <message>
438 <location filename="../base/bootloaderinstallhex.cpp" line="176"/>
439 <source>reading bootloader file failed</source>
440 <translation>lezen van bootloader bestand mislukt</translation>
441 </message>
442 <message>
443 <location filename="../base/bootloaderinstallhex.cpp" line="177"/>
444 <source>can&apos;t open output file</source>
445 <translation>kan output bestand niet openen</translation>
446 </message>
447 <message>
448 <location filename="../base/bootloaderinstallhex.cpp" line="178"/>
449 <source>writing output file failed</source>
450 <translation>schrijving van output bestand mislukt</translation>
451 </message>
452 <message>
453 <location filename="../base/bootloaderinstallhex.cpp" line="180"/>
454 <source>Error in patching: %1</source>
455 <translation>Fout in patchen: %1</translation>
456 </message>
457 <message>
458 <location filename="../base/bootloaderinstallhex.cpp" line="191"/>
459 <source>Error in scramble: %1</source>
460 <translation>Fout in coderen: %1</translation>
461 </message>
462 <message>
463 <location filename="../base/bootloaderinstallhex.cpp" line="206"/>
464 <source>Checking modified firmware file</source>
465 <translation>Bezig met controleren van gemodificeerde Firmware</translation>
466 </message>
467 <message>
468 <location filename="../base/bootloaderinstallhex.cpp" line="208"/>
469 <source>Error: modified file checksum wrong</source>
470 <translation>Fout: gemodificeerde bestands checksum fout</translation>
471 </message>
472 <message>
473 <location filename="../base/bootloaderinstallhex.cpp" line="215"/>
474 <source>A firmware file is already present on player</source>
475 <translation>Een firmware-bestand is al aanwezig op de speler</translation>
476 </message>
477 <message>
478 <location filename="../base/bootloaderinstallhex.cpp" line="220"/>
479 <source>Success: modified firmware file created</source>
480 <translation>Succes: gemodificeerde Firmware aangemaakt</translation>
481 </message>
482 <message>
483 <location filename="../base/bootloaderinstallhex.cpp" line="223"/>
484 <source>Copying modified firmware file failed</source>
485 <translation>Kopieren van aangepast firmware-bestand is mislukt</translation>
486 </message>
487 <message>
488 <location filename="../base/bootloaderinstallhex.cpp" line="237"/>
489 <source>Uninstallation not possible, only installation info removed</source>
490 <translation>Deïnstallatie niet mogelijk, alleen installatie info verwijderd</translation>
491 </message>
492 <message>
493 <location filename="../base/bootloaderinstallhex.cpp" line="258"/>
494 <source>Can&apos;t open input file</source>
495 <translation>Kan input bestand niet openen</translation>
496 </message>
497 <message>
498 <location filename="../base/bootloaderinstallhex.cpp" line="259"/>
499 <source>Can&apos;t open output file</source>
500 <translation>Kan output bestand niet openen</translation>
501 </message>
502 <message>
503 <location filename="../base/bootloaderinstallhex.cpp" line="260"/>
504 <source>invalid file: header length wrong</source>
505 <translation>ongeldig bestand: hoofding lengte verkeerd</translation>
506 </message>
507 <message>
508 <location filename="../base/bootloaderinstallhex.cpp" line="261"/>
509 <source>invalid file: unrecognized header</source>
510 <translation>ongeldig bestand: niet herkende hoofding</translation>
511 </message>
512 <message>
513 <location filename="../base/bootloaderinstallhex.cpp" line="262"/>
514 <source>invalid file: &quot;length&quot; field wrong</source>
515 <translation>ongeldig bestand: &quot;length&quot; veld verkeerd</translation>
516 </message>
517 <message>
518 <location filename="../base/bootloaderinstallhex.cpp" line="263"/>
519 <source>invalid file: &quot;length2&quot; field wrong</source>
520 <translation>ongeldig bestand: &quot;length2&quot; veld verkeerd</translation>
521 </message>
522 <message>
523 <location filename="../base/bootloaderinstallhex.cpp" line="264"/>
524 <source>invalid file: internal checksum error</source>
525 <translation>ongeldig bestand: interne checksum fout</translation>
526 </message>
527 <message>
528 <location filename="../base/bootloaderinstallhex.cpp" line="265"/>
529 <source>invalid file: &quot;length3&quot; field wrong</source>
530 <translation>ongeldig bestand: &quot;length3&quot; veld verkeerd</translation>
531 </message>
532 <message>
533 <location filename="../base/bootloaderinstallhex.cpp" line="266"/>
534 <source>unknown</source>
535 <translation>onbekend</translation>
536 </message>
537</context>
538<context>
539 <name>BootloaderInstallImx</name>
540 <message>
541 <location filename="../base/bootloaderinstallimx.cpp" line="72"/>
542 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (firmware.sb file). This file will be patched with the Rockbox bootloader and installed to your player. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
543 <translation>Voor installatie van de bootloader is het nodig dat u een kopie van de originele Sandisk firmware (firmware.sb bestand) aanlevert. Dit bestand zal aangepast en dan geïnstalleerd worden op uw speler. U moet dit bestand zelf downloaden om juridische redenen. Ga naar &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; of kijk op de &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wikipagina hoe u dit bestand kan verkrijgen.&lt;br/&gt;Druk Ok om door te gaan en om op uw computer te bladeren naar het firmware bestand.</translation>
544 </message>
545 <message>
546 <location filename="../base/bootloaderinstallimx.cpp" line="94"/>
547 <source>Could not read original firmware file</source>
548 <translation>Kon origineel firmware-bestand niet lezen</translation>
549 </message>
550 <message>
551 <location filename="../base/bootloaderinstallimx.cpp" line="100"/>
552 <source>Downloading bootloader file</source>
553 <translation>Bezig met downloaden van Bootloader</translation>
554 </message>
555 <message>
556 <location filename="../base/bootloaderinstallimx.cpp" line="110"/>
557 <source>Patching file...</source>
558 <translation>Bezig met aanpassen bestand...</translation>
559 </message>
560 <message>
561 <location filename="../base/bootloaderinstallimx.cpp" line="137"/>
562 <source>Patching the original firmware failed</source>
563 <translation>Aanpassen van het originele firmware-bestand is mislukt</translation>
564 </message>
565 <message>
566 <location filename="../base/bootloaderinstallimx.cpp" line="143"/>
567 <source>Succesfully patched firmware file</source>
568 <translation>Firmware-bestand is met succes aangepast</translation>
569 </message>
570 <message>
571 <location filename="../base/bootloaderinstallimx.cpp" line="158"/>
572 <source>Bootloader successful installed</source>
573 <translation>Bootloader succesvol geïnstalleerd</translation>
574 </message>
575 <message>
576 <location filename="../base/bootloaderinstallimx.cpp" line="164"/>
577 <source>Patched bootloader could not be installed</source>
578 <translation>Aangepaste bootloader kon niet geïnstalleerd worden</translation>
579 </message>
580 <message>
581 <location filename="../base/bootloaderinstallimx.cpp" line="175"/>
582 <source>To uninstall, perform a normal upgrade with an unmodified original firmware.</source>
583 <translation>Voor deïnstallatie, voer een normale upgrade uit met een ongewijzigde originele firmware.</translation>
584 </message>
585</context>
586<context>
587 <name>BootloaderInstallIpod</name>
588 <message>
589 <location filename="../base/bootloaderinstallipod.cpp" line="49"/>
590 <source>Error: can&apos;t allocate buffer memory!</source>
591 <translation>Fout: kan geen buffer geheugen alloceren!</translation>
592 </message>
593 <message>
594 <location filename="../base/bootloaderinstallipod.cpp" line="80"/>
595 <source>Downloading bootloader file</source>
596 <translation>Bezig met downloaden van Bootloader</translation>
597 </message>
598 <message>
599 <location filename="../base/bootloaderinstallipod.cpp" line="64"/>
600 <location filename="../base/bootloaderinstallipod.cpp" line="151"/>
601 <source>Failed to read firmware directory</source>
602 <translation>Kon firmware map niet lezen</translation>
603 </message>
604 <message>
605 <location filename="../base/bootloaderinstallipod.cpp" line="69"/>
606 <location filename="../base/bootloaderinstallipod.cpp" line="156"/>
607 <source>Unknown version number in firmware (%1)</source>
608 <translation>Onbekend versie nummer in firmware (%1)</translation>
609 </message>
610 <message>
611 <location filename="../base/bootloaderinstallipod.cpp" line="75"/>
612 <source>Warning: This is a MacPod, Rockbox only runs on WinPods.
613See http://www.rockbox.org/wiki/IpodConversionToFAT32</source>
614 <translation>Dit is een MacPod, Rockbox draait alleen op WinPods.
615Zie http://www.rockbox.org/wiki/IpodConversionToFAT32</translation>
616 </message>
617 <message>
618 <location filename="../base/bootloaderinstallipod.cpp" line="94"/>
619 <location filename="../base/bootloaderinstallipod.cpp" line="163"/>
620 <source>Could not open Ipod in R/W mode</source>
621 <translation>Kon Ipod niet openen in R/W modus</translation>
622 </message>
623 <message>
624 <location filename="../base/bootloaderinstallipod.cpp" line="104"/>
625 <source>Successfull added bootloader</source>
626 <translation>Bootloader succesvol toegevoegd</translation>
627 </message>
628 <message>
629 <location filename="../base/bootloaderinstallipod.cpp" line="115"/>
630 <source>Failed to add bootloader</source>
631 <translation>Fout tijdens toevoegen Bootloader</translation>
632 </message>
633 <message>
634 <location filename="../base/bootloaderinstallipod.cpp" line="127"/>
635 <source>Bootloader Installation complete.</source>
636 <translation>Installatie van bootloader voltooid.</translation>
637 </message>
638 <message>
639 <location filename="../base/bootloaderinstallipod.cpp" line="132"/>
640 <source>Writing log aborted</source>
641 <translation>Schrijven log afgebroken</translation>
642 </message>
643 <message>
644 <location filename="../base/bootloaderinstallipod.cpp" line="169"/>
645 <source>No bootloader detected.</source>
646 <translation>Geen Bootloader herkend.</translation>
647 </message>
648 <message>
649 <location filename="../base/bootloaderinstallipod.cpp" line="175"/>
650 <source>Successfully removed bootloader</source>
651 <translation>Bootloader succesvol verwijderd</translation>
652 </message>
653 <message>
654 <location filename="../base/bootloaderinstallipod.cpp" line="182"/>
655 <source>Removing bootloader failed.</source>
656 <translation>Verwijderen van Bootloader faalde.</translation>
657 </message>
658 <message>
659 <location filename="../base/bootloaderinstallipod.cpp" line="228"/>
660 <source>Error: could not retrieve device name</source>
661 <translation>Fout: kon apparaatnaam niet ophalen</translation>
662 </message>
663 <message>
664 <location filename="../base/bootloaderinstallipod.cpp" line="244"/>
665 <source>Error: no mountpoint specified!</source>
666 <translation>Fout: geen koppelpunt aangegeven!</translation>
667 </message>
668 <message>
669 <location filename="../base/bootloaderinstallipod.cpp" line="249"/>
670 <source>Could not open Ipod: permission denied</source>
671 <translation>Kon Ipod niet openen: toestemming geweigerd</translation>
672 </message>
673 <message>
674 <location filename="../base/bootloaderinstallipod.cpp" line="253"/>
675 <source>Could not open Ipod</source>
676 <translation>Kon Ipod niet openen</translation>
677 </message>
678 <message>
679 <location filename="../base/bootloaderinstallipod.cpp" line="258"/>
680 <source>Error reading partition table - possibly not an Ipod</source>
681 <translation>Fout tijdens lezen van de partitie tabel - mogelijks geen Ipod</translation>
682 </message>
683 <message>
684 <location filename="../base/bootloaderinstallipod.cpp" line="264"/>
685 <source>No firmware partition on disk</source>
686 <translation>Geen Firmware partitie op de schijf</translation>
687 </message>
688 <message>
689 <location filename="../base/bootloaderinstallipod.cpp" line="90"/>
690 <source>Installing Rockbox bootloader</source>
691 <translation>Bezig met installeren van Rockbox bootloader</translation>
692 </message>
693 <message>
694 <location filename="../base/bootloaderinstallipod.cpp" line="142"/>
695 <source>Uninstalling bootloader</source>
696 <translation>Bezig met desinstalleren van bootloader</translation>
697 </message>
698</context>
699<context>
700 <name>BootloaderInstallMi4</name>
701 <message>
702 <location filename="../base/bootloaderinstallmi4.cpp" line="34"/>
703 <source>Downloading bootloader</source>
704 <translation>Bezig met downloaden van Bootloader</translation>
705 </message>
706 <message>
707 <location filename="../base/bootloaderinstallmi4.cpp" line="43"/>
708 <source>Installing Rockbox bootloader</source>
709 <translation>Bezig met installeren van Rockbox bootloader</translation>
710 </message>
711 <message>
712 <location filename="../base/bootloaderinstallmi4.cpp" line="66"/>
713 <source>A firmware file is already present on player</source>
714 <translation>Een firmware-bestand is al aanwezig op de speler</translation>
715 </message>
716 <message>
717 <location filename="../base/bootloaderinstallmi4.cpp" line="71"/>
718 <location filename="../base/bootloaderinstallmi4.cpp" line="79"/>
719 <source>Bootloader successful installed</source>
720 <translation>Bootloader succesvol geïnstalleerd</translation>
721 </message>
722 <message>
723 <location filename="../base/bootloaderinstallmi4.cpp" line="74"/>
724 <source>Copying modified firmware file failed</source>
725 <translation>Kopieren van aangepast firmware-bestand is mislukt</translation>
726 </message>
727 <message>
728 <location filename="../base/bootloaderinstallmi4.cpp" line="91"/>
729 <source>Checking for Rockbox bootloader</source>
730 <translation>Bezig met controleren op Rockbox Bootloader</translation>
731 </message>
732 <message>
733 <location filename="../base/bootloaderinstallmi4.cpp" line="93"/>
734 <source>No Rockbox bootloader found</source>
735 <translation>Geen Rockbox Bootloader gevonden</translation>
736 </message>
737 <message>
738 <location filename="../base/bootloaderinstallmi4.cpp" line="98"/>
739 <source>Checking for original firmware file</source>
740 <translation>Bezig met controleren op Originele Firmware</translation>
741 </message>
742 <message>
743 <location filename="../base/bootloaderinstallmi4.cpp" line="103"/>
744 <source>Error finding original firmware file</source>
745 <translation>Fout bij vinden van Originele Firmware</translation>
746 </message>
747 <message>
748 <location filename="../base/bootloaderinstallmi4.cpp" line="113"/>
749 <source>Rockbox bootloader successful removed</source>
750 <translation>Rockbox Bootloader is succesvol verwijderd</translation>
751 </message>
752</context>
753<context>
754 <name>BootloaderInstallMpio</name>
755 <message>
756 <location filename="../base/bootloaderinstallmpio.cpp" line="34"/>
757 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
758 <translation>Voor installatie van de bootloader is het nodig dat u een kopie van de originele firmware (bin bestand) aanlevert. Dit bestand zal aangepast worden en dan geïnstalleerd op uw speler, samen met de rockbox bootloader. U moet dit bestand zelf downloaden om juridische redenen. Kijk op &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; of op &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; en de &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wikipagina hoe u dit bestand kan verkrijgen.&lt;br/&gt;Druk Ok om door te gaan en om op uw computer te bladeren naar het firmware bestand.</translation>
759 </message>
760 <message>
761 <location filename="../base/bootloaderinstallmpio.cpp" line="53"/>
762 <source>Downloading bootloader file</source>
763 <translation>Bezig met downloaden van Bootloader</translation>
764 </message>
765 <message>
766 <location filename="../base/bootloaderinstallmpio.cpp" line="80"/>
767 <source>Could not open the original firmware.</source>
768 <translation>Kon originele firmware niet openen.</translation>
769 </message>
770 <message>
771 <location filename="../base/bootloaderinstallmpio.cpp" line="83"/>
772 <source>Could not read the original firmware.</source>
773 <translation>Kon originele firmware niet lezen.</translation>
774 </message>
775 <message>
776 <location filename="../base/bootloaderinstallmpio.cpp" line="86"/>
777 <source>Loaded firmware file does not look like MPIO original firmware file.</source>
778 <translation>De geladen firmware lijkt niet op een MPIO origineel firmware-bestand.</translation>
779 </message>
780 <message>
781 <location filename="../base/bootloaderinstallmpio.cpp" line="101"/>
782 <source>Could not open output file.</source>
783 <translation>Kon uitvoerbestand niet openen.</translation>
784 </message>
785 <message>
786 <location filename="../base/bootloaderinstallmpio.cpp" line="104"/>
787 <source>Could not write output file.</source>
788 <translation>Kon niet schrijven naar uitvoerbestand.</translation>
789 </message>
790 <message>
791 <location filename="../base/bootloaderinstallmpio.cpp" line="107"/>
792 <source>Unknown error number: %1</source>
793 <translation>Onbekende foutcode: %1</translation>
794 </message>
795 <message>
796 <location filename="../base/bootloaderinstallmpio.cpp" line="89"/>
797 <source>Could not open downloaded bootloader.</source>
798 <translation>Kon ge-downloade bootloader niet openen.</translation>
799 </message>
800 <message>
801 <location filename="../base/bootloaderinstallmpio.cpp" line="92"/>
802 <source>Place for bootloader in OF file not empty.</source>
803 <translation>Plek voor bootloader in de OF is niet leeg.</translation>
804 </message>
805 <message>
806 <location filename="../base/bootloaderinstallmpio.cpp" line="95"/>
807 <source>Could not read the downloaded bootloader.</source>
808 <translation>Kon ge-downloade bootloader niet lezen.</translation>
809 </message>
810 <message>
811 <location filename="../base/bootloaderinstallmpio.cpp" line="98"/>
812 <source>Bootloader checksum error.</source>
813 <translation>Controlesom van bootloader fout.</translation>
814 </message>
815 <message>
816 <location filename="../base/bootloaderinstallmpio.cpp" line="112"/>
817 <source>Patching original firmware failed: %1</source>
818 <translation>Aanpassen van originele firmware mislukt: %1</translation>
819 </message>
820 <message>
821 <location filename="../base/bootloaderinstallmpio.cpp" line="119"/>
822 <source>Success: modified firmware file created</source>
823 <translation>Succes: gemodificeerde Firmware aangemaakt</translation>
824 </message>
825 <message>
826 <location filename="../base/bootloaderinstallmpio.cpp" line="127"/>
827 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
828 <translation>Voer een normale upgrade met een originele firmware uit, om te deïnstalleren</translation>
829 </message>
830</context>
831<context>
832 <name>BootloaderInstallSansa</name>
833 <message>
834 <location filename="../base/bootloaderinstallsansa.cpp" line="50"/>
835 <source>Error: can&apos;t allocate buffer memory!</source>
836 <translation>Fout: kan geen buffer geheugen alloceren!</translation>
837 </message>
838 <message>
839 <location filename="../base/bootloaderinstallsansa.cpp" line="55"/>
840 <source>Searching for Sansa</source>
841 <translation>Bezig met zoeken naar Sansa</translation>
842 </message>
843 <message>
844 <location filename="../base/bootloaderinstallsansa.cpp" line="59"/>
845 <source>Permission for disc access denied!
846This is required to install the bootloader</source>
847 <translation>Machtigingen voor schijf toegang geweigerd!
848Dit is vereist om de Bootloader te installeren</translation>
849 </message>
850 <message>
851 <location filename="../base/bootloaderinstallsansa.cpp" line="66"/>
852 <source>No Sansa detected!</source>
853 <translation>Geen Sansa gevonden!</translation>
854 </message>
855 <message>
856 <location filename="../base/bootloaderinstallsansa.cpp" line="79"/>
857 <source>Downloading bootloader file</source>
858 <translation>Bezig met downloaden van Bootloader</translation>
859 </message>
860 <message>
861 <location filename="../base/bootloaderinstallsansa.cpp" line="71"/>
862 <location filename="../base/bootloaderinstallsansa.cpp" line="179"/>
863 <source>OLD ROCKBOX INSTALLATION DETECTED, ABORTING.
864You must reinstall the original Sansa firmware before running
865sansapatcher for the first time.
866See http://www.rockbox.org/wiki/SansaE200Install
867</source>
868 <translation>OUDE ROCKBOX INSTALLATIE GEVONDEN, AFBREKEN.
869U moet de Originele Sansa Firmware herinstalleren vooraleer sansapatcher
870voor de eerste keer op te starten.
871Zie http://www.rockbox.org/wiki/SansaE200Install</translation>
872 </message>
873 <message>
874 <location filename="../base/bootloaderinstallsansa.cpp" line="102"/>
875 <location filename="../base/bootloaderinstallsansa.cpp" line="189"/>
876 <source>Could not open Sansa in R/W mode</source>
877 <translation>Kon Sansa niet openen in R/W modus</translation>
878 </message>
879 <message>
880 <location filename="../base/bootloaderinstallsansa.cpp" line="129"/>
881 <source>Successfully installed bootloader</source>
882 <translation>Bootloader succesvol geïnstalleerd</translation>
883 </message>
884 <message>
885 <location filename="../base/bootloaderinstallsansa.cpp" line="140"/>
886 <source>Failed to install bootloader</source>
887 <translation>Fout tijdens installeren Bootloader</translation>
888 </message>
889 <message>
890 <location filename="../base/bootloaderinstallsansa.cpp" line="153"/>
891 <source>Bootloader Installation complete.</source>
892 <translation>Bootloader-installatie voltooid.</translation>
893 </message>
894 <message>
895 <location filename="../base/bootloaderinstallsansa.cpp" line="158"/>
896 <source>Writing log aborted</source>
897 <translation>Schrijven naar logbestand afgebroken</translation>
898 </message>
899 <message>
900 <location filename="../base/bootloaderinstallsansa.cpp" line="238"/>
901 <source>Error: could not retrieve device name</source>
902 <translation>Fout: kon apparaatnaam niet ophalen</translation>
903 </message>
904 <message>
905 <location filename="../base/bootloaderinstallsansa.cpp" line="254"/>
906 <source>Can&apos;t find Sansa</source>
907 <translation>Kan Sansa niet vinden</translation>
908 </message>
909 <message>
910 <location filename="../base/bootloaderinstallsansa.cpp" line="259"/>
911 <source>Could not open Sansa</source>
912 <translation>Kon Sansa niet openen</translation>
913 </message>
914 <message>
915 <location filename="../base/bootloaderinstallsansa.cpp" line="264"/>
916 <source>Could not read partition table</source>
917 <translation>Kon de partitie tabel niet lezen</translation>
918 </message>
919 <message>
920 <location filename="../base/bootloaderinstallsansa.cpp" line="271"/>
921 <source>Disk is not a Sansa (Error %1), aborting.</source>
922 <translation>Schijf is geen Sansa (Error: %1), afbreken.</translation>
923 </message>
924 <message>
925 <location filename="../base/bootloaderinstallsansa.cpp" line="195"/>
926 <source>Successfully removed bootloader</source>
927 <translation>Bootloader succesvol verwijderd</translation>
928 </message>
929 <message>
930 <location filename="../base/bootloaderinstallsansa.cpp" line="202"/>
931 <source>Removing bootloader failed.</source>
932 <translation>Verwijderen van Bootloader faalde.</translation>
933 </message>
934 <message>
935 <location filename="../base/bootloaderinstallsansa.cpp" line="94"/>
936 <source>Installing Rockbox bootloader</source>
937 <translation>Bezig met installeren van Rockbox bootloader</translation>
938 </message>
939 <message>
940 <location filename="../base/bootloaderinstallsansa.cpp" line="111"/>
941 <source>Checking downloaded bootloader</source>
942 <translation>Bezig met controleren van de gedownloade bootloader</translation>
943 </message>
944 <message>
945 <location filename="../base/bootloaderinstallsansa.cpp" line="119"/>
946 <source>Bootloader mismatch! Aborting.</source>
947 <translation>Verkeerde bootloader! Bezig met afbreken.</translation>
948 </message>
949 <message>
950 <location filename="../base/bootloaderinstallsansa.cpp" line="170"/>
951 <source>Uninstalling bootloader</source>
952 <translation>Bezig met desinstalleren van bootloader</translation>
953 </message>
954</context>
955<context>
956 <name>BootloaderInstallTcc</name>
957 <message>
958 <location filename="../base/bootloaderinstalltcc.cpp" line="33"/>
959 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wiki page on how to obtain the file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
960 <translation>Voor installatie van de bootloader is het nodig dat u een kopie van de originele firmware (bin bestand) aanlevert. U moet dit bestand zelf downloaden om juridische redenen. Kijk op &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; en de &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wikipagina hoe u dit bestand kan verkrijgen.&lt;br/&gt;Druk Ok om door te gaan en om op uw computer te bladeren naar het firmware bestand.</translation>
961 </message>
962 <message>
963 <location filename="../base/bootloaderinstalltcc.cpp" line="50"/>
964 <source>Downloading bootloader file</source>
965 <translation>Bezig met downloaden van Bootloader</translation>
966 </message>
967 <message>
968 <location filename="../base/bootloaderinstalltcc.cpp" line="82"/>
969 <location filename="../base/bootloaderinstalltcc.cpp" line="99"/>
970 <source>Could not load %1</source>
971 <translation>Kon %1 niet laden</translation>
972 </message>
973 <message>
974 <location filename="../base/bootloaderinstalltcc.cpp" line="90"/>
975 <source>Unknown OF file used: %1</source>
976 <translation>Onbekende OF gebruikt: %1</translation>
977 </message>
978 <message>
979 <location filename="../base/bootloaderinstalltcc.cpp" line="104"/>
980 <source>Patching Firmware...</source>
981 <translation>Bezig met patchen van firmware...</translation>
982 </message>
983 <message>
984 <location filename="../base/bootloaderinstalltcc.cpp" line="111"/>
985 <source>Could not patch firmware</source>
986 <translation>Kon firmware niet aanpassen</translation>
987 </message>
988 <message>
989 <location filename="../base/bootloaderinstalltcc.cpp" line="117"/>
990 <source>Could not open %1 for writing</source>
991 <translation>Kon %1 niet openen voor schrijven</translation>
992 </message>
993 <message>
994 <location filename="../base/bootloaderinstalltcc.cpp" line="126"/>
995 <source>Could not write firmware file</source>
996 <translation>Kon het firmware bestand niet beschrijven</translation>
997 </message>
998 <message>
999 <location filename="../base/bootloaderinstalltcc.cpp" line="131"/>
1000 <source>Success: modified firmware file created</source>
1001 <translation>Succes: gemodificeerde Firmware aangemaakt</translation>
1002 </message>
1003 <message>
1004 <location filename="../base/bootloaderinstalltcc.cpp" line="151"/>
1005 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
1006 <translation>Voer een normale upgrade met een ongewijzigde firmware uit, om te deïnstalleren</translation>
1007 </message>
1008</context>
1009<context>
1010 <name>Changelog</name>
1011 <message>
1012 <location filename="../gui/changelogfrm.ui" line="17"/>
1013 <source>Changelog</source>
1014 <translation>Wijzigingsoverzicht</translation>
1015 </message>
1016 <message>
1017 <location filename="../gui/changelogfrm.ui" line="39"/>
1018 <source>Show on startup</source>
1019 <translation>Toon bij opstarten</translation>
1020 </message>
1021 <message>
1022 <location filename="../gui/changelogfrm.ui" line="46"/>
1023 <source>&amp;Ok</source>
1024 <translation>&amp;OK</translation>
1025 </message>
1026</context>
1027<context>
1028 <name>Config</name>
1029 <message>
1030 <location filename="../configure.cpp" line="340"/>
1031 <source>Showing disabled targets</source>
1032 <translation>Uitgeschakelde spelers tonen</translation>
1033 </message>
1034 <message>
1035 <location filename="../configure.cpp" line="341"/>
1036 <source>You just enabled showing targets that are marked disabled. Disabled targets are not recommended to end users. Please use this option only if you know what you are doing.</source>
1037 <translation>U heeft zojuist gekozen om spelers te tonen die als uitgeschakeld zijn gemarkeerd. Deze spelers worden niet aanbevolen voor eindgebruikers. Gebruik deze optie alleen als u weet waar u mee bezig bent.</translation>
1038 </message>
1039 <message>
1040 <location filename="../configure.cpp" line="529"/>
1041 <source>Proxy Detection</source>
1042 <translation>Proxy-detectie</translation>
1043 </message>
1044 <message>
1045 <location filename="../configure.cpp" line="530"/>
1046 <source>The System Proxy settings are invalid!
1047Rockbox Utility can&apos;t work with this proxy settings. Make sure the system proxy is set correctly. Note that &quot;proxy auto-config (PAC)&quot; scripts are not supported by Rockbox Utility. If your system uses this you need to use manual proxy settings.</source>
1048 <translation>The systeemproxy-detectie instellingen zijn ongeldig!
1049Rockbox Utility kan niet werken met deze instellingen. Stel de systeemproxy-instellingen juist in. Let op: &quot;proxy auto-config (PAC)&quot; scripts worden niet ondersteund door Rockbox Utility. Wanneer uw systeem dit gebruikt, moet u handmatige proxy-instellingen gebruiken.</translation>
1050 </message>
1051 <message>
1052 <location filename="../configure.cpp" line="643"/>
1053 <source>Set Cache Path</source>
1054 <translation>Stel cache-locatie in</translation>
1055 </message>
1056 <message>
1057 <location filename="../configure.cpp" line="788"/>
1058 <source>%1 &quot;MacPod&quot; found!
1059Rockbox needs a FAT formatted Ipod (so-called &quot;WinPod&quot;) to run. </source>
1060 <translation>%1 &quot;MacPod&quot; gevonden!
1061Rockbox heeft een FAT-geformattered Ipod (een zogenaamde &quot;WinPod&quot;) nodig om te kunnen draaien.</translation>
1062 </message>
1063 <message>
1064 <location filename="../configure.cpp" line="780"/>
1065 <source>%1 in MTP mode found!
1066You need to change your player to MSC mode for installation. </source>
1067 <translation>%1 in MTP modus gevonden!
1068U moet uw speler in MSC modus zetten voor installatie.</translation>
1069 </message>
1070 <message>
1071 <source>Until you change this installation will fail!</source>
1072 <translation type="obsolete">Installatie zal mislukken totdat u dit aanpast!</translation>
1073 </message>
1074 <message>
1075 <location filename="../configure.cpp" line="774"/>
1076 <source>Detected an unsupported player:
1077%1
1078Sorry, Rockbox doesn&apos;t run on your player.</source>
1079 <translation>Een niet-ondersteunde speler werd gedetecteerd:
1080%1
1081Sorry, Rockbox werkt niet op uw speler.</translation>
1082 </message>
1083 <message>
1084 <source>Fatal: player incompatible</source>
1085 <translation type="obsolete">Fataal: speler incompatibel</translation>
1086 </message>
1087 <message>
1088 <location filename="../configure.cpp" line="858"/>
1089 <source>Autodetection</source>
1090 <translation>Autoherkenning</translation>
1091 </message>
1092 <message>
1093 <location filename="../configure.cpp" line="859"/>
1094 <source>Could not detect a Mountpoint.
1095Select your Mountpoint manually.</source>
1096 <translation>Kon geen Mountpunt herkennen.
1097Gelieve uw Mountpunt manueel te selecteren.</translation>
1098 </message>
1099 <message>
1100 <location filename="../configure.cpp" line="764"/>
1101 <source>Could not detect a device.
1102Select your device and Mountpoint manually.</source>
1103 <translation>Kon geen apparaat herkennen.
1104Selecteer uw apparaat en Mountpunt manueel.</translation>
1105 </message>
1106 <message>
1107 <location filename="../configure.cpp" line="448"/>
1108 <location filename="../configure.cpp" line="914"/>
1109 <source>TTS error</source>
1110 <translation>TTS-fout</translation>
1111 </message>
1112 <message>
1113 <location filename="../configure.cpp" line="449"/>
1114 <location filename="../configure.cpp" line="915"/>
1115 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1116 <translation>Het initialiseren van de gekozen TTS is mislukt. Deze TTS kan niet gebruikt worden.</translation>
1117 </message>
1118 <message>
1119 <location filename="../configure.cpp" line="665"/>
1120 <source>%1 (%2 GiB of %3 GiB free)</source>
1121 <translation type="unfinished"></translation>
1122 </message>
1123 <message>
1124 <location filename="../configure.cpp" line="739"/>
1125 <source>Multiple devices have been detected. Please disconnect all players but one and try again.</source>
1126 <translation>Er zijn meerdere apparaten gedetecteerd. Ontkoppel alle spelers op een na en probeer opnieuw.</translation>
1127 </message>
1128 <message>
1129 <location filename="../configure.cpp" line="742"/>
1130 <source>Detected devices:</source>
1131 <translation>Gedetecteerde apparaten:</translation>
1132 </message>
1133 <message>
1134 <location filename="../configure.cpp" line="747"/>
1135 <source>(unknown)</source>
1136 <translation>(onbekend)</translation>
1137 </message>
1138 <message>
1139 <location filename="../configure.cpp" line="749"/>
1140 <source>%1 at %2</source>
1141 <translation type="unfinished"></translation>
1142 </message>
1143 <message>
1144 <location filename="../configure.cpp" line="755"/>
1145 <source>Note: detecting connected devices might be ambiguous. You might have less devices connected than listed. In this case it might not be possible to detect your player unambiguously.</source>
1146 <translation>Let op: het detecteren van aangesloten apparaten is niet altijd betrouwbaar. Er zijn mogelijk minder apparaten aangesloten dan aangegeven. In dat geval is het misschien niet mogelijk om uw speler betrouwbaar te detecteren.</translation>
1147 </message>
1148 <message>
1149 <location filename="../configure.cpp" line="759"/>
1150 <location filename="../configure.cpp" line="763"/>
1151 <location filename="../configure.cpp" line="805"/>
1152 <source>Device Detection</source>
1153 <translation>Apparaatdetectie</translation>
1154 </message>
1155 <message>
1156 <location filename="../configure.cpp" line="794"/>
1157 <source>The player contains an incompatible filesystem.
1158Make sure you selected the correct mountpoint and the player is set up to use a filesystem compatible with Rockbox.</source>
1159 <translation>De speler bevat een incompatibel bestandsysteem.
1160Controleer dat het juiste MountPoint geselecteerd is en dat de speler geconfigureerd is met een bestandsysteem dat compatibel is met Rockbox.</translation>
1161 </message>
1162 <message>
1163 <location filename="../configure.cpp" line="802"/>
1164 <source>An unknown error occured during player detection.</source>
1165 <translation>Een onbekende fout is opgetreden tijdens detectie van de speler.</translation>
1166 </message>
1167 <message>
1168 <location filename="../configure.cpp" line="869"/>
1169 <source>Really delete cache?</source>
1170 <translation>Wilt u zeker de cache ledigen?</translation>
1171 </message>
1172 <message>
1173 <location filename="../configure.cpp" line="870"/>
1174 <source>Do you really want to delete the cache? Make absolutely sure this setting is correct as it will remove &lt;b&gt;all&lt;/b&gt; files in this folder!</source>
1175 <translation>Wilt u zeker de cache ledigen? Wees absoluut zeker dat deze instelling correct is aangezien het &lt;b&gt;alle&lt;/b&gt; bestanden in deze map zal verwijderen!</translation>
1176 </message>
1177 <message>
1178 <location filename="../configure.cpp" line="878"/>
1179 <source>Path wrong!</source>
1180 <translation>Pad is verkeerd!</translation>
1181 </message>
1182 <message>
1183 <location filename="../configure.cpp" line="879"/>
1184 <source>The cache path is invalid. Aborting.</source>
1185 <translation>Het cache pad is ongeldig. Bezig met afbreken.</translation>
1186 </message>
1187 <message>
1188 <location filename="../configure.cpp" line="921"/>
1189 <source>TTS configuration invalid</source>
1190 <translation>TTS configuratie ongeldig</translation>
1191 </message>
1192 <message>
1193 <location filename="../configure.cpp" line="922"/>
1194 <source>TTS configuration invalid.
1195 Please configure TTS engine.</source>
1196 <translation>TTS configuratie ongeldig.
1197Gelieve de TTS engine te configureren.</translation>
1198 </message>
1199 <message>
1200 <location filename="../configure.cpp" line="927"/>
1201 <source>Could not start TTS engine.</source>
1202 <translation>Kon TTS niet starten.</translation>
1203 </message>
1204 <message>
1205 <location filename="../configure.cpp" line="946"/>
1206 <source>Could not voice test string.</source>
1207 <translation>Kon testzin niet uitspreken.</translation>
1208 </message>
1209 <message>
1210 <location filename="../configure.cpp" line="928"/>
1211 <source>Could not start TTS engine.
1212</source>
1213 <translation>Kon de TTS engine niet starten.
1214</translation>
1215 </message>
1216 <message>
1217 <location filename="../configure.cpp" line="929"/>
1218 <location filename="../configure.cpp" line="948"/>
1219 <source>
1220Please configure TTS engine.</source>
1221 <translation>
1222Gelieve de TTS engine te configureren.</translation>
1223 </message>
1224 <message>
1225 <location filename="../configure.cpp" line="943"/>
1226 <source>Rockbox Utility Voice Test</source>
1227 <translation>Rockbox Utility stemtest</translation>
1228 </message>
1229 <message>
1230 <location filename="../configure.cpp" line="947"/>
1231 <source>Could not voice test string.
1232</source>
1233 <translation>Kon de test zin niet inspreken.
1234</translation>
1235 </message>
1236 <message>
1237 <source>Fatal error</source>
1238 <translation type="obsolete">Fatale fout</translation>
1239 </message>
1240 <message>
1241 <location filename="../configure.cpp" line="322"/>
1242 <source>Current cache size is %L1 kiB.</source>
1243 <translation>Huidige cache grootte is %L1 kiB.</translation>
1244 </message>
1245 <message>
1246 <location filename="../configure.cpp" line="455"/>
1247 <location filename="../configure.cpp" line="485"/>
1248 <source>Configuration OK</source>
1249 <translation>Configuratie OK</translation>
1250 </message>
1251 <message>
1252 <location filename="../configure.cpp" line="461"/>
1253 <location filename="../configure.cpp" line="490"/>
1254 <source>Configuration INVALID</source>
1255 <translation>Configuratie ONGELDIG</translation>
1256 </message>
1257 <message>
1258 <location filename="../configure.cpp" line="130"/>
1259 <source>The following errors occurred:</source>
1260 <translation>De volgende fouten traden op:</translation>
1261 </message>
1262 <message>
1263 <location filename="../configure.cpp" line="175"/>
1264 <source>No mountpoint given</source>
1265 <translation>Geen aankoppel punt gegeven</translation>
1266 </message>
1267 <message>
1268 <location filename="../configure.cpp" line="179"/>
1269 <source>Mountpoint does not exist</source>
1270 <translation>Aankoppel punt bestaat niet</translation>
1271 </message>
1272 <message>
1273 <location filename="../configure.cpp" line="183"/>
1274 <source>Mountpoint is not a directory.</source>
1275 <translation>Aankoppel punt is geen map.</translation>
1276 </message>
1277 <message>
1278 <location filename="../configure.cpp" line="187"/>
1279 <source>Mountpoint is not writeable</source>
1280 <translation>Aankoppelpunt is niet beschrijfbaar</translation>
1281 </message>
1282 <message>
1283 <location filename="../configure.cpp" line="202"/>
1284 <source>No player selected</source>
1285 <translation>Geen speler geselecteerd</translation>
1286 </message>
1287 <message>
1288 <location filename="../configure.cpp" line="209"/>
1289 <source>Cache path not writeable. Leave path empty to default to systems temporary path.</source>
1290 <translation>Cache pad is niet schrijfbaar. Laat het pad leeg om het systeemsstandaard tijdelijke pad te gebruiken.</translation>
1291 </message>
1292 <message>
1293 <location filename="../configure.cpp" line="228"/>
1294 <source>You need to fix the above errors before you can continue.</source>
1295 <translation>U moet de bovenstaande fouten herstellen vooraleer verder te gaan.</translation>
1296 </message>
1297 <message>
1298 <location filename="../configure.cpp" line="231"/>
1299 <source>Configuration error</source>
1300 <translation>Configuratie fout</translation>
1301 </message>
1302</context>
1303<context>
1304 <name>ConfigForm</name>
1305 <message>
1306 <location filename="../configurefrm.ui" line="14"/>
1307 <source>Configuration</source>
1308 <translation>Configuratie</translation>
1309 </message>
1310 <message>
1311 <location filename="../configurefrm.ui" line="20"/>
1312 <source>Configure Rockbox Utility</source>
1313 <translation>Rockbox Utility configureren</translation>
1314 </message>
1315 <message>
1316 <location filename="../configurefrm.ui" line="35"/>
1317 <source>&amp;Device</source>
1318 <translation>&amp;Apparaat</translation>
1319 </message>
1320 <message>
1321 <location filename="../configurefrm.ui" line="41"/>
1322 <source>Select your device in the &amp;filesystem</source>
1323 <translation>Selecteer uw apparaat in het &amp;bestandssysteem</translation>
1324 </message>
1325 <message>
1326 <location filename="../configurefrm.ui" line="319"/>
1327 <source>&amp;Browse</source>
1328 <translation>&amp;Zoeken</translation>
1329 </message>
1330 <message>
1331 <location filename="../configurefrm.ui" line="72"/>
1332 <source>&amp;Select your audio player</source>
1333 <translation>&amp;Selecteer uw Audio Player</translation>
1334 </message>
1335 <message>
1336 <location filename="../configurefrm.ui" line="58"/>
1337 <source>&amp;Refresh</source>
1338 <translation>&amp;Vernieuwen</translation>
1339 </message>
1340 <message>
1341 <location filename="../configurefrm.ui" line="114"/>
1342 <source>&amp;Autodetect</source>
1343 <translation>&amp;Autoherkenning</translation>
1344 </message>
1345 <message>
1346 <location filename="../configurefrm.ui" line="136"/>
1347 <source>&amp;Proxy</source>
1348 <translation>&amp;Proxy</translation>
1349 </message>
1350 <message>
1351 <location filename="../configurefrm.ui" line="142"/>
1352 <source>&amp;No Proxy</source>
1353 <translation>&amp;Geen Proxy</translation>
1354 </message>
1355 <message>
1356 <location filename="../configurefrm.ui" line="152"/>
1357 <source>Use S&amp;ystem values</source>
1358 <translation>Gebruik s&amp;ysteem waarden</translation>
1359 </message>
1360 <message>
1361 <location filename="../configurefrm.ui" line="159"/>
1362 <source>&amp;Manual Proxy settings</source>
1363 <translation>&amp;Manuele proxy instellingen</translation>
1364 </message>
1365 <message>
1366 <location filename="../configurefrm.ui" line="166"/>
1367 <source>Proxy Values</source>
1368 <translation>Proxy instellingen</translation>
1369 </message>
1370 <message>
1371 <location filename="../configurefrm.ui" line="172"/>
1372 <source>&amp;Host:</source>
1373 <translation>&amp;Host:</translation>
1374 </message>
1375 <message>
1376 <location filename="../configurefrm.ui" line="182"/>
1377 <source>&amp;Port:</source>
1378 <translation>&amp;Poort:</translation>
1379 </message>
1380 <message>
1381 <location filename="../configurefrm.ui" line="199"/>
1382 <source>&amp;Username</source>
1383 <translation>&amp;Gebruikersnaam</translation>
1384 </message>
1385 <message>
1386 <location filename="../configurefrm.ui" line="209"/>
1387 <source>Pass&amp;word</source>
1388 <translation>Wacht&amp;woord</translation>
1389 </message>
1390 <message>
1391 <location filename="../configurefrm.ui" line="219"/>
1392 <source>Show</source>
1393 <translation>Toon</translation>
1394 </message>
1395 <message>
1396 <location filename="../configurefrm.ui" line="260"/>
1397 <source>&amp;Language</source>
1398 <translation>&amp;Taal</translation>
1399 </message>
1400 <message>
1401 <location filename="../configurefrm.ui" line="274"/>
1402 <source>Cac&amp;he</source>
1403 <translation>Cac&amp;he</translation>
1404 </message>
1405 <message>
1406 <location filename="../configurefrm.ui" line="277"/>
1407 <source>Download cache settings</source>
1408 <translation>Download cache instellingen</translation>
1409 </message>
1410 <message>
1411 <location filename="../configurefrm.ui" line="283"/>
1412 <source>Rockbox Utility uses a local download cache to save network traffic. You can change the path to the cache and use it as local repository by enabling Offline mode.</source>
1413 <translation>Rockbox Utility gebruikt een lokale download cache om het netwerkverkeer te beperken. U kan het pad naar deze cache veranderen en het gebruiken als een lokale opslagplaats door Offline modus in te schakelen.</translation>
1414 </message>
1415 <message>
1416 <location filename="../configurefrm.ui" line="293"/>
1417 <source>Current cache size is %1</source>
1418 <translation>Huidige cache grootte is %1</translation>
1419 </message>
1420 <message>
1421 <location filename="../configurefrm.ui" line="302"/>
1422 <source>P&amp;ath</source>
1423 <translation>&amp;Pad</translation>
1424 </message>
1425 <message>
1426 <location filename="../configurefrm.ui" line="312"/>
1427 <source>Entering an invalid folder will reset the path to the systems temporary path.</source>
1428 <translation>Een ongeldige map ingeven zal het pad naar de tijdelijke systeem bestanden resetten.</translation>
1429 </message>
1430 <message>
1431 <location filename="../configurefrm.ui" line="334"/>
1432 <source>Disable local &amp;download cache</source>
1433 <translation>Schakel lokale &amp;download cache uit</translation>
1434 </message>
1435 <message>
1436 <source>&lt;p&gt;This will try to use all information from the cache, even information about updates. Only use this option if you want to install without network connection. Note: you need to do the same install you want to perform later with network access first to download all required files to the cache.&lt;/p&gt;</source>
1437 <translation type="obsolete">&lt;p&gt;Dit zal proberen alle informatie van de cache te gebruiken, zelfs informatie in verband met updates.
1438Gebruik enkel deze optie als u wilt installeren zonder netwerk verbinding.
1439Pas op: u moet eerst deze installatie doen met een internet verbinding om ze later opnieuw te kunnen uitvoeren vanuit cache.&lt;/p&gt;</translation>
1440 </message>
1441 <message>
1442 <source>O&amp;ffline mode</source>
1443 <translation type="obsolete">O&amp;ffline modus</translation>
1444 </message>
1445 <message>
1446 <location filename="../configurefrm.ui" line="369"/>
1447 <source>Clean cache &amp;now</source>
1448 <translation>Ledig de cache &amp;nu</translation>
1449 </message>
1450 <message>
1451 <location filename="../configurefrm.ui" line="385"/>
1452 <source>&amp;TTS &amp;&amp; Encoder</source>
1453 <translation>&amp;TTS &amp;&amp; Encoder</translation>
1454 </message>
1455 <message>
1456 <location filename="../configurefrm.ui" line="391"/>
1457 <source>TTS Engine</source>
1458 <translation>TTS Engine</translation>
1459 </message>
1460 <message>
1461 <location filename="../configurefrm.ui" line="397"/>
1462 <source>&amp;Select TTS Engine</source>
1463 <translation>Ge&amp;selecteerde TTS Engine</translation>
1464 </message>
1465 <message>
1466 <location filename="../configurefrm.ui" line="445"/>
1467 <source>Test TTS</source>
1468 <translation>Test TTS</translation>
1469 </message>
1470 <message>
1471 <location filename="../configurefrm.ui" line="452"/>
1472 <source>&amp;Use string corrections for TTS</source>
1473 <translation>&amp;Gebruik correcties voor TTS</translation>
1474 </message>
1475 <message>
1476 <location filename="../configurefrm.ui" line="462"/>
1477 <source>Encoder Engine</source>
1478 <translation>Encoder Engine</translation>
1479 </message>
1480 <message>
1481 <location filename="../configurefrm.ui" line="536"/>
1482 <source>&amp;Ok</source>
1483 <translation>&amp;OK</translation>
1484 </message>
1485 <message>
1486 <location filename="../configurefrm.ui" line="547"/>
1487 <source>&amp;Cancel</source>
1488 <translation>&amp;Annuleren</translation>
1489 </message>
1490 <message>
1491 <location filename="../configurefrm.ui" line="410"/>
1492 <source>Configure TTS Engine</source>
1493 <translation>Configureer TTS Engine</translation>
1494 </message>
1495 <message>
1496 <location filename="../configurefrm.ui" line="95"/>
1497 <source>Show disabled targets</source>
1498 <translation>Toon &apos;uitgeschakelde&apos; spelers</translation>
1499 </message>
1500 <message>
1501 <location filename="../configurefrm.ui" line="417"/>
1502 <location filename="../configurefrm.ui" line="468"/>
1503 <source>Configuration invalid!</source>
1504 <translation>Configuratie ongeldig!</translation>
1505 </message>
1506 <message>
1507 <location filename="../configurefrm.ui" line="434"/>
1508 <source>Configure &amp;TTS</source>
1509 <translation>Configureer &amp;TTS</translation>
1510 </message>
1511 <message>
1512 <location filename="../configurefrm.ui" line="485"/>
1513 <source>Configure &amp;Enc</source>
1514 <translation>Configureer &amp;Enc</translation>
1515 </message>
1516 <message>
1517 <location filename="../configurefrm.ui" line="496"/>
1518 <source>encoder name</source>
1519 <translation>encoder naam</translation>
1520 </message>
1521</context>
1522<context>
1523 <name>Configure</name>
1524 <message>
1525 <location filename="../configure.cpp" line="589"/>
1526 <source>English</source>
1527 <comment>This is the localized language name, i.e. your language.</comment>
1528 <translation>Nederlands</translation>
1529 </message>
1530</context>
1531<context>
1532 <name>CreateVoiceFrm</name>
1533 <message>
1534 <location filename="../createvoicefrm.ui" line="17"/>
1535 <source>Create Voice File</source>
1536 <translation>Creëer een Voice bestand</translation>
1537 </message>
1538 <message>
1539 <location filename="../createvoicefrm.ui" line="42"/>
1540 <source>Select the Language you want to generate a voicefile for:</source>
1541 <translation>Selecteer de taal waarvan u een voicebestand wilt maken:</translation>
1542 </message>
1543 <message>
1544 <location filename="../createvoicefrm.ui" line="55"/>
1545 <source>TTS:</source>
1546 <translation>TTS:</translation>
1547 </message>
1548 <message>
1549 <location filename="../createvoicefrm.ui" line="101"/>
1550 <source>Silence threshold</source>
1551 <translation>Stiltedrempel</translation>
1552 </message>
1553 <message>
1554 <location filename="../createvoicefrm.ui" line="163"/>
1555 <source>Language</source>
1556 <translation>Taal</translation>
1557 </message>
1558 <message>
1559 <location filename="../createvoicefrm.ui" line="49"/>
1560 <source>Generation settings</source>
1561 <translation>Generatie instellingen</translation>
1562 </message>
1563 <message>
1564 <location filename="../createvoicefrm.ui" line="68"/>
1565 <source>Change</source>
1566 <translation>Veranderen</translation>
1567 </message>
1568 <message>
1569 <location filename="../createvoicefrm.ui" line="139"/>
1570 <source>&amp;Install</source>
1571 <translation>&amp;Installeer</translation>
1572 </message>
1573 <message>
1574 <location filename="../createvoicefrm.ui" line="150"/>
1575 <source>&amp;Cancel</source>
1576 <translation>&amp;Annuleren</translation>
1577 </message>
1578 <message>
1579 <location filename="../createvoicefrm.ui" line="88"/>
1580 <source>Wavtrim Threshold</source>
1581 <translation>Wavtrim drempel</translation>
1582 </message>
1583</context>
1584<context>
1585 <name>CreateVoiceWindow</name>
1586 <message>
1587 <location filename="../createvoicewindow.cpp" line="100"/>
1588 <source>TTS error</source>
1589 <translation>TTS-fout</translation>
1590 </message>
1591 <message>
1592 <location filename="../createvoicewindow.cpp" line="101"/>
1593 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1594 <translation>Het initialiseren van de gekozen TTS is mislukt. Deze TTS kan niet gebruikt worden.</translation>
1595 </message>
1596 <message>
1597 <location filename="../createvoicewindow.cpp" line="105"/>
1598 <location filename="../createvoicewindow.cpp" line="108"/>
1599 <source>Engine: &lt;b&gt;%1&lt;/b&gt;</source>
1600 <translation>Engine: &lt;b&gt;%1&lt;/b&gt;</translation>
1601 </message>
1602</context>
1603<context>
1604 <name>EncTtsCfgGui</name>
1605 <message>
1606 <location filename="../encttscfggui.cpp" line="45"/>
1607 <source>Waiting for engine...</source>
1608 <translation>Bezig met wachten op de engine...</translation>
1609 </message>
1610 <message>
1611 <location filename="../encttscfggui.cpp" line="95"/>
1612 <source>Ok</source>
1613 <translation>Ok</translation>
1614 </message>
1615 <message>
1616 <location filename="../encttscfggui.cpp" line="98"/>
1617 <source>Cancel</source>
1618 <translation>Annuleren</translation>
1619 </message>
1620 <message>
1621 <location filename="../encttscfggui.cpp" line="197"/>
1622 <source>Browse</source>
1623 <translation>Bladeren</translation>
1624 </message>
1625 <message>
1626 <location filename="../encttscfggui.cpp" line="205"/>
1627 <source>Refresh</source>
1628 <translation>Vernieuwen</translation>
1629 </message>
1630 <message>
1631 <location filename="../encttscfggui.cpp" line="377"/>
1632 <source>Select executable</source>
1633 <translation>Selecteer programma</translation>
1634 </message>
1635</context>
1636<context>
1637 <name>EncoderExe</name>
1638 <message>
1639 <location filename="../base/encoderexe.cpp" line="41"/>
1640 <source>Path to Encoder:</source>
1641 <translation>Pad naar encoder:</translation>
1642 </message>
1643 <message>
1644 <location filename="../base/encoderexe.cpp" line="43"/>
1645 <source>Encoder options:</source>
1646 <translation>Encoder opties:</translation>
1647 </message>
1648</context>
1649<context>
1650 <name>EncoderLame</name>
1651 <message>
1652 <location filename="../base/encoderlame.cpp" line="73"/>
1653 <location filename="../base/encoderlame.cpp" line="83"/>
1654 <source>LAME</source>
1655 <translation>LAME</translation>
1656 </message>
1657 <message>
1658 <location filename="../base/encoderlame.cpp" line="75"/>
1659 <source>Volume</source>
1660 <translation>Volume</translation>
1661 </message>
1662 <message>
1663 <location filename="../base/encoderlame.cpp" line="79"/>
1664 <source>Quality</source>
1665 <translation>Kwaliteit</translation>
1666 </message>
1667 <message>
1668 <location filename="../base/encoderlame.cpp" line="83"/>
1669 <source>Could not find libmp3lame!</source>
1670 <translation>libmp3lame kon niet gevonden worden!</translation>
1671 </message>
1672</context>
1673<context>
1674 <name>EncoderRbSpeex</name>
1675 <message>
1676 <location filename="../base/encoderrbspeex.cpp" line="34"/>
1677 <source>Volume:</source>
1678 <translation>Volume:</translation>
1679 </message>
1680 <message>
1681 <location filename="../base/encoderrbspeex.cpp" line="36"/>
1682 <source>Quality:</source>
1683 <translation>Kwaliteit:</translation>
1684 </message>
1685 <message>
1686 <location filename="../base/encoderrbspeex.cpp" line="38"/>
1687 <source>Complexity:</source>
1688 <translation>Complexiteit:</translation>
1689 </message>
1690 <message>
1691 <location filename="../base/encoderrbspeex.cpp" line="40"/>
1692 <source>Use Narrowband:</source>
1693 <translation>Gebruik smalband:</translation>
1694 </message>
1695</context>
1696<context>
1697 <name>InfoWidget</name>
1698 <message>
1699 <location filename="../gui/infowidget.cpp" line="30"/>
1700 <location filename="../gui/infowidget.cpp" line="107"/>
1701 <source>File</source>
1702 <translation>Bestand</translation>
1703 </message>
1704 <message>
1705 <location filename="../gui/infowidget.cpp" line="30"/>
1706 <location filename="../gui/infowidget.cpp" line="107"/>
1707 <source>Version</source>
1708 <translation>Versie</translation>
1709 </message>
1710</context>
1711<context>
1712 <name>InfoWidgetFrm</name>
1713 <message>
1714 <location filename="../gui/infowidgetfrm.ui" line="14"/>
1715 <source>Info</source>
1716 <translation>Info</translation>
1717 </message>
1718 <message>
1719 <location filename="../gui/infowidgetfrm.ui" line="20"/>
1720 <source>Currently installed packages.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; if you manually installed packages this might not be correct!</source>
1721 <translation>Huidige geïnstalleerde pakketten.&lt;br/&gt;&lt;b&gt;Pas op:&lt;/b&gt; als u handmatig pakketten installeert kan dit incorrect zijn!</translation>
1722 </message>
1723 <message>
1724 <location filename="../gui/infowidgetfrm.ui" line="34"/>
1725 <source>Package</source>
1726 <translation>Package</translation>
1727 </message>
1728</context>
1729<context>
1730 <name>InstallTalkFrm</name>
1731 <message>
1732 <location filename="../installtalkfrm.ui" line="17"/>
1733 <source>Install Talk Files</source>
1734 <translation>Installeer Talk bestanden</translation>
1735 </message>
1736 <message>
1737 <location filename="../installtalkfrm.ui" line="78"/>
1738 <source>TTS profile:</source>
1739 <translation>TTS profiel:</translation>
1740 </message>
1741 <message>
1742 <location filename="../installtalkfrm.ui" line="36"/>
1743 <source>Generation options</source>
1744 <translation>Generatie instellingen</translation>
1745 </message>
1746 <message>
1747 <location filename="../installtalkfrm.ui" line="42"/>
1748 <source>Strip Extensions</source>
1749 <translation>Extensies weghalen</translation>
1750 </message>
1751 <message>
1752 <location filename="../installtalkfrm.ui" line="154"/>
1753 <source>&amp;Cancel</source>
1754 <translation>&amp;Annuleren</translation>
1755 </message>
1756 <message>
1757 <location filename="../installtalkfrm.ui" line="143"/>
1758 <source>&amp;Install</source>
1759 <translation>&amp;Installeren</translation>
1760 </message>
1761 <message>
1762 <location filename="../installtalkfrm.ui" line="52"/>
1763 <source>Generate for files</source>
1764 <translation>Genereren voor bestanden</translation>
1765 </message>
1766 <message>
1767 <location filename="../installtalkfrm.ui" line="85"/>
1768 <source>Generate for folders</source>
1769 <translation>Genereren voor folders</translation>
1770 </message>
1771 <message>
1772 <location filename="../installtalkfrm.ui" line="95"/>
1773 <source>Recurse into folders</source>
1774 <translation>Folders recursief doorlopen</translation>
1775 </message>
1776 <message>
1777 <location filename="../installtalkfrm.ui" line="111"/>
1778 <source>Change</source>
1779 <translation>Veranderen</translation>
1780 </message>
1781 <message>
1782 <location filename="../installtalkfrm.ui" line="118"/>
1783 <source>Ignore files</source>
1784 <translation>Negeer bestanden</translation>
1785 </message>
1786 <message>
1787 <location filename="../installtalkfrm.ui" line="128"/>
1788 <source>Skip existing</source>
1789 <translation>Bestaande overslaan</translation>
1790 </message>
1791 <message>
1792 <location filename="../installtalkfrm.ui" line="170"/>
1793 <source>Select folders for Talkfile generation (Ctrl for multiselect)</source>
1794 <translation>Selecteers folder voor Talkfile-generatie (Ctrl voor multi-select)</translation>
1795 </message>
1796</context>
1797<context>
1798 <name>InstallTalkWindow</name>
1799 <message>
1800 <source>&lt;b&gt;%1&lt;/b&gt;</source>
1801 <translation type="obsolete">&lt;b&gt;%1&lt;/b&gt;</translation>
1802 </message>
1803 <message>
1804 <location filename="../installtalkwindow.cpp" line="96"/>
1805 <source>Empty selection</source>
1806 <translation>Lege selectie</translation>
1807 </message>
1808 <message>
1809 <location filename="../installtalkwindow.cpp" line="97"/>
1810 <source>No files or folders selected. Please select files or folders first.</source>
1811 <translation>Geen bestanden of mappen geselecteerd. Kies bestanden of mappen.</translation>
1812 </message>
1813 <message>
1814 <location filename="../installtalkwindow.cpp" line="137"/>
1815 <source>TTS error</source>
1816 <translation>TTS-fout</translation>
1817 </message>
1818 <message>
1819 <location filename="../installtalkwindow.cpp" line="138"/>
1820 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1821 <translation>Het initialiseren van de gekozen TTS is mislukt. Deze TTS kan niet gebruikt worden.</translation>
1822 </message>
1823</context>
1824<context>
1825 <name>ManualWidget</name>
1826 <message>
1827 <location filename="../gui/manualwidget.cpp" line="44"/>
1828 <source>&lt;a href=&apos;%1&apos;&gt;PDF Manual&lt;/a&gt;</source>
1829 <translation>&lt;a href=&apos;%1&apos;&gt;PDF Handboek&lt;/a&gt;</translation>
1830 </message>
1831 <message>
1832 <location filename="../gui/manualwidget.cpp" line="46"/>
1833 <source>&lt;a href=&apos;%1&apos;&gt;HTML Manual (opens in browser)&lt;/a&gt;</source>
1834 <translation>&lt;a href=&apos;%1&apos;&gt;HTML Handboek (opent in een browser)&lt;/a&gt;</translation>
1835 </message>
1836 <message>
1837 <location filename="../gui/manualwidget.cpp" line="50"/>
1838 <source>Select a device for a link to the correct manual</source>
1839 <translation>Selecteer een apparaat voor een link naar het correcte handboek</translation>
1840 </message>
1841 <message>
1842 <location filename="../gui/manualwidget.cpp" line="51"/>
1843 <source>&lt;a href=&apos;%1&apos;&gt;Manual Overview&lt;/a&gt;</source>
1844 <translation>&lt;a href=&apos;%1&apos;&gt;Handboek overzicht&lt;/a&gt;</translation>
1845 </message>
1846 <message>
1847 <location filename="../gui/manualwidget.cpp" line="62"/>
1848 <source>Confirm download</source>
1849 <translation>Bevestig download</translation>
1850 </message>
1851 <message>
1852 <location filename="../gui/manualwidget.cpp" line="63"/>
1853 <source>Do you really want to download the manual? The manual will be saved to the root folder of your player.</source>
1854 <translation>Wilt u zeker het handboek downloaden? Dit handboek zal opgeslagen worden in de hoofdmap van uw speler.</translation>
1855 </message>
1856</context>
1857<context>
1858 <name>ManualWidgetFrm</name>
1859 <message>
1860 <location filename="../gui/manualwidgetfrm.ui" line="14"/>
1861 <source>Manual</source>
1862 <translation>Handleiding</translation>
1863 </message>
1864 <message>
1865 <location filename="../gui/manualwidgetfrm.ui" line="20"/>
1866 <source>Read the manual</source>
1867 <translation>Lees de handleiding</translation>
1868 </message>
1869 <message>
1870 <location filename="../gui/manualwidgetfrm.ui" line="26"/>
1871 <source>PDF manual</source>
1872 <translation>PDF handleiding</translation>
1873 </message>
1874 <message>
1875 <location filename="../gui/manualwidgetfrm.ui" line="39"/>
1876 <source>HTML manual</source>
1877 <translation>HTML handleiding</translation>
1878 </message>
1879 <message>
1880 <location filename="../gui/manualwidgetfrm.ui" line="55"/>
1881 <source>Download the manual</source>
1882 <translation>Download de handleiding</translation>
1883 </message>
1884 <message>
1885 <location filename="../gui/manualwidgetfrm.ui" line="63"/>
1886 <source>&amp;PDF version</source>
1887 <translation>&amp;PDF versie</translation>
1888 </message>
1889 <message>
1890 <location filename="../gui/manualwidgetfrm.ui" line="70"/>
1891 <source>&amp;HTML version (zip file)</source>
1892 <translation>&amp;HTML versie (zip bestand)</translation>
1893 </message>
1894 <message>
1895 <location filename="../gui/manualwidgetfrm.ui" line="92"/>
1896 <source>Down&amp;load</source>
1897 <translation>Down&amp;load</translation>
1898 </message>
1899</context>
1900<context>
1901 <name>MsPackUtil</name>
1902 <message>
1903 <location filename="../base/mspackutil.cpp" line="101"/>
1904 <source>Creating output path failed</source>
1905 <translation>Aanmaken uitvoerlokatie mislukt</translation>
1906 </message>
1907 <message>
1908 <location filename="../base/mspackutil.cpp" line="109"/>
1909 <source>Error during CAB operation</source>
1910 <translation>Fout tijdens CAB-bewerking</translation>
1911 </message>
1912</context>
1913<context>
1914 <name>PreviewFrm</name>
1915 <message>
1916 <location filename="../previewfrm.ui" line="16"/>
1917 <source>Preview</source>
1918 <translation>Voorbeeld</translation>
1919 </message>
1920</context>
1921<context>
1922 <name>ProgressLoggerFrm</name>
1923 <message>
1924 <location filename="../progressloggerfrm.ui" line="13"/>
1925 <location filename="../progressloggerfrm.ui" line="19"/>
1926 <source>Progress</source>
1927 <translation>Vooruitgang</translation>
1928 </message>
1929 <message>
1930 <location filename="../progressloggerfrm.ui" line="58"/>
1931 <source>Save Log</source>
1932 <translation>Log opslaan</translation>
1933 </message>
1934 <message>
1935 <location filename="../progressloggerfrm.ui" line="82"/>
1936 <source>&amp;Abort</source>
1937 <translation>&amp;Afbreken</translation>
1938 </message>
1939 <message>
1940 <location filename="../progressloggerfrm.ui" line="32"/>
1941 <source>progresswindow</source>
1942 <translation>Voortgangsvenster</translation>
1943 </message>
1944</context>
1945<context>
1946 <name>ProgressLoggerGui</name>
1947 <message>
1948 <location filename="../progressloggergui.cpp" line="122"/>
1949 <source>&amp;Ok</source>
1950 <translation>&amp;OK</translation>
1951 </message>
1952 <message>
1953 <location filename="../progressloggergui.cpp" line="146"/>
1954 <source>Save system trace log</source>
1955 <translation>Systeem trace log opslaan</translation>
1956 </message>
1957 <message>
1958 <location filename="../progressloggergui.cpp" line="104"/>
1959 <source>&amp;Abort</source>
1960 <translation>&amp;Afbreken</translation>
1961 </message>
1962</context>
1963<context>
1964 <name>QObject</name>
1965 <message>
1966 <location filename="../configure.cpp" line="625"/>
1967 <location filename="../main.cpp" line="83"/>
1968 <source>LTR</source>
1969 <extracomment>This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.
1970----------
1971This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.</extracomment>
1972 <translation>LTR</translation>
1973 </message>
1974 <message>
1975 <location filename="../base/system.cpp" line="385"/>
1976 <source>(unknown vendor name) </source>
1977 <translation>(onbekende fabrikantnaam)</translation>
1978 </message>
1979 <message>
1980 <location filename="../base/system.cpp" line="403"/>
1981 <source>(unknown product name)</source>
1982 <translation>(onbekende productnaam)</translation>
1983 </message>
1984 <message>
1985 <location filename="../base/bootloaderinstallhelper.cpp" line="80"/>
1986 <source>Bootloader installation is almost complete. Installation &lt;b&gt;requires&lt;/b&gt; you to perform the following steps manually:</source>
1987 <translation>Bootloader installatie is bijna voltooid. De installatie &lt;b&gt;vereist&lt;/b&gt; dat u de volgende stappen handmatig uitvoert:</translation>
1988 </message>
1989 <message>
1990 <location filename="../base/bootloaderinstallhelper.cpp" line="86"/>
1991 <source>&lt;li&gt;Safely remove your player.&lt;/li&gt;</source>
1992 <translation>&lt;li&gt;Verwijder veilig uw speler.&lt;/li&gt;</translation>
1993 </message>
1994 <message>
1995 <location filename="../base/bootloaderinstallhelper.cpp" line="91"/>
1996 <source>&lt;li&gt;Reboot your player into the original firmware.&lt;/li&gt;&lt;li&gt;Perform a firmware upgrade using the update functionality of the original firmware. Please refer to your player&apos;s manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before starting the firmware update process.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1997 <translation>&lt;li&gt;Herstart uw speler en ga naar de originele firmware.&lt;/li&gt;&lt;li&gt;Voer een firmware-upgrade uit met de updatefunctionaliteit van de originele firmware. Kijk in de handleiding van uw speler voor details.&lt;br/&gt;&lt;b&gt;Belangrijk:&lt;/b&gt; De firmware-upgrade is een kritiek proces dat niet onderbroken mag worden.&lt;b&gt;Verzeker u ervan dat de speler is opgeladen voordat het firmware-upgrade proces wordt gestart.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Herstart uw speler nadat de firmware-upgrade is voltooid.&lt;/li&gt;</translation>
1998 </message>
1999 <message>
2000 <location filename="../base/bootloaderinstallhelper.cpp" line="102"/>
2001 <source>&lt;li&gt;Remove any previously inserted microSD card&lt;/li&gt;</source>
2002 <translation>&lt;li&gt;Verwijder eventuele ingestoken microSD kaart&lt;/li&gt;</translation>
2003 </message>
2004 <message>
2005 <location filename="../base/bootloaderinstallhelper.cpp" line="103"/>
2006 <source>&lt;li&gt;Disconnect your player. The player will reboot and perform an update of the original firmware. Please refer to your players manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before disconnecting the player.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
2007 <translation>&lt;li&gt;Koppel uw speler los. De speler zal opnieuw opstarten en een upgrade van de originele firmware uitvoeren. Kijk in de handleiding van uw speler voor details.&lt;br/&gt;&lt;b&gt;Belangrijk:&lt;/b&gt; De firmware-upgrade is een kritiek proces dat niet onderbroken mag worden. &lt;b&gt;Verzeker u ervan dat de speler is opgeladen voordat het firmware-upgrade proces wordt gestart.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Herstart uw speler nadat de firmware-upgrade is voltooid.&lt;/li&gt;</translation>
2008 </message>
2009 <message>
2010 <location filename="../base/bootloaderinstallhelper.cpp" line="114"/>
2011 <source>&lt;li&gt;Turn the player off&lt;/li&gt;&lt;li&gt;Insert the charger&lt;/li&gt;</source>
2012 <translation>&lt;li&gt;Zet de speler uit&lt;/li&gt;&lt;li&gt;Steek de oplader erin&lt;/li&gt;</translation>
2013 </message>
2014 <message>
2015 <location filename="../base/bootloaderinstallhelper.cpp" line="119"/>
2016 <source>&lt;li&gt;Unplug USB and power adaptors&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to turn the player off&lt;/li&gt;&lt;li&gt;Toggle the battery switch on the player&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to boot into Rockbox&lt;/li&gt;</source>
2017 <translation>&lt;li&gt;Ontkoppel USB en stroomadapters&lt;/li&gt;&lt;li&gt;Hou &lt;i&gt;Power&lt;/i&gt; ingedrukt om de speler uit te schakelen&lt;/li&gt;&lt;li&gt;Zet de batterij schakelaar uit en aan op de speler&lt;/li&gt;&lt;li&gt;Hou &lt;i&gt;Power&lt;/i&gt; ingedrukt om in Rockbox op te starten&lt;/li&gt;</translation>
2018 </message>
2019 <message>
2020 <location filename="../base/bootloaderinstallhelper.cpp" line="125"/>
2021 <source>&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You can safely install other parts first, but the above steps are &lt;b&gt;required&lt;/b&gt; to finish the installation!&lt;/p&gt;</source>
2022 <translation>&lt;p&gt;&lt;b&gt;Noot:&lt;/b&gt; U kan veilig andere delen eerst installeren, maar de hierboven vermelde stappen zijn &lt;b&gt;vereist&lt;/b&gt; om de installatie te voltooien!&lt;/p&gt;</translation>
2023 </message>
2024</context>
2025<context>
2026 <name>QuaZipFile</name>
2027 <message>
2028 <location filename="../quazip/quazipfile.cpp" line="141"/>
2029 <source>ZIP/UNZIP API error %1</source>
2030 <translation>ZIP/UNZIP API-fout %1</translation>
2031 </message>
2032</context>
2033<context>
2034 <name>RbUtilQt</name>
2035 <message>
2036 <location filename="../rbutilqt.cpp" line="224"/>
2037 <source>Downloading build information, please wait ...</source>
2038 <translation>Bezig met downloaden van build informatie, wachten aub...</translation>
2039 </message>
2040 <message>
2041 <location filename="../rbutilqt.cpp" line="235"/>
2042 <source>Can&apos;t get version information!</source>
2043 <translation>Kan versie-informatie niet verkrijgen!</translation>
2044 </message>
2045 <message>
2046 <location filename="../rbutilqt.cpp" line="249"/>
2047 <source>Download build information finished.</source>
2048 <translation>Downloaden van build informatie voltooid.</translation>
2049 </message>
2050 <message>
2051 <location filename="../rbutilqt.cpp" line="450"/>
2052 <source>Confirm Installation</source>
2053 <translation>Bevestig Installatie</translation>
2054 </message>
2055 <message>
2056 <location filename="../rbutilqt.cpp" line="582"/>
2057 <source>Mount point is wrong!</source>
2058 <translation>Mount punt is verkeerd!</translation>
2059 </message>
2060 <message>
2061 <location filename="../rbutilqt.cpp" line="430"/>
2062 <source>No Rockbox installation found</source>
2063 <translation>Geen rockbox installatie gevonden</translation>
2064 </message>
2065 <message>
2066 <location filename="../rbutilqt.cpp" line="431"/>
2067 <source>Could not determine the installed Rockbox version. Please install a Rockbox build before installing voice files.</source>
2068 <translation>Kon de versie van de Rockbox-installatie niet bepalen. Installeer eerst Rockbox voordat u Talk bestanden installeert.</translation>
2069 </message>
2070 <message>
2071 <location filename="../rbutilqt.cpp" line="451"/>
2072 <source>Do you really want to install the voice file?</source>
2073 <translation>Wilt u zeker de spraakbestanden?</translation>
2074 </message>
2075 <message>
2076 <location filename="../rbutilqt.cpp" line="439"/>
2077 <source>No voice file available</source>
2078 <translation>Geen spraakbestand beschikbaar</translation>
2079 </message>
2080 <message>
2081 <location filename="../rbutilqt.cpp" line="440"/>
2082 <source>The installed version of Rockbox is a development version. Pre-built voices are only available for release versions of Rockbox. Please generate a voice yourself using the &quot;Create voice file&quot; functionality.</source>
2083 <translation>De geïnstalleerde versie van Rockbox is een development-versie. Voorgenerereerde spraakbestanden zijn alleen beschikbaar voor release-versies van Rockbox. U kunt een spraakbestand genereren met de &quot;Creëer spraakbestanden&quot; functionaliteit.</translation>
2084 </message>
2085 <message>
2086 <location filename="../rbutilqt.cpp" line="512"/>
2087 <source>Confirm Uninstallation</source>
2088 <translation>Bevestig Deïnstallatie</translation>
2089 </message>
2090 <message>
2091 <location filename="../rbutilqt.cpp" line="513"/>
2092 <source>Do you really want to uninstall the Bootloader?</source>
2093 <translation>Wilt u zeker de Bootloader deïnstalleren?</translation>
2094 </message>
2095 <message>
2096 <location filename="../rbutilqt.cpp" line="528"/>
2097 <source>No uninstall method for this target known.</source>
2098 <translation>Geen deïnstallatiemethode voor de speler gevonden.</translation>
2099 </message>
2100 <message>
2101 <location filename="../rbutilqt.cpp" line="542"/>
2102 <source>Rockbox Utility can not uninstall the bootloader on this target. Try a normal firmware update to remove the booloader.</source>
2103 <translation>Rockbox Utility kon de bootloader van deze speler niet deïnstalleren. Probeer een normale firmware update om de bootloader te verwijderen.</translation>
2104 </message>
2105 <message>
2106 <location filename="../rbutilqt.cpp" line="550"/>
2107 <source>No Rockbox bootloader found.</source>
2108 <translation>Geen Rockbox bootloader gevonden.</translation>
2109 </message>
2110 <message>
2111 <location filename="../rbutilqt.cpp" line="568"/>
2112 <source>Confirm installation</source>
2113 <translation>Bevestig installatie</translation>
2114 </message>
2115 <message>
2116 <location filename="../rbutilqt.cpp" line="569"/>
2117 <source>Do you really want to install Rockbox Utility to your player? After installation you can run it from the players hard drive.</source>
2118 <translation>Wilt u zeker Rockbox Utility installeren op uw speler? Na installatie kan u het opstarten vanaf de harde schijf van uw speler.</translation>
2119 </message>
2120 <message>
2121 <location filename="../rbutilqt.cpp" line="578"/>
2122 <source>Installing Rockbox Utility</source>
2123 <translation>Bezig met installeren van Rockbox Utility</translation>
2124 </message>
2125 <message>
2126 <location filename="../rbutilqt.cpp" line="596"/>
2127 <source>Error installing Rockbox Utility</source>
2128 <translation>Fout tijdens installeren van Rockbox Utility</translation>
2129 </message>
2130 <message>
2131 <location filename="../rbutilqt.cpp" line="600"/>
2132 <source>Installing user configuration</source>
2133 <translation>Bezig met installeren van gebruikerconfiguratie</translation>
2134 </message>
2135 <message>
2136 <location filename="../rbutilqt.cpp" line="604"/>
2137 <source>Error installing user configuration</source>
2138 <translation>Fout tijdens installeren van gebruikersconfiguratie</translation>
2139 </message>
2140 <message>
2141 <location filename="../rbutilqt.cpp" line="608"/>
2142 <source>Successfully installed Rockbox Utility.</source>
2143 <translation>Rockbox Utility is succesvol geïnstalleerd.</translation>
2144 </message>
2145 <message>
2146 <location filename="../rbutilqt.cpp" line="664"/>
2147 <source>Checking for update ...</source>
2148 <translation>Controleren op een update...</translation>
2149 </message>
2150 <message>
2151 <location filename="../rbutilqt.cpp" line="729"/>
2152 <source>RockboxUtility Update available</source>
2153 <translation>Rockbox Utility update gevonden</translation>
2154 </message>
2155 <message>
2156 <location filename="../rbutilqt.cpp" line="730"/>
2157 <source>&lt;b&gt;New RockboxUtility Version available.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Download it from here: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</source>
2158 <translation>&lt;b&gt;Nieuwe versie Rockbox Utility beschikbaar.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Download het hier: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</translation>
2159 </message>
2160 <message>
2161 <location filename="../rbutilqt.cpp" line="733"/>
2162 <source>New version of Rockbox Utility available.</source>
2163 <translation>Nieuwe versie van Rockbox Utility beschikbaar.</translation>
2164 </message>
2165 <message>
2166 <location filename="../rbutilqt.cpp" line="736"/>
2167 <source>Rockbox Utility is up to date.</source>
2168 <translation>Rockbox Utility is de meest actuele versie.</translation>
2169 </message>
2170 <message>
2171 <location filename="../rbutilqt.cpp" line="759"/>
2172 <source>Device ejected</source>
2173 <translation>Apparaat ontkoppeld</translation>
2174 </message>
2175 <message>
2176 <location filename="../rbutilqt.cpp" line="760"/>
2177 <source>Device successfully ejected. You may now disconnect the player from the PC.</source>
2178 <translation>Apparaat succesvol ontkoppeld. U kunt nu de speler van de PC loskoppelen.</translation>
2179 </message>
2180 <message>
2181 <location filename="../rbutilqt.cpp" line="764"/>
2182 <source>Ejecting failed</source>
2183 <translation>Ontkoppelen mislukt</translation>
2184 </message>
2185 <message>
2186 <location filename="../rbutilqt.cpp" line="765"/>
2187 <source>Ejecting the device failed. Please make sure no programs are accessing files on the device. If ejecting still fails please use your computers eject funtionality.</source>
2188 <translation>Ontkoppelen van het apparaat mislukt. Controleer dat er geen programma&apos;s zijn die bestanden op het apparaat benaderen. Als ontkoppelen dan nog steeds mislukt, gebruik dan de ontkoppelfunctie van de computer. </translation>
2189 </message>
2190 <message>
2191 <location filename="../rbutilqt.cpp" line="337"/>
2192 <location filename="../rbutilqt.cpp" line="642"/>
2193 <source>Configuration error</source>
2194 <translation>Configuratie fout</translation>
2195 </message>
2196 <message>
2197 <location filename="../rbutilqt.cpp" line="643"/>
2198 <source>Your configuration is invalid. Please go to the configuration dialog and make sure the selected values are correct.</source>
2199 <translation>Uw configuratie is ongeldig. Gelieve naar het configuratie scherm te gaan en de juiste instellingen te gebruiken.</translation>
2200 </message>
2201 <message>
2202 <location filename="../rbutilqt.cpp" line="330"/>
2203 <source>This is a new installation of Rockbox Utility, or a new version. The configuration dialog will now open to allow you to setup the program, or review your settings.</source>
2204 <translation>Dit is een nieuwe installatie van Rockbox Utility, of een nieuwe versie. Het configuratie scherm zal nu openen, zodat u het programma kan instellen, of uw instellingen nakijken.</translation>
2205 </message>
2206 <message>
2207 <location filename="../rbutilqt.cpp" line="110"/>
2208 <source>Wine detected!</source>
2209 <translation>Wine gedetecteerd!</translation>
2210 </message>
2211 <message>
2212 <location filename="../rbutilqt.cpp" line="111"/>
2213 <source>It seems you are trying to run this program under Wine. Please don&apos;t do this, running under Wine will fail. Use the native Linux binary instead.</source>
2214 <translation>Het lijkt erop dat u dit programma onder Wine draait. Doe dit alstublieft niet, draaien onder Wine zal mislukken. Gebruik in plaats daarvan de Linux applicatie.</translation>
2215 </message>
2216 <message>
2217 <location filename="../rbutilqt.cpp" line="237"/>
2218 <source>Can&apos;t get version information.
2219Network error: %1. Please check your network and proxy settings.</source>
2220 <translation>Can versie-informatie niet ophalen.
2221Netwerkfout: %1. Controleer uw netwerk- en proxy-instellingen.</translation>
2222 </message>
2223 <message>
2224 <location filename="../rbutilqt.cpp" line="416"/>
2225 <source>Warning</source>
2226 <translation>Waarschuwing</translation>
2227 </message>
2228 <message>
2229 <location filename="../rbutilqt.cpp" line="417"/>
2230 <source>The Application is still downloading Information about new Builds. Please try again shortly.</source>
2231 <translation>Deze applicatie is nog steeds bezig met informatie over nieuwe Builds te downloaden. Gelieve binnen een korte periode opnieuw te proberen.</translation>
2232 </message>
2233 <message>
2234 <location filename="../rbutilqt.cpp" line="329"/>
2235 <source>New installation</source>
2236 <translation>Nieuwe installatie</translation>
2237 </message>
2238 <message>
2239 <location filename="../rbutilqt.cpp" line="338"/>
2240 <source>Your configuration is invalid. This is most likely due to a changed device path. The configuration dialog will now open to allow you to correct the problem.</source>
2241 <translation>Uw configuratie is ongeldig. Dit komt waarschijnlijk door een veranderd apparaat pad. Het configuratie scherm zal nu openen zodat u de fout kan herstellen.</translation>
2242 </message>
2243 <message>
2244 <location filename="../rbutilqt.cpp" line="236"/>
2245 <source>Network error</source>
2246 <translation>Netwerk fout</translation>
2247 </message>
2248</context>
2249<context>
2250 <name>RbUtilQtFrm</name>
2251 <message>
2252 <location filename="../rbutilqtfrm.ui" line="14"/>
2253 <source>Rockbox Utility</source>
2254 <translation>Rockbox Utility</translation>
2255 </message>
2256 <message>
2257 <location filename="../rbutilqtfrm.ui" line="31"/>
2258 <source>Device</source>
2259 <translation>Apparaat</translation>
2260 </message>
2261 <message>
2262 <location filename="../rbutilqtfrm.ui" line="92"/>
2263 <source>&amp;Change</source>
2264 <translation>&amp;Veranderen</translation>
2265 </message>
2266 <message>
2267 <location filename="../rbutilqtfrm.ui" line="163"/>
2268 <source>Welcome</source>
2269 <translation>Welkom</translation>
2270 </message>
2271 <message>
2272 <location filename="../rbutilqtfrm.ui" line="160"/>
2273 <location filename="../rbutilqtfrm.ui" line="658"/>
2274 <source>&amp;Installation</source>
2275 <translation>&amp;Installatie</translation>
2276 </message>
2277 <message>
2278 <location filename="../rbutilqtfrm.ui" line="168"/>
2279 <location filename="../rbutilqtfrm.ui" line="450"/>
2280 <source>&amp;Accessibility</source>
2281 <translation>&amp;Toegankelijkheid</translation>
2282 </message>
2283 <message>
2284 <location filename="../rbutilqtfrm.ui" line="171"/>
2285 <source>Install accessibility add-ons</source>
2286 <translation>Installeer toegankelijkheid add-ons</translation>
2287 </message>
2288 <message>
2289 <location filename="../rbutilqtfrm.ui" line="177"/>
2290 <source>Install Voice files</source>
2291 <translation>Installeer de spraakbestanden</translation>
2292 </message>
2293 <message>
2294 <location filename="../rbutilqtfrm.ui" line="204"/>
2295 <source>Install Talk files</source>
2296 <translation>Installeer de Talk bestanden</translation>
2297 </message>
2298 <message>
2299 <location filename="../rbutilqtfrm.ui" line="458"/>
2300 <source>&amp;Uninstallation</source>
2301 <translation>&amp;Deïnstallatie</translation>
2302 </message>
2303 <message>
2304 <location filename="../rbutilqtfrm.ui" line="286"/>
2305 <location filename="../rbutilqtfrm.ui" line="319"/>
2306 <source>Uninstall Rockbox</source>
2307 <translation>Deïnstalleer Rockbox</translation>
2308 </message>
2309 <message>
2310 <location filename="../rbutilqtfrm.ui" line="121"/>
2311 <source>mountpoint unknown or invalid</source>
2312 <translation>Koppelpunt onbekend of ongeldig</translation>
2313 </message>
2314 <message>
2315 <location filename="../rbutilqtfrm.ui" line="114"/>
2316 <source>Mountpoint:</source>
2317 <translation>Koppelpunt:</translation>
2318 </message>
2319 <message>
2320 <location filename="../rbutilqtfrm.ui" line="72"/>
2321 <source>device unknown or invalid</source>
2322 <translation>apparaat onbekend of ongeldig</translation>
2323 </message>
2324 <message>
2325 <location filename="../rbutilqtfrm.ui" line="65"/>
2326 <source>Device:</source>
2327 <translation>Apparaat:</translation>
2328 </message>
2329 <message>
2330 <location filename="../rbutilqtfrm.ui" line="292"/>
2331 <source>Uninstall Bootloader</source>
2332 <translation>Deïnstalleer de Bootloader</translation>
2333 </message>
2334 <message>
2335 <location filename="../rbutilqtfrm.ui" line="393"/>
2336 <source>&amp;Manual</source>
2337 <translation>&amp;Handleiding</translation>
2338 </message>
2339 <message>
2340 <location filename="../rbutilqtfrm.ui" line="396"/>
2341 <source>View and download the manual</source>
2342 <translation>Lees en download de handleiding</translation>
2343 </message>
2344 <message>
2345 <location filename="../rbutilqtfrm.ui" line="401"/>
2346 <source>Inf&amp;o</source>
2347 <translation>Inf&amp;o</translation>
2348 </message>
2349 <message>
2350 <location filename="../rbutilqtfrm.ui" line="419"/>
2351 <source>&amp;File</source>
2352 <translation>&amp;Bestand</translation>
2353 </message>
2354 <message>
2355 <location filename="../rbutilqtfrm.ui" line="432"/>
2356 <source>&amp;Troubleshoot</source>
2357 <translation>&amp;Probleem oplossen</translation>
2358 </message>
2359 <message>
2360 <location filename="../rbutilqtfrm.ui" line="497"/>
2361 <source>&amp;About</source>
2362 <translation>&amp;Over</translation>
2363 </message>
2364 <message>
2365 <location filename="../rbutilqtfrm.ui" line="653"/>
2366 <source>System &amp;Trace</source>
2367 <translation>Systeem &amp;Trace</translation>
2368 </message>
2369 <message>
2370 <location filename="../rbutilqtfrm.ui" line="474"/>
2371 <source>Empty local download cache</source>
2372 <translation>Ledig de lokale download cache</translation>
2373 </message>
2374 <message>
2375 <location filename="../rbutilqtfrm.ui" line="479"/>
2376 <source>Install Rockbox Utility on player</source>
2377 <translation>Installeer Rockbox utility op uw speler</translation>
2378 </message>
2379 <message>
2380 <location filename="../rbutilqtfrm.ui" line="484"/>
2381 <source>&amp;Configure</source>
2382 <translation>&amp;Configuratie</translation>
2383 </message>
2384 <message>
2385 <location filename="../rbutilqtfrm.ui" line="489"/>
2386 <source>E&amp;xit</source>
2387 <translation>&amp;Verlaten</translation>
2388 </message>
2389 <message>
2390 <location filename="../rbutilqtfrm.ui" line="492"/>
2391 <source>Ctrl+Q</source>
2392 <translation>Ctrl+Q</translation>
2393 </message>
2394 <message>
2395 <location filename="../rbutilqtfrm.ui" line="502"/>
2396 <source>About &amp;Qt</source>
2397 <translation>Over &amp;Qt</translation>
2398 </message>
2399 <message>
2400 <location filename="../rbutilqtfrm.ui" line="428"/>
2401 <location filename="../rbutilqtfrm.ui" line="507"/>
2402 <source>&amp;Help</source>
2403 <translation>&amp;Help</translation>
2404 </message>
2405 <message>
2406 <location filename="../rbutilqtfrm.ui" line="446"/>
2407 <source>Action&amp;s</source>
2408 <translation>Actie&amp;s</translation>
2409 </message>
2410 <message>
2411 <location filename="../rbutilqtfrm.ui" line="512"/>
2412 <source>Info</source>
2413 <translation>Info</translation>
2414 </message>
2415 <message>
2416 <location filename="../rbutilqtfrm.ui" line="640"/>
2417 <source>Create &amp;Voice File</source>
2418 <translation>Creëer een &amp;Voice bestand</translation>
2419 </message>
2420 <message>
2421 <location filename="../rbutilqtfrm.ui" line="616"/>
2422 <source>Read PDF manual</source>
2423 <translation>Lees de PDF handleiding</translation>
2424 </message>
2425 <message>
2426 <location filename="../rbutilqtfrm.ui" line="621"/>
2427 <source>Read HTML manual</source>
2428 <translation>Lees de HTML handleiding</translation>
2429 </message>
2430 <message>
2431 <location filename="../rbutilqtfrm.ui" line="626"/>
2432 <source>Download PDF manual</source>
2433 <translation>Download de PDF handleiding</translation>
2434 </message>
2435 <message>
2436 <location filename="../rbutilqtfrm.ui" line="631"/>
2437 <source>Download HTML manual (zip)</source>
2438 <translation>Download de HTM handleiding (zip)</translation>
2439 </message>
2440 <message>
2441 <location filename="../rbutilqtfrm.ui" line="254"/>
2442 <source>Create Voice files</source>
2443 <translation>Creëer spraakbestanden</translation>
2444 </message>
2445 <message>
2446 <location filename="../rbutilqtfrm.ui" line="643"/>
2447 <source>Create Voice File</source>
2448 <translation>Creëer spraakbestanden</translation>
2449 </message>
2450 <message>
2451 <location filename="../rbutilqtfrm.ui" line="194"/>
2452 <source>&lt;b&gt;Install Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so if you installed the voice file Rockbox will speak.</source>
2453 <translation>&lt;b&gt;Installeer spraakbestanden&lt;/b&gt;&lt;br/&gt;Spraakbestanden zijn nodig om Rockbox de gebruikersinterface te laten spreken. Dit is standaard ingeschakeld, dus als u dit installeert zal Rockbox spreken.</translation>
2454 </message>
2455 <message>
2456 <location filename="../rbutilqtfrm.ui" line="103"/>
2457 <source>&amp;Eject</source>
2458 <translation>&amp;Ontkoppelen</translation>
2459 </message>
2460 <message>
2461 <location filename="../rbutilqtfrm.ui" line="221"/>
2462 <source>&lt;b&gt;Create Talk Files&lt;/b&gt;&lt;br/&gt;Talkfiles are needed to let Rockbox speak File and Foldernames</source>
2463 <translation>&lt;b&gt;Creëer Talk bestanden&lt;/b&gt;&lt;br/&gt;Talk bestanden zijn nodig om Rockbox bestands- en mapnamen te laten spreken</translation>
2464 </message>
2465 <message>
2466 <location filename="../rbutilqtfrm.ui" line="271"/>
2467 <source>&lt;b&gt;Create Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so
2468 if you installed the voice file Rockbox will speak.</source>
2469 <translation>&lt;b&gt;Creëer spraakbestanden&lt;/b&gt;&lt;br/&gt;Spraakbestanden zijn nodig om Rockbox de gebruikersinterface te laten spreken. Dit is standaard ingeschakeld, dus als u dit installeert zal Rockbox spreken.</translation>
2470 </message>
2471 <message>
2472 <location filename="../rbutilqtfrm.ui" line="283"/>
2473 <source>Backup &amp;&amp; &amp;Uninstallation</source>
2474 <translation>Backup &amp;&amp; &amp;Deïnstallatie</translation>
2475 </message>
2476 <message>
2477 <location filename="../rbutilqtfrm.ui" line="309"/>
2478 <source>&lt;b&gt;Remove the bootloader&lt;/b&gt;&lt;br/&gt;After removing the bootloader you won&apos;t be able to start Rockbox.</source>
2479 <translation>&lt;b&gt;Verwijder de bootloader&lt;/b&gt;&lt;br/&gt;Na het verwijderen van de bootloader zal u Rockbox niet meer kunnen opstarten.</translation>
2480 </message>
2481 <message>
2482 <location filename="../rbutilqtfrm.ui" line="336"/>
2483 <source>&lt;b&gt;Uninstall Rockbox from your audio player.&lt;/b&gt;&lt;br/&gt;This will leave the bootloader in place (you need to remove it manually).</source>
2484 <translation>&lt;b&gt;Deïnstalleer Rockbox van uw audio player.&lt;/b&gt;&lt;br/&gt;Dit zal de bootloader onaangetast laten (u zal het manueel moeten verwijderen).</translation>
2485 </message>
2486 <message>
2487 <location filename="../rbutilqtfrm.ui" line="349"/>
2488 <source>Backup</source>
2489 <translation>Backup</translation>
2490 </message>
2491 <message>
2492 <location filename="../rbutilqtfrm.ui" line="366"/>
2493 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup current installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Create a backup by archiving the contents of the Rockbox installation folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2494 <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup huidige installatie.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Maak een backup door de inhoud van de Rockbox installatiefolder te archiveren.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
2495 </message>
2496 <message>
2497 <location filename="../rbutilqtfrm.ui" line="539"/>
2498 <source>Install &amp;Bootloader</source>
2499 <translation>Installeer de &amp;Bootloader</translation>
2500 </message>
2501 <message>
2502 <location filename="../rbutilqtfrm.ui" line="548"/>
2503 <source>Install &amp;Rockbox</source>
2504 <translation>Installeer &amp;Rockbox</translation>
2505 </message>
2506 <message>
2507 <location filename="../rbutilqtfrm.ui" line="557"/>
2508 <source>Install &amp;Fonts Package</source>
2509 <translation>Installeer het &amp;lettertypen pakket</translation>
2510 </message>
2511 <message>
2512 <location filename="../rbutilqtfrm.ui" line="566"/>
2513 <source>Install &amp;Themes</source>
2514 <translation>Installeer &amp;thema&apos;s</translation>
2515 </message>
2516 <message>
2517 <location filename="../rbutilqtfrm.ui" line="575"/>
2518 <source>Install &amp;Game Files</source>
2519 <translation>Installeer &amp;spelbestanden</translation>
2520 </message>
2521 <message>
2522 <location filename="../rbutilqtfrm.ui" line="584"/>
2523 <source>&amp;Install Voice File</source>
2524 <translation>&amp;Installeer de spraakbestanden</translation>
2525 </message>
2526 <message>
2527 <location filename="../rbutilqtfrm.ui" line="593"/>
2528 <source>Create &amp;Talk Files</source>
2529 <translation>Creëer &amp;Talk bestanden</translation>
2530 </message>
2531 <message>
2532 <location filename="../rbutilqtfrm.ui" line="602"/>
2533 <source>Remove &amp;bootloader</source>
2534 <translation>Verwijder de &amp;Bootloader</translation>
2535 </message>
2536 <message>
2537 <location filename="../rbutilqtfrm.ui" line="611"/>
2538 <source>Uninstall &amp;Rockbox</source>
2539 <translation>Deïnstalleer &amp;Rockbox</translation>
2540 </message>
2541 <message>
2542 <location filename="../rbutilqtfrm.ui" line="648"/>
2543 <source>&amp;System Info</source>
2544 <translation>&amp;Systeem Info</translation>
2545 </message>
2546 <message>
2547 <location filename="../rbutilqtfrm.ui" line="663"/>
2548 <source>Show &amp;Changelog</source>
2549 <translation>Toon &amp;Wijzigingsoverzicht</translation>
2550 </message>
2551 <message>
2552 <location filename="../rbutilqtfrm.ui" line="521"/>
2553 <source>&amp;Complete Installation</source>
2554 <translation>&amp;Complete installatie</translation>
2555 </message>
2556 <message>
2557 <location filename="../rbutilqtfrm.ui" line="530"/>
2558 <source>&amp;Minimal Installation</source>
2559 <translation>&amp;Minimale installatie</translation>
2560 </message>
2561</context>
2562<context>
2563 <name>SelectiveInstallWidget</name>
2564 <message>
2565 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="20"/>
2566 <source>Selective Installation</source>
2567 <translation>Selectieve installatie</translation>
2568 </message>
2569 <message>
2570 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="26"/>
2571 <source>Rockbox version to install</source>
2572 <translation>Rockbox-versie om te installeren</translation>
2573 </message>
2574 <message>
2575 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="35"/>
2576 <source>Version information not available yet.</source>
2577 <translation>Versie-informatie nog niet beschikbaar.</translation>
2578 </message>
2579 <message>
2580 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="54"/>
2581 <source>Rockbox components to install</source>
2582 <translation>Rockbox-componenten om te installeren</translation>
2583 </message>
2584 <message>
2585 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="60"/>
2586 <source>&amp;Bootloader</source>
2587 <translation>&amp;Bootloader</translation>
2588 </message>
2589 <message>
2590 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="80"/>
2591 <source>The main Rockbox firmware.</source>
2592 <translation>De Rockbox firmware zelf.</translation>
2593 </message>
2594 <message>
2595 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="90"/>
2596 <source>Fonts</source>
2597 <translation>Lettertypen</translation>
2598 </message>
2599 <message>
2600 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="104"/>
2601 <source>&amp;Rockbox</source>
2602 <translation>&amp;Rockbox</translation>
2603 </message>
2604 <message>
2605 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="124"/>
2606 <source>Some game plugins require additional files.</source>
2607 <translation>Sommige spel-plugins hebben extra bestanden nodig.</translation>
2608 </message>
2609 <message>
2610 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="140"/>
2611 <source>Additional fonts for the User Interface.</source>
2612 <translation>Extra fonts voor de gebruikersinterface.</translation>
2613 </message>
2614 <message>
2615 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="156"/>
2616 <source>The bootloader is required for starting Rockbox. Only necessary for first time install.</source>
2617 <translation>De bootloader is vereist voor het starten van Rockbox. Alleen nodig tijdens de eerste installatie.</translation>
2618 </message>
2619 <message>
2620 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="166"/>
2621 <source>Game Files</source>
2622 <translation>Spelbestanden</translation>
2623 </message>
2624 <message>
2625 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="177"/>
2626 <source>Customize</source>
2627 <translation>Aanpassen</translation>
2628 </message>
2629 <message>
2630 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="188"/>
2631 <source>Themes</source>
2632 <translation>Thema&apos;s</translation>
2633 </message>
2634 <message>
2635 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="205"/>
2636 <source>Themes allow adjusting the user interface of Rockbox. Use &quot;Customize&quot; to select themes.</source>
2637 <translation>Met thema&apos;s kan de gebruikersinterface van Rockbox aangepast worden. Gebruik &quot;Aanpassen&quot; om thema&apos;s te selecteren.</translation>
2638 </message>
2639 <message>
2640 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="250"/>
2641 <source>&amp;Install</source>
2642 <translation>&amp;Installeer</translation>
2643 </message>
2644 <message>
2645 <location filename="../gui/selectiveinstallwidget.cpp" line="67"/>
2646 <source>This is the latest stable release available.</source>
2647 <translation>Dit is de meest recente stabiele release die beschikbaar is.</translation>
2648 </message>
2649 <message>
2650 <location filename="../gui/selectiveinstallwidget.cpp" line="70"/>
2651 <source>The development version is updated on every code change. Last update was on %1</source>
2652 <translation>De development-versie wordt bijgewerkt na elke verandering van de broncode. De meest recente update was op %1</translation>
2653 </message>
2654 <message>
2655 <location filename="../gui/selectiveinstallwidget.cpp" line="74"/>
2656 <source>This will eventually become the next Rockbox version. Install it to help testing.</source>
2657 <translation>Dit wordt uiteindelijk de volgende Rockbox-versie. Installeer deze om te helpen met testen.</translation>
2658 </message>
2659 <message>
2660 <location filename="../gui/selectiveinstallwidget.cpp" line="100"/>
2661 <source>Stable Release (Version %1)</source>
2662 <translation>Stabiele release (Versie %1)</translation>
2663 </message>
2664 <message>
2665 <location filename="../gui/selectiveinstallwidget.cpp" line="104"/>
2666 <source>Development Version (Revison %1)</source>
2667 <translation>Development-versie (Revisie %1)</translation>
2668 </message>
2669 <message>
2670 <location filename="../gui/selectiveinstallwidget.cpp" line="108"/>
2671 <source>Release Candidate (Revison %1)</source>
2672 <translation>Release Candidate (Revisie %1)</translation>
2673 </message>
2674 <message>
2675 <location filename="../gui/selectiveinstallwidget.cpp" line="131"/>
2676 <source>The selected player doesn&apos;t need a bootloader.</source>
2677 <translation>De gekozen speler heeft geen bootloader nodig.</translation>
2678 </message>
2679 <message>
2680 <location filename="../gui/selectiveinstallwidget.cpp" line="136"/>
2681 <source>The bootloader is required for starting Rockbox. Installation of the bootloader is only necessary on first time installation.</source>
2682 <translation>De bootloader is vereist voor het starten van Rockbox. Installatie van de bootloader is alleen nodig tijdens de eerste installatie.</translation>
2683 </message>
2684 <message>
2685 <location filename="../gui/selectiveinstallwidget.cpp" line="183"/>
2686 <source>Mountpoint is wrong</source>
2687 <translation>Koppelpunt is onjuist</translation>
2688 </message>
2689 <message>
2690 <location filename="../gui/selectiveinstallwidget.cpp" line="239"/>
2691 <source>No install method known.</source>
2692 <translation>Geen installatie methode bekend.</translation>
2693 </message>
2694 <message>
2695 <location filename="../gui/selectiveinstallwidget.cpp" line="266"/>
2696 <source>Bootloader detected</source>
2697 <translation>Bootloader gevonden</translation>
2698 </message>
2699 <message>
2700 <location filename="../gui/selectiveinstallwidget.cpp" line="267"/>
2701 <source>Bootloader already installed. Do you want to reinstall the bootloader?</source>
2702 <translation>Bootloader is al geïnstalleerd. Wilt u de Bootloader herinstalleren?</translation>
2703 </message>
2704 <message>
2705 <location filename="../gui/selectiveinstallwidget.cpp" line="271"/>
2706 <source>Bootloader installation skipped</source>
2707 <translation>Bootloader installatie overgeslagen</translation>
2708 </message>
2709 <message>
2710 <location filename="../gui/selectiveinstallwidget.cpp" line="284"/>
2711 <source>Create Bootloader backup</source>
2712 <translation>Maak Bootloader backup</translation>
2713 </message>
2714 <message>
2715 <location filename="../gui/selectiveinstallwidget.cpp" line="285"/>
2716 <source>You can create a backup of the original bootloader file. Press &quot;Yes&quot; to select an output folder on your computer to save the file to. The file will get placed in a new folder &quot;%1&quot; created below the selected folder.
2717Press &quot;No&quot; to skip this step.</source>
2718 <translation>U kan een backup maken van de Originele Bootloader. Kies &quot;Ja&quot; om de output map op uw computer te selecteren waarin het bestand zal worden opgeslagen. Dit bestand zal geplaatst worden in een nieuwe map &quot;%1&quot; die zal worden aangemaakt onder de geselecteerde map.
2719Kies &quot;Nee&quot; om deze stap over te slaan.</translation>
2720 </message>
2721 <message>
2722 <location filename="../gui/selectiveinstallwidget.cpp" line="292"/>
2723 <source>Browse backup folder</source>
2724 <translation>Blader naar backup map</translation>
2725 </message>
2726 <message>
2727 <location filename="../gui/selectiveinstallwidget.cpp" line="304"/>
2728 <source>Prerequisites</source>
2729 <translation>Vereisten</translation>
2730 </message>
2731 <message>
2732 <location filename="../gui/selectiveinstallwidget.cpp" line="309"/>
2733 <source>Bootloader installation aborted</source>
2734 <translation>Bootloader installatie afgebroken</translation>
2735 </message>
2736 <message>
2737 <location filename="../gui/selectiveinstallwidget.cpp" line="319"/>
2738 <source>Bootloader files (%1)</source>
2739 <translation>Bootloader-bestanden (%1)</translation>
2740 </message>
2741 <message>
2742 <location filename="../gui/selectiveinstallwidget.cpp" line="321"/>
2743 <source>All files (*)</source>
2744 <translation>Alle bestanden (*)</translation>
2745 </message>
2746 <message>
2747 <location filename="../gui/selectiveinstallwidget.cpp" line="323"/>
2748 <source>Select firmware file</source>
2749 <translation>Selecteer firmware bestand</translation>
2750 </message>
2751 <message>
2752 <location filename="../gui/selectiveinstallwidget.cpp" line="325"/>
2753 <source>Error opening firmware file</source>
2754 <translation>Fout bij openen van firmware bestand</translation>
2755 </message>
2756 <message>
2757 <location filename="../gui/selectiveinstallwidget.cpp" line="331"/>
2758 <source>Error reading firmware file</source>
2759 <translation>Fout bij het lezen van firmware bestand</translation>
2760 </message>
2761 <message>
2762 <location filename="../gui/selectiveinstallwidget.cpp" line="341"/>
2763 <source>Backup error</source>
2764 <translation>Backup fout</translation>
2765 </message>
2766 <message>
2767 <location filename="../gui/selectiveinstallwidget.cpp" line="342"/>
2768 <source>Could not create backup file. Continue?</source>
2769 <translation>Kon geen backup maken. Verdergaan?</translation>
2770 </message>
2771 <message>
2772 <location filename="../gui/selectiveinstallwidget.cpp" line="366"/>
2773 <source>Manual steps required</source>
2774 <translation>Handmatige stappen zijn genoodzaakt</translation>
2775 </message>
2776 <message>
2777 <location filename="../gui/selectiveinstallwidget.cpp" line="171"/>
2778 <source>Continue with installation?</source>
2779 <translation>Doorgaan met installatie?</translation>
2780 </message>
2781 <message>
2782 <location filename="../gui/selectiveinstallwidget.cpp" line="172"/>
2783 <source>Really continue?</source>
2784 <translation>Wilt u zeker verdergaan?</translation>
2785 </message>
2786 <message>
2787 <source>Aborted!</source>
2788 <translation type="obsolete">Afgebroken!</translation>
2789 </message>
2790 <message>
2791 <location filename="../gui/selectiveinstallwidget.cpp" line="490"/>
2792 <source>Your installation doesn&apos;t require game files, skipping.</source>
2793 <translation></translation>
2794 </message>
2795</context>
2796<context>
2797 <name>ServerInfo</name>
2798 <message>
2799 <location filename="../base/serverinfo.cpp" line="117"/>
2800 <source>Unknown</source>
2801 <translation>Onbekend</translation>
2802 </message>
2803 <message>
2804 <location filename="../base/serverinfo.cpp" line="121"/>
2805 <source>Unusable</source>
2806 <translation>Onbruikbaar</translation>
2807 </message>
2808 <message>
2809 <location filename="../base/serverinfo.cpp" line="124"/>
2810 <source>Unstable</source>
2811 <translation>Onstabiel</translation>
2812 </message>
2813 <message>
2814 <location filename="../base/serverinfo.cpp" line="127"/>
2815 <source>Stable</source>
2816 <translation>Stabiel</translation>
2817 </message>
2818</context>
2819<context>
2820 <name>SysTrace</name>
2821 <message>
2822 <location filename="../systrace.cpp" line="98"/>
2823 <location filename="../systrace.cpp" line="107"/>
2824 <source>Save system trace log</source>
2825 <translation>Systeem trace log opslaan</translation>
2826 </message>
2827</context>
2828<context>
2829 <name>SysTraceFrm</name>
2830 <message>
2831 <location filename="../systracefrm.ui" line="14"/>
2832 <source>System Trace</source>
2833 <translation>Systeem trace</translation>
2834 </message>
2835 <message>
2836 <location filename="../systracefrm.ui" line="20"/>
2837 <source>System State trace</source>
2838 <translation>Systeem trace staat</translation>
2839 </message>
2840 <message>
2841 <location filename="../systracefrm.ui" line="46"/>
2842 <source>&amp;Close</source>
2843 <translation>&amp;Sluiten</translation>
2844 </message>
2845 <message>
2846 <location filename="../systracefrm.ui" line="57"/>
2847 <source>&amp;Save</source>
2848 <translation>&amp;Opslaan</translation>
2849 </message>
2850 <message>
2851 <location filename="../systracefrm.ui" line="68"/>
2852 <source>&amp;Refresh</source>
2853 <translation>&amp;Vernieuwen</translation>
2854 </message>
2855 <message>
2856 <location filename="../systracefrm.ui" line="79"/>
2857 <source>Save &amp;previous</source>
2858 <translation>Opslaan &amp;vorige</translation>
2859 </message>
2860</context>
2861<context>
2862 <name>Sysinfo</name>
2863 <message>
2864 <location filename="../sysinfo.cpp" line="45"/>
2865 <source>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</source>
2866 <translation>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</translation>
2867 </message>
2868 <message>
2869 <location filename="../sysinfo.cpp" line="46"/>
2870 <source>&lt;b&gt;Username&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2871 <translation>&lt;b&gt;Gebruikersnaam&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2872 </message>
2873 <message>
2874 <location filename="../sysinfo.cpp" line="48"/>
2875 <source>&lt;b&gt;Permissions&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2876 <translation>&lt;b&gt;Machtigingen&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2877 </message>
2878 <message>
2879 <location filename="../sysinfo.cpp" line="50"/>
2880 <source>&lt;b&gt;Attached USB devices&lt;/b&gt;&lt;br/&gt;</source>
2881 <translation>&lt;b&gt;Aangesloten USB apparaten&lt;/b&gt;&lt;br/&gt;</translation>
2882 </message>
2883 <message>
2884 <location filename="../sysinfo.cpp" line="54"/>
2885 <source>VID: %1 PID: %2, %3</source>
2886 <translation>VID: %1 PID: %2, %3</translation>
2887 </message>
2888 <message>
2889 <location filename="../sysinfo.cpp" line="63"/>
2890 <source>Filesystem</source>
2891 <translation>Bestandssysteem</translation>
2892 </message>
2893 <message>
2894 <location filename="../sysinfo.cpp" line="66"/>
2895 <source>Mountpoint</source>
2896 <translation>Koppelpunt</translation>
2897 </message>
2898 <message>
2899 <location filename="../sysinfo.cpp" line="66"/>
2900 <source>Label</source>
2901 <translation>Label</translation>
2902 </message>
2903 <message>
2904 <location filename="../sysinfo.cpp" line="67"/>
2905 <source>Free</source>
2906 <translation>Beschikbaar</translation>
2907 </message>
2908 <message>
2909 <location filename="../sysinfo.cpp" line="67"/>
2910 <source>Total</source>
2911 <translation>Totaal</translation>
2912 </message>
2913 <message>
2914 <location filename="../sysinfo.cpp" line="68"/>
2915 <source>Cluster Size</source>
2916 <translation>Clustergrootte</translation>
2917 </message>
2918 <message>
2919 <location filename="../sysinfo.cpp" line="70"/>
2920 <source>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</source>
2921 <translation>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</translation>
2922 </message>
2923</context>
2924<context>
2925 <name>SysinfoFrm</name>
2926 <message>
2927 <location filename="../sysinfofrm.ui" line="13"/>
2928 <source>System Info</source>
2929 <translation>Systeem info</translation>
2930 </message>
2931 <message>
2932 <location filename="../sysinfofrm.ui" line="22"/>
2933 <source>&amp;Refresh</source>
2934 <translation>&amp;Vernieuwen</translation>
2935 </message>
2936 <message>
2937 <location filename="../sysinfofrm.ui" line="45"/>
2938 <source>&amp;OK</source>
2939 <translation>&amp;OK</translation>
2940 </message>
2941</context>
2942<context>
2943 <name>System</name>
2944 <message>
2945 <location filename="../base/system.cpp" line="121"/>
2946 <source>Guest</source>
2947 <translation>Gast</translation>
2948 </message>
2949 <message>
2950 <location filename="../base/system.cpp" line="124"/>
2951 <source>Admin</source>
2952 <translation>Hoofdgebruiker</translation>
2953 </message>
2954 <message>
2955 <location filename="../base/system.cpp" line="127"/>
2956 <source>User</source>
2957 <translation>Gebruiker</translation>
2958 </message>
2959 <message>
2960 <location filename="../base/system.cpp" line="130"/>
2961 <source>Error</source>
2962 <translation>Fout</translation>
2963 </message>
2964 <message>
2965 <location filename="../base/system.cpp" line="278"/>
2966 <location filename="../base/system.cpp" line="323"/>
2967 <source>(no description available)</source>
2968 <translation>(geen beschrijving beschikbaar)</translation>
2969 </message>
2970</context>
2971<context>
2972 <name>TTSBase</name>
2973 <message>
2974 <location filename="../base/ttsbase.cpp" line="45"/>
2975 <source>Espeak TTS Engine</source>
2976 <translation>Espeak TTS</translation>
2977 </message>
2978 <message>
2979 <location filename="../base/ttsbase.cpp" line="47"/>
2980 <source>Flite TTS Engine</source>
2981 <translation>Flite TTS</translation>
2982 </message>
2983 <message>
2984 <location filename="../base/ttsbase.cpp" line="48"/>
2985 <source>Swift TTS Engine</source>
2986 <translation>Swift TTS</translation>
2987 </message>
2988 <message>
2989 <location filename="../base/ttsbase.cpp" line="51"/>
2990 <source>SAPI4 TTS Engine</source>
2991 <translation>SAPI4 TTS</translation>
2992 </message>
2993 <message>
2994 <location filename="../base/ttsbase.cpp" line="53"/>
2995 <source>SAPI5 TTS Engine</source>
2996 <translation>SAPI5 TTS</translation>
2997 </message>
2998 <message>
2999 <location filename="../base/ttsbase.cpp" line="54"/>
3000 <source>MS Speech Platform</source>
3001 <translation>MS Speech Platform</translation>
3002 </message>
3003 <message>
3004 <source>SAPI TTS Engine</source>
3005 <translation type="obsolete">SAPI TTS</translation>
3006 </message>
3007 <message>
3008 <location filename="../base/ttsbase.cpp" line="57"/>
3009 <source>Festival TTS Engine</source>
3010 <translation>Festival TTS</translation>
3011 </message>
3012 <message>
3013 <location filename="../base/ttsbase.cpp" line="60"/>
3014 <source>OS X System Engine</source>
3015 <translation>OS X Systeem</translation>
3016 </message>
3017</context>
3018<context>
3019 <name>TTSCarbon</name>
3020 <message>
3021 <location filename="../base/ttscarbon.cpp" line="139"/>
3022 <source>Voice:</source>
3023 <translation>Stem:</translation>
3024 </message>
3025 <message>
3026 <location filename="../base/ttscarbon.cpp" line="145"/>
3027 <source>Speed (words/min):</source>
3028 <translation>Snelheid (woorden/min):</translation>
3029 </message>
3030 <message>
3031 <location filename="../base/ttscarbon.cpp" line="152"/>
3032 <source>Pitch (0 for default):</source>
3033 <translation>Toonhoogte (0 voor standaard):</translation>
3034 </message>
3035 <message>
3036 <location filename="../base/ttscarbon.cpp" line="222"/>
3037 <source>Could not voice string</source>
3038 <translation>Kon zin niet uitspreken</translation>
3039 </message>
3040 <message>
3041 <location filename="../base/ttscarbon.cpp" line="232"/>
3042 <source>Could not convert intermediate file</source>
3043 <translation>Kon tussenbestand niet omzetten</translation>
3044 </message>
3045</context>
3046<context>
3047 <name>TTSExes</name>
3048 <message>
3049 <location filename="../base/ttsexes.cpp" line="78"/>
3050 <source>TTS executable not found</source>
3051 <translation>TTS programma niet gevonden</translation>
3052 </message>
3053 <message>
3054 <location filename="../base/ttsexes.cpp" line="44"/>
3055 <source>Path to TTS engine:</source>
3056 <translation>Pad naar TTS engine:</translation>
3057 </message>
3058 <message>
3059 <location filename="../base/ttsexes.cpp" line="46"/>
3060 <source>TTS engine options:</source>
3061 <translation>TTS engine opties:</translation>
3062 </message>
3063</context>
3064<context>
3065 <name>TTSFestival</name>
3066 <message>
3067 <location filename="../base/ttsfestival.cpp" line="207"/>
3068 <source>engine could not voice string</source>
3069 <translation>engine kon de stem string niet vinden</translation>
3070 </message>
3071 <message>
3072 <location filename="../base/ttsfestival.cpp" line="290"/>
3073 <source>No description available</source>
3074 <translation>Geen beschrijving beschikbaar</translation>
3075 </message>
3076 <message>
3077 <location filename="../base/ttsfestival.cpp" line="53"/>
3078 <source>Path to Festival client:</source>
3079 <translation>Pad naar Festival client:</translation>
3080 </message>
3081 <message>
3082 <location filename="../base/ttsfestival.cpp" line="58"/>
3083 <source>Voice:</source>
3084 <translation>Stem:</translation>
3085 </message>
3086 <message>
3087 <location filename="../base/ttsfestival.cpp" line="67"/>
3088 <source>Voice description:</source>
3089 <translation>Stem beschrijving:</translation>
3090 </message>
3091</context>
3092<context>
3093 <name>TTSSapi</name>
3094 <message>
3095 <location filename="../base/ttssapi.cpp" line="49"/>
3096 <source>Language:</source>
3097 <translation>Taal:</translation>
3098 </message>
3099 <message>
3100 <location filename="../base/ttssapi.cpp" line="56"/>
3101 <source>Voice:</source>
3102 <translation>Stem:</translation>
3103 </message>
3104 <message>
3105 <location filename="../base/ttssapi.cpp" line="68"/>
3106 <source>Speed:</source>
3107 <translation>Snelheid:</translation>
3108 </message>
3109 <message>
3110 <location filename="../base/ttssapi.cpp" line="71"/>
3111 <source>Options:</source>
3112 <translation>Opties:</translation>
3113 </message>
3114 <message>
3115 <location filename="../base/ttssapi.cpp" line="115"/>
3116 <source>Could not copy the SAPI script</source>
3117 <translation>SAPI script kon niet gekopieerd worden</translation>
3118 </message>
3119 <message>
3120 <location filename="../base/ttssapi.cpp" line="133"/>
3121 <source>Could not start SAPI process</source>
3122 <translation>SAPI proces kon niet gestart worden</translation>
3123 </message>
3124</context>
3125<context>
3126 <name>TalkFileCreator</name>
3127 <message>
3128 <location filename="../base/talkfile.cpp" line="45"/>
3129 <source>Talk file creation aborted</source>
3130 <translation>Talk bestand creatie afgebroken</translation>
3131 </message>
3132 <message>
3133 <location filename="../base/talkfile.cpp" line="80"/>
3134 <source>Finished creating Talk files</source>
3135 <translation>Klaar met genereren van Talk bestanden</translation>
3136 </message>
3137 <message>
3138 <location filename="../base/talkfile.cpp" line="42"/>
3139 <source>Reading Filelist...</source>
3140 <translation>Bezig met inlezen van de bestandslijst...</translation>
3141 </message>
3142 <message>
3143 <location filename="../base/talkfile.cpp" line="36"/>
3144 <source>Starting Talk file generation for folder %1</source>
3145 <translation>Starten met Talk-bestand generatie voor folder %1</translation>
3146 </message>
3147 <message>
3148 <location filename="../base/talkfile.cpp" line="68"/>
3149 <source>Copying Talkfiles...</source>
3150 <translation>Bezig met kopiëren van Talk bestanden...</translation>
3151 </message>
3152 <message>
3153 <location filename="../base/talkfile.cpp" line="240"/>
3154 <source>File copy aborted</source>
3155 <translation>Kopiëren afgebroken</translation>
3156 </message>
3157 <message>
3158 <location filename="../base/talkfile.cpp" line="259"/>
3159 <source>Copying of %1 to %2 failed</source>
3160 <translation>Kopiëren van %1 naar %2 mislukt</translation>
3161 </message>
3162 <message>
3163 <location filename="../base/talkfile.cpp" line="280"/>
3164 <source>Cleaning up...</source>
3165 <translation>Opruimen...</translation>
3166 </message>
3167 <message>
3168 <location filename="../base/talkfile.cpp" line="291"/>
3169 <source>Finished</source>
3170 <translation>Voltooid</translation>
3171 </message>
3172</context>
3173<context>
3174 <name>TalkGenerator</name>
3175 <message>
3176 <location filename="../base/talkgenerator.cpp" line="39"/>
3177 <source>Starting TTS Engine</source>
3178 <translation>Bezig met starten van de TTS engine</translation>
3179 </message>
3180 <message>
3181 <location filename="../base/talkgenerator.cpp" line="44"/>
3182 <location filename="../base/talkgenerator.cpp" line="51"/>
3183 <source>Init of TTS engine failed</source>
3184 <translation>Initialisatie van de TTS engine is mislukt</translation>
3185 </message>
3186 <message>
3187 <location filename="../base/talkgenerator.cpp" line="58"/>
3188 <source>Starting Encoder Engine</source>
3189 <translation>Bezig met starten van de Encoder engine</translation>
3190 </message>
3191 <message>
3192 <location filename="../base/talkgenerator.cpp" line="62"/>
3193 <source>Init of Encoder engine failed</source>
3194 <translation>Initialisatie van de Encoder engine is mislukt</translation>
3195 </message>
3196 <message>
3197 <location filename="../base/talkgenerator.cpp" line="72"/>
3198 <source>Voicing entries...</source>
3199 <translation>Bezig met inspreken van items...</translation>
3200 </message>
3201 <message>
3202 <location filename="../base/talkgenerator.cpp" line="87"/>
3203 <source>Encoding files...</source>
3204 <translation>Bezig met encoderen van bestanden...</translation>
3205 </message>
3206 <message>
3207 <location filename="../base/talkgenerator.cpp" line="126"/>
3208 <source>Voicing aborted</source>
3209 <translation>Inspreken afgebroken</translation>
3210 </message>
3211 <message>
3212 <location filename="../base/talkgenerator.cpp" line="162"/>
3213 <location filename="../base/talkgenerator.cpp" line="167"/>
3214 <source>Voicing of %1 failed: %2</source>
3215 <translation>Omzetten naar spraak van %1 mislukt: %2</translation>
3216 </message>
3217 <message>
3218 <location filename="../base/talkgenerator.cpp" line="211"/>
3219 <source>Encoding aborted</source>
3220 <translation>Encoderen afgebroken</translation>
3221 </message>
3222 <message>
3223 <location filename="../base/talkgenerator.cpp" line="239"/>
3224 <source>Encoding of %1 failed</source>
3225 <translation>Encoderen van %1 mislukt</translation>
3226 </message>
3227</context>
3228<context>
3229 <name>ThemeInstallFrm</name>
3230 <message>
3231 <location filename="../themesinstallfrm.ui" line="13"/>
3232 <source>Theme Installation</source>
3233 <translation>Thema installatie</translation>
3234 </message>
3235 <message>
3236 <location filename="../themesinstallfrm.ui" line="48"/>
3237 <source>Selected Theme</source>
3238 <translation>Geselecteerd thema</translation>
3239 </message>
3240 <message>
3241 <location filename="../themesinstallfrm.ui" line="73"/>
3242 <source>Description</source>
3243 <translation>Beschrijving</translation>
3244 </message>
3245 <message>
3246 <location filename="../themesinstallfrm.ui" line="83"/>
3247 <source>Download size:</source>
3248 <translation>Download grootte:</translation>
3249 </message>
3250 <message>
3251 <location filename="../themesinstallfrm.ui" line="125"/>
3252 <source>&amp;Cancel</source>
3253 <translation>&amp;Annuleren</translation>
3254 </message>
3255 <message>
3256 <location filename="../themesinstallfrm.ui" line="115"/>
3257 <source>&amp;Install</source>
3258 <translation>&amp;Installeren</translation>
3259 </message>
3260 <message>
3261 <location filename="../themesinstallfrm.ui" line="93"/>
3262 <source>Hold Ctrl to select multiple item, Shift for a range</source>
3263 <translation>Houd CTRL ingedrukt om meerdere items te selecteren, SHIFT voor een bereik</translation>
3264 </message>
3265</context>
3266<context>
3267 <name>ThemesInstallWindow</name>
3268 <message>
3269 <location filename="../themesinstallwindow.cpp" line="40"/>
3270 <source>no theme selected</source>
3271 <translation>geen thema geselecteerd</translation>
3272 </message>
3273 <message>
3274 <location filename="../themesinstallwindow.cpp" line="125"/>
3275 <source>Network error: %1.
3276Please check your network and proxy settings.</source>
3277 <translation>Netwerk fout: %1.
3278Gelieve uw netwerk en proxy instellingen te bekijken.</translation>
3279 </message>
3280 <message>
3281 <location filename="../themesinstallwindow.cpp" line="138"/>
3282 <source>the following error occured:
3283%1</source>
3284 <translation>de volgende fout is opgetreden:
3285%1</translation>
3286 </message>
3287 <message>
3288 <location filename="../themesinstallwindow.cpp" line="144"/>
3289 <source>done.</source>
3290 <translation>klaar.</translation>
3291 </message>
3292 <message>
3293 <location filename="../themesinstallwindow.cpp" line="211"/>
3294 <source>fetching details for %1</source>
3295 <translation>bezig met ophalen van details voor %1</translation>
3296 </message>
3297 <message>
3298 <location filename="../themesinstallwindow.cpp" line="214"/>
3299 <source>fetching preview ...</source>
3300 <translation>bezig met ophalen van voorbeeld...</translation>
3301 </message>
3302 <message>
3303 <location filename="../themesinstallwindow.cpp" line="227"/>
3304 <source>&lt;b&gt;Author:&lt;/b&gt; %1&lt;hr/&gt;</source>
3305 <translation>&lt;b&gt;Auteur :&lt;/b&gt; %1&lt;hr/&gt;</translation>
3306 </message>
3307 <message>
3308 <location filename="../themesinstallwindow.cpp" line="228"/>
3309 <location filename="../themesinstallwindow.cpp" line="230"/>
3310 <source>unknown</source>
3311 <translation>onbekend</translation>
3312 </message>
3313 <message>
3314 <location filename="../themesinstallwindow.cpp" line="229"/>
3315 <source>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</source>
3316 <translation>&lt;b&gt;Versie:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3317 </message>
3318 <message>
3319 <location filename="../themesinstallwindow.cpp" line="231"/>
3320 <source>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</source>
3321 <translation>&lt;b&gt;Beschrijving:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3322 </message>
3323 <message>
3324 <location filename="../themesinstallwindow.cpp" line="232"/>
3325 <source>no description</source>
3326 <translation>geen beschrijving</translation>
3327 </message>
3328 <message>
3329 <location filename="../themesinstallwindow.cpp" line="260"/>
3330 <source>no theme preview</source>
3331 <translation>geen thema voorbeeld</translation>
3332 </message>
3333 <message>
3334 <location filename="../themesinstallwindow.cpp" line="289"/>
3335 <source>Select</source>
3336 <translation>Selecteer</translation>
3337 </message>
3338 <message>
3339 <location filename="../themesinstallwindow.cpp" line="296"/>
3340 <source>getting themes information ...</source>
3341 <translation>bezig met ophalen van thema informatie...</translation>
3342 </message>
3343 <message>
3344 <location filename="../themesinstallwindow.cpp" line="326"/>
3345 <source>No themes selected, skipping</source>
3346 <translation>Geen thema&apos;s geselecteerd, overslaan</translation>
3347 </message>
3348 <message>
3349 <location filename="../themesinstallwindow.cpp" line="356"/>
3350 <source>Mount point is wrong!</source>
3351 <translation>Mount punt is verkeerd!</translation>
3352 </message>
3353 <message>
3354 <location filename="../themesinstallwindow.cpp" line="41"/>
3355 <source>no selection</source>
3356 <translation>geen selectie</translation>
3357 </message>
3358 <message>
3359 <location filename="../themesinstallwindow.cpp" line="181"/>
3360 <source>Information</source>
3361 <translation>Informatie</translation>
3362 </message>
3363 <message numerus="yes">
3364 <location filename="../themesinstallwindow.cpp" line="198"/>
3365 <source>Download size %L1 kiB (%n item(s))</source>
3366 <translation>
3367 <numerusform>Download grootte %L1 kiB (%n item)</numerusform>
3368 <numerusform>Download grootte %L1 kiB (%n items)</numerusform>
3369 </translation>
3370 </message>
3371 <message>
3372 <location filename="../themesinstallwindow.cpp" line="248"/>
3373 <source>Retrieving theme preview failed.
3374HTTP response code: %1</source>
3375 <translation>Ophalen van thema voorbeeld mislukt.\nHTTP respons code: %1</translation>
3376 </message>
3377</context>
3378<context>
3379 <name>UninstallFrm</name>
3380 <message>
3381 <location filename="../uninstallfrm.ui" line="16"/>
3382 <source>Uninstall Rockbox</source>
3383 <translation>Deïnstalleer Rockbox</translation>
3384 </message>
3385 <message>
3386 <location filename="../uninstallfrm.ui" line="35"/>
3387 <source>Please select the Uninstallation Method</source>
3388 <translation>Gelieve de deïnstallatie methode te selecteren</translation>
3389 </message>
3390 <message>
3391 <location filename="../uninstallfrm.ui" line="45"/>
3392 <source>Uninstallation Method</source>
3393 <translation>Deïnstallatie Methode</translation>
3394 </message>
3395 <message>
3396 <location filename="../uninstallfrm.ui" line="51"/>
3397 <source>Complete Uninstallation</source>
3398 <translation>Volledige Deïnstallatie</translation>
3399 </message>
3400 <message>
3401 <location filename="../uninstallfrm.ui" line="58"/>
3402 <source>Smart Uninstallation</source>
3403 <translation>Slimme Deïnstallatie</translation>
3404 </message>
3405 <message>
3406 <location filename="../uninstallfrm.ui" line="68"/>
3407 <source>Please select what you want to uninstall</source>
3408 <translation>Gelieve te selecteren wat u wilt deïnstalleren</translation>
3409 </message>
3410 <message>
3411 <location filename="../uninstallfrm.ui" line="78"/>
3412 <source>Installed Parts</source>
3413 <translation>Geïnstalleerde onderdelen</translation>
3414 </message>
3415 <message>
3416 <location filename="../uninstallfrm.ui" line="138"/>
3417 <source>&amp;Cancel</source>
3418 <translation>&amp;Annuleren</translation>
3419 </message>
3420 <message>
3421 <location filename="../uninstallfrm.ui" line="128"/>
3422 <source>&amp;Uninstall</source>
3423 <translation>&amp;Deïnstalleren</translation>
3424 </message>
3425</context>
3426<context>
3427 <name>Uninstaller</name>
3428 <message>
3429 <location filename="../base/uninstall.cpp" line="32"/>
3430 <location filename="../base/uninstall.cpp" line="43"/>
3431 <source>Starting Uninstallation</source>
3432 <translation>Bezig met starten van deïnstallatie</translation>
3433 </message>
3434 <message>
3435 <location filename="../base/uninstall.cpp" line="36"/>
3436 <source>Finished Uninstallation</source>
3437 <translation>Deïnstallatie voltooid</translation>
3438 </message>
3439 <message>
3440 <location filename="../base/uninstall.cpp" line="49"/>
3441 <source>Uninstalling %1...</source>
3442 <translation>%1 deïnstalleren...</translation>
3443 </message>
3444 <message>
3445 <location filename="../base/uninstall.cpp" line="80"/>
3446 <source>Could not delete %1</source>
3447 <translation>Kon %1 niet wissen</translation>
3448 </message>
3449 <message>
3450 <location filename="../base/uninstall.cpp" line="109"/>
3451 <source>Uninstallation finished</source>
3452 <translation>Deïnstallatie voltooid</translation>
3453 </message>
3454</context>
3455<context>
3456 <name>Utils</name>
3457 <message>
3458 <location filename="../base/utils.cpp" line="312"/>
3459 <source>&lt;li&gt;Permissions insufficient for bootloader installation.
3460Administrator priviledges are necessary.&lt;/li&gt;</source>
3461 <translation>&lt;li&gt;Uw machtigingen zijn niet voldoende om de Bootloader te installeren.
3462Administrator privileges zijn nodig.&lt;/li&gt;</translation>
3463 </message>
3464 <message>
3465 <location filename="../base/utils.cpp" line="324"/>
3466 <source>&lt;li&gt;Target mismatch detected.&lt;br/&gt;Installed target: %1&lt;br/&gt;Selected target: %2.&lt;/li&gt;</source>
3467 <translation>&lt;li&gt;Verkeerde combinatie gedetecteerd.&lt;br&gt;Geïnstalleerd: %1&lt;br/&gt;Gekozen: %2.&lt;/li&gt;</translation>
3468 </message>
3469 <message>
3470 <location filename="../base/utils.cpp" line="331"/>
3471 <source>Problem detected:</source>
3472 <translation>Probleem gevonden:</translation>
3473 </message>
3474</context>
3475<context>
3476 <name>VoiceFileCreator</name>
3477 <message>
3478 <location filename="../base/voicefile.cpp" line="43"/>
3479 <source>Starting Voicefile generation</source>
3480 <translation>Bezig met starten van spraakbestanden generatie</translation>
3481 </message>
3482 <message>
3483 <location filename="../base/voicefile.cpp" line="90"/>
3484 <source>Extracted voice strings from installation</source>
3485 <translation>Spraak-strings zijn uitgepakt van installatie</translation>
3486 </message>
3487 <message>
3488 <location filename="../base/voicefile.cpp" line="100"/>
3489 <source>Extracted voice strings incompatible</source>
3490 <translation>Uitgepakte spraak-strings zijn incompatibel</translation>
3491 </message>
3492 <message>
3493 <location filename="../base/voicefile.cpp" line="145"/>
3494 <source>Could not retrieve strings from installation, downloading</source>
3495 <translation>Strings konden niet uit installatie verkregen worden, worden gedownload</translation>
3496 </message>
3497 <message>
3498 <location filename="../base/voicefile.cpp" line="171"/>
3499 <source>Downloading voice info...</source>
3500 <translation>Downloaden van steminformatie...</translation>
3501 </message>
3502 <message>
3503 <location filename="../base/voicefile.cpp" line="184"/>
3504 <source>Download error: received HTTP error %1.</source>
3505 <translation>Download fout: HTTP fout %1.</translation>
3506 </message>
3507 <message>
3508 <location filename="../base/voicefile.cpp" line="191"/>
3509 <source>Cached file used.</source>
3510 <translation>Gecached bestand gebruikt.</translation>
3511 </message>
3512 <message>
3513 <location filename="../base/voicefile.cpp" line="194"/>
3514 <source>Download error: %1</source>
3515 <translation>Download fout : %1</translation>
3516 </message>
3517 <message>
3518 <location filename="../base/voicefile.cpp" line="199"/>
3519 <source>Download finished.</source>
3520 <translation>Download voltooid.</translation>
3521 </message>
3522 <message>
3523 <location filename="../base/voicefile.cpp" line="212"/>
3524 <source>failed to open downloaded file</source>
3525 <translation>kon gedownload bestand niet openen</translation>
3526 </message>
3527 <message>
3528 <location filename="../base/voicefile.cpp" line="218"/>
3529 <source>Reading strings...</source>
3530 <translation>Bezig met inlezen van zinnen...</translation>
3531 </message>
3532 <message>
3533 <location filename="../base/voicefile.cpp" line="297"/>
3534 <source>Creating voicefiles...</source>
3535 <translation>Bezig met aanmaken van spraakbestanden...</translation>
3536 </message>
3537 <message>
3538 <location filename="../base/voicefile.cpp" line="342"/>
3539 <source>Cleaning up...</source>
3540 <translation>Opruimen...</translation>
3541 </message>
3542 <message>
3543 <location filename="../base/voicefile.cpp" line="353"/>
3544 <source>Finished</source>
3545 <translation>Voltooid</translation>
3546 </message>
3547 <message>
3548 <location filename="../base/voicefile.cpp" line="271"/>
3549 <source>The downloaded file was empty!</source>
3550 <translation>Het gedownloadede bestand was leeg!</translation>
3551 </message>
3552 <message>
3553 <location filename="../base/voicefile.cpp" line="302"/>
3554 <source>Error opening downloaded file</source>
3555 <translation>Fout bij openen van gedownload bestand</translation>
3556 </message>
3557 <message>
3558 <location filename="../base/voicefile.cpp" line="313"/>
3559 <source>Error opening output file</source>
3560 <translation>Fout bij openen van output bestand</translation>
3561 </message>
3562 <message>
3563 <location filename="../base/voicefile.cpp" line="333"/>
3564 <source>successfully created.</source>
3565 <translation>succesvol gecreëerd.</translation>
3566 </message>
3567 <message>
3568 <location filename="../base/voicefile.cpp" line="56"/>
3569 <source>could not find rockbox-info.txt</source>
3570 <translation>kon het bestand rockbox-info.txt niet vinden</translation>
3571 </message>
3572</context>
3573<context>
3574 <name>ZipInstaller</name>
3575 <message>
3576 <location filename="../base/zipinstaller.cpp" line="60"/>
3577 <source>done.</source>
3578 <translation>klaar.</translation>
3579 </message>
3580 <message>
3581 <location filename="../base/zipinstaller.cpp" line="68"/>
3582 <source>Package installation finished successfully.</source>
3583 <translation>Installatie van pakket succesvol afgerond.</translation>
3584 </message>
3585 <message>
3586 <location filename="../base/zipinstaller.cpp" line="80"/>
3587 <source>Downloading file %1.%2</source>
3588 <translation>Bezig met downloaden van bestand %1.%2</translation>
3589 </message>
3590 <message>
3591 <location filename="../base/zipinstaller.cpp" line="115"/>
3592 <source>Download error: received HTTP error %1.</source>
3593 <translation>Download fout: HTTP fout %1.</translation>
3594 </message>
3595 <message>
3596 <location filename="../base/zipinstaller.cpp" line="121"/>
3597 <source>Cached file used.</source>
3598 <translation>Gecached bestand gebruikt.</translation>
3599 </message>
3600 <message>
3601 <location filename="../base/zipinstaller.cpp" line="123"/>
3602 <source>Download error: %1</source>
3603 <translation>Download fout : %1</translation>
3604 </message>
3605 <message>
3606 <location filename="../base/zipinstaller.cpp" line="127"/>
3607 <source>Download finished.</source>
3608 <translation>Download voltooid.</translation>
3609 </message>
3610 <message>
3611 <location filename="../base/zipinstaller.cpp" line="133"/>
3612 <source>Extracting file.</source>
3613 <translation>Bezig met uitpakken van bestand.</translation>
3614 </message>
3615 <message>
3616 <location filename="../base/zipinstaller.cpp" line="153"/>
3617 <source>Extraction failed!</source>
3618 <translation>Uitpakken mislukt!</translation>
3619 </message>
3620 <message>
3621 <location filename="../base/zipinstaller.cpp" line="162"/>
3622 <source>Installing file.</source>
3623 <translation>Bezig met installeren van bestand.</translation>
3624 </message>
3625 <message>
3626 <location filename="../base/zipinstaller.cpp" line="173"/>
3627 <source>Installing file failed.</source>
3628 <translation>Installeren van bestand mislukt.</translation>
3629 </message>
3630 <message>
3631 <location filename="../base/zipinstaller.cpp" line="186"/>
3632 <source>Creating installation log</source>
3633 <translation>Bezig met creëren van installatie log</translation>
3634 </message>
3635 <message>
3636 <location filename="../base/zipinstaller.cpp" line="146"/>
3637 <source>Not enough disk space! Aborting.</source>
3638 <translation>Niet genoeg schijfruimte! Bezig met afbreken.</translation>
3639 </message>
3640</context>
3641<context>
3642 <name>ZipUtil</name>
3643 <message>
3644 <location filename="../base/ziputil.cpp" line="125"/>
3645 <source>Creating output path failed</source>
3646 <translation>Aanmaken uitvoerlokatie mislukt</translation>
3647 </message>
3648 <message>
3649 <location filename="../base/ziputil.cpp" line="132"/>
3650 <source>Creating output file failed</source>
3651 <translation>Aanmaken uitvoerbestand mislukt</translation>
3652 </message>
3653 <message>
3654 <location filename="../base/ziputil.cpp" line="141"/>
3655 <source>Error during Zip operation</source>
3656 <translation>Fout tijdens Zip-bewerking</translation>
3657 </message>
3658</context>
3659<context>
3660 <name>aboutBox</name>
3661 <message>
3662 <location filename="../aboutbox.ui" line="14"/>
3663 <source>About Rockbox Utility</source>
3664 <translation>Over Rockbox Utility</translation>
3665 </message>
3666 <message>
3667 <location filename="../aboutbox.ui" line="32"/>
3668 <source>The Rockbox Utility</source>
3669 <translation>Rockbox Utility</translation>
3670 </message>
3671 <message utf8="true">
3672 <location filename="../aboutbox.ui" line="54"/>
3673 <source>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</source>
3674 <translation>Installatie en schoonmaak hulpmiddel voor de Rockbox open source digitale audio speler firmware.&lt;br/&gt;© Het Rockbox Team&lt;br/&gt;Vrijgegeven onder GNU General Public License v2.&lt;br/&gt;Gebruikt iconen van het &lt;a href=&quot;http://tango.freedesktop.org&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</translation>
3675 </message>
3676 <message>
3677 <location filename="../aboutbox.ui" line="74"/>
3678 <source>&amp;Credits</source>
3679 <translation>&amp;Medewerkers</translation>
3680 </message>
3681 <message>
3682 <location filename="../aboutbox.ui" line="106"/>
3683 <source>&amp;License</source>
3684 <translation>&amp;Licentie</translation>
3685 </message>
3686 <message>
3687 <location filename="../aboutbox.ui" line="132"/>
3688 <source>&amp;Speex License</source>
3689 <translation>&amp;Speex Licentie</translation>
3690 </message>
3691 <message>
3692 <location filename="../aboutbox.ui" line="158"/>
3693 <source>&amp;Ok</source>
3694 <translation>&amp;OK</translation>
3695 </message>
3696</context>
3697</TS>
diff --git a/utils/rbutilqt/lang/rbutil_pl.ts b/utils/rbutilqt/lang/rbutil_pl.ts
new file mode 100644
index 0000000000..3bf1f43eef
--- /dev/null
+++ b/utils/rbutilqt/lang/rbutil_pl.ts
@@ -0,0 +1,3696 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE TS>
3<TS version="2.0" language="pl_PL" sourcelanguage="pl_PL">
4<context>
5 <name>BackupDialog</name>
6 <message>
7 <location filename="../gui/backupdialogfrm.ui" line="17"/>
8 <location filename="../gui/backupdialogfrm.ui" line="43"/>
9 <source>Backup</source>
10 <translation type="unfinished">Kopia zapasowa</translation>
11 </message>
12 <message>
13 <location filename="../gui/backupdialogfrm.ui" line="33"/>
14 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This dialog will create a backup by archiving the contents of the Rockbox installation on the player into a zip file. This will include installed themes and settings stored below the .rockbox folder on the player.&lt;/p&gt;&lt;p&gt;The backup filename will be created based on the installed version. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
15 <translation type="unfinished">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;W tym oknie wykonasz kopię zapasową, archiwizując do pliku zip instalację Rockboxa znajdującą się na odtwarzaczu. Archiwum będzie zawierać wcześniej zainstalowane style i ustawienia znajdujące się w folderze .rockbox.&lt;/p&gt;&lt;p&gt;Nazwa dla pliku archiwum będzie dobrana na podstawie zainstalowanej wersji Rockboxa. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
16 </message>
17 <message>
18 <location filename="../gui/backupdialogfrm.ui" line="49"/>
19 <source>Size: unknown</source>
20 <translation type="unfinished">Rozmiar: nieznany</translation>
21 </message>
22 <message>
23 <location filename="../gui/backupdialogfrm.ui" line="56"/>
24 <source>Backup to: unknown</source>
25 <translation type="unfinished">Utwórz do: nieznany</translation>
26 </message>
27 <message>
28 <location filename="../gui/backupdialogfrm.ui" line="76"/>
29 <source>&amp;Change</source>
30 <translation type="unfinished">&amp;Zmień</translation>
31 </message>
32 <message>
33 <location filename="../gui/backupdialogfrm.ui" line="116"/>
34 <source>&amp;Backup</source>
35 <translation type="unfinished">&amp;Utwórz</translation>
36 </message>
37 <message>
38 <location filename="../gui/backupdialogfrm.ui" line="127"/>
39 <source>&amp;Cancel</source>
40 <translation type="unfinished">&amp;Anuluj</translation>
41 </message>
42 <message>
43 <location filename="../gui/backupdialog.cpp" line="70"/>
44 <source>Installation size: calculating ...</source>
45 <translation type="unfinished">Rozmiar archiwum: obliczanie...</translation>
46 </message>
47 <message>
48 <location filename="../gui/backupdialog.cpp" line="89"/>
49 <source>Select Backup Filename</source>
50 <translation type="unfinished">Wybierz nazwę dla kopii</translation>
51 </message>
52 <message>
53 <location filename="../gui/backupdialog.cpp" line="109"/>
54 <source>Installation size: %L1 %2</source>
55 <translation type="unfinished">Rozmiar archiwum: %L1 %2</translation>
56 </message>
57 <message>
58 <location filename="../gui/backupdialog.cpp" line="116"/>
59 <source>File exists</source>
60 <translation type="unfinished">Plik istnieje</translation>
61 </message>
62 <message>
63 <location filename="../gui/backupdialog.cpp" line="117"/>
64 <source>The selected backup file already exists. Overwrite?</source>
65 <translation type="unfinished">Plik kopii zapasowej o takiej nazwie już istnieje. Zamienić obecną wersję na nową?</translation>
66 </message>
67 <message>
68 <location filename="../gui/backupdialog.cpp" line="125"/>
69 <source>Starting backup ...</source>
70 <translation type="unfinished">Rozpoczynanie wykonywania kopii zapasowej...</translation>
71 </message>
72 <message>
73 <location filename="../gui/backupdialog.cpp" line="144"/>
74 <source>Backup successful.</source>
75 <translation type="unfinished">Kopia zapasowa wykonana pomyślnie.</translation>
76 </message>
77 <message>
78 <location filename="../gui/backupdialog.cpp" line="147"/>
79 <source>Backup failed!</source>
80 <translation type="unfinished">Nie udało się wykonać kopii zapasowej!</translation>
81 </message>
82</context>
83<context>
84 <name>BootloaderInstallAms</name>
85 <message>
86 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
87 <translation type="obsolete">Przy instalacji bootloadera potrzebny jest oryginalny firmware dostarczany przez Sandisk (plik bin). Oryginalny plik zostanie zmodyfikowany tak aby zawierał bootloader rockboxa, a następnie zostanie wgrany do urządzenia. Oryginalny firmware musisz pobrać samodzielnie z powodów licencyjnych. Proszę przejdź pod adres &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt; forum Sansy&lt;/a&gt; lub zapoznaj się z &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;instrukcją&lt;/a&gt; oraz stroną wiki o &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt;, gdzie dowiesz się jak pobrać plik.&lt;/br&gt;Naciśnij Ok aby kontynuować i wyszukać plik na komputerze.</translation>
88 </message>
89 <message>
90 <location filename="../base/bootloaderinstallams.cpp" line="33"/>
91 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; This file is not present on your player and will disappear automatically after installing it.&lt;br/&gt;&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
92 <translation type="unfinished">Instalacja bootloadera wymaga oryginalnego pliku firmware dostarczanego przez Sandisk (plik bin). Oryginalny plik zostanie zmodyfikowany tak aby zawierał bootloader rockboxa, a następnie zostanie wgrany do urządzenia. Oryginalny firmware musisz pobrać samodzielnie z powodów licencyjnych. Proszę przejdź pod adres &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt; forum Sansy&lt;/a&gt; lub zapoznaj się z &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;instrukcją&lt;/a&gt; oraz stroną wiki o &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt;, gdzie dowiesz się jak pobrać plik.&lt;br/&gt;&lt;b&gt;Uwaga:&lt;/b&gt; Ten plik nie jest obecny na twoim odtwarzaczu i zniknie automatycznie po jego instalacji.&lt;br/&gt;&lt;/br&gt;Naciśnij Ok aby kontynuować i wyszukać plik na komputerze.</translation>
93 </message>
94 <message>
95 <location filename="../base/bootloaderinstallams.cpp" line="58"/>
96 <source>Downloading bootloader file</source>
97 <translation>Pobieranie pliku bootloadera</translation>
98 </message>
99 <message>
100 <location filename="../base/bootloaderinstallams.cpp" line="100"/>
101 <location filename="../base/bootloaderinstallams.cpp" line="113"/>
102 <source>Could not load %1</source>
103 <translation>Nie można załadować %1</translation>
104 </message>
105 <message>
106 <location filename="../base/bootloaderinstallams.cpp" line="127"/>
107 <source>No room to insert bootloader, try another firmware version</source>
108 <translation type="unfinished">Za mało miejsca na wstawienie bootloadera, spróbuj inną wersję firmware</translation>
109 </message>
110 <message>
111 <location filename="../base/bootloaderinstallams.cpp" line="137"/>
112 <source>Patching Firmware...</source>
113 <translation>Patchowanie firmware...</translation>
114 </message>
115 <message>
116 <location filename="../base/bootloaderinstallams.cpp" line="148"/>
117 <source>Could not open %1 for writing</source>
118 <translation>Nie można otworzyć %1 w celu zapisania</translation>
119 </message>
120 <message>
121 <location filename="../base/bootloaderinstallams.cpp" line="161"/>
122 <source>Could not write firmware file</source>
123 <translation>Nie można zapisac pliku firmware</translation>
124 </message>
125 <message>
126 <location filename="../base/bootloaderinstallams.cpp" line="177"/>
127 <source>Success: modified firmware file created</source>
128 <translation>Sukces: stworzono zmodyfikowany firmware</translation>
129 </message>
130 <message>
131 <location filename="../base/bootloaderinstallams.cpp" line="185"/>
132 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
133 <translation type="unfinished">Aby odinstalować bootloadera, przeprowadź normalny proces aktualizacji używając oryginalnego, niemodyfikowanego pliku z oryginalnym firmware</translation>
134 </message>
135</context>
136<context>
137 <name>BootloaderInstallBase</name>
138 <message>
139 <location filename="../base/bootloaderinstallbase.cpp" line="78"/>
140 <source>Download error: received HTTP error %1.</source>
141 <translation>Błąd pobierania: błąd serwera HTTP %1.</translation>
142 </message>
143 <message>
144 <location filename="../base/bootloaderinstallbase.cpp" line="84"/>
145 <source>Download error: %1</source>
146 <translation>Błąd pobierania: %1</translation>
147 </message>
148 <message>
149 <location filename="../base/bootloaderinstallbase.cpp" line="90"/>
150 <source>Download finished (cache used).</source>
151 <translation>Pobieranie zakończone (użyto bufora).</translation>
152 </message>
153 <message>
154 <location filename="../base/bootloaderinstallbase.cpp" line="92"/>
155 <source>Download finished.</source>
156 <translation>Pobieranie zakończone.</translation>
157 </message>
158 <message>
159 <location filename="../base/bootloaderinstallbase.cpp" line="113"/>
160 <source>Creating backup of original firmware file.</source>
161 <translation>Tworzenie kopii zapasowej oryginalnego firmware.</translation>
162 </message>
163 <message>
164 <location filename="../base/bootloaderinstallbase.cpp" line="115"/>
165 <source>Creating backup folder failed</source>
166 <translation>Nie można utworzyć nowego folderu</translation>
167 </message>
168 <message>
169 <location filename="../base/bootloaderinstallbase.cpp" line="121"/>
170 <source>Creating backup copy failed.</source>
171 <translation>Nie można utworzyć nowego folderu.</translation>
172 </message>
173 <message>
174 <location filename="../base/bootloaderinstallbase.cpp" line="124"/>
175 <source>Backup created.</source>
176 <translation>Kopia została utworzona.</translation>
177 </message>
178 <message>
179 <location filename="../base/bootloaderinstallbase.cpp" line="137"/>
180 <source>Creating installation log</source>
181 <translation type="unfinished">Tworzenie dziennika zdarzeń instalacji</translation>
182 </message>
183 <message>
184 <location filename="../base/bootloaderinstallbase.cpp" line="149"/>
185 <source>Installation log created</source>
186 <translation type="unfinished">Utworzono dziennik zdarzeń instalacji</translation>
187 </message>
188 <message>
189 <location filename="../base/bootloaderinstallbase.cpp" line="226"/>
190 <source>Zip file format detected</source>
191 <translation type="unfinished">Wykryto format Zip</translation>
192 </message>
193 <message>
194 <location filename="../base/bootloaderinstallbase.cpp" line="238"/>
195 <source>CAB file format detected</source>
196 <translation type="unfinished">Wykryto format CAB</translation>
197 </message>
198 <message>
199 <location filename="../base/bootloaderinstallbase.cpp" line="259"/>
200 <source>Extracting firmware %1 from archive</source>
201 <translation type="unfinished">Wypakowywanie firmware %1 z archiwum</translation>
202 </message>
203 <message>
204 <location filename="../base/bootloaderinstallbase.cpp" line="266"/>
205 <source>Error extracting firmware from archive</source>
206 <translation type="unfinished">Błąd podczas wypakowywania archiwum</translation>
207 </message>
208 <message>
209 <location filename="../base/bootloaderinstallbase.cpp" line="275"/>
210 <source>Could not find firmware in archive</source>
211 <translation type="unfinished">Nie można odnaleźć firmware w archiwum</translation>
212 </message>
213 <message>
214 <location filename="../base/bootloaderinstallbase.cpp" line="159"/>
215 <source>Waiting for system to remount player</source>
216 <translation>Czekaj aż system zamontuje urządzenie ponownie</translation>
217 </message>
218 <message>
219 <location filename="../base/bootloaderinstallbase.cpp" line="189"/>
220 <source>Player remounted</source>
221 <translation>Odtwarzacz ponownie zamontowany</translation>
222 </message>
223 <message>
224 <location filename="../base/bootloaderinstallbase.cpp" line="194"/>
225 <source>Timeout on remount</source>
226 <translation>Czas potrzebny na ponowne zamontowanie się skończył</translation>
227 </message>
228</context>
229<context>
230 <name>BootloaderInstallChinaChip</name>
231 <message>
232 <location filename="../base/bootloaderinstallchinachip.cpp" line="33"/>
233 <source>Bootloader installation requires you to provide a firmware file of the original firmware (HXF file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
234 <translation type="unfinished">Instalacja bootloadera wymaga dostarczenia oryginalnego pliku firmware (.HXF). Musisz samodzielnie pobrać plik aby być w zgodzie z prawem. Przejdź do &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;instrukcji&lt;/a&gt; lub do &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;strony wiki o OndaVX747&lt;/a&gt;, gdzie dowiesz się jak pobrać plik.&lt;br/&gt;Naciśnij Ok aby kontynuować.</translation>
235 </message>
236 <message>
237 <location filename="../base/bootloaderinstallchinachip.cpp" line="50"/>
238 <source>Downloading bootloader file</source>
239 <translation>Pobieranie pliku firmware</translation>
240 </message>
241 <message>
242 <location filename="../base/bootloaderinstallchinachip.cpp" line="75"/>
243 <source>Could not open firmware file</source>
244 <translation type="unfinished">Nie można otworzyć pliku firmware</translation>
245 </message>
246 <message>
247 <location filename="../base/bootloaderinstallchinachip.cpp" line="78"/>
248 <source>Could not open bootloader file</source>
249 <translation type="unfinished">Nie można otworzyć pliku bootloadera</translation>
250 </message>
251 <message>
252 <location filename="../base/bootloaderinstallchinachip.cpp" line="81"/>
253 <source>Could not allocate memory</source>
254 <translation type="unfinished">Nie można zaalokować pamięci</translation>
255 </message>
256 <message>
257 <location filename="../base/bootloaderinstallchinachip.cpp" line="84"/>
258 <source>Could not load firmware file</source>
259 <translation type="unfinished">Nie można załadować pliku firmware</translation>
260 </message>
261 <message>
262 <location filename="../base/bootloaderinstallchinachip.cpp" line="87"/>
263 <source>File is not a valid ChinaChip firmware</source>
264 <translation type="unfinished">Dany plik nie jest plikiem firmware ChinaChip</translation>
265 </message>
266 <message>
267 <location filename="../base/bootloaderinstallchinachip.cpp" line="90"/>
268 <source>Could not find ccpmp.bin in input file</source>
269 <translation type="unfinished">Nie można odnaleźć ccpmp.bin w pliku wejściowym</translation>
270 </message>
271 <message>
272 <location filename="../base/bootloaderinstallchinachip.cpp" line="93"/>
273 <source>Could not open backup file for ccpmp.bin</source>
274 <translation type="unfinished">Nie można otworzyć kopii zapasowej ccpmp.bin</translation>
275 </message>
276 <message>
277 <location filename="../base/bootloaderinstallchinachip.cpp" line="96"/>
278 <source>Could not write backup file for ccpmp.bin</source>
279 <translation type="unfinished">Nie można utworzyć kopii zapasowej ccpmp.bin</translation>
280 </message>
281 <message>
282 <location filename="../base/bootloaderinstallchinachip.cpp" line="99"/>
283 <source>Could not load bootloader file</source>
284 <translation type="unfinished">Nie można załadować pliku bootloadera</translation>
285 </message>
286 <message>
287 <location filename="../base/bootloaderinstallchinachip.cpp" line="102"/>
288 <source>Could not get current time</source>
289 <translation type="unfinished">Nie można pobrać aktualnej godziny</translation>
290 </message>
291 <message>
292 <location filename="../base/bootloaderinstallchinachip.cpp" line="105"/>
293 <source>Could not open output file</source>
294 <translation type="unfinished">Nie można otworzyć pliku wyjściowego</translation>
295 </message>
296 <message>
297 <location filename="../base/bootloaderinstallchinachip.cpp" line="108"/>
298 <source>Could not write output file</source>
299 <translation type="unfinished">Nie można zapisać pliku wyjściowego</translation>
300 </message>
301 <message>
302 <location filename="../base/bootloaderinstallchinachip.cpp" line="111"/>
303 <source>Unexpected error from chinachippatcher</source>
304 <translation type="unfinished">Niespodziewany błąd chinachippatchera</translation>
305 </message>
306</context>
307<context>
308 <name>BootloaderInstallFile</name>
309 <message>
310 <location filename="../base/bootloaderinstallfile.cpp" line="34"/>
311 <source>Downloading bootloader</source>
312 <translation>Pobieranie bootloadera</translation>
313 </message>
314 <message>
315 <location filename="../base/bootloaderinstallfile.cpp" line="43"/>
316 <source>Installing Rockbox bootloader</source>
317 <translation>Instalowanie bootloadera Rockboxa</translation>
318 </message>
319 <message>
320 <location filename="../base/bootloaderinstallfile.cpp" line="75"/>
321 <source>Error accessing output folder</source>
322 <translation>Brak dostępu do folderu wyjściowego</translation>
323 </message>
324 <message>
325 <location filename="../base/bootloaderinstallfile.cpp" line="89"/>
326 <source>A firmware file is already present on player</source>
327 <translation type="unfinished">Plik firmware już znajduje się w odtwarzaczu</translation>
328 </message>
329 <message>
330 <location filename="../base/bootloaderinstallfile.cpp" line="94"/>
331 <source>Bootloader successful installed</source>
332 <translation>Bootloader zainstalowany pomyślnie</translation>
333 </message>
334 <message>
335 <location filename="../base/bootloaderinstallfile.cpp" line="97"/>
336 <source>Copying modified firmware file failed</source>
337 <translation type="unfinished">Kopiowanie zmodyfikowanego pliku firmware nie powiodło się</translation>
338 </message>
339 <message>
340 <location filename="../base/bootloaderinstallfile.cpp" line="111"/>
341 <source>Removing Rockbox bootloader</source>
342 <translation>Usuwanie bootloadera Rockboxa</translation>
343 </message>
344 <message>
345 <location filename="../base/bootloaderinstallfile.cpp" line="115"/>
346 <source>No original firmware file found.</source>
347 <translation>Nie znaleziono pliku oryginalnego firmware.</translation>
348 </message>
349 <message>
350 <location filename="../base/bootloaderinstallfile.cpp" line="121"/>
351 <source>Can&apos;t remove Rockbox bootloader file.</source>
352 <translation>Nie można usunąć plik bootloadera Rockboxa.</translation>
353 </message>
354 <message>
355 <location filename="../base/bootloaderinstallfile.cpp" line="126"/>
356 <source>Can&apos;t restore bootloader file.</source>
357 <translation>Nie można przywrócić pliku bootloadera.</translation>
358 </message>
359 <message>
360 <location filename="../base/bootloaderinstallfile.cpp" line="130"/>
361 <source>Original bootloader restored successfully.</source>
362 <translation>Oryginalny bootloader przywrócony pomyslnie.</translation>
363 </message>
364</context>
365<context>
366 <name>BootloaderInstallHex</name>
367 <message>
368 <location filename="../base/bootloaderinstallhex.cpp" line="50"/>
369 <source>Bootloader installation requires you to provide a firmware file of the original firmware (hex file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
370 <translation type="unfinished">Instalacja bootloadera wymaga dostarczenia oryginalnego pliku firmware (.hex). Musisz samodzielnie pobrać plik aby być w zgodzie z prawem. Przejdź do &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;instrukcji&lt;/a&gt; lub do &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;strony wiki o IriverBoot&lt;/a&gt;, gdzie dowiesz się jak pobrać plik.&lt;br/&gt;Naciśnij Ok aby kontynuować.</translation>
371 </message>
372 <message>
373 <location filename="../base/bootloaderinstallhex.cpp" line="69"/>
374 <source>checking MD5 hash of input file ...</source>
375 <translation>sprawdzanie sumy kontrolnej MD5 pliku wejściowego...</translation>
376 </message>
377 <message>
378 <location filename="../base/bootloaderinstallhex.cpp" line="80"/>
379 <source>Could not verify original firmware file</source>
380 <translation>Nie można zweryfikować oryginalnego pliku firmware</translation>
381 </message>
382 <message>
383 <location filename="../base/bootloaderinstallhex.cpp" line="95"/>
384 <source>Firmware file not recognized.</source>
385 <translation>Nie rozpoznano pliku firmware.</translation>
386 </message>
387 <message>
388 <location filename="../base/bootloaderinstallhex.cpp" line="99"/>
389 <source>MD5 hash ok</source>
390 <translation>Suma MD5 ok</translation>
391 </message>
392 <message>
393 <location filename="../base/bootloaderinstallhex.cpp" line="106"/>
394 <source>Firmware file doesn&apos;t match selected player.</source>
395 <translation>Plik firmware nie pasuje do wybranego odtwarzacza.</translation>
396 </message>
397 <message>
398 <location filename="../base/bootloaderinstallhex.cpp" line="111"/>
399 <source>Descrambling file</source>
400 <translation>Dekryptowanie pliku</translation>
401 </message>
402 <message>
403 <location filename="../base/bootloaderinstallhex.cpp" line="119"/>
404 <source>Error in descramble: %1</source>
405 <translation>Błąd przy dekryptowaniu: %1</translation>
406 </message>
407 <message>
408 <location filename="../base/bootloaderinstallhex.cpp" line="124"/>
409 <source>Downloading bootloader file</source>
410 <translation>Pobieranie pliku bootloadera</translation>
411 </message>
412 <message>
413 <location filename="../base/bootloaderinstallhex.cpp" line="134"/>
414 <source>Adding bootloader to firmware file</source>
415 <translation>Dołączanie bootloadera do pliku firmware</translation>
416 </message>
417 <message>
418 <location filename="../base/bootloaderinstallhex.cpp" line="172"/>
419 <source>could not open input file</source>
420 <translation>nie można otworzyć pliku wejściowego</translation>
421 </message>
422 <message>
423 <location filename="../base/bootloaderinstallhex.cpp" line="173"/>
424 <source>reading header failed</source>
425 <translation>błąd odczytu nagłówka</translation>
426 </message>
427 <message>
428 <location filename="../base/bootloaderinstallhex.cpp" line="174"/>
429 <source>reading firmware failed</source>
430 <translation>błąd odczytu firmware</translation>
431 </message>
432 <message>
433 <location filename="../base/bootloaderinstallhex.cpp" line="175"/>
434 <source>can&apos;t open bootloader file</source>
435 <translation>nie można otworzyć pliku bootloadera</translation>
436 </message>
437 <message>
438 <location filename="../base/bootloaderinstallhex.cpp" line="176"/>
439 <source>reading bootloader file failed</source>
440 <translation>odczytanie bootloadera nie powiodło się</translation>
441 </message>
442 <message>
443 <location filename="../base/bootloaderinstallhex.cpp" line="177"/>
444 <source>can&apos;t open output file</source>
445 <translation>nie można otworzyć pliku wyjściowego</translation>
446 </message>
447 <message>
448 <location filename="../base/bootloaderinstallhex.cpp" line="178"/>
449 <source>writing output file failed</source>
450 <translation>zapisywanie pliku wyjściowego nie powiodło się</translation>
451 </message>
452 <message>
453 <location filename="../base/bootloaderinstallhex.cpp" line="180"/>
454 <source>Error in patching: %1</source>
455 <translation>Błąd przy patchowaniu: %1</translation>
456 </message>
457 <message>
458 <location filename="../base/bootloaderinstallhex.cpp" line="191"/>
459 <source>Error in scramble: %1</source>
460 <translation>Błąd przy kryptowaniu: %1</translation>
461 </message>
462 <message>
463 <location filename="../base/bootloaderinstallhex.cpp" line="206"/>
464 <source>Checking modified firmware file</source>
465 <translation>Sprawdzanie zmodyfikowanego firmware</translation>
466 </message>
467 <message>
468 <location filename="../base/bootloaderinstallhex.cpp" line="208"/>
469 <source>Error: modified file checksum wrong</source>
470 <translation>Błąd: zła suma kontrolna</translation>
471 </message>
472 <message>
473 <location filename="../base/bootloaderinstallhex.cpp" line="215"/>
474 <source>A firmware file is already present on player</source>
475 <translation type="unfinished">Plik firmware już znajduje się w odtwarzaczu</translation>
476 </message>
477 <message>
478 <location filename="../base/bootloaderinstallhex.cpp" line="220"/>
479 <source>Success: modified firmware file created</source>
480 <translation>Sukces: stworzono zmodyfikowany firmware</translation>
481 </message>
482 <message>
483 <location filename="../base/bootloaderinstallhex.cpp" line="223"/>
484 <source>Copying modified firmware file failed</source>
485 <translation type="unfinished">Kopiowanie zmodyfikowanego pliku firmware nie powiodło się</translation>
486 </message>
487 <message>
488 <location filename="../base/bootloaderinstallhex.cpp" line="237"/>
489 <source>Uninstallation not possible, only installation info removed</source>
490 <translation type="unfinished">Odinstalowanie nie jest możliwe, usunięto tylko informację o instalacji</translation>
491 </message>
492 <message>
493 <location filename="../base/bootloaderinstallhex.cpp" line="258"/>
494 <source>Can&apos;t open input file</source>
495 <translation>Nie można otworzyć pliku wejściowego</translation>
496 </message>
497 <message>
498 <location filename="../base/bootloaderinstallhex.cpp" line="259"/>
499 <source>Can&apos;t open output file</source>
500 <translation>Nie można otworzyć pliku wyjściowego</translation>
501 </message>
502 <message>
503 <location filename="../base/bootloaderinstallhex.cpp" line="260"/>
504 <source>invalid file: header length wrong</source>
505 <translation>błąd pliku: zła długość nagłówka</translation>
506 </message>
507 <message>
508 <location filename="../base/bootloaderinstallhex.cpp" line="261"/>
509 <source>invalid file: unrecognized header</source>
510 <translation>błąd pliku: nie rozpoznano nagłówka</translation>
511 </message>
512 <message>
513 <location filename="../base/bootloaderinstallhex.cpp" line="262"/>
514 <source>invalid file: &quot;length&quot; field wrong</source>
515 <translation>błąd pliku: złe pole &quot;długość&quot;</translation>
516 </message>
517 <message>
518 <location filename="../base/bootloaderinstallhex.cpp" line="263"/>
519 <source>invalid file: &quot;length2&quot; field wrong</source>
520 <translation>błąd pliku: złe pole &quot;długość2&quot;</translation>
521 </message>
522 <message>
523 <location filename="../base/bootloaderinstallhex.cpp" line="264"/>
524 <source>invalid file: internal checksum error</source>
525 <translation>błąd pliku: błąd wewnętrznej sumy kontrolnej</translation>
526 </message>
527 <message>
528 <location filename="../base/bootloaderinstallhex.cpp" line="265"/>
529 <source>invalid file: &quot;length3&quot; field wrong</source>
530 <translation>błąd pliku: złe pole :długość3&quot;</translation>
531 </message>
532 <message>
533 <location filename="../base/bootloaderinstallhex.cpp" line="266"/>
534 <source>unknown</source>
535 <translation>nieznany</translation>
536 </message>
537</context>
538<context>
539 <name>BootloaderInstallImx</name>
540 <message>
541 <location filename="../base/bootloaderinstallimx.cpp" line="72"/>
542 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (firmware.sb file). This file will be patched with the Rockbox bootloader and installed to your player. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
543 <translation type="unfinished">Instalacja bootloadera wymaga oryginalnego pliku firmware dostarczanego przez Sandisk (plik sb). Oryginalny plik zostanie zmodyfikowany tak aby zawierał bootloader rockboxa, a następnie zostanie wgrany do urządzenia. Oryginalny firmware musisz pobrać samodzielnie z powodów licencyjnych. Proszę przejdź pod adres &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;forum Sansy&lt;/a&gt; lub zapoznaj się ze stroną wiki o &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt;, gdzie dowiesz się jak pobrać plik.&lt;/br&gt;Naciśnij Ok aby kontynuować.</translation>
544 </message>
545 <message>
546 <location filename="../base/bootloaderinstallimx.cpp" line="94"/>
547 <source>Could not read original firmware file</source>
548 <translation type="unfinished">Nie można wczytać oryginalnego pliku firmware</translation>
549 </message>
550 <message>
551 <location filename="../base/bootloaderinstallimx.cpp" line="100"/>
552 <source>Downloading bootloader file</source>
553 <translation type="unfinished">Pobieranie pliku bootloadera</translation>
554 </message>
555 <message>
556 <location filename="../base/bootloaderinstallimx.cpp" line="110"/>
557 <source>Patching file...</source>
558 <translation type="unfinished">Patchowanie pliku...</translation>
559 </message>
560 <message>
561 <location filename="../base/bootloaderinstallimx.cpp" line="137"/>
562 <source>Patching the original firmware failed</source>
563 <translation type="unfinished">Patchowanie pliku oryginalnego firmware zakończone niepowodzeniem</translation>
564 </message>
565 <message>
566 <location filename="../base/bootloaderinstallimx.cpp" line="143"/>
567 <source>Succesfully patched firmware file</source>
568 <translation type="unfinished">Oryginalny plik firmware spatchowany pomyślnie</translation>
569 </message>
570 <message>
571 <location filename="../base/bootloaderinstallimx.cpp" line="158"/>
572 <source>Bootloader successful installed</source>
573 <translation type="unfinished">Bootloader zainstalowany pomyślnie</translation>
574 </message>
575 <message>
576 <location filename="../base/bootloaderinstallimx.cpp" line="164"/>
577 <source>Patched bootloader could not be installed</source>
578 <translation type="unfinished">Spatchowany plik bootloadera nie może być zainstalowany</translation>
579 </message>
580 <message>
581 <location filename="../base/bootloaderinstallimx.cpp" line="175"/>
582 <source>To uninstall, perform a normal upgrade with an unmodified original firmware.</source>
583 <translation type="unfinished">Aby odinstalować, przeprowadź standardową aktualizację oryginalnym firmware.</translation>
584 </message>
585</context>
586<context>
587 <name>BootloaderInstallIpod</name>
588 <message>
589 <location filename="../base/bootloaderinstallipod.cpp" line="49"/>
590 <source>Error: can&apos;t allocate buffer memory!</source>
591 <translation>Błąd: nie można zaalokować pamięci dla bufora!</translation>
592 </message>
593 <message>
594 <location filename="../base/bootloaderinstallipod.cpp" line="80"/>
595 <source>Downloading bootloader file</source>
596 <translation>Pobieranie pliku bootloadera</translation>
597 </message>
598 <message>
599 <location filename="../base/bootloaderinstallipod.cpp" line="90"/>
600 <source>Installing Rockbox bootloader</source>
601 <translation>Instalowanie bootloadera Rockboxa</translation>
602 </message>
603 <message>
604 <location filename="../base/bootloaderinstallipod.cpp" line="64"/>
605 <location filename="../base/bootloaderinstallipod.cpp" line="151"/>
606 <source>Failed to read firmware directory</source>
607 <translation>Nie ma dostępu do folderu z firmware</translation>
608 </message>
609 <message>
610 <location filename="../base/bootloaderinstallipod.cpp" line="69"/>
611 <location filename="../base/bootloaderinstallipod.cpp" line="156"/>
612 <source>Unknown version number in firmware (%1)</source>
613 <translation>Nieznany numer wersji firmware (%1)</translation>
614 </message>
615 <message>
616 <location filename="../base/bootloaderinstallipod.cpp" line="75"/>
617 <source>Warning: This is a MacPod, Rockbox only runs on WinPods.
618See http://www.rockbox.org/wiki/IpodConversionToFAT32</source>
619 <translation>Ostrzeżenie: Posiadasz MacPod&apos;a, Rockbox działa jedynie na WinPod&apos;ach.
620Zobacz http://www.rockbox.org/wiki/IpodConversionToFAT32</translation>
621 </message>
622 <message>
623 <location filename="../base/bootloaderinstallipod.cpp" line="94"/>
624 <location filename="../base/bootloaderinstallipod.cpp" line="163"/>
625 <source>Could not open Ipod in R/W mode</source>
626 <translation>Nie można otworzyć iPoda w trybie odczytu/zapisu</translation>
627 </message>
628 <message>
629 <location filename="../base/bootloaderinstallipod.cpp" line="104"/>
630 <source>Successfull added bootloader</source>
631 <translation>Bootloader został dodany pomyślnie</translation>
632 </message>
633 <message>
634 <location filename="../base/bootloaderinstallipod.cpp" line="115"/>
635 <source>Failed to add bootloader</source>
636 <translation>Nie udało sie dodać bootloadera</translation>
637 </message>
638 <message>
639 <location filename="../base/bootloaderinstallipod.cpp" line="127"/>
640 <source>Bootloader Installation complete.</source>
641 <translation>Zakończono instalację bootloadera.</translation>
642 </message>
643 <message>
644 <location filename="../base/bootloaderinstallipod.cpp" line="132"/>
645 <source>Writing log aborted</source>
646 <translation>Przerwano zapisywanie dziennika zdarzeń</translation>
647 </message>
648 <message>
649 <location filename="../base/bootloaderinstallipod.cpp" line="142"/>
650 <source>Uninstalling bootloader</source>
651 <translation>Odinstalowywanie bootloadera</translation>
652 </message>
653 <message>
654 <location filename="../base/bootloaderinstallipod.cpp" line="169"/>
655 <source>No bootloader detected.</source>
656 <translation>Bootloader nie został wykryty.</translation>
657 </message>
658 <message>
659 <location filename="../base/bootloaderinstallipod.cpp" line="175"/>
660 <source>Successfully removed bootloader</source>
661 <translation>Bootloader został pomyślnie usunięty</translation>
662 </message>
663 <message>
664 <location filename="../base/bootloaderinstallipod.cpp" line="182"/>
665 <source>Removing bootloader failed.</source>
666 <translation>Nie udało się usunąć bootloadera.</translation>
667 </message>
668 <message>
669 <location filename="../base/bootloaderinstallipod.cpp" line="228"/>
670 <source>Error: could not retrieve device name</source>
671 <translation type="unfinished">Błąd: Nie można znaleźć nazwy urządzenia</translation>
672 </message>
673 <message>
674 <location filename="../base/bootloaderinstallipod.cpp" line="244"/>
675 <source>Error: no mountpoint specified!</source>
676 <translation>Błąd: punkt montowania nie został podany!</translation>
677 </message>
678 <message>
679 <location filename="../base/bootloaderinstallipod.cpp" line="249"/>
680 <source>Could not open Ipod: permission denied</source>
681 <translation>Nie można otworzyć iPoda: dostęp zabroniony</translation>
682 </message>
683 <message>
684 <location filename="../base/bootloaderinstallipod.cpp" line="253"/>
685 <source>Could not open Ipod</source>
686 <translation>Nie można otworzyć iPoda</translation>
687 </message>
688 <message>
689 <location filename="../base/bootloaderinstallipod.cpp" line="258"/>
690 <source>Error reading partition table - possibly not an Ipod</source>
691 <translation>Błąd odczytu tablicy partycji - możliwe że urządzenie nie jest iPodem</translation>
692 </message>
693 <message>
694 <location filename="../base/bootloaderinstallipod.cpp" line="264"/>
695 <source>No firmware partition on disk</source>
696 <translation>Dysk nie ma partycji z firmware</translation>
697 </message>
698</context>
699<context>
700 <name>BootloaderInstallMi4</name>
701 <message>
702 <location filename="../base/bootloaderinstallmi4.cpp" line="34"/>
703 <source>Downloading bootloader</source>
704 <translation>Pobieranie bootloadera</translation>
705 </message>
706 <message>
707 <location filename="../base/bootloaderinstallmi4.cpp" line="43"/>
708 <source>Installing Rockbox bootloader</source>
709 <translation>Instalowanie bootloadera Rockboxa</translation>
710 </message>
711 <message>
712 <location filename="../base/bootloaderinstallmi4.cpp" line="66"/>
713 <source>A firmware file is already present on player</source>
714 <translation type="unfinished">Plik firmware już znajduje się w odtwarzaczu</translation>
715 </message>
716 <message>
717 <location filename="../base/bootloaderinstallmi4.cpp" line="71"/>
718 <location filename="../base/bootloaderinstallmi4.cpp" line="79"/>
719 <source>Bootloader successful installed</source>
720 <translation>Bootloader zainstalowany pomyślnie</translation>
721 </message>
722 <message>
723 <location filename="../base/bootloaderinstallmi4.cpp" line="74"/>
724 <source>Copying modified firmware file failed</source>
725 <translation type="unfinished">Kopiowanie zmodyfikowanego pliku firmware nie powiodło się</translation>
726 </message>
727 <message>
728 <location filename="../base/bootloaderinstallmi4.cpp" line="91"/>
729 <source>Checking for Rockbox bootloader</source>
730 <translation>Sprawdzanie dostepności bootloadera Rockboxa</translation>
731 </message>
732 <message>
733 <location filename="../base/bootloaderinstallmi4.cpp" line="93"/>
734 <source>No Rockbox bootloader found</source>
735 <translation>Nie znaleziono bootloadera Rockboxa</translation>
736 </message>
737 <message>
738 <location filename="../base/bootloaderinstallmi4.cpp" line="98"/>
739 <source>Checking for original firmware file</source>
740 <translation>Sprawdzanie dostępności oryginalego firmware</translation>
741 </message>
742 <message>
743 <location filename="../base/bootloaderinstallmi4.cpp" line="103"/>
744 <source>Error finding original firmware file</source>
745 <translation>Nie znaleziono oryginalnego pliku firmware</translation>
746 </message>
747 <message>
748 <location filename="../base/bootloaderinstallmi4.cpp" line="113"/>
749 <source>Rockbox bootloader successful removed</source>
750 <translation>Bootloader Rockboxa pomyślnie odinstalowany</translation>
751 </message>
752</context>
753<context>
754 <name>BootloaderInstallMpio</name>
755 <message>
756 <location filename="../base/bootloaderinstallmpio.cpp" line="34"/>
757 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
758 <translation type="unfinished">Instalacja bootloadera wymaga dostarczenia oryginalnego pliku firmware (plik binarny). Oryginalny firmware musisz pobrać samodzielnie z powodów licencyjnych. Proszę zapoznaj się z &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;instrukcją&lt;/a&gt; oraz stroną wiki o &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt;, gdzie dowiesz się jak pobrać plik.&lt;/br&gt;Naciśnij Ok aby kontynuować.</translation>
759 </message>
760 <message>
761 <location filename="../base/bootloaderinstallmpio.cpp" line="53"/>
762 <source>Downloading bootloader file</source>
763 <translation>Pobieranie pliku bootloadera</translation>
764 </message>
765 <message>
766 <location filename="../base/bootloaderinstallmpio.cpp" line="80"/>
767 <source>Could not open the original firmware.</source>
768 <translation>Nie można otworzyć pliku z oryginalnym firmware.</translation>
769 </message>
770 <message>
771 <location filename="../base/bootloaderinstallmpio.cpp" line="83"/>
772 <source>Could not read the original firmware.</source>
773 <translation>Nie można czytać z pliku oryginalnego firmware.</translation>
774 </message>
775 <message>
776 <location filename="../base/bootloaderinstallmpio.cpp" line="86"/>
777 <source>Loaded firmware file does not look like MPIO original firmware file.</source>
778 <translation>Wskazany plik nie wygląda na oryginalny firmware MPIO.</translation>
779 </message>
780 <message>
781 <location filename="../base/bootloaderinstallmpio.cpp" line="101"/>
782 <source>Could not open output file.</source>
783 <translation>Nie można otworzyć pliku wyjściowego.</translation>
784 </message>
785 <message>
786 <location filename="../base/bootloaderinstallmpio.cpp" line="104"/>
787 <source>Could not write output file.</source>
788 <translation>Nie można zapisać do pliku wyjściowego.</translation>
789 </message>
790 <message>
791 <location filename="../base/bootloaderinstallmpio.cpp" line="107"/>
792 <source>Unknown error number: %1</source>
793 <translation>Nieznany błąd nr: %1</translation>
794 </message>
795 <message>
796 <location filename="../base/bootloaderinstallmpio.cpp" line="89"/>
797 <source>Could not open downloaded bootloader.</source>
798 <translation type="unfinished">Nie można otworzyć pobranego bootloadera.</translation>
799 </message>
800 <message>
801 <location filename="../base/bootloaderinstallmpio.cpp" line="92"/>
802 <source>Place for bootloader in OF file not empty.</source>
803 <translation>Miejsce na bootloader w oryginalnym pliku nie jest puste.</translation>
804 </message>
805 <message>
806 <location filename="../base/bootloaderinstallmpio.cpp" line="95"/>
807 <source>Could not read the downloaded bootloader.</source>
808 <translation>Nie można czytać z pobranego pliku bootloadera.</translation>
809 </message>
810 <message>
811 <location filename="../base/bootloaderinstallmpio.cpp" line="98"/>
812 <source>Bootloader checksum error.</source>
813 <translation>Błąd sumy kontrolnej.</translation>
814 </message>
815 <message>
816 <location filename="../base/bootloaderinstallmpio.cpp" line="112"/>
817 <source>Patching original firmware failed: %1</source>
818 <translation>Modyfikacja oryginalnego firmware nie powiodła się: %1</translation>
819 </message>
820 <message>
821 <location filename="../base/bootloaderinstallmpio.cpp" line="119"/>
822 <source>Success: modified firmware file created</source>
823 <translation>Sukces: utowrzono zmodyfikowany plik z firmware</translation>
824 </message>
825 <message>
826 <location filename="../base/bootloaderinstallmpio.cpp" line="127"/>
827 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
828 <translation type="unfinished">Aby odinstalować bootloadera, przeprowadź normalny proces aktualizacji używając oryginalnego, niemodyfikowanego pliku z firmware</translation>
829 </message>
830</context>
831<context>
832 <name>BootloaderInstallSansa</name>
833 <message>
834 <location filename="../base/bootloaderinstallsansa.cpp" line="50"/>
835 <source>Error: can&apos;t allocate buffer memory!</source>
836 <translation>Błąd: nie można zaalokować pamięci dla bufora!</translation>
837 </message>
838 <message>
839 <location filename="../base/bootloaderinstallsansa.cpp" line="55"/>
840 <source>Searching for Sansa</source>
841 <translation>Wyszukiwanie Sansy</translation>
842 </message>
843 <message>
844 <location filename="../base/bootloaderinstallsansa.cpp" line="59"/>
845 <source>Permission for disc access denied!
846This is required to install the bootloader</source>
847 <translation>Dostęp do dysku zabroniony!
848Prawo dostępu jest wymagane do instalacji bootloadera</translation>
849 </message>
850 <message>
851 <location filename="../base/bootloaderinstallsansa.cpp" line="66"/>
852 <source>No Sansa detected!</source>
853 <translation>Nie wykryto Sansy!</translation>
854 </message>
855 <message>
856 <location filename="../base/bootloaderinstallsansa.cpp" line="79"/>
857 <source>Downloading bootloader file</source>
858 <translation>Pobieranie pliku bootloadera</translation>
859 </message>
860 <message>
861 <location filename="../base/bootloaderinstallsansa.cpp" line="94"/>
862 <source>Installing Rockbox bootloader</source>
863 <translation>Instalowanie bootloadera Rockboxa</translation>
864 </message>
865 <message>
866 <location filename="../base/bootloaderinstallsansa.cpp" line="71"/>
867 <location filename="../base/bootloaderinstallsansa.cpp" line="179"/>
868 <source>OLD ROCKBOX INSTALLATION DETECTED, ABORTING.
869You must reinstall the original Sansa firmware before running
870sansapatcher for the first time.
871See http://www.rockbox.org/wiki/SansaE200Install
872</source>
873 <translation>WYKRYTO STAREGO ROCKBOXA, ANULOWANIE.
874Musisz zreinstalować oryginalny firmware Sansy zanim
875będziesz mógł uruchomić po raz pierwszy sansapatcher.
876Zobacz http://www.rockbox.org/wiki/SansaE200Install
877</translation>
878 </message>
879 <message>
880 <location filename="../base/bootloaderinstallsansa.cpp" line="102"/>
881 <location filename="../base/bootloaderinstallsansa.cpp" line="189"/>
882 <source>Could not open Sansa in R/W mode</source>
883 <translation>Nie można otworzyć Sansy w trybie odczytu/zapisu</translation>
884 </message>
885 <message>
886 <location filename="../base/bootloaderinstallsansa.cpp" line="111"/>
887 <source>Checking downloaded bootloader</source>
888 <translation>Sprawdzanie pobranego bootloadera</translation>
889 </message>
890 <message>
891 <location filename="../base/bootloaderinstallsansa.cpp" line="119"/>
892 <source>Bootloader mismatch! Aborting.</source>
893 <translation>Nieodpowiedni bootloader! Anulowanie.</translation>
894 </message>
895 <message>
896 <location filename="../base/bootloaderinstallsansa.cpp" line="129"/>
897 <source>Successfully installed bootloader</source>
898 <translation>Bootloader zainstalowany pomyślnie</translation>
899 </message>
900 <message>
901 <location filename="../base/bootloaderinstallsansa.cpp" line="140"/>
902 <source>Failed to install bootloader</source>
903 <translation>Bootloader nie został pomyślnie zainstalowany</translation>
904 </message>
905 <message>
906 <location filename="../base/bootloaderinstallsansa.cpp" line="153"/>
907 <source>Bootloader Installation complete.</source>
908 <translation>Instalacja bootloadera zakończona.</translation>
909 </message>
910 <message>
911 <location filename="../base/bootloaderinstallsansa.cpp" line="158"/>
912 <source>Writing log aborted</source>
913 <translation type="unfinished">Przerwano zapisywanie dziennika zdarzeń</translation>
914 </message>
915 <message>
916 <location filename="../base/bootloaderinstallsansa.cpp" line="170"/>
917 <source>Uninstalling bootloader</source>
918 <translation>Odinstalowywanie bootloadera</translation>
919 </message>
920 <message>
921 <location filename="../base/bootloaderinstallsansa.cpp" line="195"/>
922 <source>Successfully removed bootloader</source>
923 <translation>Bootloader został pomyślnie usunięty</translation>
924 </message>
925 <message>
926 <location filename="../base/bootloaderinstallsansa.cpp" line="202"/>
927 <source>Removing bootloader failed.</source>
928 <translation>Bootloader nie został usunięty.</translation>
929 </message>
930 <message>
931 <location filename="../base/bootloaderinstallsansa.cpp" line="238"/>
932 <source>Error: could not retrieve device name</source>
933 <translation type="unfinished">Błąd: Nie można znaleźć nazwy urządzenia</translation>
934 </message>
935 <message>
936 <location filename="../base/bootloaderinstallsansa.cpp" line="254"/>
937 <source>Can&apos;t find Sansa</source>
938 <translation>Nie można wykryć Sansy</translation>
939 </message>
940 <message>
941 <location filename="../base/bootloaderinstallsansa.cpp" line="259"/>
942 <source>Could not open Sansa</source>
943 <translation>Nie można otworzyć Sansy</translation>
944 </message>
945 <message>
946 <location filename="../base/bootloaderinstallsansa.cpp" line="264"/>
947 <source>Could not read partition table</source>
948 <translation>Nie można odczytać tablicy partycji</translation>
949 </message>
950 <message>
951 <location filename="../base/bootloaderinstallsansa.cpp" line="271"/>
952 <source>Disk is not a Sansa (Error %1), aborting.</source>
953 <translation>Dysk nie jest Sansą (Błąd %1), anulowanie.</translation>
954 </message>
955</context>
956<context>
957 <name>BootloaderInstallTcc</name>
958 <message>
959 <location filename="../base/bootloaderinstalltcc.cpp" line="33"/>
960 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wiki page on how to obtain the file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
961 <translation type="unfinished">Instalacja bootloadera wymaga dostarczenia oryginalnego pliku firmware (plik binarny). Oryginalny firmware musisz pobrać samodzielnie z powodów licencyjnych. Proszę zapoznaj się z &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;instrukcją&lt;/a&gt; oraz stroną wiki o &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2&lt;/a&gt;, gdzie dowiesz się jak pobrać plik.&lt;/br&gt;Naciśnij Ok aby kontynuować.</translation>
962 </message>
963 <message>
964 <location filename="../base/bootloaderinstalltcc.cpp" line="50"/>
965 <source>Downloading bootloader file</source>
966 <translation>Pobieranie pliku bootloadera</translation>
967 </message>
968 <message>
969 <location filename="../base/bootloaderinstalltcc.cpp" line="82"/>
970 <location filename="../base/bootloaderinstalltcc.cpp" line="99"/>
971 <source>Could not load %1</source>
972 <translation>Nie można załadować %1</translation>
973 </message>
974 <message>
975 <location filename="../base/bootloaderinstalltcc.cpp" line="90"/>
976 <source>Unknown OF file used: %1</source>
977 <translation>Nieznana wersja oryginalnego firmware:%1</translation>
978 </message>
979 <message>
980 <location filename="../base/bootloaderinstalltcc.cpp" line="104"/>
981 <source>Patching Firmware...</source>
982 <translation>Patchowanie firmware...</translation>
983 </message>
984 <message>
985 <location filename="../base/bootloaderinstalltcc.cpp" line="111"/>
986 <source>Could not patch firmware</source>
987 <translation>Nie można zmodyfikować firmware</translation>
988 </message>
989 <message>
990 <location filename="../base/bootloaderinstalltcc.cpp" line="117"/>
991 <source>Could not open %1 for writing</source>
992 <translation>Nie można otworzyć %1 w trybie zapisu</translation>
993 </message>
994 <message>
995 <location filename="../base/bootloaderinstalltcc.cpp" line="126"/>
996 <source>Could not write firmware file</source>
997 <translation>Nie można zapisac pliku firmware</translation>
998 </message>
999 <message>
1000 <location filename="../base/bootloaderinstalltcc.cpp" line="131"/>
1001 <source>Success: modified firmware file created</source>
1002 <translation>Sukces: utworzono zmodyfikowany firmware</translation>
1003 </message>
1004 <message>
1005 <location filename="../base/bootloaderinstalltcc.cpp" line="151"/>
1006 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
1007 <translation type="unfinished">Aby odinstalować bootloadera, przeprowadź standardowy proces aktualizacji używając oryginalnego, niemodyfikowanego pliku z oryginalnym firmware</translation>
1008 </message>
1009</context>
1010<context>
1011 <name>Changelog</name>
1012 <message>
1013 <location filename="../gui/changelogfrm.ui" line="17"/>
1014 <source>Changelog</source>
1015 <translation>Lista zmian</translation>
1016 </message>
1017 <message>
1018 <location filename="../gui/changelogfrm.ui" line="39"/>
1019 <source>Show on startup</source>
1020 <translation>Pokazuj przy starcie</translation>
1021 </message>
1022 <message>
1023 <location filename="../gui/changelogfrm.ui" line="46"/>
1024 <source>&amp;Ok</source>
1025 <translation>&amp;Ok</translation>
1026 </message>
1027</context>
1028<context>
1029 <name>Config</name>
1030 <message>
1031 <location filename="../configure.cpp" line="130"/>
1032 <source>The following errors occurred:</source>
1033 <translation>Wystapiły następujące błędy:</translation>
1034 </message>
1035 <message>
1036 <location filename="../configure.cpp" line="175"/>
1037 <source>No mountpoint given</source>
1038 <translation>Nie określono punktu montowania</translation>
1039 </message>
1040 <message>
1041 <location filename="../configure.cpp" line="179"/>
1042 <source>Mountpoint does not exist</source>
1043 <translation>Punkt montowania nie istnieje</translation>
1044 </message>
1045 <message>
1046 <location filename="../configure.cpp" line="183"/>
1047 <source>Mountpoint is not a directory.</source>
1048 <translation type="unfinished">Punkt montowania nie jest folderem.</translation>
1049 </message>
1050 <message>
1051 <location filename="../configure.cpp" line="187"/>
1052 <source>Mountpoint is not writeable</source>
1053 <translation type="unfinished">Nie można zapisać do punktu montowania</translation>
1054 </message>
1055 <message>
1056 <location filename="../configure.cpp" line="202"/>
1057 <source>No player selected</source>
1058 <translation>Nie wybrano urządzenia</translation>
1059 </message>
1060 <message>
1061 <location filename="../configure.cpp" line="209"/>
1062 <source>Cache path not writeable. Leave path empty to default to systems temporary path.</source>
1063 <translation>Nie można nic zapisać do bufora. Zmień ścieżkę na domyślną aby wykorzystać bufor systemowy.</translation>
1064 </message>
1065 <message>
1066 <location filename="../configure.cpp" line="228"/>
1067 <source>You need to fix the above errors before you can continue.</source>
1068 <translation>Musisz usunąć powyższe błędy zanim będziesz mógł kontynuować operację.</translation>
1069 </message>
1070 <message>
1071 <location filename="../configure.cpp" line="231"/>
1072 <source>Configuration error</source>
1073 <translation>Błąd konfiguracji</translation>
1074 </message>
1075 <message>
1076 <location filename="../configure.cpp" line="322"/>
1077 <source>Current cache size is %L1 kiB.</source>
1078 <translation>Rozmiar bufora to %L1 kB.</translation>
1079 </message>
1080 <message>
1081 <location filename="../configure.cpp" line="340"/>
1082 <source>Showing disabled targets</source>
1083 <translation type="unfinished">Pokazywanie urządzeń zablokowanych</translation>
1084 </message>
1085 <message>
1086 <location filename="../configure.cpp" line="341"/>
1087 <source>You just enabled showing targets that are marked disabled. Disabled targets are not recommended to end users. Please use this option only if you know what you are doing.</source>
1088 <translation type="unfinished">Właśnie wybrałeś pokazywanie urządzeń zablokowanych. Używanie Rockbox Utility z tymi odtwarzaczami nie jest zalecane dla zwykłych użytkowników. Użyj tej opcji jedynie jeśli dobrze wiesz co robisz.</translation>
1089 </message>
1090 <message>
1091 <location filename="../configure.cpp" line="448"/>
1092 <location filename="../configure.cpp" line="914"/>
1093 <source>TTS error</source>
1094 <translation type="unfinished">Błąd TTS</translation>
1095 </message>
1096 <message>
1097 <location filename="../configure.cpp" line="449"/>
1098 <location filename="../configure.cpp" line="915"/>
1099 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1100 <translation type="unfinished">Wybrany silnik TTS nie mógł zostać zainicjowany. Nie możesz wybrać tego silnika TTS.</translation>
1101 </message>
1102 <message>
1103 <location filename="../configure.cpp" line="455"/>
1104 <location filename="../configure.cpp" line="485"/>
1105 <source>Configuration OK</source>
1106 <translation>Konfiguracja jest poprawna</translation>
1107 </message>
1108 <message>
1109 <location filename="../configure.cpp" line="461"/>
1110 <location filename="../configure.cpp" line="490"/>
1111 <source>Configuration INVALID</source>
1112 <translation>Niepoprawna konfiguracja</translation>
1113 </message>
1114 <message>
1115 <location filename="../configure.cpp" line="529"/>
1116 <source>Proxy Detection</source>
1117 <translation>Wykrywanie proxy</translation>
1118 </message>
1119 <message>
1120 <location filename="../configure.cpp" line="530"/>
1121 <source>The System Proxy settings are invalid!
1122Rockbox Utility can&apos;t work with this proxy settings. Make sure the system proxy is set correctly. Note that &quot;proxy auto-config (PAC)&quot; scripts are not supported by Rockbox Utility. If your system uses this you need to use manual proxy settings.</source>
1123 <translation>Globalne ustawienia Proxy są nieprawidłowe!
1124Rockbox Utility nie może pracować z tymi ustawieniami. Proszę sprawdź, że ustawienia są poprawne. Skrypty PAC (proxy auto-config) nie są obsługiwane przez Rockbox Utility. Jeżeli korzystasz z takich skryptów, musisz użyć ustawień ręcznych.</translation>
1125 </message>
1126 <message>
1127 <location filename="../configure.cpp" line="643"/>
1128 <source>Set Cache Path</source>
1129 <translation>Ustaw ścieżkę do bufora</translation>
1130 </message>
1131 <message>
1132 <location filename="../configure.cpp" line="665"/>
1133 <source>%1 (%2 GiB of %3 GiB free)</source>
1134 <translation type="unfinished">%1 (%2 GiB z %3 GiB wolnego)</translation>
1135 </message>
1136 <message>
1137 <location filename="../configure.cpp" line="739"/>
1138 <source>Multiple devices have been detected. Please disconnect all players but one and try again.</source>
1139 <translation type="unfinished">Wykryto wiele urządzeń. Prosze odłącz urządzenia pozostawiając tylko jedno i spróbuj ponownie.</translation>
1140 </message>
1141 <message>
1142 <location filename="../configure.cpp" line="742"/>
1143 <source>Detected devices:</source>
1144 <translation type="unfinished">Wykryte urządzenia:</translation>
1145 </message>
1146 <message>
1147 <location filename="../configure.cpp" line="747"/>
1148 <source>(unknown)</source>
1149 <translation type="unfinished">(nieznany)</translation>
1150 </message>
1151 <message>
1152 <location filename="../configure.cpp" line="749"/>
1153 <source>%1 at %2</source>
1154 <translation type="unfinished">%1 przy %2</translation>
1155 </message>
1156 <message>
1157 <location filename="../configure.cpp" line="755"/>
1158 <source>Note: detecting connected devices might be ambiguous. You might have less devices connected than listed. In this case it might not be possible to detect your player unambiguously.</source>
1159 <translation type="unfinished">Uwaga: wykrywanie podłączonych urządzeń nie zawsze może być pewne. Możesz mieć mniej urządzeń podłączonych niż wyświetlonych na liście. W tym przypadku może nie być możliwym wykryć twój odtwarzacz z całkowitą pewnością.</translation>
1160 </message>
1161 <message>
1162 <location filename="../configure.cpp" line="759"/>
1163 <location filename="../configure.cpp" line="763"/>
1164 <location filename="../configure.cpp" line="805"/>
1165 <source>Device Detection</source>
1166 <translation type="unfinished">Wykrywanie urządzenia</translation>
1167 </message>
1168 <message>
1169 <location filename="../configure.cpp" line="788"/>
1170 <source>%1 &quot;MacPod&quot; found!
1171Rockbox needs a FAT formatted Ipod (so-called &quot;WinPod&quot;) to run. </source>
1172 <translation>znaleziono \&quot;MaxPod\&quot; %1!
1173Rockbox obsługuje wyłącznie Ipody z systemem plików FAT (tak zwane \&quot;WinPod\&quot;).</translation>
1174 </message>
1175 <message>
1176 <source>Fatal error</source>
1177 <translation type="obsolete">Błąd krytyczny</translation>
1178 </message>
1179 <message>
1180 <location filename="../configure.cpp" line="774"/>
1181 <source>Detected an unsupported player:
1182%1
1183Sorry, Rockbox doesn&apos;t run on your player.</source>
1184 <translation>Wykryto nieobsługiwane urządzenie:
1185%1
1186Niestety, Rockbox nie działa na tym urządzeniu.</translation>
1187 </message>
1188 <message>
1189 <source>Fatal: player incompatible</source>
1190 <translation type="obsolete">Uwaga: nieobsługiwane urządznie</translation>
1191 </message>
1192 <message>
1193 <location filename="../configure.cpp" line="858"/>
1194 <source>Autodetection</source>
1195 <translation>Autodetekcja</translation>
1196 </message>
1197 <message>
1198 <location filename="../configure.cpp" line="859"/>
1199 <source>Could not detect a Mountpoint.
1200Select your Mountpoint manually.</source>
1201 <translation>Nie można wykryć punktu montowania.
1202Wybierz ręcznie punkt montowania.</translation>
1203 </message>
1204 <message>
1205 <location filename="../configure.cpp" line="764"/>
1206 <source>Could not detect a device.
1207Select your device and Mountpoint manually.</source>
1208 <translation>Nie mozna wykryć urządzenia.
1209Wybierz ręcznie urządzenie i punkt montowania.</translation>
1210 </message>
1211 <message>
1212 <location filename="../configure.cpp" line="794"/>
1213 <source>The player contains an incompatible filesystem.
1214Make sure you selected the correct mountpoint and the player is set up to use a filesystem compatible with Rockbox.</source>
1215 <translation type="unfinished">Odtwarzacz zawiera niekompatybilny system plików.
1216Upewnij się że wybrałeś prawidłowy punkt montowania i że odtwarzacz jest ustawiony na działanie w systemie plików kompatybilnym z Rockboxem.</translation>
1217 </message>
1218 <message>
1219 <location filename="../configure.cpp" line="802"/>
1220 <source>An unknown error occured during player detection.</source>
1221 <translation type="unfinished">Wystąpił nieznany błąd podczas wykrywania odtwarzacza.</translation>
1222 </message>
1223 <message>
1224 <location filename="../configure.cpp" line="869"/>
1225 <source>Really delete cache?</source>
1226 <translation>Na pewno opróżnić bufor?</translation>
1227 </message>
1228 <message>
1229 <location filename="../configure.cpp" line="870"/>
1230 <source>Do you really want to delete the cache? Make absolutely sure this setting is correct as it will remove &lt;b&gt;all&lt;/b&gt; files in this folder!</source>
1231 <translation>Czy na pewno chcesz wyczyścić bufor? Upewnij się że ustawienia są poprawne gdyż zostaną usunięte &lt;b&gt;wszystkie&lt;/b&gt; pliki z tego folderu!</translation>
1232 </message>
1233 <message>
1234 <location filename="../configure.cpp" line="878"/>
1235 <source>Path wrong!</source>
1236 <translation>Błędna ścieżka!</translation>
1237 </message>
1238 <message>
1239 <location filename="../configure.cpp" line="879"/>
1240 <source>The cache path is invalid. Aborting.</source>
1241 <translation>Nieprawidłowa ścieżka do bufora. Anulowanie.</translation>
1242 </message>
1243 <message>
1244 <location filename="../configure.cpp" line="921"/>
1245 <source>TTS configuration invalid</source>
1246 <translation>Niepoprawna kofiguracja silnika TTS</translation>
1247 </message>
1248 <message>
1249 <location filename="../configure.cpp" line="922"/>
1250 <source>TTS configuration invalid.
1251 Please configure TTS engine.</source>
1252 <translation>Niepoprawna konfiguracja silnika TTS.
1253Prosze skonfigurować silnik TTS.</translation>
1254 </message>
1255 <message>
1256 <location filename="../configure.cpp" line="927"/>
1257 <source>Could not start TTS engine.</source>
1258 <translation>Nie mozna zainicjować silnika TTS.</translation>
1259 </message>
1260 <message>
1261 <location filename="../configure.cpp" line="946"/>
1262 <source>Could not voice test string.</source>
1263 <translation type="unfinished">Nie można nadać głosu ścieżce testowej.</translation>
1264 </message>
1265 <message>
1266 <location filename="../configure.cpp" line="928"/>
1267 <source>Could not start TTS engine.
1268</source>
1269 <translation>Nie można zainicjować silnika TTS.
1270</translation>
1271 </message>
1272 <message>
1273 <location filename="../configure.cpp" line="780"/>
1274 <source>%1 in MTP mode found!
1275You need to change your player to MSC mode for installation. </source>
1276 <translation>znaleziono %1 w trybie MTP!
1277Musisz przełączyć swój odtwarzacz w tryb MSC aby kontynuować instalację.</translation>
1278 </message>
1279 <message>
1280 <source>Until you change this installation will fail!</source>
1281 <translation type="obsolete">Dopóki nie zmienisz tego ustawienia instalacja nie powiedzie się!</translation>
1282 </message>
1283 <message>
1284 <location filename="../configure.cpp" line="929"/>
1285 <location filename="../configure.cpp" line="948"/>
1286 <source>
1287Please configure TTS engine.</source>
1288 <translation>
1289Prosze skonfigurować silnik TTS.</translation>
1290 </message>
1291 <message>
1292 <location filename="../configure.cpp" line="943"/>
1293 <source>Rockbox Utility Voice Test</source>
1294 <translation>Test Głosu Rockbox Utility</translation>
1295 </message>
1296 <message>
1297 <location filename="../configure.cpp" line="947"/>
1298 <source>Could not voice test string.
1299</source>
1300 <translation type="unfinished">Nie można nadać głosu ścieżce testowej.</translation>
1301 </message>
1302</context>
1303<context>
1304 <name>ConfigForm</name>
1305 <message>
1306 <location filename="../configurefrm.ui" line="14"/>
1307 <source>Configuration</source>
1308 <translation>Konfiguracja</translation>
1309 </message>
1310 <message>
1311 <location filename="../configurefrm.ui" line="20"/>
1312 <source>Configure Rockbox Utility</source>
1313 <translation>Konfiguruj Rockbox Utility</translation>
1314 </message>
1315 <message>
1316 <location filename="../configurefrm.ui" line="35"/>
1317 <source>&amp;Device</source>
1318 <translation>&amp;Urządzenie</translation>
1319 </message>
1320 <message>
1321 <location filename="../configurefrm.ui" line="41"/>
1322 <source>Select your device in the &amp;filesystem</source>
1323 <translation>Wybierz swoje urządzenie wśród dostępnych &amp;dysków</translation>
1324 </message>
1325 <message>
1326 <location filename="../configurefrm.ui" line="319"/>
1327 <source>&amp;Browse</source>
1328 <translation>&amp;Otwórz</translation>
1329 </message>
1330 <message>
1331 <location filename="../configurefrm.ui" line="72"/>
1332 <source>&amp;Select your audio player</source>
1333 <translation>&amp;Wybierz swój odtwarzacz</translation>
1334 </message>
1335 <message>
1336 <location filename="../configurefrm.ui" line="58"/>
1337 <source>&amp;Refresh</source>
1338 <translation>&amp;Odśwież</translation>
1339 </message>
1340 <message>
1341 <location filename="../configurefrm.ui" line="95"/>
1342 <source>Show disabled targets</source>
1343 <translation type="unfinished">Pokaż urządzenia zablokowane</translation>
1344 </message>
1345 <message>
1346 <location filename="../configurefrm.ui" line="114"/>
1347 <source>&amp;Autodetect</source>
1348 <translation>&amp;Autowykrywanie</translation>
1349 </message>
1350 <message>
1351 <location filename="../configurefrm.ui" line="136"/>
1352 <source>&amp;Proxy</source>
1353 <translation>Serwer &amp;proxy</translation>
1354 </message>
1355 <message>
1356 <location filename="../configurefrm.ui" line="142"/>
1357 <source>&amp;No Proxy</source>
1358 <translation>&amp;Bez proxy</translation>
1359 </message>
1360 <message>
1361 <location filename="../configurefrm.ui" line="152"/>
1362 <source>Use S&amp;ystem values</source>
1363 <translation>Użyj wartości &amp;systemowych</translation>
1364 </message>
1365 <message>
1366 <location filename="../configurefrm.ui" line="159"/>
1367 <source>&amp;Manual Proxy settings</source>
1368 <translation>&amp;Ręczne ustawienia proxy</translation>
1369 </message>
1370 <message>
1371 <location filename="../configurefrm.ui" line="166"/>
1372 <source>Proxy Values</source>
1373 <translation>Dane proxy</translation>
1374 </message>
1375 <message>
1376 <location filename="../configurefrm.ui" line="172"/>
1377 <source>&amp;Host:</source>
1378 <translation>&amp;Host:</translation>
1379 </message>
1380 <message>
1381 <location filename="../configurefrm.ui" line="182"/>
1382 <source>&amp;Port:</source>
1383 <translation>&amp;Port:</translation>
1384 </message>
1385 <message>
1386 <location filename="../configurefrm.ui" line="199"/>
1387 <source>&amp;Username</source>
1388 <translation>&amp;Nazwa użytkownika</translation>
1389 </message>
1390 <message>
1391 <location filename="../configurefrm.ui" line="209"/>
1392 <source>Pass&amp;word</source>
1393 <translation>&amp;Hasło</translation>
1394 </message>
1395 <message>
1396 <location filename="../configurefrm.ui" line="219"/>
1397 <source>Show</source>
1398 <translation type="unfinished">Pokaż</translation>
1399 </message>
1400 <message>
1401 <location filename="../configurefrm.ui" line="260"/>
1402 <source>&amp;Language</source>
1403 <translation>&amp;Język</translation>
1404 </message>
1405 <message>
1406 <location filename="../configurefrm.ui" line="274"/>
1407 <source>Cac&amp;he</source>
1408 <translation>&amp;Bufor</translation>
1409 </message>
1410 <message>
1411 <location filename="../configurefrm.ui" line="277"/>
1412 <source>Download cache settings</source>
1413 <translation>Pobierz ustawienia bufora</translation>
1414 </message>
1415 <message>
1416 <location filename="../configurefrm.ui" line="283"/>
1417 <source>Rockbox Utility uses a local download cache to save network traffic. You can change the path to the cache and use it as local repository by enabling Offline mode.</source>
1418 <translation>Rockbox Utility używa lokalnego bufora aby ograniczyć ruch sieciowy. Możesz zmienić ścieżkę do tego folderu i użyć go jako źródło, przechodząc w tryb Offline.</translation>
1419 </message>
1420 <message>
1421 <location filename="../configurefrm.ui" line="293"/>
1422 <source>Current cache size is %1</source>
1423 <translation>Rozmiar bufora to %1</translation>
1424 </message>
1425 <message>
1426 <location filename="../configurefrm.ui" line="302"/>
1427 <source>P&amp;ath</source>
1428 <translation>&amp;Ścieżka</translation>
1429 </message>
1430 <message>
1431 <location filename="../configurefrm.ui" line="312"/>
1432 <source>Entering an invalid folder will reset the path to the systems temporary path.</source>
1433 <translation>Po wybraniu niewłaściwego folderu, ścieżka zostanie zmieniona na systemową.</translation>
1434 </message>
1435 <message>
1436 <location filename="../configurefrm.ui" line="334"/>
1437 <source>Disable local &amp;download cache</source>
1438 <translation>&amp;Wyłącz tymczasowy bufor pobierania</translation>
1439 </message>
1440 <message>
1441 <source>&lt;p&gt;This will try to use all information from the cache, even information about updates. Only use this option if you want to install without network connection. Note: you need to do the same install you want to perform later with network access first to download all required files to the cache.&lt;/p&gt;</source>
1442 <translation type="obsolete">&lt;p&gt;To spowoduje, że wszystkie informacje będą pobierane z bufora, nawet aktualizacje. Użyj tej opcji tylko jesli chcesz przeprowadzić instalację bez połączenia z internetem. Uwaga: żeby przeprowadzić daną instalację, musisz wpierw dokonać instalacji z internetu, aby pliki instalacyjne zostały zapisane w buforze.&lt;/p&gt;</translation>
1443 </message>
1444 <message>
1445 <source>O&amp;ffline mode</source>
1446 <translation type="obsolete">Tryb &amp;Offline</translation>
1447 </message>
1448 <message>
1449 <location filename="../configurefrm.ui" line="369"/>
1450 <source>Clean cache &amp;now</source>
1451 <translation>&amp;Wyczyść teraz bufor</translation>
1452 </message>
1453 <message>
1454 <location filename="../configurefrm.ui" line="385"/>
1455 <source>&amp;TTS &amp;&amp; Encoder</source>
1456 <translation type="unfinished">&amp;TTS &amp;&amp; Koder</translation>
1457 </message>
1458 <message>
1459 <location filename="../configurefrm.ui" line="391"/>
1460 <source>TTS Engine</source>
1461 <translation>Silnik Text-To-Speech</translation>
1462 </message>
1463 <message>
1464 <location filename="../configurefrm.ui" line="397"/>
1465 <source>&amp;Select TTS Engine</source>
1466 <translation>&amp;Wybierz silnik TTS</translation>
1467 </message>
1468 <message>
1469 <location filename="../configurefrm.ui" line="410"/>
1470 <source>Configure TTS Engine</source>
1471 <translation>Konfiguruj silnik TTS</translation>
1472 </message>
1473 <message>
1474 <location filename="../configurefrm.ui" line="417"/>
1475 <location filename="../configurefrm.ui" line="468"/>
1476 <source>Configuration invalid!</source>
1477 <translation>Nieprawidłowa konfiguracja!</translation>
1478 </message>
1479 <message>
1480 <location filename="../configurefrm.ui" line="434"/>
1481 <source>Configure &amp;TTS</source>
1482 <translation>Konfiguruj &amp;TTS</translation>
1483 </message>
1484 <message>
1485 <location filename="../configurefrm.ui" line="445"/>
1486 <source>Test TTS</source>
1487 <translation>Testuj TTS</translation>
1488 </message>
1489 <message>
1490 <location filename="../configurefrm.ui" line="452"/>
1491 <source>&amp;Use string corrections for TTS</source>
1492 <translation>&amp;Użyj korekty dla TTS</translation>
1493 </message>
1494 <message>
1495 <location filename="../configurefrm.ui" line="462"/>
1496 <source>Encoder Engine</source>
1497 <translation type="unfinished">Silnik kodera</translation>
1498 </message>
1499 <message>
1500 <location filename="../configurefrm.ui" line="485"/>
1501 <source>Configure &amp;Enc</source>
1502 <translation type="unfinished">&amp;Konfiguruj koder</translation>
1503 </message>
1504 <message>
1505 <location filename="../configurefrm.ui" line="496"/>
1506 <source>encoder name</source>
1507 <translation type="unfinished">nazwa kodera</translation>
1508 </message>
1509 <message>
1510 <location filename="../configurefrm.ui" line="536"/>
1511 <source>&amp;Ok</source>
1512 <translation>&amp;Ok</translation>
1513 </message>
1514 <message>
1515 <location filename="../configurefrm.ui" line="547"/>
1516 <source>&amp;Cancel</source>
1517 <translation>&amp;Wyjdź</translation>
1518 </message>
1519</context>
1520<context>
1521 <name>Configure</name>
1522 <message>
1523 <location filename="../configure.cpp" line="589"/>
1524 <source>English</source>
1525 <comment>This is the localized language name, i.e. your language.</comment>
1526 <translation>Polski</translation>
1527 </message>
1528</context>
1529<context>
1530 <name>CreateVoiceFrm</name>
1531 <message>
1532 <location filename="../createvoicefrm.ui" line="17"/>
1533 <source>Create Voice File</source>
1534 <translation>Stwórz plik głosowy</translation>
1535 </message>
1536 <message>
1537 <location filename="../createvoicefrm.ui" line="42"/>
1538 <source>Select the Language you want to generate a voicefile for:</source>
1539 <translation>Wybierz język dla którego chcesz stworzyć plik głosowy:</translation>
1540 </message>
1541 <message>
1542 <location filename="../createvoicefrm.ui" line="55"/>
1543 <source>TTS:</source>
1544 <translation>TTS:</translation>
1545 </message>
1546 <message>
1547 <location filename="../createvoicefrm.ui" line="101"/>
1548 <source>Silence threshold</source>
1549 <translation>Próg ciszy</translation>
1550 </message>
1551 <message>
1552 <location filename="../createvoicefrm.ui" line="163"/>
1553 <source>Language</source>
1554 <translation>Język</translation>
1555 </message>
1556 <message>
1557 <location filename="../createvoicefrm.ui" line="49"/>
1558 <source>Generation settings</source>
1559 <translation>Ustawienia</translation>
1560 </message>
1561 <message>
1562 <location filename="../createvoicefrm.ui" line="68"/>
1563 <source>Change</source>
1564 <translation>Zmień</translation>
1565 </message>
1566 <message>
1567 <location filename="../createvoicefrm.ui" line="139"/>
1568 <source>&amp;Install</source>
1569 <translation>&amp;Instaluj</translation>
1570 </message>
1571 <message>
1572 <location filename="../createvoicefrm.ui" line="150"/>
1573 <source>&amp;Cancel</source>
1574 <translation>&amp;Wyjdź</translation>
1575 </message>
1576 <message>
1577 <location filename="../createvoicefrm.ui" line="88"/>
1578 <source>Wavtrim Threshold</source>
1579 <translation>Próg szumu narzędzia wavtrim</translation>
1580 </message>
1581</context>
1582<context>
1583 <name>CreateVoiceWindow</name>
1584 <message>
1585 <location filename="../createvoicewindow.cpp" line="100"/>
1586 <source>TTS error</source>
1587 <translation>Błąd TTS</translation>
1588 </message>
1589 <message>
1590 <location filename="../createvoicewindow.cpp" line="101"/>
1591 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1592 <translation>Wybrany silnik TTS nie mógł zostać zainicjowany. Nie możesz wybrać tego silnika TTS.</translation>
1593 </message>
1594 <message>
1595 <location filename="../createvoicewindow.cpp" line="105"/>
1596 <location filename="../createvoicewindow.cpp" line="108"/>
1597 <source>Engine: &lt;b&gt;%1&lt;/b&gt;</source>
1598 <translation>Silnik: &lt;b&gt;%1&lt;/b&gt;</translation>
1599 </message>
1600</context>
1601<context>
1602 <name>EncTtsCfgGui</name>
1603 <message>
1604 <location filename="../encttscfggui.cpp" line="45"/>
1605 <source>Waiting for engine...</source>
1606 <translation>Czekaj na silnik...</translation>
1607 </message>
1608 <message>
1609 <location filename="../encttscfggui.cpp" line="95"/>
1610 <source>Ok</source>
1611 <translation>Ok</translation>
1612 </message>
1613 <message>
1614 <location filename="../encttscfggui.cpp" line="98"/>
1615 <source>Cancel</source>
1616 <translation>Anuluj</translation>
1617 </message>
1618 <message>
1619 <location filename="../encttscfggui.cpp" line="197"/>
1620 <source>Browse</source>
1621 <translation>Otwórz</translation>
1622 </message>
1623 <message>
1624 <location filename="../encttscfggui.cpp" line="205"/>
1625 <source>Refresh</source>
1626 <translation>Odśwież</translation>
1627 </message>
1628 <message>
1629 <location filename="../encttscfggui.cpp" line="377"/>
1630 <source>Select executable</source>
1631 <translation>Wybierz plik wykonywalny</translation>
1632 </message>
1633</context>
1634<context>
1635 <name>EncoderExe</name>
1636 <message>
1637 <location filename="../base/encoderexe.cpp" line="41"/>
1638 <source>Path to Encoder:</source>
1639 <translation>Ścieżka do kodera:</translation>
1640 </message>
1641 <message>
1642 <location filename="../base/encoderexe.cpp" line="43"/>
1643 <source>Encoder options:</source>
1644 <translation>Opcje kodera:</translation>
1645 </message>
1646</context>
1647<context>
1648 <name>EncoderLame</name>
1649 <message>
1650 <location filename="../base/encoderlame.cpp" line="73"/>
1651 <location filename="../base/encoderlame.cpp" line="83"/>
1652 <source>LAME</source>
1653 <translation>LAME</translation>
1654 </message>
1655 <message>
1656 <location filename="../base/encoderlame.cpp" line="75"/>
1657 <source>Volume</source>
1658 <translation>Głośność</translation>
1659 </message>
1660 <message>
1661 <location filename="../base/encoderlame.cpp" line="79"/>
1662 <source>Quality</source>
1663 <translation>Jakość</translation>
1664 </message>
1665 <message>
1666 <location filename="../base/encoderlame.cpp" line="83"/>
1667 <source>Could not find libmp3lame!</source>
1668 <translation>Nie można odnaleźć libmp3lame!</translation>
1669 </message>
1670</context>
1671<context>
1672 <name>EncoderRbSpeex</name>
1673 <message>
1674 <location filename="../base/encoderrbspeex.cpp" line="34"/>
1675 <source>Volume:</source>
1676 <translation>Głośność:</translation>
1677 </message>
1678 <message>
1679 <location filename="../base/encoderrbspeex.cpp" line="36"/>
1680 <source>Quality:</source>
1681 <translation>Jakość:</translation>
1682 </message>
1683 <message>
1684 <location filename="../base/encoderrbspeex.cpp" line="38"/>
1685 <source>Complexity:</source>
1686 <translation>Złożoność:</translation>
1687 </message>
1688 <message>
1689 <location filename="../base/encoderrbspeex.cpp" line="40"/>
1690 <source>Use Narrowband:</source>
1691 <translation>Wąskie pasmo:</translation>
1692 </message>
1693</context>
1694<context>
1695 <name>InfoWidget</name>
1696 <message>
1697 <location filename="../gui/infowidget.cpp" line="30"/>
1698 <location filename="../gui/infowidget.cpp" line="107"/>
1699 <source>File</source>
1700 <translation>Plik</translation>
1701 </message>
1702 <message>
1703 <location filename="../gui/infowidget.cpp" line="30"/>
1704 <location filename="../gui/infowidget.cpp" line="107"/>
1705 <source>Version</source>
1706 <translation>Wersja</translation>
1707 </message>
1708</context>
1709<context>
1710 <name>InfoWidgetFrm</name>
1711 <message>
1712 <location filename="../gui/infowidgetfrm.ui" line="14"/>
1713 <source>Info</source>
1714 <translation>Info</translation>
1715 </message>
1716 <message>
1717 <location filename="../gui/infowidgetfrm.ui" line="20"/>
1718 <source>Currently installed packages.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; if you manually installed packages this might not be correct!</source>
1719 <translation>Obecnie zainstalowane składniki.&lt;br/&gt;&lt;b&gt;Uwaga:&lt;/b&gt; jeśli składniki instalowałeś ręcznie, podane wartości mogą być nieprawdziwe!</translation>
1720 </message>
1721 <message>
1722 <location filename="../gui/infowidgetfrm.ui" line="34"/>
1723 <source>Package</source>
1724 <translation>Składnik</translation>
1725 </message>
1726</context>
1727<context>
1728 <name>InstallTalkFrm</name>
1729 <message>
1730 <location filename="../installtalkfrm.ui" line="17"/>
1731 <source>Install Talk Files</source>
1732 <translation>Instaluj pliki .talk</translation>
1733 </message>
1734 <message>
1735 <location filename="../installtalkfrm.ui" line="52"/>
1736 <source>Generate for files</source>
1737 <translation type="unfinished">Generuj dla plików</translation>
1738 </message>
1739 <message>
1740 <location filename="../installtalkfrm.ui" line="78"/>
1741 <source>TTS profile:</source>
1742 <translation>Profil TTS:</translation>
1743 </message>
1744 <message>
1745 <location filename="../installtalkfrm.ui" line="85"/>
1746 <source>Generate for folders</source>
1747 <translation type="unfinished">Generuj dla folderów</translation>
1748 </message>
1749 <message>
1750 <location filename="../installtalkfrm.ui" line="95"/>
1751 <source>Recurse into folders</source>
1752 <translation type="unfinished">Rekursuj do folderów</translation>
1753 </message>
1754 <message>
1755 <location filename="../installtalkfrm.ui" line="111"/>
1756 <source>Change</source>
1757 <translation>Zmień</translation>
1758 </message>
1759 <message>
1760 <location filename="../installtalkfrm.ui" line="118"/>
1761 <source>Ignore files</source>
1762 <translation type="unfinished">Ignoruj pliki</translation>
1763 </message>
1764 <message>
1765 <location filename="../installtalkfrm.ui" line="128"/>
1766 <source>Skip existing</source>
1767 <translation type="unfinished">Opuść istniejące</translation>
1768 </message>
1769 <message>
1770 <location filename="../installtalkfrm.ui" line="143"/>
1771 <source>&amp;Install</source>
1772 <translation>&amp;Instaluj</translation>
1773 </message>
1774 <message>
1775 <location filename="../installtalkfrm.ui" line="154"/>
1776 <source>&amp;Cancel</source>
1777 <translation>&amp;Wyjdź</translation>
1778 </message>
1779 <message>
1780 <location filename="../installtalkfrm.ui" line="170"/>
1781 <source>Select folders for Talkfile generation (Ctrl for multiselect)</source>
1782 <translation type="unfinished">Wybierz foldery dla których stworzysz pliki .talk (naciśnij Ctrl aby zaznaczyć kilka z nich)</translation>
1783 </message>
1784 <message>
1785 <location filename="../installtalkfrm.ui" line="36"/>
1786 <source>Generation options</source>
1787 <translation>Opcje</translation>
1788 </message>
1789 <message>
1790 <location filename="../installtalkfrm.ui" line="42"/>
1791 <source>Strip Extensions</source>
1792 <translation>Omiń rozszerzenia</translation>
1793 </message>
1794</context>
1795<context>
1796 <name>InstallTalkWindow</name>
1797 <message>
1798 <source>&lt;b&gt;%1&lt;/b&gt;</source>
1799 <translation type="obsolete">&lt;b&gt;%1&lt;/b&gt;</translation>
1800 </message>
1801 <message>
1802 <location filename="../installtalkwindow.cpp" line="96"/>
1803 <source>Empty selection</source>
1804 <translation type="unfinished">Nic nie wybrano</translation>
1805 </message>
1806 <message>
1807 <location filename="../installtalkwindow.cpp" line="97"/>
1808 <source>No files or folders selected. Please select files or folders first.</source>
1809 <translation type="unfinished">Nie zaznaczono żadnych plików ani folderów. Prosze wybierz najpierw pliki lub foldery.</translation>
1810 </message>
1811 <message>
1812 <location filename="../installtalkwindow.cpp" line="137"/>
1813 <source>TTS error</source>
1814 <translation>Błąd TTS</translation>
1815 </message>
1816 <message>
1817 <location filename="../installtalkwindow.cpp" line="138"/>
1818 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1819 <translation>Wybrany silnik TTS nie mógł zostać zainicjowany. Nie możesz wybrać tego silnika TTS.</translation>
1820 </message>
1821</context>
1822<context>
1823 <name>ManualWidget</name>
1824 <message>
1825 <location filename="../gui/manualwidget.cpp" line="44"/>
1826 <source>&lt;a href=&apos;%1&apos;&gt;PDF Manual&lt;/a&gt;</source>
1827 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Instrukcja PDF&lt;/a&gt;</translation>
1828 </message>
1829 <message>
1830 <location filename="../gui/manualwidget.cpp" line="46"/>
1831 <source>&lt;a href=&apos;%1&apos;&gt;HTML Manual (opens in browser)&lt;/a&gt;</source>
1832 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Instrukcja HTML (otwierana w przeglądarce)&lt;/a&gt;</translation>
1833 </message>
1834 <message>
1835 <location filename="../gui/manualwidget.cpp" line="50"/>
1836 <source>Select a device for a link to the correct manual</source>
1837 <translation type="unfinished">Wybierz urządzenie aby przeglądać odpowiednią instrukcję</translation>
1838 </message>
1839 <message>
1840 <location filename="../gui/manualwidget.cpp" line="51"/>
1841 <source>&lt;a href=&apos;%1&apos;&gt;Manual Overview&lt;/a&gt;</source>
1842 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Podgląd instrukcji&lt;/a&gt;</translation>
1843 </message>
1844 <message>
1845 <location filename="../gui/manualwidget.cpp" line="62"/>
1846 <source>Confirm download</source>
1847 <translation type="unfinished">Potwierdź pobieranie</translation>
1848 </message>
1849 <message>
1850 <location filename="../gui/manualwidget.cpp" line="63"/>
1851 <source>Do you really want to download the manual? The manual will be saved to the root folder of your player.</source>
1852 <translation type="unfinished">Czy na pewno chcesz pobrać instrukcję obsługi? Instrukcja zostanie zapisana w głównym katalogu odtwarzacza.</translation>
1853 </message>
1854</context>
1855<context>
1856 <name>ManualWidgetFrm</name>
1857 <message>
1858 <location filename="../gui/manualwidgetfrm.ui" line="14"/>
1859 <source>Manual</source>
1860 <translation type="unfinished">Instrukcja obsługi</translation>
1861 </message>
1862 <message>
1863 <location filename="../gui/manualwidgetfrm.ui" line="20"/>
1864 <source>Read the manual</source>
1865 <translation type="unfinished">Przeczytaj instrukcję</translation>
1866 </message>
1867 <message>
1868 <location filename="../gui/manualwidgetfrm.ui" line="26"/>
1869 <source>PDF manual</source>
1870 <translation type="unfinished">Instrukcja w formacie PDF</translation>
1871 </message>
1872 <message>
1873 <location filename="../gui/manualwidgetfrm.ui" line="39"/>
1874 <source>HTML manual</source>
1875 <translation type="unfinished">Instrukcja w formacie HTML</translation>
1876 </message>
1877 <message>
1878 <location filename="../gui/manualwidgetfrm.ui" line="55"/>
1879 <source>Download the manual</source>
1880 <translation type="unfinished">Pobierz instrukcję</translation>
1881 </message>
1882 <message>
1883 <location filename="../gui/manualwidgetfrm.ui" line="63"/>
1884 <source>&amp;PDF version</source>
1885 <translation type="unfinished">&amp;PDF</translation>
1886 </message>
1887 <message>
1888 <location filename="../gui/manualwidgetfrm.ui" line="70"/>
1889 <source>&amp;HTML version (zip file)</source>
1890 <translation type="unfinished">&amp;HTML (plik zip)</translation>
1891 </message>
1892 <message>
1893 <location filename="../gui/manualwidgetfrm.ui" line="92"/>
1894 <source>Down&amp;load</source>
1895 <translation type="unfinished">&amp;Pobierz</translation>
1896 </message>
1897</context>
1898<context>
1899 <name>MsPackUtil</name>
1900 <message>
1901 <location filename="../base/mspackutil.cpp" line="101"/>
1902 <source>Creating output path failed</source>
1903 <translation type="unfinished">Utworzenie ścieżki wyjściowej nie powiodło się</translation>
1904 </message>
1905 <message>
1906 <location filename="../base/mspackutil.cpp" line="109"/>
1907 <source>Error during CAB operation</source>
1908 <translation type="unfinished">Błąd podczas działania na CAB</translation>
1909 </message>
1910</context>
1911<context>
1912 <name>PreviewFrm</name>
1913 <message>
1914 <location filename="../previewfrm.ui" line="16"/>
1915 <source>Preview</source>
1916 <translation>Podgląd</translation>
1917 </message>
1918</context>
1919<context>
1920 <name>ProgressLoggerFrm</name>
1921 <message>
1922 <location filename="../progressloggerfrm.ui" line="13"/>
1923 <location filename="../progressloggerfrm.ui" line="19"/>
1924 <source>Progress</source>
1925 <translation>Postęp</translation>
1926 </message>
1927 <message>
1928 <location filename="../progressloggerfrm.ui" line="32"/>
1929 <source>progresswindow</source>
1930 <translation>okno postępu</translation>
1931 </message>
1932 <message>
1933 <location filename="../progressloggerfrm.ui" line="58"/>
1934 <source>Save Log</source>
1935 <translation>Zapisz dziennik zdarzeń</translation>
1936 </message>
1937 <message>
1938 <location filename="../progressloggerfrm.ui" line="82"/>
1939 <source>&amp;Abort</source>
1940 <translation>&amp;Przerwij</translation>
1941 </message>
1942</context>
1943<context>
1944 <name>ProgressLoggerGui</name>
1945 <message>
1946 <location filename="../progressloggergui.cpp" line="104"/>
1947 <source>&amp;Abort</source>
1948 <translation>&amp;Przerwij</translation>
1949 </message>
1950 <message>
1951 <location filename="../progressloggergui.cpp" line="122"/>
1952 <source>&amp;Ok</source>
1953 <translation></translation>
1954 </message>
1955 <message>
1956 <location filename="../progressloggergui.cpp" line="146"/>
1957 <source>Save system trace log</source>
1958 <translation>Zapisz dzienik zdarzeń systemu</translation>
1959 </message>
1960</context>
1961<context>
1962 <name>QObject</name>
1963 <message>
1964 <location filename="../configure.cpp" line="625"/>
1965 <location filename="../main.cpp" line="83"/>
1966 <source>LTR</source>
1967 <extracomment>This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.
1968----------
1969This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.</extracomment>
1970 <translation>LTR</translation>
1971 </message>
1972 <message>
1973 <location filename="../base/system.cpp" line="385"/>
1974 <source>(unknown vendor name) </source>
1975 <translation>(nieznany producent)</translation>
1976 </message>
1977 <message>
1978 <location filename="../base/system.cpp" line="403"/>
1979 <source>(unknown product name)</source>
1980 <translation>(nieznanane urządzenie)</translation>
1981 </message>
1982 <message>
1983 <location filename="../base/bootloaderinstallhelper.cpp" line="80"/>
1984 <source>Bootloader installation is almost complete. Installation &lt;b&gt;requires&lt;/b&gt; you to perform the following steps manually:</source>
1985 <translation type="unfinished">Instalacja bootloadera została prawie ukończona. Dokończenie instalacji &lt;b&gt;wymaga&lt;/b&gt; aby nastepujące kroki zostały wykonane samodzielnie:</translation>
1986 </message>
1987 <message>
1988 <location filename="../base/bootloaderinstallhelper.cpp" line="86"/>
1989 <source>&lt;li&gt;Safely remove your player.&lt;/li&gt;</source>
1990 <translation type="unfinished">&lt;li&gt;Odłącz bezpiecznie swoje urządzenie.&lt;/li&gt;</translation>
1991 </message>
1992 <message>
1993 <location filename="../base/bootloaderinstallhelper.cpp" line="91"/>
1994 <source>&lt;li&gt;Reboot your player into the original firmware.&lt;/li&gt;&lt;li&gt;Perform a firmware upgrade using the update functionality of the original firmware. Please refer to your player&apos;s manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before starting the firmware update process.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1995 <translation type="unfinished">&lt;li&gt;Uruchom ponownie odtwarzacz na oryginalnym firmware.&lt;/li&gt;&lt;li&gt;Przeprowadź aktualizację używając funkcji zawartej w oryginalnym oprogramowaniu. Prosze sprawdzić instrukcję obsługi odtwarzacza aby uzyskać więcej szczegółów.&lt;br/&gt;&lt;b&gt;Ważne:&lt;/b&gt; aktualizacja oprogramowania jest procesem krytycznym, który nie może zostać przerwany. &lt;b&gt;Upewnij się, że przed przeprowadzeniem aktualizacji bateria odtwarzacza będzie w pełni naładowana.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Po aktualizacji firmware, ponownie uruchom urządzenie.&lt;/li&gt;</translation>
1996 </message>
1997 <message>
1998 <location filename="../base/bootloaderinstallhelper.cpp" line="102"/>
1999 <source>&lt;li&gt;Remove any previously inserted microSD card&lt;/li&gt;</source>
2000 <translation type="unfinished">&lt;li&gt;Wyjmij jakąkolwiek poprzednio włożoną kartę microSD&lt;/li&gt;</translation>
2001 </message>
2002 <message>
2003 <location filename="../base/bootloaderinstallhelper.cpp" line="103"/>
2004 <source>&lt;li&gt;Disconnect your player. The player will reboot and perform an update of the original firmware. Please refer to your players manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before disconnecting the player.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
2005 <translation type="unfinished">&lt;li&gt;Odłącz urządzenie. Odtwarzacz uruchomi się ponownie i przeprowadzi aktualizację do oryginalnego oprogramowania. Prosze sprawdzić instrukcję obsługi odtwarzacza aby uzyskać więcej szczegółów.&lt;br/&gt;&lt;b&gt;Ważne:&lt;/b&gt; aktualizacja oprogramowania jest procesem krytycznym, który nie może zostać przerwany. &lt;b&gt;Upewnij się, że przed odłączeniem bateria odtwarzacza będzie w pełni naładowana.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Po aktualizacji firmware, ponownie uruchom urządzenie.&lt;/li&gt;</translation>
2006 </message>
2007 <message>
2008 <location filename="../base/bootloaderinstallhelper.cpp" line="114"/>
2009 <source>&lt;li&gt;Turn the player off&lt;/li&gt;&lt;li&gt;Insert the charger&lt;/li&gt;</source>
2010 <translation type="unfinished">&lt;li&gt;Wyłącz odtwarzacz&lt;/li&gt;&lt;li&gt;Podłącz ładowarkę do urządzenia&lt;/li&gt;</translation>
2011 </message>
2012 <message>
2013 <location filename="../base/bootloaderinstallhelper.cpp" line="119"/>
2014 <source>&lt;li&gt;Unplug USB and power adaptors&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to turn the player off&lt;/li&gt;&lt;li&gt;Toggle the battery switch on the player&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to boot into Rockbox&lt;/li&gt;</source>
2015 <translation type="unfinished">&lt;li&gt;Odłącz od USB i zasilaczy&lt;/li&gt;&lt;li&gt;Przytrzymaj &lt;i&gt;przycisk włączania&lt;/i&gt; aby wyłączyć odtwarzacz&lt;/li&gt;&lt;li&gt;Zmień położenie włącznika baterii na urządzeniu&lt;/li&gt;&lt;li&gt;Przytrzymaj &lt;i&gt;przycisk włączania&lt;/i&gt; aby uruchomić Rockboxa&lt;/li&gt;</translation>
2016 </message>
2017 <message>
2018 <location filename="../base/bootloaderinstallhelper.cpp" line="125"/>
2019 <source>&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You can safely install other parts first, but the above steps are &lt;b&gt;required&lt;/b&gt; to finish the installation!&lt;/p&gt;</source>
2020 <translation type="unfinished">&lt;p&gt;&lt;b&gt;Uwaga:&lt;/b&gt; Możesz najpierw zainstalować inne składniki, ale powyższe kroki są &lt;b&gt;wymagane&lt;/b&gt; do zakończenia instalacji!&lt;/p&gt;</translation>
2021 </message>
2022</context>
2023<context>
2024 <name>QuaZipFile</name>
2025 <message>
2026 <location filename="../quazip/quazipfile.cpp" line="141"/>
2027 <source>ZIP/UNZIP API error %1</source>
2028 <translation>błąd ZIP/UNZIP API %1</translation>
2029 </message>
2030</context>
2031<context>
2032 <name>RbUtilQt</name>
2033 <message>
2034 <location filename="../rbutilqt.cpp" line="224"/>
2035 <source>Downloading build information, please wait ...</source>
2036 <translation>Pobieranie informacji o buildzie, prosze czekać...</translation>
2037 </message>
2038 <message>
2039 <location filename="../rbutilqt.cpp" line="235"/>
2040 <source>Can&apos;t get version information!</source>
2041 <translation>Nie można pobrać informacji!</translation>
2042 </message>
2043 <message>
2044 <location filename="../rbutilqt.cpp" line="236"/>
2045 <source>Network error</source>
2046 <translation>Błąd połączenia</translation>
2047 </message>
2048 <message>
2049 <location filename="../rbutilqt.cpp" line="329"/>
2050 <source>New installation</source>
2051 <translation>Nowa instalacja</translation>
2052 </message>
2053 <message>
2054 <location filename="../rbutilqt.cpp" line="330"/>
2055 <source>This is a new installation of Rockbox Utility, or a new version. The configuration dialog will now open to allow you to setup the program, or review your settings.</source>
2056 <translation></translation>
2057 </message>
2058 <message>
2059 <location filename="../rbutilqt.cpp" line="337"/>
2060 <location filename="../rbutilqt.cpp" line="642"/>
2061 <source>Configuration error</source>
2062 <translation>Błąd konfiguracji</translation>
2063 </message>
2064 <message>
2065 <location filename="../rbutilqt.cpp" line="338"/>
2066 <source>Your configuration is invalid. This is most likely due to a changed device path. The configuration dialog will now open to allow you to correct the problem.</source>
2067 <translation>Twoja konfiguracja jest niewłaściwa. Prawdopodobnie spowodowane jest to zmianą ścieżki do urządzenia. Zostanie teraz otwarte okno konfiguracji, w którym zmienisz ustawienia.</translation>
2068 </message>
2069 <message>
2070 <location filename="../rbutilqt.cpp" line="249"/>
2071 <source>Download build information finished.</source>
2072 <translation>Skończono pobieranie informacji.</translation>
2073 </message>
2074 <message>
2075 <location filename="../rbutilqt.cpp" line="110"/>
2076 <source>Wine detected!</source>
2077 <translation>Wykryto Wine!</translation>
2078 </message>
2079 <message>
2080 <location filename="../rbutilqt.cpp" line="111"/>
2081 <source>It seems you are trying to run this program under Wine. Please don&apos;t do this, running under Wine will fail. Use the native Linux binary instead.</source>
2082 <translation>Wygląda na to, że uruchomiłeś ten program przy pomocy Wine. Program tak uruchomiony może nie działać poprawnie. Użyj natywnej wersji linuxowej.</translation>
2083 </message>
2084 <message>
2085 <location filename="../rbutilqt.cpp" line="237"/>
2086 <source>Can&apos;t get version information.
2087Network error: %1. Please check your network and proxy settings.</source>
2088 <translation>Nie można pobrać informacji o wersji.
2089Problem z połączeniem sieciowym: %1. Sprawdź ustawienia sieciowe oraz konfigurację proxy.</translation>
2090 </message>
2091 <message>
2092 <location filename="../rbutilqt.cpp" line="450"/>
2093 <source>Confirm Installation</source>
2094 <translation>Potwierdź instalację</translation>
2095 </message>
2096 <message>
2097 <location filename="../rbutilqt.cpp" line="582"/>
2098 <source>Mount point is wrong!</source>
2099 <translation>Błędny punkt montowania!</translation>
2100 </message>
2101 <message>
2102 <location filename="../rbutilqt.cpp" line="430"/>
2103 <source>No Rockbox installation found</source>
2104 <translation>Nie znaleziono instalacji Rockboxa</translation>
2105 </message>
2106 <message>
2107 <location filename="../rbutilqt.cpp" line="416"/>
2108 <source>Warning</source>
2109 <translation>Ostrzeżenie</translation>
2110 </message>
2111 <message>
2112 <location filename="../rbutilqt.cpp" line="417"/>
2113 <source>The Application is still downloading Information about new Builds. Please try again shortly.</source>
2114 <translation>Aplikacja jest w trakcie pobierania informacji o nowych wersjach. Spróbuj ponownie za krótką chwilę.</translation>
2115 </message>
2116 <message>
2117 <location filename="../rbutilqt.cpp" line="431"/>
2118 <source>Could not determine the installed Rockbox version. Please install a Rockbox build before installing voice files.</source>
2119 <translation>Nie można sprawdzić wersji zainstalowanego Rockboxa. Proszę zainstalować Rockboxa przed instalacją plików głosowych.</translation>
2120 </message>
2121 <message>
2122 <location filename="../rbutilqt.cpp" line="451"/>
2123 <source>Do you really want to install the voice file?</source>
2124 <translation>Czy na pewno chcesz zainstalować pliki głosowe?</translation>
2125 </message>
2126 <message>
2127 <location filename="../rbutilqt.cpp" line="512"/>
2128 <source>Confirm Uninstallation</source>
2129 <translation>Potwierdź usunięcie</translation>
2130 </message>
2131 <message>
2132 <location filename="../rbutilqt.cpp" line="513"/>
2133 <source>Do you really want to uninstall the Bootloader?</source>
2134 <translation>Czy na pewno chcesz odinstalowac bootloadera?</translation>
2135 </message>
2136 <message>
2137 <location filename="../rbutilqt.cpp" line="528"/>
2138 <source>No uninstall method for this target known.</source>
2139 <translation>Nie obsługiwana metoda odinstalowania dla tego odtwarzacza.</translation>
2140 </message>
2141 <message>
2142 <location filename="../rbutilqt.cpp" line="542"/>
2143 <source>Rockbox Utility can not uninstall the bootloader on this target. Try a normal firmware update to remove the booloader.</source>
2144 <translation>Rockbox Utility nie obsługuje usuwania bootloadera na tym urządzeniu. Przeprowadź normalną procedurę uaktualnienia firmware aby usunąć bootloader.</translation>
2145 </message>
2146 <message>
2147 <location filename="../rbutilqt.cpp" line="733"/>
2148 <source>New version of Rockbox Utility available.</source>
2149 <translation>Dostępna nowa wersja Rockbox Utility.</translation>
2150 </message>
2151 <message>
2152 <location filename="../rbutilqt.cpp" line="736"/>
2153 <source>Rockbox Utility is up to date.</source>
2154 <translation>Rockbox Utility jest aktualne.</translation>
2155 </message>
2156 <message>
2157 <location filename="../rbutilqt.cpp" line="568"/>
2158 <source>Confirm installation</source>
2159 <translation>Potwierdź instalację</translation>
2160 </message>
2161 <message>
2162 <location filename="../rbutilqt.cpp" line="439"/>
2163 <source>No voice file available</source>
2164 <translation type="unfinished">Brak dostępnego pliku głosowego</translation>
2165 </message>
2166 <message>
2167 <location filename="../rbutilqt.cpp" line="440"/>
2168 <source>The installed version of Rockbox is a development version. Pre-built voices are only available for release versions of Rockbox. Please generate a voice yourself using the &quot;Create voice file&quot; functionality.</source>
2169 <translation>Zainstalowana wersja Rockboxa jest wersją rozwojową. Wcześniej utworzone pliki głosowe są dostępne tylko dla oficjalnych wydań Rockboxa. Możesz samodzielnie wygenerować plik głosowy .voice dzięki opcji &quot;Stwórz plik głosowy&quot;.</translation>
2170 </message>
2171 <message>
2172 <location filename="../rbutilqt.cpp" line="550"/>
2173 <source>No Rockbox bootloader found.</source>
2174 <translation type="unfinished">Nie znaleziono bootloadera Rockboxa.</translation>
2175 </message>
2176 <message>
2177 <location filename="../rbutilqt.cpp" line="569"/>
2178 <source>Do you really want to install Rockbox Utility to your player? After installation you can run it from the players hard drive.</source>
2179 <translation>Czy na pewno chcesz zainstalować Rockbox Utility na urządzeniu? Po instalacji mozesz uruchomić aplikację z dysku urządzenia.</translation>
2180 </message>
2181 <message>
2182 <location filename="../rbutilqt.cpp" line="578"/>
2183 <source>Installing Rockbox Utility</source>
2184 <translation>Instalowanie Rockbox Utility</translation>
2185 </message>
2186 <message>
2187 <location filename="../rbutilqt.cpp" line="596"/>
2188 <source>Error installing Rockbox Utility</source>
2189 <translation>Błąd podczas instalacji Rockbox Utility</translation>
2190 </message>
2191 <message>
2192 <location filename="../rbutilqt.cpp" line="600"/>
2193 <source>Installing user configuration</source>
2194 <translation>Instalowanie konfiguracji użytkownika</translation>
2195 </message>
2196 <message>
2197 <location filename="../rbutilqt.cpp" line="604"/>
2198 <source>Error installing user configuration</source>
2199 <translation>Błąd instalacji konfiguracji użytkownika</translation>
2200 </message>
2201 <message>
2202 <location filename="../rbutilqt.cpp" line="608"/>
2203 <source>Successfully installed Rockbox Utility.</source>
2204 <translation>Rockbox Utility zainstalowano pomyślnie.</translation>
2205 </message>
2206 <message>
2207 <location filename="../rbutilqt.cpp" line="643"/>
2208 <source>Your configuration is invalid. Please go to the configuration dialog and make sure the selected values are correct.</source>
2209 <translation>Twoja konfiguracja jest nieprawidłowa. Przejdź do okna konfiguracji i upewnij się że wybrane wartości są poprawne.</translation>
2210 </message>
2211 <message>
2212 <location filename="../rbutilqt.cpp" line="664"/>
2213 <source>Checking for update ...</source>
2214 <translation>Sprawdzanie aktualizacji...</translation>
2215 </message>
2216 <message>
2217 <location filename="../rbutilqt.cpp" line="729"/>
2218 <source>RockboxUtility Update available</source>
2219 <translation>Dostępna jest nowa wersja programu</translation>
2220 </message>
2221 <message>
2222 <location filename="../rbutilqt.cpp" line="730"/>
2223 <source>&lt;b&gt;New RockboxUtility Version available.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Download it from here: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</source>
2224 <translation>&lt;b&gt;Dostępna jest nowa wersja programu.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Pobierz go z: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</translation>
2225 </message>
2226 <message>
2227 <location filename="../rbutilqt.cpp" line="759"/>
2228 <source>Device ejected</source>
2229 <translation type="unfinished">Urządzenie wysunięto</translation>
2230 </message>
2231 <message>
2232 <location filename="../rbutilqt.cpp" line="760"/>
2233 <source>Device successfully ejected. You may now disconnect the player from the PC.</source>
2234 <translation type="unfinished">Urządzenie zostało pomyślnie wysunięte. Możesz teraz odłączyć odtwarzać od komputera.</translation>
2235 </message>
2236 <message>
2237 <location filename="../rbutilqt.cpp" line="764"/>
2238 <source>Ejecting failed</source>
2239 <translation type="unfinished">Wysuwanie zakończone niepowodzeniem</translation>
2240 </message>
2241 <message>
2242 <location filename="../rbutilqt.cpp" line="765"/>
2243 <source>Ejecting the device failed. Please make sure no programs are accessing files on the device. If ejecting still fails please use your computers eject funtionality.</source>
2244 <translation type="unfinished">Wysuwanie urządzenia zakończyło się niepowodzeniem. Proszę upewnij się, że żadne programy nie próbują uzyskać dostępu do urządzenia.Jeśli wysuwanie dalej zakończy się niepowodzeniem użyj wysuwania systemowego.</translation>
2245 </message>
2246</context>
2247<context>
2248 <name>RbUtilQtFrm</name>
2249 <message>
2250 <location filename="../rbutilqtfrm.ui" line="14"/>
2251 <source>Rockbox Utility</source>
2252 <translation></translation>
2253 </message>
2254 <message>
2255 <location filename="../rbutilqtfrm.ui" line="31"/>
2256 <source>Device</source>
2257 <translation>Urządzenie</translation>
2258 </message>
2259 <message>
2260 <location filename="../rbutilqtfrm.ui" line="92"/>
2261 <source>&amp;Change</source>
2262 <translation>&amp;Zmień</translation>
2263 </message>
2264 <message>
2265 <location filename="../rbutilqtfrm.ui" line="163"/>
2266 <source>Welcome</source>
2267 <translation>Witaj</translation>
2268 </message>
2269 <message>
2270 <location filename="../rbutilqtfrm.ui" line="160"/>
2271 <location filename="../rbutilqtfrm.ui" line="658"/>
2272 <source>&amp;Installation</source>
2273 <translation>&amp;Instalacja</translation>
2274 </message>
2275 <message>
2276 <location filename="../rbutilqtfrm.ui" line="168"/>
2277 <location filename="../rbutilqtfrm.ui" line="450"/>
2278 <source>&amp;Accessibility</source>
2279 <translation type="unfinished">&amp;Ułatwienia dostępu</translation>
2280 </message>
2281 <message>
2282 <location filename="../rbutilqtfrm.ui" line="171"/>
2283 <source>Install accessibility add-ons</source>
2284 <translation type="unfinished">Instalacja dodatków ułatwiających obsługę Rockboxa</translation>
2285 </message>
2286 <message>
2287 <location filename="../rbutilqtfrm.ui" line="177"/>
2288 <source>Install Voice files</source>
2289 <translation>Instaluj pliki głosowe</translation>
2290 </message>
2291 <message>
2292 <location filename="../rbutilqtfrm.ui" line="194"/>
2293 <source>&lt;b&gt;Install Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so if you installed the voice file Rockbox will speak.</source>
2294 <translation type="unfinished">&lt;b&gt;Instaluj plik głosowy&lt;/b&gt;&lt;br/&gt;Dzięki plikowi .voice Rockbox może komunikować się za pomocą interfejsu mówionego. Wymowa jest domyślnie włączona w opcji Menu Głosowe, więc jeśli zainstalujesz plik głosowy, Rockbox &quot;przemówi&quot;.</translation>
2295 </message>
2296 <message>
2297 <location filename="../rbutilqtfrm.ui" line="204"/>
2298 <source>Install Talk files</source>
2299 <translation>Instaluj pliki .talk</translation>
2300 </message>
2301 <message>
2302 <location filename="../rbutilqtfrm.ui" line="221"/>
2303 <source>&lt;b&gt;Create Talk Files&lt;/b&gt;&lt;br/&gt;Talkfiles are needed to let Rockbox speak File and Foldernames</source>
2304 <translation type="unfinished">&lt;b&gt;Stwórz pliki .talk&lt;/b&gt;&lt;br/&gt;Pliki .talk są potrzebne aby interfejs Rockboxa mógł wymawiać nazwy plików i folderów</translation>
2305 </message>
2306 <message>
2307 <location filename="../rbutilqtfrm.ui" line="254"/>
2308 <source>Create Voice files</source>
2309 <translation>Stwórz pliki głosowe</translation>
2310 </message>
2311 <message>
2312 <location filename="../rbutilqtfrm.ui" line="271"/>
2313 <source>&lt;b&gt;Create Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so
2314 if you installed the voice file Rockbox will speak.</source>
2315 <translation type="unfinished">&lt;b&gt;Stwórz plik głosowy&lt;/b&gt;&lt;br/&gt;Pliki głosowe są wymagane do działania interfejsu mówionego Rockboxa. Wymowa jest domyślnie włączona w opcji Menu Głosowe, więc jeśli stworzysz plik głosowy, Rockbox &quot;przemówi&quot;.</translation>
2316 </message>
2317 <message>
2318 <location filename="../rbutilqtfrm.ui" line="458"/>
2319 <source>&amp;Uninstallation</source>
2320 <translation>&amp;Deinstalacja</translation>
2321 </message>
2322 <message>
2323 <location filename="../rbutilqtfrm.ui" line="286"/>
2324 <location filename="../rbutilqtfrm.ui" line="319"/>
2325 <source>Uninstall Rockbox</source>
2326 <translation>Odinstalowywanie Rockboxa</translation>
2327 </message>
2328 <message>
2329 <location filename="../rbutilqtfrm.ui" line="121"/>
2330 <source>mountpoint unknown or invalid</source>
2331 <translation type="unfinished">nieznany lub błędny</translation>
2332 </message>
2333 <message>
2334 <location filename="../rbutilqtfrm.ui" line="114"/>
2335 <source>Mountpoint:</source>
2336 <translation type="unfinished">Punkt montowania:</translation>
2337 </message>
2338 <message>
2339 <location filename="../rbutilqtfrm.ui" line="72"/>
2340 <source>device unknown or invalid</source>
2341 <translation type="unfinished">nieznany lub niewłaściwy</translation>
2342 </message>
2343 <message>
2344 <location filename="../rbutilqtfrm.ui" line="65"/>
2345 <source>Device:</source>
2346 <translation type="unfinished">Model:</translation>
2347 </message>
2348 <message>
2349 <location filename="../rbutilqtfrm.ui" line="283"/>
2350 <source>Backup &amp;&amp; &amp;Uninstallation</source>
2351 <translation type="unfinished">Kopia &amp;i &amp;Deinstalacja</translation>
2352 </message>
2353 <message>
2354 <location filename="../rbutilqtfrm.ui" line="292"/>
2355 <source>Uninstall Bootloader</source>
2356 <translation>Odinstalowywanie bootloadera</translation>
2357 </message>
2358 <message>
2359 <location filename="../rbutilqtfrm.ui" line="309"/>
2360 <source>&lt;b&gt;Remove the bootloader&lt;/b&gt;&lt;br/&gt;After removing the bootloader you won&apos;t be able to start Rockbox.</source>
2361 <translation>&lt;b&gt;Usuń bootloadera&lt;/b&gt;&lt;br/&gt;Po usunięciu bootloadera nie będziesz mógł uruchomić Rockboxa.</translation>
2362 </message>
2363 <message>
2364 <location filename="../rbutilqtfrm.ui" line="336"/>
2365 <source>&lt;b&gt;Uninstall Rockbox from your audio player.&lt;/b&gt;&lt;br/&gt;This will leave the bootloader in place (you need to remove it manually).</source>
2366 <translation type="unfinished">&lt;b&gt;Odinstaluj Rockboxa ze swojego urządzenia&lt;/b&gt;&lt;br/&gt;Tylko Rockbox zostanie usunięty. Bootloader będziesz musiał usunąć samodzielnie.</translation>
2367 </message>
2368 <message>
2369 <location filename="../rbutilqtfrm.ui" line="349"/>
2370 <source>Backup</source>
2371 <translation type="unfinished">Kopia zapasowa</translation>
2372 </message>
2373 <message>
2374 <location filename="../rbutilqtfrm.ui" line="366"/>
2375 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup current installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Create a backup by archiving the contents of the Rockbox installation folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2376 <translation type="unfinished">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Wykonaj kopię zapasową Rockboxa.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Tworzy kopię poprzez zarchiwizowanie całej zawartości folderu instalacyjnego Rockoxa.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
2377 </message>
2378 <message>
2379 <location filename="../rbutilqtfrm.ui" line="393"/>
2380 <source>&amp;Manual</source>
2381 <translation>&amp;Instrukcje</translation>
2382 </message>
2383 <message>
2384 <location filename="../rbutilqtfrm.ui" line="396"/>
2385 <source>View and download the manual</source>
2386 <translation>Pobierz i przeczytaj instrukcję obsługi</translation>
2387 </message>
2388 <message>
2389 <location filename="../rbutilqtfrm.ui" line="401"/>
2390 <source>Inf&amp;o</source>
2391 <translation>&amp;Informacje</translation>
2392 </message>
2393 <message>
2394 <location filename="../rbutilqtfrm.ui" line="419"/>
2395 <source>&amp;File</source>
2396 <translation>&amp;Plik</translation>
2397 </message>
2398 <message>
2399 <location filename="../rbutilqtfrm.ui" line="432"/>
2400 <source>&amp;Troubleshoot</source>
2401 <translation>&amp;Rozwiązywanie problemów</translation>
2402 </message>
2403 <message>
2404 <location filename="../rbutilqtfrm.ui" line="446"/>
2405 <source>Action&amp;s</source>
2406 <translation>&amp;Czynności</translation>
2407 </message>
2408 <message>
2409 <location filename="../rbutilqtfrm.ui" line="474"/>
2410 <source>Empty local download cache</source>
2411 <translation>Wyczyść tymczasowy bufor pobierania</translation>
2412 </message>
2413 <message>
2414 <location filename="../rbutilqtfrm.ui" line="479"/>
2415 <source>Install Rockbox Utility on player</source>
2416 <translation>Zainstaluj Rockbox Utility na urządzeniu</translation>
2417 </message>
2418 <message>
2419 <location filename="../rbutilqtfrm.ui" line="484"/>
2420 <source>&amp;Configure</source>
2421 <translation>&amp;Konfiguruj</translation>
2422 </message>
2423 <message>
2424 <location filename="../rbutilqtfrm.ui" line="489"/>
2425 <source>E&amp;xit</source>
2426 <translation>&amp;Zamknij</translation>
2427 </message>
2428 <message>
2429 <location filename="../rbutilqtfrm.ui" line="492"/>
2430 <source>Ctrl+Q</source>
2431 <translation>Ctrl+Q</translation>
2432 </message>
2433 <message>
2434 <location filename="../rbutilqtfrm.ui" line="497"/>
2435 <source>&amp;About</source>
2436 <translation>&amp;Info o Rockbox Utility</translation>
2437 </message>
2438 <message>
2439 <location filename="../rbutilqtfrm.ui" line="502"/>
2440 <source>About &amp;Qt</source>
2441 <translation>Info o &amp;Qt</translation>
2442 </message>
2443 <message>
2444 <location filename="../rbutilqtfrm.ui" line="428"/>
2445 <location filename="../rbutilqtfrm.ui" line="507"/>
2446 <source>&amp;Help</source>
2447 <translation>&amp;Pomoc</translation>
2448 </message>
2449 <message>
2450 <location filename="../rbutilqtfrm.ui" line="103"/>
2451 <source>&amp;Eject</source>
2452 <translation type="unfinished">&amp;Wysuń</translation>
2453 </message>
2454 <message>
2455 <location filename="../rbutilqtfrm.ui" line="512"/>
2456 <source>Info</source>
2457 <translation>Info</translation>
2458 </message>
2459 <message>
2460 <location filename="../rbutilqtfrm.ui" line="521"/>
2461 <source>&amp;Complete Installation</source>
2462 <translation>&amp;Kompletna instalacja</translation>
2463 </message>
2464 <message>
2465 <location filename="../rbutilqtfrm.ui" line="530"/>
2466 <source>&amp;Minimal Installation</source>
2467 <translation>&amp;Podstawowa instalacja</translation>
2468 </message>
2469 <message>
2470 <location filename="../rbutilqtfrm.ui" line="539"/>
2471 <source>Install &amp;Bootloader</source>
2472 <translation>Zainstaluj &amp;bootloadera</translation>
2473 </message>
2474 <message>
2475 <location filename="../rbutilqtfrm.ui" line="548"/>
2476 <source>Install &amp;Rockbox</source>
2477 <translation>Zainstaluj &amp;Rockboxa</translation>
2478 </message>
2479 <message>
2480 <location filename="../rbutilqtfrm.ui" line="557"/>
2481 <source>Install &amp;Fonts Package</source>
2482 <translation>Zainstaluj &amp;Czcionki</translation>
2483 </message>
2484 <message>
2485 <location filename="../rbutilqtfrm.ui" line="566"/>
2486 <source>Install &amp;Themes</source>
2487 <translation>Zainstaluj &amp;Style</translation>
2488 </message>
2489 <message>
2490 <location filename="../rbutilqtfrm.ui" line="575"/>
2491 <source>Install &amp;Game Files</source>
2492 <translation>Zainstaluj pliki &amp;gier</translation>
2493 </message>
2494 <message>
2495 <location filename="../rbutilqtfrm.ui" line="584"/>
2496 <source>&amp;Install Voice File</source>
2497 <translation>&amp;Instaluj plik głosowy</translation>
2498 </message>
2499 <message>
2500 <location filename="../rbutilqtfrm.ui" line="593"/>
2501 <source>Create &amp;Talk Files</source>
2502 <translation>Stwórz pliki .&amp;talk</translation>
2503 </message>
2504 <message>
2505 <location filename="../rbutilqtfrm.ui" line="602"/>
2506 <source>Remove &amp;bootloader</source>
2507 <translation>Usuń &amp;bootloadera</translation>
2508 </message>
2509 <message>
2510 <location filename="../rbutilqtfrm.ui" line="611"/>
2511 <source>Uninstall &amp;Rockbox</source>
2512 <translation>Odinstaluj &amp;Rockboxa</translation>
2513 </message>
2514 <message>
2515 <location filename="../rbutilqtfrm.ui" line="616"/>
2516 <source>Read PDF manual</source>
2517 <translation>Przeczytaj instrukcję PDF</translation>
2518 </message>
2519 <message>
2520 <location filename="../rbutilqtfrm.ui" line="621"/>
2521 <source>Read HTML manual</source>
2522 <translation>Przeczytaj instrukcję HTML</translation>
2523 </message>
2524 <message>
2525 <location filename="../rbutilqtfrm.ui" line="626"/>
2526 <source>Download PDF manual</source>
2527 <translation>Pobierz instrukcję PDF</translation>
2528 </message>
2529 <message>
2530 <location filename="../rbutilqtfrm.ui" line="631"/>
2531 <source>Download HTML manual (zip)</source>
2532 <translation>Pobierz instrukcję HTML (zip)</translation>
2533 </message>
2534 <message>
2535 <location filename="../rbutilqtfrm.ui" line="640"/>
2536 <source>Create &amp;Voice File</source>
2537 <translation>S&amp;twórz plik głosowy</translation>
2538 </message>
2539 <message>
2540 <location filename="../rbutilqtfrm.ui" line="643"/>
2541 <source>Create Voice File</source>
2542 <translation>Stwórz plik głosowy</translation>
2543 </message>
2544 <message>
2545 <location filename="../rbutilqtfrm.ui" line="648"/>
2546 <source>&amp;System Info</source>
2547 <translation>Informacje o &amp;systemie</translation>
2548 </message>
2549 <message>
2550 <location filename="../rbutilqtfrm.ui" line="653"/>
2551 <source>System &amp;Trace</source>
2552 <translation>&amp;Dziennik zdarzeń systemu</translation>
2553 </message>
2554 <message>
2555 <location filename="../rbutilqtfrm.ui" line="663"/>
2556 <source>Show &amp;Changelog</source>
2557 <translation>Pokaż &amp;Listę zmian</translation>
2558 </message>
2559</context>
2560<context>
2561 <name>SelectiveInstallWidget</name>
2562 <message>
2563 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="20"/>
2564 <source>Selective Installation</source>
2565 <translation type="unfinished">Selektywna instalacja</translation>
2566 </message>
2567 <message>
2568 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="26"/>
2569 <source>Rockbox version to install</source>
2570 <translation type="unfinished">Wersja Rockboxa do zainstalowania</translation>
2571 </message>
2572 <message>
2573 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="35"/>
2574 <source>Version information not available yet.</source>
2575 <translation type="unfinished">Informacja o wersji jeszcze niedostępna.</translation>
2576 </message>
2577 <message>
2578 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="54"/>
2579 <source>Rockbox components to install</source>
2580 <translation type="unfinished">Składniki Rockboxa które można zainstalować</translation>
2581 </message>
2582 <message>
2583 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="60"/>
2584 <source>&amp;Bootloader</source>
2585 <translation type="unfinished">&amp;Bootloader</translation>
2586 </message>
2587 <message>
2588 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="80"/>
2589 <source>The main Rockbox firmware.</source>
2590 <translation type="unfinished">Podstawowy firmware Rockoboxa.</translation>
2591 </message>
2592 <message>
2593 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="90"/>
2594 <source>Fonts</source>
2595 <translation type="unfinished">Czcionki</translation>
2596 </message>
2597 <message>
2598 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="104"/>
2599 <source>&amp;Rockbox</source>
2600 <translation type="unfinished">&amp;Rockbox</translation>
2601 </message>
2602 <message>
2603 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="124"/>
2604 <source>Some game plugins require additional files.</source>
2605 <translation type="unfinished">Niektóre gry wymagają dodatkowych plików.</translation>
2606 </message>
2607 <message>
2608 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="140"/>
2609 <source>Additional fonts for the User Interface.</source>
2610 <translation type="unfinished">Dodatkowe czcionki.</translation>
2611 </message>
2612 <message>
2613 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="156"/>
2614 <source>The bootloader is required for starting Rockbox. Only necessary for first time install.</source>
2615 <translation type="unfinished">Aby uruchomić Rockboxa wymagany jest bootloader. Instaluje się go tylko za pierwszym razem.</translation>
2616 </message>
2617 <message>
2618 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="166"/>
2619 <source>Game Files</source>
2620 <translation type="unfinished">Pliki gier</translation>
2621 </message>
2622 <message>
2623 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="177"/>
2624 <source>Customize</source>
2625 <translation type="unfinished">Dostosuj</translation>
2626 </message>
2627 <message>
2628 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="188"/>
2629 <source>Themes</source>
2630 <translation type="unfinished">Style</translation>
2631 </message>
2632 <message>
2633 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="205"/>
2634 <source>Themes allow adjusting the user interface of Rockbox. Use &quot;Customize&quot; to select themes.</source>
2635 <translation type="unfinished">Style pozwalają na zmianę wyglądu interfejsu Rockboxa. Użyj &quot;Dostosuj&quot; aby wybrać dostępne style.</translation>
2636 </message>
2637 <message>
2638 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="250"/>
2639 <source>&amp;Install</source>
2640 <translation type="unfinished">&amp;Instaluj</translation>
2641 </message>
2642 <message>
2643 <location filename="../gui/selectiveinstallwidget.cpp" line="67"/>
2644 <source>This is the latest stable release available.</source>
2645 <translation type="unfinished">To jest obecnie najnowsze stabilne wydanie.</translation>
2646 </message>
2647 <message>
2648 <location filename="../gui/selectiveinstallwidget.cpp" line="70"/>
2649 <source>The development version is updated on every code change. Last update was on %1</source>
2650 <translation type="unfinished">Wersja rozwojowa jest uaktualniana z każdą zmianą kodu źródłowego. Ostatnia aktualizacja nastąpiła: %1</translation>
2651 </message>
2652 <message>
2653 <location filename="../gui/selectiveinstallwidget.cpp" line="74"/>
2654 <source>This will eventually become the next Rockbox version. Install it to help testing.</source>
2655 <translation type="unfinished">To ostatecznie będzie następne wydanie Rockboxa. Zainstaluj aby pomóc w testach.</translation>
2656 </message>
2657 <message>
2658 <location filename="../gui/selectiveinstallwidget.cpp" line="100"/>
2659 <source>Stable Release (Version %1)</source>
2660 <translation type="unfinished">Wydanie stabilne (Wersja %1)</translation>
2661 </message>
2662 <message>
2663 <location filename="../gui/selectiveinstallwidget.cpp" line="104"/>
2664 <source>Development Version (Revison %1)</source>
2665 <translation type="unfinished">Wersja rozwojowa (Rewizja %1)</translation>
2666 </message>
2667 <message>
2668 <location filename="../gui/selectiveinstallwidget.cpp" line="108"/>
2669 <source>Release Candidate (Revison %1)</source>
2670 <translation type="unfinished">Kandydat do wydania (Rewizja %1)</translation>
2671 </message>
2672 <message>
2673 <location filename="../gui/selectiveinstallwidget.cpp" line="131"/>
2674 <source>The selected player doesn&apos;t need a bootloader.</source>
2675 <translation type="unfinished">Wybrany odtwarzacz nie potrzebuje bootloadera.</translation>
2676 </message>
2677 <message>
2678 <location filename="../gui/selectiveinstallwidget.cpp" line="136"/>
2679 <source>The bootloader is required for starting Rockbox. Installation of the bootloader is only necessary on first time installation.</source>
2680 <translation type="unfinished">Bootloader jest wymagany aby Rockbox mógł być uruchomiony na urządzeniu. Instalacja bootloadera jest wymagana tylko za pierwszym razem.</translation>
2681 </message>
2682 <message>
2683 <location filename="../gui/selectiveinstallwidget.cpp" line="183"/>
2684 <source>Mountpoint is wrong</source>
2685 <translation type="unfinished">Nieprawidłowy punkt montowania</translation>
2686 </message>
2687 <message>
2688 <location filename="../gui/selectiveinstallwidget.cpp" line="239"/>
2689 <source>No install method known.</source>
2690 <translation type="unfinished">Nieznana metoda instalacji.</translation>
2691 </message>
2692 <message>
2693 <location filename="../gui/selectiveinstallwidget.cpp" line="266"/>
2694 <source>Bootloader detected</source>
2695 <translation type="unfinished">Wykryto bootloadera</translation>
2696 </message>
2697 <message>
2698 <location filename="../gui/selectiveinstallwidget.cpp" line="267"/>
2699 <source>Bootloader already installed. Do you want to reinstall the bootloader?</source>
2700 <translation type="unfinished">Bootloader jest już zainstalowany. Czy na pewno chcesz go zainstalować ponownie?</translation>
2701 </message>
2702 <message>
2703 <location filename="../gui/selectiveinstallwidget.cpp" line="271"/>
2704 <source>Bootloader installation skipped</source>
2705 <translation type="unfinished">Pominięto instalację bootloadera</translation>
2706 </message>
2707 <message>
2708 <location filename="../gui/selectiveinstallwidget.cpp" line="284"/>
2709 <source>Create Bootloader backup</source>
2710 <translation type="unfinished">Stworzono kopię bootloadera</translation>
2711 </message>
2712 <message>
2713 <location filename="../gui/selectiveinstallwidget.cpp" line="285"/>
2714 <source>You can create a backup of the original bootloader file. Press &quot;Yes&quot; to select an output folder on your computer to save the file to. The file will get placed in a new folder &quot;%1&quot; created below the selected folder.
2715Press &quot;No&quot; to skip this step.</source>
2716 <translation type="unfinished">Możesz stworzyć kopię zapasową oryginalnego bootloadera. Naciśnij &quot;Tak&quot; aby wybrać folder, gdzie zapiszesz plik bootloadera. Plik pojawi się w nowym folderze &quot;%1&quot;, stworzonym poniżej zaznaczonego folderu.
2717Naciśnij &quot;Nie&quot; aby pominąć ten etap.</translation>
2718 </message>
2719 <message>
2720 <location filename="../gui/selectiveinstallwidget.cpp" line="292"/>
2721 <source>Browse backup folder</source>
2722 <translation type="unfinished">Otwórz folder z kopią zapasową</translation>
2723 </message>
2724 <message>
2725 <location filename="../gui/selectiveinstallwidget.cpp" line="304"/>
2726 <source>Prerequisites</source>
2727 <translation type="unfinished">Wymogi</translation>
2728 </message>
2729 <message>
2730 <location filename="../gui/selectiveinstallwidget.cpp" line="309"/>
2731 <source>Bootloader installation aborted</source>
2732 <translation type="unfinished">Instalacja bootloadera została przerwana</translation>
2733 </message>
2734 <message>
2735 <location filename="../gui/selectiveinstallwidget.cpp" line="319"/>
2736 <source>Bootloader files (%1)</source>
2737 <translation type="unfinished">Pliki bootloadera (%1)</translation>
2738 </message>
2739 <message>
2740 <location filename="../gui/selectiveinstallwidget.cpp" line="321"/>
2741 <source>All files (*)</source>
2742 <translation type="unfinished">Wszystkie pliki (*)</translation>
2743 </message>
2744 <message>
2745 <location filename="../gui/selectiveinstallwidget.cpp" line="323"/>
2746 <source>Select firmware file</source>
2747 <translation type="unfinished">Wybierz plik firmware</translation>
2748 </message>
2749 <message>
2750 <location filename="../gui/selectiveinstallwidget.cpp" line="325"/>
2751 <source>Error opening firmware file</source>
2752 <translation type="unfinished">Błąd podczas otwierania pliku firmware</translation>
2753 </message>
2754 <message>
2755 <location filename="../gui/selectiveinstallwidget.cpp" line="331"/>
2756 <source>Error reading firmware file</source>
2757 <translation type="unfinished">Błąd podczas wczytywania pliku firmware</translation>
2758 </message>
2759 <message>
2760 <location filename="../gui/selectiveinstallwidget.cpp" line="341"/>
2761 <source>Backup error</source>
2762 <translation type="unfinished">Błąd tworzenia kopii</translation>
2763 </message>
2764 <message>
2765 <location filename="../gui/selectiveinstallwidget.cpp" line="342"/>
2766 <source>Could not create backup file. Continue?</source>
2767 <translation type="unfinished">Nie można stworzyć kopii. Kontynuować?</translation>
2768 </message>
2769 <message>
2770 <location filename="../gui/selectiveinstallwidget.cpp" line="366"/>
2771 <source>Manual steps required</source>
2772 <translation type="unfinished">Dalsze kroki wymagają samodzielnego działania</translation>
2773 </message>
2774 <message>
2775 <location filename="../gui/selectiveinstallwidget.cpp" line="171"/>
2776 <source>Continue with installation?</source>
2777 <translation type="unfinished">Kontynuować instalację?</translation>
2778 </message>
2779 <message>
2780 <location filename="../gui/selectiveinstallwidget.cpp" line="172"/>
2781 <source>Really continue?</source>
2782 <translation type="unfinished">Na pewno kontynuować?</translation>
2783 </message>
2784 <message>
2785 <source>Aborted!</source>
2786 <translation type="obsolete">Przerwano!</translation>
2787 </message>
2788 <message>
2789 <location filename="../gui/selectiveinstallwidget.cpp" line="490"/>
2790 <source>Your installation doesn&apos;t require game files, skipping.</source>
2791 <translation type="unfinished">Twoja instalacja nie wymaga plików gier, pomijanie.</translation>
2792 </message>
2793</context>
2794<context>
2795 <name>ServerInfo</name>
2796 <message>
2797 <location filename="../base/serverinfo.cpp" line="117"/>
2798 <source>Unknown</source>
2799 <translation>Nieznany</translation>
2800 </message>
2801 <message>
2802 <location filename="../base/serverinfo.cpp" line="121"/>
2803 <source>Unusable</source>
2804 <translation type="unfinished">Nieużyteczny</translation>
2805 </message>
2806 <message>
2807 <location filename="../base/serverinfo.cpp" line="124"/>
2808 <source>Unstable</source>
2809 <translation>Niestabilny</translation>
2810 </message>
2811 <message>
2812 <location filename="../base/serverinfo.cpp" line="127"/>
2813 <source>Stable</source>
2814 <translation>Stabilny</translation>
2815 </message>
2816</context>
2817<context>
2818 <name>SysTrace</name>
2819 <message>
2820 <location filename="../systrace.cpp" line="98"/>
2821 <location filename="../systrace.cpp" line="107"/>
2822 <source>Save system trace log</source>
2823 <translation>Zapisz dziennik zdarzeń systemu</translation>
2824 </message>
2825</context>
2826<context>
2827 <name>SysTraceFrm</name>
2828 <message>
2829 <location filename="../systracefrm.ui" line="14"/>
2830 <source>System Trace</source>
2831 <translation>Dziennik zdarzeń</translation>
2832 </message>
2833 <message>
2834 <location filename="../systracefrm.ui" line="20"/>
2835 <source>System State trace</source>
2836 <translation>Dziennik zdarzeń systemu</translation>
2837 </message>
2838 <message>
2839 <location filename="../systracefrm.ui" line="46"/>
2840 <source>&amp;Close</source>
2841 <translation>&amp;Wyjdź</translation>
2842 </message>
2843 <message>
2844 <location filename="../systracefrm.ui" line="57"/>
2845 <source>&amp;Save</source>
2846 <translation>&amp;Zapisz</translation>
2847 </message>
2848 <message>
2849 <location filename="../systracefrm.ui" line="68"/>
2850 <source>&amp;Refresh</source>
2851 <translation>&amp;Odśwież</translation>
2852 </message>
2853 <message>
2854 <location filename="../systracefrm.ui" line="79"/>
2855 <source>Save &amp;previous</source>
2856 <translation>Zapisz &amp;poprzednie</translation>
2857 </message>
2858</context>
2859<context>
2860 <name>Sysinfo</name>
2861 <message>
2862 <location filename="../sysinfo.cpp" line="45"/>
2863 <source>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</source>
2864 <translation>&lt;b&gt;System operacyjny&lt;/b&gt;&lt;br/&gt;</translation>
2865 </message>
2866 <message>
2867 <location filename="../sysinfo.cpp" line="46"/>
2868 <source>&lt;b&gt;Username&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2869 <translation>&lt;b&gt;Nazwa użytkownika&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2870 </message>
2871 <message>
2872 <location filename="../sysinfo.cpp" line="48"/>
2873 <source>&lt;b&gt;Permissions&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2874 <translation>&lt;b&gt;Zabezpieczenia&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2875 </message>
2876 <message>
2877 <location filename="../sysinfo.cpp" line="50"/>
2878 <source>&lt;b&gt;Attached USB devices&lt;/b&gt;&lt;br/&gt;</source>
2879 <translation>&lt;b&gt;Podłączone urządzenia USB&lt;/b&gt;&lt;br/&gt;</translation>
2880 </message>
2881 <message>
2882 <location filename="../sysinfo.cpp" line="54"/>
2883 <source>VID: %1 PID: %2, %3</source>
2884 <translation>VID: %1 PID: %2, %3</translation>
2885 </message>
2886 <message>
2887 <location filename="../sysinfo.cpp" line="63"/>
2888 <source>Filesystem</source>
2889 <translation>System plików</translation>
2890 </message>
2891 <message>
2892 <location filename="../sysinfo.cpp" line="66"/>
2893 <source>Mountpoint</source>
2894 <translation>Dysk</translation>
2895 </message>
2896 <message>
2897 <location filename="../sysinfo.cpp" line="66"/>
2898 <source>Label</source>
2899 <translation>Nazwa</translation>
2900 </message>
2901 <message>
2902 <location filename="../sysinfo.cpp" line="67"/>
2903 <source>Free</source>
2904 <translation>Dostępne</translation>
2905 </message>
2906 <message>
2907 <location filename="../sysinfo.cpp" line="67"/>
2908 <source>Total</source>
2909 <translation>Łącznie</translation>
2910 </message>
2911 <message>
2912 <location filename="../sysinfo.cpp" line="68"/>
2913 <source>Cluster Size</source>
2914 <translation>Rozmiar klastra</translation>
2915 </message>
2916 <message>
2917 <location filename="../sysinfo.cpp" line="70"/>
2918 <source>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</source>
2919 <translation>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</translation>
2920 </message>
2921</context>
2922<context>
2923 <name>SysinfoFrm</name>
2924 <message>
2925 <location filename="../sysinfofrm.ui" line="13"/>
2926 <source>System Info</source>
2927 <translation>Informacje o systemie</translation>
2928 </message>
2929 <message>
2930 <location filename="../sysinfofrm.ui" line="22"/>
2931 <source>&amp;Refresh</source>
2932 <translation>&amp;Odśwież</translation>
2933 </message>
2934 <message>
2935 <location filename="../sysinfofrm.ui" line="45"/>
2936 <source>&amp;OK</source>
2937 <translation></translation>
2938 </message>
2939</context>
2940<context>
2941 <name>System</name>
2942 <message>
2943 <location filename="../base/system.cpp" line="121"/>
2944 <source>Guest</source>
2945 <translation>Gość</translation>
2946 </message>
2947 <message>
2948 <location filename="../base/system.cpp" line="124"/>
2949 <source>Admin</source>
2950 <translation>Administrator</translation>
2951 </message>
2952 <message>
2953 <location filename="../base/system.cpp" line="127"/>
2954 <source>User</source>
2955 <translation>Użytkownik</translation>
2956 </message>
2957 <message>
2958 <location filename="../base/system.cpp" line="130"/>
2959 <source>Error</source>
2960 <translation>Błąd</translation>
2961 </message>
2962 <message>
2963 <location filename="../base/system.cpp" line="278"/>
2964 <location filename="../base/system.cpp" line="323"/>
2965 <source>(no description available)</source>
2966 <translation>(opis niedostępny)</translation>
2967 </message>
2968</context>
2969<context>
2970 <name>TTSBase</name>
2971 <message>
2972 <location filename="../base/ttsbase.cpp" line="45"/>
2973 <source>Espeak TTS Engine</source>
2974 <translation>Silnik TTS Espeak</translation>
2975 </message>
2976 <message>
2977 <location filename="../base/ttsbase.cpp" line="47"/>
2978 <source>Flite TTS Engine</source>
2979 <translation>Silnik TTS Flite</translation>
2980 </message>
2981 <message>
2982 <location filename="../base/ttsbase.cpp" line="48"/>
2983 <source>Swift TTS Engine</source>
2984 <translation>Silnik TTS Swift</translation>
2985 </message>
2986 <message>
2987 <location filename="../base/ttsbase.cpp" line="51"/>
2988 <source>SAPI4 TTS Engine</source>
2989 <translation>Silnik TTS SAPI4</translation>
2990 </message>
2991 <message>
2992 <location filename="../base/ttsbase.cpp" line="53"/>
2993 <source>SAPI5 TTS Engine</source>
2994 <translation>Silnik TTS SAPI5</translation>
2995 </message>
2996 <message>
2997 <location filename="../base/ttsbase.cpp" line="54"/>
2998 <source>MS Speech Platform</source>
2999 <translation>Silnik MS Speech Platform</translation>
3000 </message>
3001 <message>
3002 <source>SAPI TTS Engine</source>
3003 <translation type="obsolete">Silnik TTS Sapi</translation>
3004 </message>
3005 <message>
3006 <location filename="../base/ttsbase.cpp" line="57"/>
3007 <source>Festival TTS Engine</source>
3008 <translation>Silnik TTS Festival</translation>
3009 </message>
3010 <message>
3011 <location filename="../base/ttsbase.cpp" line="60"/>
3012 <source>OS X System Engine</source>
3013 <translation>Silnik systemu OS X</translation>
3014 </message>
3015</context>
3016<context>
3017 <name>TTSCarbon</name>
3018 <message>
3019 <location filename="../base/ttscarbon.cpp" line="139"/>
3020 <source>Voice:</source>
3021 <translation>Głos:</translation>
3022 </message>
3023 <message>
3024 <location filename="../base/ttscarbon.cpp" line="145"/>
3025 <source>Speed (words/min):</source>
3026 <translation>Szybkośc (słowa/min):</translation>
3027 </message>
3028 <message>
3029 <location filename="../base/ttscarbon.cpp" line="152"/>
3030 <source>Pitch (0 for default):</source>
3031 <translation>Wysokość (0 domyślnie):</translation>
3032 </message>
3033 <message>
3034 <location filename="../base/ttscarbon.cpp" line="222"/>
3035 <source>Could not voice string</source>
3036 <translation>Nie można przeczytać </translation>
3037 </message>
3038 <message>
3039 <location filename="../base/ttscarbon.cpp" line="232"/>
3040 <source>Could not convert intermediate file</source>
3041 <translation>Nie można przekonwertować pliku pośredniego</translation>
3042 </message>
3043</context>
3044<context>
3045 <name>TTSExes</name>
3046 <message>
3047 <location filename="../base/ttsexes.cpp" line="44"/>
3048 <source>Path to TTS engine:</source>
3049 <translation>Ścieżka do silnika TTS:</translation>
3050 </message>
3051 <message>
3052 <location filename="../base/ttsexes.cpp" line="46"/>
3053 <source>TTS engine options:</source>
3054 <translation>Opcje silnika TTS:</translation>
3055 </message>
3056 <message>
3057 <location filename="../base/ttsexes.cpp" line="78"/>
3058 <source>TTS executable not found</source>
3059 <translation>Nie znaleziono pliku exe</translation>
3060 </message>
3061</context>
3062<context>
3063 <name>TTSFestival</name>
3064 <message>
3065 <location filename="../base/ttsfestival.cpp" line="53"/>
3066 <source>Path to Festival client:</source>
3067 <translation>Ścieżka do klienta Festival:</translation>
3068 </message>
3069 <message>
3070 <location filename="../base/ttsfestival.cpp" line="58"/>
3071 <source>Voice:</source>
3072 <translation>Głos:</translation>
3073 </message>
3074 <message>
3075 <location filename="../base/ttsfestival.cpp" line="67"/>
3076 <source>Voice description:</source>
3077 <translation>Opis głosów:</translation>
3078 </message>
3079 <message>
3080 <location filename="../base/ttsfestival.cpp" line="207"/>
3081 <source>engine could not voice string</source>
3082 <translation>silnik nie mógł stworzyc ścieżki głosowej</translation>
3083 </message>
3084 <message>
3085 <location filename="../base/ttsfestival.cpp" line="290"/>
3086 <source>No description available</source>
3087 <translation>Opis niedostepny</translation>
3088 </message>
3089</context>
3090<context>
3091 <name>TTSSapi</name>
3092 <message>
3093 <location filename="../base/ttssapi.cpp" line="49"/>
3094 <source>Language:</source>
3095 <translation>Język:</translation>
3096 </message>
3097 <message>
3098 <location filename="../base/ttssapi.cpp" line="56"/>
3099 <source>Voice:</source>
3100 <translation>Głos:</translation>
3101 </message>
3102 <message>
3103 <location filename="../base/ttssapi.cpp" line="68"/>
3104 <source>Speed:</source>
3105 <translation>Szybkość:</translation>
3106 </message>
3107 <message>
3108 <location filename="../base/ttssapi.cpp" line="71"/>
3109 <source>Options:</source>
3110 <translation>Opcje:</translation>
3111 </message>
3112 <message>
3113 <location filename="../base/ttssapi.cpp" line="115"/>
3114 <source>Could not copy the SAPI script</source>
3115 <translation type="unfinished">Nie można skopiować skryptu SAPI</translation>
3116 </message>
3117 <message>
3118 <location filename="../base/ttssapi.cpp" line="133"/>
3119 <source>Could not start SAPI process</source>
3120 <translation type="unfinished">Nie można rozpocząć procesu SAPI</translation>
3121 </message>
3122</context>
3123<context>
3124 <name>TalkFileCreator</name>
3125 <message>
3126 <location filename="../base/talkfile.cpp" line="36"/>
3127 <source>Starting Talk file generation for folder %1</source>
3128 <translation type="unfinished">Rozpoczynanie tworzenia plików .talk dla folderu %1</translation>
3129 </message>
3130 <message>
3131 <location filename="../base/talkfile.cpp" line="42"/>
3132 <source>Reading Filelist...</source>
3133 <translation>Wczytywanie listy plików...</translation>
3134 </message>
3135 <message>
3136 <location filename="../base/talkfile.cpp" line="45"/>
3137 <source>Talk file creation aborted</source>
3138 <translation>Tworzenie plików .talk zostało przerwane</translation>
3139 </message>
3140 <message>
3141 <location filename="../base/talkfile.cpp" line="68"/>
3142 <source>Copying Talkfiles...</source>
3143 <translation>Kopiowanie plików .talk...</translation>
3144 </message>
3145 <message>
3146 <location filename="../base/talkfile.cpp" line="80"/>
3147 <source>Finished creating Talk files</source>
3148 <translation>Tworzenie plików .talk zostało zakończone</translation>
3149 </message>
3150 <message>
3151 <location filename="../base/talkfile.cpp" line="240"/>
3152 <source>File copy aborted</source>
3153 <translation>Kopiowanie anulowane</translation>
3154 </message>
3155 <message>
3156 <location filename="../base/talkfile.cpp" line="259"/>
3157 <source>Copying of %1 to %2 failed</source>
3158 <translation>Kopiowanie %1 do %2 nie powiodło się</translation>
3159 </message>
3160 <message>
3161 <location filename="../base/talkfile.cpp" line="280"/>
3162 <source>Cleaning up...</source>
3163 <translation>Czyszczenie...</translation>
3164 </message>
3165 <message>
3166 <location filename="../base/talkfile.cpp" line="291"/>
3167 <source>Finished</source>
3168 <translation>Zakończono</translation>
3169 </message>
3170</context>
3171<context>
3172 <name>TalkGenerator</name>
3173 <message>
3174 <location filename="../base/talkgenerator.cpp" line="39"/>
3175 <source>Starting TTS Engine</source>
3176 <translation>Uruchamianie silnika TTS</translation>
3177 </message>
3178 <message>
3179 <location filename="../base/talkgenerator.cpp" line="44"/>
3180 <location filename="../base/talkgenerator.cpp" line="51"/>
3181 <source>Init of TTS engine failed</source>
3182 <translation>Nie można uruchomić silnika TTS</translation>
3183 </message>
3184 <message>
3185 <location filename="../base/talkgenerator.cpp" line="58"/>
3186 <source>Starting Encoder Engine</source>
3187 <translation type="unfinished">Uruchamianie silnika kodera</translation>
3188 </message>
3189 <message>
3190 <location filename="../base/talkgenerator.cpp" line="62"/>
3191 <source>Init of Encoder engine failed</source>
3192 <translation type="unfinished">Nie można uruchomić silnika kodera</translation>
3193 </message>
3194 <message>
3195 <location filename="../base/talkgenerator.cpp" line="72"/>
3196 <source>Voicing entries...</source>
3197 <translation>Przetwarzanie ścieżek na pliki głosowe...</translation>
3198 </message>
3199 <message>
3200 <location filename="../base/talkgenerator.cpp" line="87"/>
3201 <source>Encoding files...</source>
3202 <translation>Kompresowanie plików...</translation>
3203 </message>
3204 <message>
3205 <location filename="../base/talkgenerator.cpp" line="126"/>
3206 <source>Voicing aborted</source>
3207 <translation>Przetwarzanie anulowano</translation>
3208 </message>
3209 <message>
3210 <location filename="../base/talkgenerator.cpp" line="162"/>
3211 <location filename="../base/talkgenerator.cpp" line="167"/>
3212 <source>Voicing of %1 failed: %2</source>
3213 <translation>Przetwarzanie %1 niepomyślne: %2</translation>
3214 </message>
3215 <message>
3216 <location filename="../base/talkgenerator.cpp" line="211"/>
3217 <source>Encoding aborted</source>
3218 <translation>Przerwano kompresję</translation>
3219 </message>
3220 <message>
3221 <location filename="../base/talkgenerator.cpp" line="239"/>
3222 <source>Encoding of %1 failed</source>
3223 <translation>Kompresja niepomyślna dla %1</translation>
3224 </message>
3225</context>
3226<context>
3227 <name>ThemeInstallFrm</name>
3228 <message>
3229 <location filename="../themesinstallfrm.ui" line="13"/>
3230 <source>Theme Installation</source>
3231 <translation>Instalacja stylu</translation>
3232 </message>
3233 <message>
3234 <location filename="../themesinstallfrm.ui" line="48"/>
3235 <source>Selected Theme</source>
3236 <translation>Zaznaczony styl</translation>
3237 </message>
3238 <message>
3239 <location filename="../themesinstallfrm.ui" line="73"/>
3240 <source>Description</source>
3241 <translation>Opis</translation>
3242 </message>
3243 <message>
3244 <location filename="../themesinstallfrm.ui" line="83"/>
3245 <source>Download size:</source>
3246 <translation>Rozmiar:</translation>
3247 </message>
3248 <message>
3249 <location filename="../themesinstallfrm.ui" line="93"/>
3250 <source>Hold Ctrl to select multiple item, Shift for a range</source>
3251 <translation>Przytrzymaj Ctrl aby zaznaczyc kilka pozycji, Shift aby zaznaczyć zakres</translation>
3252 </message>
3253 <message>
3254 <location filename="../themesinstallfrm.ui" line="115"/>
3255 <source>&amp;Install</source>
3256 <translation>&amp;Zainstaluj</translation>
3257 </message>
3258 <message>
3259 <location filename="../themesinstallfrm.ui" line="125"/>
3260 <source>&amp;Cancel</source>
3261 <translation>&amp;Wyjdź</translation>
3262 </message>
3263</context>
3264<context>
3265 <name>ThemesInstallWindow</name>
3266 <message>
3267 <location filename="../themesinstallwindow.cpp" line="40"/>
3268 <source>no theme selected</source>
3269 <translation>nie wybrano stylu</translation>
3270 </message>
3271 <message>
3272 <location filename="../themesinstallwindow.cpp" line="41"/>
3273 <source>no selection</source>
3274 <translation type="unfinished">nic nie wybrano</translation>
3275 </message>
3276 <message>
3277 <location filename="../themesinstallwindow.cpp" line="125"/>
3278 <source>Network error: %1.
3279Please check your network and proxy settings.</source>
3280 <translation>Błąd połączenia: %1.
3281Sprawdź połączenia sieciowe i ustawienia serwera proxy.</translation>
3282 </message>
3283 <message>
3284 <location filename="../themesinstallwindow.cpp" line="138"/>
3285 <source>the following error occured:
3286%1</source>
3287 <translation>wystapił nastepujący błąd: %1</translation>
3288 </message>
3289 <message>
3290 <location filename="../themesinstallwindow.cpp" line="144"/>
3291 <source>done.</source>
3292 <translation>zrobione.</translation>
3293 </message>
3294 <message>
3295 <location filename="../themesinstallwindow.cpp" line="181"/>
3296 <source>Information</source>
3297 <translation>Informacje</translation>
3298 </message>
3299 <message numerus="yes">
3300 <location filename="../themesinstallwindow.cpp" line="198"/>
3301 <source>Download size %L1 kiB (%n item(s))</source>
3302 <translation>
3303 <numerusform>Rozmiar %L1 kB (%n plik)</numerusform>
3304 <numerusform>Rozmiar %L1 kB (%n pliki)</numerusform>
3305 <numerusform>Rozmiar %L1 kB (%n plików)</numerusform>
3306 </translation>
3307 </message>
3308 <message>
3309 <location filename="../themesinstallwindow.cpp" line="211"/>
3310 <source>fetching details for %1</source>
3311 <translation>zbieranie informacji dla %1</translation>
3312 </message>
3313 <message>
3314 <location filename="../themesinstallwindow.cpp" line="214"/>
3315 <source>fetching preview ...</source>
3316 <translation>przygotowywanie podglądu...</translation>
3317 </message>
3318 <message>
3319 <location filename="../themesinstallwindow.cpp" line="227"/>
3320 <source>&lt;b&gt;Author:&lt;/b&gt; %1&lt;hr/&gt;</source>
3321 <translation>&lt;b&gt;Autor:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3322 </message>
3323 <message>
3324 <location filename="../themesinstallwindow.cpp" line="228"/>
3325 <location filename="../themesinstallwindow.cpp" line="230"/>
3326 <source>unknown</source>
3327 <translation>nieznany</translation>
3328 </message>
3329 <message>
3330 <location filename="../themesinstallwindow.cpp" line="229"/>
3331 <source>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</source>
3332 <translation>&lt;b&gt;Wersja:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3333 </message>
3334 <message>
3335 <location filename="../themesinstallwindow.cpp" line="231"/>
3336 <source>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</source>
3337 <translation>&lt;b&gt;Opis:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3338 </message>
3339 <message>
3340 <location filename="../themesinstallwindow.cpp" line="232"/>
3341 <source>no description</source>
3342 <translation>brak opisu</translation>
3343 </message>
3344 <message>
3345 <location filename="../themesinstallwindow.cpp" line="248"/>
3346 <source>Retrieving theme preview failed.
3347HTTP response code: %1</source>
3348 <translation>Błąd pobierania obrazka stylu.
3349Odpowiedź z serwera HTTP: %1</translation>
3350 </message>
3351 <message>
3352 <location filename="../themesinstallwindow.cpp" line="260"/>
3353 <source>no theme preview</source>
3354 <translation>brak podglądu</translation>
3355 </message>
3356 <message>
3357 <location filename="../themesinstallwindow.cpp" line="289"/>
3358 <source>Select</source>
3359 <translation>Wybierz</translation>
3360 </message>
3361 <message>
3362 <location filename="../themesinstallwindow.cpp" line="296"/>
3363 <source>getting themes information ...</source>
3364 <translation>pobieranie informacji o stylach...</translation>
3365 </message>
3366 <message>
3367 <location filename="../themesinstallwindow.cpp" line="326"/>
3368 <source>No themes selected, skipping</source>
3369 <translation type="unfinished">Nie wybrano żadnego stylu, pomijanie</translation>
3370 </message>
3371 <message>
3372 <location filename="../themesinstallwindow.cpp" line="356"/>
3373 <source>Mount point is wrong!</source>
3374 <translation>Zły punkt montowania!</translation>
3375 </message>
3376</context>
3377<context>
3378 <name>UninstallFrm</name>
3379 <message>
3380 <location filename="../uninstallfrm.ui" line="16"/>
3381 <source>Uninstall Rockbox</source>
3382 <translation>Odinstaluj Rockboxa</translation>
3383 </message>
3384 <message>
3385 <location filename="../uninstallfrm.ui" line="35"/>
3386 <source>Please select the Uninstallation Method</source>
3387 <translation>Wybierz metodę dezinstalacji</translation>
3388 </message>
3389 <message>
3390 <location filename="../uninstallfrm.ui" line="45"/>
3391 <source>Uninstallation Method</source>
3392 <translation>Metoda dezinstalacji</translation>
3393 </message>
3394 <message>
3395 <location filename="../uninstallfrm.ui" line="51"/>
3396 <source>Complete Uninstallation</source>
3397 <translation>Całkowite odinstalowywanie</translation>
3398 </message>
3399 <message>
3400 <location filename="../uninstallfrm.ui" line="58"/>
3401 <source>Smart Uninstallation</source>
3402 <translation>Szybkie odinstalowywanie</translation>
3403 </message>
3404 <message>
3405 <location filename="../uninstallfrm.ui" line="68"/>
3406 <source>Please select what you want to uninstall</source>
3407 <translation>Wybierz co chcesz odinstalować</translation>
3408 </message>
3409 <message>
3410 <location filename="../uninstallfrm.ui" line="78"/>
3411 <source>Installed Parts</source>
3412 <translation>Zainstalowane części</translation>
3413 </message>
3414 <message>
3415 <location filename="../uninstallfrm.ui" line="128"/>
3416 <source>&amp;Uninstall</source>
3417 <translation>&amp;Odisnatluj</translation>
3418 </message>
3419 <message>
3420 <location filename="../uninstallfrm.ui" line="138"/>
3421 <source>&amp;Cancel</source>
3422 <translation>&amp;Anuluj</translation>
3423 </message>
3424</context>
3425<context>
3426 <name>Uninstaller</name>
3427 <message>
3428 <location filename="../base/uninstall.cpp" line="32"/>
3429 <location filename="../base/uninstall.cpp" line="43"/>
3430 <source>Starting Uninstallation</source>
3431 <translation>Rozpoczynanie odinstalowywania</translation>
3432 </message>
3433 <message>
3434 <location filename="../base/uninstall.cpp" line="36"/>
3435 <source>Finished Uninstallation</source>
3436 <translation>Skończono odinstalowywanie</translation>
3437 </message>
3438 <message>
3439 <location filename="../base/uninstall.cpp" line="49"/>
3440 <source>Uninstalling %1...</source>
3441 <translation>Trwa odinstalowywanie %1...</translation>
3442 </message>
3443 <message>
3444 <location filename="../base/uninstall.cpp" line="80"/>
3445 <source>Could not delete %1</source>
3446 <translation>Nie można usunąć %1</translation>
3447 </message>
3448 <message>
3449 <location filename="../base/uninstall.cpp" line="109"/>
3450 <source>Uninstallation finished</source>
3451 <translation>Odinstalowywanie zakończone</translation>
3452 </message>
3453</context>
3454<context>
3455 <name>Utils</name>
3456 <message>
3457 <location filename="../base/utils.cpp" line="312"/>
3458 <source>&lt;li&gt;Permissions insufficient for bootloader installation.
3459Administrator priviledges are necessary.&lt;/li&gt;</source>
3460 <translation>&lt;li&gt;Nie posiadasz odpowiednich praw do instalacji bootloadera.
3461Wymagane są prawa administratora.&lt;/li&gt;</translation>
3462 </message>
3463 <message>
3464 <location filename="../base/utils.cpp" line="324"/>
3465 <source>&lt;li&gt;Target mismatch detected.&lt;br/&gt;Installed target: %1&lt;br/&gt;Selected target: %2.&lt;/li&gt;</source>
3466 <translation>&lt;li&gt;Wykryto niezgodność wybranego odtwarzacza.&lt;br/&gt;Podłączony udtwarzacz: %1&lt;br/&gt;Wybrany odtwarzacz: %2.&lt;/li&gt;</translation>
3467 </message>
3468 <message>
3469 <location filename="../base/utils.cpp" line="331"/>
3470 <source>Problem detected:</source>
3471 <translation>Wykryto problem:</translation>
3472 </message>
3473</context>
3474<context>
3475 <name>VoiceFileCreator</name>
3476 <message>
3477 <location filename="../base/voicefile.cpp" line="43"/>
3478 <source>Starting Voicefile generation</source>
3479 <translation>Rozpoczynanie tworzenia plików głosowych</translation>
3480 </message>
3481 <message>
3482 <location filename="../base/voicefile.cpp" line="56"/>
3483 <source>could not find rockbox-info.txt</source>
3484 <translation>nie mozna znaleźć rockbox-info.txt</translation>
3485 </message>
3486 <message>
3487 <location filename="../base/voicefile.cpp" line="90"/>
3488 <source>Extracted voice strings from installation</source>
3489 <translation type="unfinished">Wyodrębniono ścieżki głosowe z instalacji</translation>
3490 </message>
3491 <message>
3492 <location filename="../base/voicefile.cpp" line="100"/>
3493 <source>Extracted voice strings incompatible</source>
3494 <translation type="unfinished">Wyodrębnione ścieżki głosowe są niekompatybilne</translation>
3495 </message>
3496 <message>
3497 <location filename="../base/voicefile.cpp" line="145"/>
3498 <source>Could not retrieve strings from installation, downloading</source>
3499 <translation type="unfinished">Nie można znaleźć ścieżek w instalacji, pobieranie</translation>
3500 </message>
3501 <message>
3502 <location filename="../base/voicefile.cpp" line="171"/>
3503 <source>Downloading voice info...</source>
3504 <translation>Pobieranie info...</translation>
3505 </message>
3506 <message>
3507 <location filename="../base/voicefile.cpp" line="184"/>
3508 <source>Download error: received HTTP error %1.</source>
3509 <translation>Błąd pobierania: błąd serwera HTTP %1.</translation>
3510 </message>
3511 <message>
3512 <location filename="../base/voicefile.cpp" line="191"/>
3513 <source>Cached file used.</source>
3514 <translation>Użycie pliku z bufora.</translation>
3515 </message>
3516 <message>
3517 <location filename="../base/voicefile.cpp" line="194"/>
3518 <source>Download error: %1</source>
3519 <translation>Błąd pobierania: %1</translation>
3520 </message>
3521 <message>
3522 <location filename="../base/voicefile.cpp" line="199"/>
3523 <source>Download finished.</source>
3524 <translation>Pobieranie zakończone.</translation>
3525 </message>
3526 <message>
3527 <location filename="../base/voicefile.cpp" line="212"/>
3528 <source>failed to open downloaded file</source>
3529 <translation>nie można otworzyć pobranego pliku</translation>
3530 </message>
3531 <message>
3532 <location filename="../base/voicefile.cpp" line="218"/>
3533 <source>Reading strings...</source>
3534 <translation>Czytanie ścieżek...</translation>
3535 </message>
3536 <message>
3537 <location filename="../base/voicefile.cpp" line="271"/>
3538 <source>The downloaded file was empty!</source>
3539 <translation>Pobrany plik jest pusty!</translation>
3540 </message>
3541 <message>
3542 <location filename="../base/voicefile.cpp" line="297"/>
3543 <source>Creating voicefiles...</source>
3544 <translation>Tworzenie plików głosowych...</translation>
3545 </message>
3546 <message>
3547 <location filename="../base/voicefile.cpp" line="302"/>
3548 <source>Error opening downloaded file</source>
3549 <translation>Błąd otwarcia pobranego pliku</translation>
3550 </message>
3551 <message>
3552 <location filename="../base/voicefile.cpp" line="313"/>
3553 <source>Error opening output file</source>
3554 <translation>Błąd otwarcia pliku wyjściowego</translation>
3555 </message>
3556 <message>
3557 <location filename="../base/voicefile.cpp" line="333"/>
3558 <source>successfully created.</source>
3559 <translation>stworzono pomyślnie.</translation>
3560 </message>
3561 <message>
3562 <location filename="../base/voicefile.cpp" line="342"/>
3563 <source>Cleaning up...</source>
3564 <translation>Czyszczenie...</translation>
3565 </message>
3566 <message>
3567 <location filename="../base/voicefile.cpp" line="353"/>
3568 <source>Finished</source>
3569 <translation>Zakończono</translation>
3570 </message>
3571</context>
3572<context>
3573 <name>ZipInstaller</name>
3574 <message>
3575 <location filename="../base/zipinstaller.cpp" line="60"/>
3576 <source>done.</source>
3577 <translation>zrobione.</translation>
3578 </message>
3579 <message>
3580 <location filename="../base/zipinstaller.cpp" line="80"/>
3581 <source>Downloading file %1.%2</source>
3582 <translation>Pobieranie pliku %1.%2</translation>
3583 </message>
3584 <message>
3585 <location filename="../base/zipinstaller.cpp" line="115"/>
3586 <source>Download error: received HTTP error %1.</source>
3587 <translation>Błąd pobierania: błąd serwera HTTP %1.</translation>
3588 </message>
3589 <message>
3590 <location filename="../base/zipinstaller.cpp" line="121"/>
3591 <source>Cached file used.</source>
3592 <translation>Użycie pliku z bufora.</translation>
3593 </message>
3594 <message>
3595 <location filename="../base/zipinstaller.cpp" line="123"/>
3596 <source>Download error: %1</source>
3597 <translation>Błąd pobierania: %1</translation>
3598 </message>
3599 <message>
3600 <location filename="../base/zipinstaller.cpp" line="127"/>
3601 <source>Download finished.</source>
3602 <translation>Pobieranie zakończone.</translation>
3603 </message>
3604 <message>
3605 <location filename="../base/zipinstaller.cpp" line="133"/>
3606 <source>Extracting file.</source>
3607 <translation>Wypakowywanie.</translation>
3608 </message>
3609 <message>
3610 <location filename="../base/zipinstaller.cpp" line="153"/>
3611 <source>Extraction failed!</source>
3612 <translation>Rozpakowanie nie powiodło się!</translation>
3613 </message>
3614 <message>
3615 <location filename="../base/zipinstaller.cpp" line="146"/>
3616 <source>Not enough disk space! Aborting.</source>
3617 <translation type="unfinished">Brak wystarczającego miejsca na dysku! Przerywanie instalacji.</translation>
3618 </message>
3619 <message>
3620 <location filename="../base/zipinstaller.cpp" line="68"/>
3621 <source>Package installation finished successfully.</source>
3622 <translation type="unfinished">Instalowanie pakietu zakończone powodzeniem.</translation>
3623 </message>
3624 <message>
3625 <location filename="../base/zipinstaller.cpp" line="162"/>
3626 <source>Installing file.</source>
3627 <translation>Instalowanie.</translation>
3628 </message>
3629 <message>
3630 <location filename="../base/zipinstaller.cpp" line="173"/>
3631 <source>Installing file failed.</source>
3632 <translation>Instalacja niepomyślna.</translation>
3633 </message>
3634 <message>
3635 <location filename="../base/zipinstaller.cpp" line="186"/>
3636 <source>Creating installation log</source>
3637 <translation type="unfinished">Tworzenie dziennika zdarzeń instalacji</translation>
3638 </message>
3639</context>
3640<context>
3641 <name>ZipUtil</name>
3642 <message>
3643 <location filename="../base/ziputil.cpp" line="125"/>
3644 <source>Creating output path failed</source>
3645 <translation>Utworzenie ścieżki wyjściowej nie powiodło się</translation>
3646 </message>
3647 <message>
3648 <location filename="../base/ziputil.cpp" line="132"/>
3649 <source>Creating output file failed</source>
3650 <translation>Utworzenie pliku wyjściowego nie powiodło się</translation>
3651 </message>
3652 <message>
3653 <location filename="../base/ziputil.cpp" line="141"/>
3654 <source>Error during Zip operation</source>
3655 <translation>Błąd podczas obsługi archiwum Zip</translation>
3656 </message>
3657</context>
3658<context>
3659 <name>aboutBox</name>
3660 <message>
3661 <location filename="../aboutbox.ui" line="14"/>
3662 <source>About Rockbox Utility</source>
3663 <translation>Informacje o Rockbox Utility</translation>
3664 </message>
3665 <message>
3666 <location filename="../aboutbox.ui" line="32"/>
3667 <source>The Rockbox Utility</source>
3668 <translation>Rockbox Utility</translation>
3669 </message>
3670 <message utf8="true">
3671 <location filename="../aboutbox.ui" line="54"/>
3672 <source>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</source>
3673 <translation>Instalator i narzędzie dla Rockboxa - otwartoźródłowego firmware dla przenośnych odtwarzaczy muzycznych.&lt;br/&gt;© Zespół Rockboxa.&lt;br/&gt;Wydano na licencji GNU General Public License v2.&lt;br/&gt;Ikony pochodzą z &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Projektu Tango&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</translation>
3674 </message>
3675 <message>
3676 <location filename="../aboutbox.ui" line="74"/>
3677 <source>&amp;Credits</source>
3678 <translation>&amp;Podziękowania</translation>
3679 </message>
3680 <message>
3681 <location filename="../aboutbox.ui" line="106"/>
3682 <source>&amp;License</source>
3683 <translation>&amp;Licencja</translation>
3684 </message>
3685 <message>
3686 <location filename="../aboutbox.ui" line="132"/>
3687 <source>&amp;Speex License</source>
3688 <translation>Licencja &amp;Speex</translation>
3689 </message>
3690 <message>
3691 <location filename="../aboutbox.ui" line="158"/>
3692 <source>&amp;Ok</source>
3693 <translation>&amp;Ok</translation>
3694 </message>
3695</context>
3696</TS>
diff --git a/utils/rbutilqt/lang/rbutil_pt.ts b/utils/rbutilqt/lang/rbutil_pt.ts
new file mode 100644
index 0000000000..0c00d82a09
--- /dev/null
+++ b/utils/rbutilqt/lang/rbutil_pt.ts
@@ -0,0 +1,3665 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE TS>
3<TS version="2.0" language="pt">
4<context>
5 <name>BackupDialog</name>
6 <message>
7 <location filename="../gui/backupdialogfrm.ui" line="17"/>
8 <location filename="../gui/backupdialogfrm.ui" line="43"/>
9 <source>Backup</source>
10 <translation type="unfinished">Cópia de Segurança</translation>
11 </message>
12 <message>
13 <location filename="../gui/backupdialogfrm.ui" line="33"/>
14 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This dialog will create a backup by archiving the contents of the Rockbox installation on the player into a zip file. This will include installed themes and settings stored below the .rockbox folder on the player.&lt;/p&gt;&lt;p&gt;The backup filename will be created based on the installed version. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
15 <translation type="unfinished"></translation>
16 </message>
17 <message>
18 <location filename="../gui/backupdialogfrm.ui" line="49"/>
19 <source>Size: unknown</source>
20 <translation type="unfinished"></translation>
21 </message>
22 <message>
23 <location filename="../gui/backupdialogfrm.ui" line="56"/>
24 <source>Backup to: unknown</source>
25 <translation type="unfinished"></translation>
26 </message>
27 <message>
28 <location filename="../gui/backupdialogfrm.ui" line="76"/>
29 <source>&amp;Change</source>
30 <translation type="unfinished">A&amp;lterar</translation>
31 </message>
32 <message>
33 <location filename="../gui/backupdialogfrm.ui" line="116"/>
34 <source>&amp;Backup</source>
35 <translation type="unfinished"></translation>
36 </message>
37 <message>
38 <location filename="../gui/backupdialogfrm.ui" line="127"/>
39 <source>&amp;Cancel</source>
40 <translation type="unfinished">&amp;Cancelar</translation>
41 </message>
42 <message>
43 <location filename="../gui/backupdialog.cpp" line="70"/>
44 <source>Installation size: calculating ...</source>
45 <translation type="unfinished"></translation>
46 </message>
47 <message>
48 <location filename="../gui/backupdialog.cpp" line="89"/>
49 <source>Select Backup Filename</source>
50 <translation type="unfinished"></translation>
51 </message>
52 <message>
53 <location filename="../gui/backupdialog.cpp" line="109"/>
54 <source>Installation size: %L1 %2</source>
55 <translation type="unfinished"></translation>
56 </message>
57 <message>
58 <location filename="../gui/backupdialog.cpp" line="116"/>
59 <source>File exists</source>
60 <translation type="unfinished"></translation>
61 </message>
62 <message>
63 <location filename="../gui/backupdialog.cpp" line="117"/>
64 <source>The selected backup file already exists. Overwrite?</source>
65 <translation type="unfinished"></translation>
66 </message>
67 <message>
68 <location filename="../gui/backupdialog.cpp" line="125"/>
69 <source>Starting backup ...</source>
70 <translation type="unfinished"></translation>
71 </message>
72 <message>
73 <location filename="../gui/backupdialog.cpp" line="144"/>
74 <source>Backup successful.</source>
75 <translation type="unfinished"></translation>
76 </message>
77 <message>
78 <location filename="../gui/backupdialog.cpp" line="147"/>
79 <source>Backup failed!</source>
80 <translation type="unfinished">Falha na cópia de segurança!</translation>
81 </message>
82</context>
83<context>
84 <name>BootloaderInstallAms</name>
85 <message>
86 <location filename="../base/bootloaderinstallams.cpp" line="33"/>
87 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; This file is not present on your player and will disappear automatically after installing it.&lt;br/&gt;&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
88 <translation type="unfinished"></translation>
89 </message>
90 <message>
91 <location filename="../base/bootloaderinstallams.cpp" line="58"/>
92 <source>Downloading bootloader file</source>
93 <translation type="unfinished">Transferindo rotina de arranque</translation>
94 </message>
95 <message>
96 <location filename="../base/bootloaderinstallams.cpp" line="100"/>
97 <location filename="../base/bootloaderinstallams.cpp" line="113"/>
98 <source>Could not load %1</source>
99 <translation type="unfinished"></translation>
100 </message>
101 <message>
102 <location filename="../base/bootloaderinstallams.cpp" line="127"/>
103 <source>No room to insert bootloader, try another firmware version</source>
104 <translation type="unfinished"></translation>
105 </message>
106 <message>
107 <location filename="../base/bootloaderinstallams.cpp" line="137"/>
108 <source>Patching Firmware...</source>
109 <translation type="unfinished"></translation>
110 </message>
111 <message>
112 <location filename="../base/bootloaderinstallams.cpp" line="148"/>
113 <source>Could not open %1 for writing</source>
114 <translation type="unfinished"></translation>
115 </message>
116 <message>
117 <location filename="../base/bootloaderinstallams.cpp" line="161"/>
118 <source>Could not write firmware file</source>
119 <translation type="unfinished"></translation>
120 </message>
121 <message>
122 <location filename="../base/bootloaderinstallams.cpp" line="177"/>
123 <source>Success: modified firmware file created</source>
124 <translation type="unfinished">Sucesso: ficheiro de firmware modificado criado</translation>
125 </message>
126 <message>
127 <location filename="../base/bootloaderinstallams.cpp" line="185"/>
128 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
129 <translation type="unfinished"></translation>
130 </message>
131</context>
132<context>
133 <name>BootloaderInstallBase</name>
134 <message>
135 <location filename="../base/bootloaderinstallbase.cpp" line="78"/>
136 <source>Download error: received HTTP error %1.</source>
137 <translation>Erro de transferência: recebido erro de HTTP %1.</translation>
138 </message>
139 <message>
140 <location filename="../base/bootloaderinstallbase.cpp" line="84"/>
141 <source>Download error: %1</source>
142 <translation>Erro de transferência: %1</translation>
143 </message>
144 <message>
145 <location filename="../base/bootloaderinstallbase.cpp" line="90"/>
146 <source>Download finished (cache used).</source>
147 <translation>Tranferência terminada (cache usada).</translation>
148 </message>
149 <message>
150 <location filename="../base/bootloaderinstallbase.cpp" line="92"/>
151 <source>Download finished.</source>
152 <translation>Tranferência terminada.</translation>
153 </message>
154 <message>
155 <location filename="../base/bootloaderinstallbase.cpp" line="113"/>
156 <source>Creating backup of original firmware file.</source>
157 <translation>Criando cópia de segurança do ficheiro de firmware original.</translation>
158 </message>
159 <message>
160 <location filename="../base/bootloaderinstallbase.cpp" line="115"/>
161 <source>Creating backup folder failed</source>
162 <translation>Falha na criação da directoria da cópia de segurança</translation>
163 </message>
164 <message>
165 <location filename="../base/bootloaderinstallbase.cpp" line="121"/>
166 <source>Creating backup copy failed.</source>
167 <translation>Falha na criação da cópia de segurança.</translation>
168 </message>
169 <message>
170 <location filename="../base/bootloaderinstallbase.cpp" line="124"/>
171 <source>Backup created.</source>
172 <translation>Cópia de segurança criada.</translation>
173 </message>
174 <message>
175 <location filename="../base/bootloaderinstallbase.cpp" line="137"/>
176 <source>Creating installation log</source>
177 <translation>Criando registo da instalação</translation>
178 </message>
179 <message>
180 <location filename="../base/bootloaderinstallbase.cpp" line="226"/>
181 <source>Zip file format detected</source>
182 <translation type="unfinished"></translation>
183 </message>
184 <message>
185 <location filename="../base/bootloaderinstallbase.cpp" line="238"/>
186 <source>CAB file format detected</source>
187 <translation type="unfinished"></translation>
188 </message>
189 <message>
190 <location filename="../base/bootloaderinstallbase.cpp" line="259"/>
191 <source>Extracting firmware %1 from archive</source>
192 <translation type="unfinished"></translation>
193 </message>
194 <message>
195 <location filename="../base/bootloaderinstallbase.cpp" line="266"/>
196 <source>Error extracting firmware from archive</source>
197 <translation type="unfinished"></translation>
198 </message>
199 <message>
200 <location filename="../base/bootloaderinstallbase.cpp" line="275"/>
201 <source>Could not find firmware in archive</source>
202 <translation type="unfinished"></translation>
203 </message>
204 <message>
205 <location filename="../base/bootloaderinstallbase.cpp" line="159"/>
206 <source>Waiting for system to remount player</source>
207 <translation type="unfinished"></translation>
208 </message>
209 <message>
210 <location filename="../base/bootloaderinstallbase.cpp" line="189"/>
211 <source>Player remounted</source>
212 <translation type="unfinished"></translation>
213 </message>
214 <message>
215 <location filename="../base/bootloaderinstallbase.cpp" line="194"/>
216 <source>Timeout on remount</source>
217 <translation type="unfinished"></translation>
218 </message>
219 <message>
220 <location filename="../base/bootloaderinstallbase.cpp" line="149"/>
221 <source>Installation log created</source>
222 <translation type="unfinished"></translation>
223 </message>
224</context>
225<context>
226 <name>BootloaderInstallChinaChip</name>
227 <message>
228 <location filename="../base/bootloaderinstallchinachip.cpp" line="33"/>
229 <source>Bootloader installation requires you to provide a firmware file of the original firmware (HXF file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
230 <translation type="unfinished"></translation>
231 </message>
232 <message>
233 <location filename="../base/bootloaderinstallchinachip.cpp" line="50"/>
234 <source>Downloading bootloader file</source>
235 <translation type="unfinished">Transferindo rotina de arranque</translation>
236 </message>
237 <message>
238 <location filename="../base/bootloaderinstallchinachip.cpp" line="75"/>
239 <source>Could not open firmware file</source>
240 <translation type="unfinished"></translation>
241 </message>
242 <message>
243 <location filename="../base/bootloaderinstallchinachip.cpp" line="78"/>
244 <source>Could not open bootloader file</source>
245 <translation type="unfinished"></translation>
246 </message>
247 <message>
248 <location filename="../base/bootloaderinstallchinachip.cpp" line="81"/>
249 <source>Could not allocate memory</source>
250 <translation type="unfinished"></translation>
251 </message>
252 <message>
253 <location filename="../base/bootloaderinstallchinachip.cpp" line="84"/>
254 <source>Could not load firmware file</source>
255 <translation type="unfinished"></translation>
256 </message>
257 <message>
258 <location filename="../base/bootloaderinstallchinachip.cpp" line="87"/>
259 <source>File is not a valid ChinaChip firmware</source>
260 <translation type="unfinished"></translation>
261 </message>
262 <message>
263 <location filename="../base/bootloaderinstallchinachip.cpp" line="90"/>
264 <source>Could not find ccpmp.bin in input file</source>
265 <translation type="unfinished"></translation>
266 </message>
267 <message>
268 <location filename="../base/bootloaderinstallchinachip.cpp" line="93"/>
269 <source>Could not open backup file for ccpmp.bin</source>
270 <translation type="unfinished"></translation>
271 </message>
272 <message>
273 <location filename="../base/bootloaderinstallchinachip.cpp" line="96"/>
274 <source>Could not write backup file for ccpmp.bin</source>
275 <translation type="unfinished"></translation>
276 </message>
277 <message>
278 <location filename="../base/bootloaderinstallchinachip.cpp" line="99"/>
279 <source>Could not load bootloader file</source>
280 <translation type="unfinished"></translation>
281 </message>
282 <message>
283 <location filename="../base/bootloaderinstallchinachip.cpp" line="102"/>
284 <source>Could not get current time</source>
285 <translation type="unfinished"></translation>
286 </message>
287 <message>
288 <location filename="../base/bootloaderinstallchinachip.cpp" line="105"/>
289 <source>Could not open output file</source>
290 <translation type="unfinished"></translation>
291 </message>
292 <message>
293 <location filename="../base/bootloaderinstallchinachip.cpp" line="108"/>
294 <source>Could not write output file</source>
295 <translation type="unfinished"></translation>
296 </message>
297 <message>
298 <location filename="../base/bootloaderinstallchinachip.cpp" line="111"/>
299 <source>Unexpected error from chinachippatcher</source>
300 <translation type="unfinished"></translation>
301 </message>
302</context>
303<context>
304 <name>BootloaderInstallFile</name>
305 <message>
306 <location filename="../base/bootloaderinstallfile.cpp" line="34"/>
307 <source>Downloading bootloader</source>
308 <translation>Transferindo a rotina de arranque</translation>
309 </message>
310 <message>
311 <location filename="../base/bootloaderinstallfile.cpp" line="43"/>
312 <source>Installing Rockbox bootloader</source>
313 <translation>Instalando a rotina de arranque do Rockbox</translation>
314 </message>
315 <message>
316 <location filename="../base/bootloaderinstallfile.cpp" line="75"/>
317 <source>Error accessing output folder</source>
318 <translation>Erro ao aceder à directoria de saída</translation>
319 </message>
320 <message>
321 <location filename="../base/bootloaderinstallfile.cpp" line="89"/>
322 <source>A firmware file is already present on player</source>
323 <translation type="unfinished"></translation>
324 </message>
325 <message>
326 <location filename="../base/bootloaderinstallfile.cpp" line="94"/>
327 <source>Bootloader successful installed</source>
328 <translation>Rotina de arranque instalada com sucesso</translation>
329 </message>
330 <message>
331 <location filename="../base/bootloaderinstallfile.cpp" line="97"/>
332 <source>Copying modified firmware file failed</source>
333 <translation type="unfinished"></translation>
334 </message>
335 <message>
336 <location filename="../base/bootloaderinstallfile.cpp" line="111"/>
337 <source>Removing Rockbox bootloader</source>
338 <translation>Removendo a rotina de arranque do Rockbox</translation>
339 </message>
340 <message>
341 <location filename="../base/bootloaderinstallfile.cpp" line="115"/>
342 <source>No original firmware file found.</source>
343 <translation>Ficheiro firmware original não encontrado.</translation>
344 </message>
345 <message>
346 <location filename="../base/bootloaderinstallfile.cpp" line="121"/>
347 <source>Can&apos;t remove Rockbox bootloader file.</source>
348 <translation>Falha na remoção da rotina de arranque do Rockbox.</translation>
349 </message>
350 <message>
351 <location filename="../base/bootloaderinstallfile.cpp" line="126"/>
352 <source>Can&apos;t restore bootloader file.</source>
353 <translation>Falha no restauro da rotina de arranque.</translation>
354 </message>
355 <message>
356 <location filename="../base/bootloaderinstallfile.cpp" line="130"/>
357 <source>Original bootloader restored successfully.</source>
358 <translation>Rotina de arranque original restaurada com sucesso.</translation>
359 </message>
360</context>
361<context>
362 <name>BootloaderInstallHex</name>
363 <message>
364 <location filename="../base/bootloaderinstallhex.cpp" line="69"/>
365 <source>checking MD5 hash of input file ...</source>
366 <translation>verificando código MD5 do ficheiro de entrada ...</translation>
367 </message>
368 <message>
369 <location filename="../base/bootloaderinstallhex.cpp" line="80"/>
370 <source>Could not verify original firmware file</source>
371 <translation>Mão consegiu verficar o ficheiro do firmware original</translation>
372 </message>
373 <message>
374 <location filename="../base/bootloaderinstallhex.cpp" line="95"/>
375 <source>Firmware file not recognized.</source>
376 <translation>Ficherio de firmware não reconhecido.</translation>
377 </message>
378 <message>
379 <location filename="../base/bootloaderinstallhex.cpp" line="99"/>
380 <source>MD5 hash ok</source>
381 <translation>Código MD5 ok</translation>
382 </message>
383 <message>
384 <location filename="../base/bootloaderinstallhex.cpp" line="106"/>
385 <source>Firmware file doesn&apos;t match selected player.</source>
386 <translation>Ficheiro de firmware não corrosponde ao reprodutor seleccionado.</translation>
387 </message>
388 <message>
389 <location filename="../base/bootloaderinstallhex.cpp" line="111"/>
390 <source>Descrambling file</source>
391 <translation>Desbaralhando ficheiro</translation>
392 </message>
393 <message>
394 <location filename="../base/bootloaderinstallhex.cpp" line="119"/>
395 <source>Error in descramble: %1</source>
396 <translation>Erro ao desbaralhar: %1</translation>
397 </message>
398 <message>
399 <location filename="../base/bootloaderinstallhex.cpp" line="124"/>
400 <source>Downloading bootloader file</source>
401 <translation>Transferindo rotina de arranque</translation>
402 </message>
403 <message>
404 <location filename="../base/bootloaderinstallhex.cpp" line="134"/>
405 <source>Adding bootloader to firmware file</source>
406 <translation>Adicionando rotina de arranque ao ficheiro de firmware</translation>
407 </message>
408 <message>
409 <location filename="../base/bootloaderinstallhex.cpp" line="172"/>
410 <source>could not open input file</source>
411 <translation>não consegiu abrir ficheiro de entrada</translation>
412 </message>
413 <message>
414 <location filename="../base/bootloaderinstallhex.cpp" line="173"/>
415 <source>reading header failed</source>
416 <translation>falha na leitura do cabeçalho</translation>
417 </message>
418 <message>
419 <location filename="../base/bootloaderinstallhex.cpp" line="174"/>
420 <source>reading firmware failed</source>
421 <translation>falha na leitura do firmware</translation>
422 </message>
423 <message>
424 <location filename="../base/bootloaderinstallhex.cpp" line="175"/>
425 <source>can&apos;t open bootloader file</source>
426 <translation>falha na abertura do ficheiro da rotina de arranque</translation>
427 </message>
428 <message>
429 <location filename="../base/bootloaderinstallhex.cpp" line="176"/>
430 <source>reading bootloader file failed</source>
431 <translation>falha na leitura da rotina de arranque</translation>
432 </message>
433 <message>
434 <location filename="../base/bootloaderinstallhex.cpp" line="177"/>
435 <source>can&apos;t open output file</source>
436 <translation>não consegue abrir ficheiro de saída</translation>
437 </message>
438 <message>
439 <location filename="../base/bootloaderinstallhex.cpp" line="178"/>
440 <source>writing output file failed</source>
441 <translation>falha na escrita do ficheiro de saída</translation>
442 </message>
443 <message>
444 <location filename="../base/bootloaderinstallhex.cpp" line="180"/>
445 <source>Error in patching: %1</source>
446 <translation>Erro ao corrigir: %1</translation>
447 </message>
448 <message>
449 <location filename="../base/bootloaderinstallhex.cpp" line="191"/>
450 <source>Error in scramble: %1</source>
451 <translation>Erro ao baralhar: %1</translation>
452 </message>
453 <message>
454 <location filename="../base/bootloaderinstallhex.cpp" line="206"/>
455 <source>Checking modified firmware file</source>
456 <translation>Verificando ficheiro do firmware modificado</translation>
457 </message>
458 <message>
459 <location filename="../base/bootloaderinstallhex.cpp" line="208"/>
460 <source>Error: modified file checksum wrong</source>
461 <translation>Erro: soma de controlo do ficheiro modificado incorrecta</translation>
462 </message>
463 <message>
464 <location filename="../base/bootloaderinstallhex.cpp" line="215"/>
465 <source>A firmware file is already present on player</source>
466 <translation type="unfinished"></translation>
467 </message>
468 <message>
469 <location filename="../base/bootloaderinstallhex.cpp" line="220"/>
470 <source>Success: modified firmware file created</source>
471 <translation>Sucesso: ficheiro de firmware modificado criado</translation>
472 </message>
473 <message>
474 <location filename="../base/bootloaderinstallhex.cpp" line="223"/>
475 <source>Copying modified firmware file failed</source>
476 <translation type="unfinished"></translation>
477 </message>
478 <message>
479 <location filename="../base/bootloaderinstallhex.cpp" line="237"/>
480 <source>Uninstallation not possible, only installation info removed</source>
481 <translation type="unfinished"></translation>
482 </message>
483 <message>
484 <location filename="../base/bootloaderinstallhex.cpp" line="258"/>
485 <source>Can&apos;t open input file</source>
486 <translation>Não consegue abrir ficheiro de entrada</translation>
487 </message>
488 <message>
489 <location filename="../base/bootloaderinstallhex.cpp" line="259"/>
490 <source>Can&apos;t open output file</source>
491 <translation>Não consegue abrir ficheiro de saída</translation>
492 </message>
493 <message>
494 <location filename="../base/bootloaderinstallhex.cpp" line="260"/>
495 <source>invalid file: header length wrong</source>
496 <translation>ficheiro inválido: comprimento do cabeçalho incorrecto</translation>
497 </message>
498 <message>
499 <location filename="../base/bootloaderinstallhex.cpp" line="261"/>
500 <source>invalid file: unrecognized header</source>
501 <translation>ficheiro inválido: cabeçalho irreconhecível</translation>
502 </message>
503 <message>
504 <location filename="../base/bootloaderinstallhex.cpp" line="262"/>
505 <source>invalid file: &quot;length&quot; field wrong</source>
506 <translation>ficheiro inválido: campo &quot;length&quot; incorrecto</translation>
507 </message>
508 <message>
509 <location filename="../base/bootloaderinstallhex.cpp" line="263"/>
510 <source>invalid file: &quot;length2&quot; field wrong</source>
511 <translation>ficheiro inválido: campo &quot;length2&quot; incorrecto</translation>
512 </message>
513 <message>
514 <location filename="../base/bootloaderinstallhex.cpp" line="264"/>
515 <source>invalid file: internal checksum error</source>
516 <translation>ficheiro inválido: erro na soma de controlo interna</translation>
517 </message>
518 <message>
519 <location filename="../base/bootloaderinstallhex.cpp" line="265"/>
520 <source>invalid file: &quot;length3&quot; field wrong</source>
521 <translation>ficheiro inválido: campo &quot;length3&quot; incorrecto</translation>
522 </message>
523 <message>
524 <location filename="../base/bootloaderinstallhex.cpp" line="266"/>
525 <source>unknown</source>
526 <translation>desconhecido</translation>
527 </message>
528 <message>
529 <location filename="../base/bootloaderinstallhex.cpp" line="50"/>
530 <source>Bootloader installation requires you to provide a firmware file of the original firmware (hex file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
531 <translation type="unfinished">Instalação da rotina de arranque obriga-o a fornecer um ficheiro de firmware do firmware original (ficheiro hexadecimal). Deve transferi-lo você mesmo devido a razões legais. Por favor veja o &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; e a página wiki &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; para saber como obter este ficheiro.&lt;br/&gt;Pressione Ok para continuar e explorar o seu computador pelo ficheiro de firmware.</translation>
532 </message>
533</context>
534<context>
535 <name>BootloaderInstallImx</name>
536 <message>
537 <location filename="../base/bootloaderinstallimx.cpp" line="72"/>
538 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (firmware.sb file). This file will be patched with the Rockbox bootloader and installed to your player. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
539 <translation type="unfinished"></translation>
540 </message>
541 <message>
542 <location filename="../base/bootloaderinstallimx.cpp" line="94"/>
543 <source>Could not read original firmware file</source>
544 <translation type="unfinished"></translation>
545 </message>
546 <message>
547 <location filename="../base/bootloaderinstallimx.cpp" line="100"/>
548 <source>Downloading bootloader file</source>
549 <translation type="unfinished">Transferindo rotina de arranque</translation>
550 </message>
551 <message>
552 <location filename="../base/bootloaderinstallimx.cpp" line="110"/>
553 <source>Patching file...</source>
554 <translation type="unfinished"></translation>
555 </message>
556 <message>
557 <location filename="../base/bootloaderinstallimx.cpp" line="137"/>
558 <source>Patching the original firmware failed</source>
559 <translation type="unfinished"></translation>
560 </message>
561 <message>
562 <location filename="../base/bootloaderinstallimx.cpp" line="143"/>
563 <source>Succesfully patched firmware file</source>
564 <translation type="unfinished"></translation>
565 </message>
566 <message>
567 <location filename="../base/bootloaderinstallimx.cpp" line="158"/>
568 <source>Bootloader successful installed</source>
569 <translation type="unfinished">Rotina de arranque instalada com sucesso</translation>
570 </message>
571 <message>
572 <location filename="../base/bootloaderinstallimx.cpp" line="164"/>
573 <source>Patched bootloader could not be installed</source>
574 <translation type="unfinished"></translation>
575 </message>
576 <message>
577 <location filename="../base/bootloaderinstallimx.cpp" line="175"/>
578 <source>To uninstall, perform a normal upgrade with an unmodified original firmware.</source>
579 <translation type="unfinished"></translation>
580 </message>
581</context>
582<context>
583 <name>BootloaderInstallIpod</name>
584 <message>
585 <location filename="../base/bootloaderinstallipod.cpp" line="49"/>
586 <source>Error: can&apos;t allocate buffer memory!</source>
587 <translation>Erro: não consegue alocar memória para o buffer!</translation>
588 </message>
589 <message>
590 <location filename="../base/bootloaderinstallipod.cpp" line="80"/>
591 <source>Downloading bootloader file</source>
592 <translation>Transferindo rotina de arranque</translation>
593 </message>
594 <message>
595 <location filename="../base/bootloaderinstallipod.cpp" line="64"/>
596 <location filename="../base/bootloaderinstallipod.cpp" line="151"/>
597 <source>Failed to read firmware directory</source>
598 <translation>Falha na leitura da directoria do firmware</translation>
599 </message>
600 <message>
601 <location filename="../base/bootloaderinstallipod.cpp" line="69"/>
602 <location filename="../base/bootloaderinstallipod.cpp" line="156"/>
603 <source>Unknown version number in firmware (%1)</source>
604 <translation>Número de versão desconhecido no firmware (%1)</translation>
605 </message>
606 <message>
607 <location filename="../base/bootloaderinstallipod.cpp" line="75"/>
608 <source>Warning: This is a MacPod, Rockbox only runs on WinPods.
609See http://www.rockbox.org/wiki/IpodConversionToFAT32</source>
610 <translation type="unfinished"></translation>
611 </message>
612 <message>
613 <location filename="../base/bootloaderinstallipod.cpp" line="94"/>
614 <location filename="../base/bootloaderinstallipod.cpp" line="163"/>
615 <source>Could not open Ipod in R/W mode</source>
616 <translation>Falha na abertura do Ipod em modo de leitura e escrita (R/W)</translation>
617 </message>
618 <message>
619 <location filename="../base/bootloaderinstallipod.cpp" line="104"/>
620 <source>Successfull added bootloader</source>
621 <translation>Adição com sucesso da rotina de arranque</translation>
622 </message>
623 <message>
624 <location filename="../base/bootloaderinstallipod.cpp" line="115"/>
625 <source>Failed to add bootloader</source>
626 <translation>Falha ao adicionar rotina de arranque</translation>
627 </message>
628 <message>
629 <location filename="../base/bootloaderinstallipod.cpp" line="127"/>
630 <source>Bootloader Installation complete.</source>
631 <translation type="unfinished"></translation>
632 </message>
633 <message>
634 <location filename="../base/bootloaderinstallipod.cpp" line="132"/>
635 <source>Writing log aborted</source>
636 <translation type="unfinished"></translation>
637 </message>
638 <message>
639 <location filename="../base/bootloaderinstallipod.cpp" line="169"/>
640 <source>No bootloader detected.</source>
641 <translation>Nenhuma rotina de arranque detectada.</translation>
642 </message>
643 <message>
644 <location filename="../base/bootloaderinstallipod.cpp" line="175"/>
645 <source>Successfully removed bootloader</source>
646 <translation>Remoção com sucesso da rotina de arranque</translation>
647 </message>
648 <message>
649 <location filename="../base/bootloaderinstallipod.cpp" line="182"/>
650 <source>Removing bootloader failed.</source>
651 <translation>Falha na remoção da rotina de arranque.</translation>
652 </message>
653 <message>
654 <location filename="../base/bootloaderinstallipod.cpp" line="228"/>
655 <source>Error: could not retrieve device name</source>
656 <translation type="unfinished"></translation>
657 </message>
658 <message>
659 <location filename="../base/bootloaderinstallipod.cpp" line="244"/>
660 <source>Error: no mountpoint specified!</source>
661 <translation type="unfinished"></translation>
662 </message>
663 <message>
664 <location filename="../base/bootloaderinstallipod.cpp" line="249"/>
665 <source>Could not open Ipod: permission denied</source>
666 <translation type="unfinished"></translation>
667 </message>
668 <message>
669 <location filename="../base/bootloaderinstallipod.cpp" line="253"/>
670 <source>Could not open Ipod</source>
671 <translation>Não consegiu abrir o Ipod</translation>
672 </message>
673 <message>
674 <location filename="../base/bootloaderinstallipod.cpp" line="264"/>
675 <source>No firmware partition on disk</source>
676 <translation>Nenhuma partição do firmware no disco</translation>
677 </message>
678 <message>
679 <location filename="../base/bootloaderinstallipod.cpp" line="90"/>
680 <source>Installing Rockbox bootloader</source>
681 <translation type="unfinished">Instalando a rotina de arranque do Rockbox</translation>
682 </message>
683 <message>
684 <location filename="../base/bootloaderinstallipod.cpp" line="142"/>
685 <source>Uninstalling bootloader</source>
686 <translation type="unfinished"></translation>
687 </message>
688 <message>
689 <location filename="../base/bootloaderinstallipod.cpp" line="258"/>
690 <source>Error reading partition table - possibly not an Ipod</source>
691 <translation type="unfinished"></translation>
692 </message>
693</context>
694<context>
695 <name>BootloaderInstallMi4</name>
696 <message>
697 <location filename="../base/bootloaderinstallmi4.cpp" line="34"/>
698 <source>Downloading bootloader</source>
699 <translation>Transferindo a rotina de arranque</translation>
700 </message>
701 <message>
702 <location filename="../base/bootloaderinstallmi4.cpp" line="43"/>
703 <source>Installing Rockbox bootloader</source>
704 <translation>Instalando a rotina de arranque do Rockbox</translation>
705 </message>
706 <message>
707 <location filename="../base/bootloaderinstallmi4.cpp" line="66"/>
708 <source>A firmware file is already present on player</source>
709 <translation type="unfinished"></translation>
710 </message>
711 <message>
712 <location filename="../base/bootloaderinstallmi4.cpp" line="71"/>
713 <location filename="../base/bootloaderinstallmi4.cpp" line="79"/>
714 <source>Bootloader successful installed</source>
715 <translation>Rotina de arranque instalada com sucesso</translation>
716 </message>
717 <message>
718 <location filename="../base/bootloaderinstallmi4.cpp" line="74"/>
719 <source>Copying modified firmware file failed</source>
720 <translation type="unfinished"></translation>
721 </message>
722 <message>
723 <location filename="../base/bootloaderinstallmi4.cpp" line="91"/>
724 <source>Checking for Rockbox bootloader</source>
725 <translation>Procurando pela rotina de arranque do Rockbox</translation>
726 </message>
727 <message>
728 <location filename="../base/bootloaderinstallmi4.cpp" line="93"/>
729 <source>No Rockbox bootloader found</source>
730 <translation>Não encontrada a rotina de arranque do Rockbox</translation>
731 </message>
732 <message>
733 <location filename="../base/bootloaderinstallmi4.cpp" line="98"/>
734 <source>Checking for original firmware file</source>
735 <translation>Procurando o ficheiro de firmware original</translation>
736 </message>
737 <message>
738 <location filename="../base/bootloaderinstallmi4.cpp" line="103"/>
739 <source>Error finding original firmware file</source>
740 <translation>Erro ao procurar o ficheiro firmware original</translation>
741 </message>
742 <message>
743 <location filename="../base/bootloaderinstallmi4.cpp" line="113"/>
744 <source>Rockbox bootloader successful removed</source>
745 <translation>Rotina de arranque do Rockbox removida com sucesso</translation>
746 </message>
747</context>
748<context>
749 <name>BootloaderInstallMpio</name>
750 <message>
751 <location filename="../base/bootloaderinstallmpio.cpp" line="34"/>
752 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
753 <translation type="unfinished"></translation>
754 </message>
755 <message>
756 <location filename="../base/bootloaderinstallmpio.cpp" line="53"/>
757 <source>Downloading bootloader file</source>
758 <translation type="unfinished">Transferindo rotina de arranque</translation>
759 </message>
760 <message>
761 <location filename="../base/bootloaderinstallmpio.cpp" line="80"/>
762 <source>Could not open the original firmware.</source>
763 <translation type="unfinished"></translation>
764 </message>
765 <message>
766 <location filename="../base/bootloaderinstallmpio.cpp" line="83"/>
767 <source>Could not read the original firmware.</source>
768 <translation type="unfinished"></translation>
769 </message>
770 <message>
771 <location filename="../base/bootloaderinstallmpio.cpp" line="86"/>
772 <source>Loaded firmware file does not look like MPIO original firmware file.</source>
773 <translation type="unfinished"></translation>
774 </message>
775 <message>
776 <location filename="../base/bootloaderinstallmpio.cpp" line="101"/>
777 <source>Could not open output file.</source>
778 <translation type="unfinished"></translation>
779 </message>
780 <message>
781 <location filename="../base/bootloaderinstallmpio.cpp" line="104"/>
782 <source>Could not write output file.</source>
783 <translation type="unfinished"></translation>
784 </message>
785 <message>
786 <location filename="../base/bootloaderinstallmpio.cpp" line="107"/>
787 <source>Unknown error number: %1</source>
788 <translation type="unfinished"></translation>
789 </message>
790 <message>
791 <location filename="../base/bootloaderinstallmpio.cpp" line="89"/>
792 <source>Could not open downloaded bootloader.</source>
793 <translation type="unfinished"></translation>
794 </message>
795 <message>
796 <location filename="../base/bootloaderinstallmpio.cpp" line="92"/>
797 <source>Place for bootloader in OF file not empty.</source>
798 <translation type="unfinished"></translation>
799 </message>
800 <message>
801 <location filename="../base/bootloaderinstallmpio.cpp" line="95"/>
802 <source>Could not read the downloaded bootloader.</source>
803 <translation type="unfinished"></translation>
804 </message>
805 <message>
806 <location filename="../base/bootloaderinstallmpio.cpp" line="98"/>
807 <source>Bootloader checksum error.</source>
808 <translation type="unfinished"></translation>
809 </message>
810 <message>
811 <location filename="../base/bootloaderinstallmpio.cpp" line="112"/>
812 <source>Patching original firmware failed: %1</source>
813 <translation type="unfinished"></translation>
814 </message>
815 <message>
816 <location filename="../base/bootloaderinstallmpio.cpp" line="119"/>
817 <source>Success: modified firmware file created</source>
818 <translation type="unfinished">Sucesso: ficheiro de firmware modificado criado</translation>
819 </message>
820 <message>
821 <location filename="../base/bootloaderinstallmpio.cpp" line="127"/>
822 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
823 <translation type="unfinished"></translation>
824 </message>
825</context>
826<context>
827 <name>BootloaderInstallSansa</name>
828 <message>
829 <location filename="../base/bootloaderinstallsansa.cpp" line="50"/>
830 <source>Error: can&apos;t allocate buffer memory!</source>
831 <translation>Erro: não consegue alocar memória para o buffer!</translation>
832 </message>
833 <message>
834 <location filename="../base/bootloaderinstallsansa.cpp" line="55"/>
835 <source>Searching for Sansa</source>
836 <translation>Procurando pelo Sansa</translation>
837 </message>
838 <message>
839 <location filename="../base/bootloaderinstallsansa.cpp" line="59"/>
840 <source>Permission for disc access denied!
841This is required to install the bootloader</source>
842 <translation>Permissão para o acesso ao disco negada!
843Esta é necessária para instalar a rotina de arranque</translation>
844 </message>
845 <message>
846 <location filename="../base/bootloaderinstallsansa.cpp" line="66"/>
847 <source>No Sansa detected!</source>
848 <translation>Nenhum Sansa detectado!</translation>
849 </message>
850 <message>
851 <location filename="../base/bootloaderinstallsansa.cpp" line="79"/>
852 <source>Downloading bootloader file</source>
853 <translation>Transferindo rotina de arranque</translation>
854 </message>
855 <message>
856 <location filename="../base/bootloaderinstallsansa.cpp" line="71"/>
857 <location filename="../base/bootloaderinstallsansa.cpp" line="179"/>
858 <source>OLD ROCKBOX INSTALLATION DETECTED, ABORTING.
859You must reinstall the original Sansa firmware before running
860sansapatcher for the first time.
861See http://www.rockbox.org/wiki/SansaE200Install
862</source>
863 <translation>INSTALAÇÃO ANTIGA DO ROCKBOX DETECTADA, A ABORTAR
864Deve reinstalar o firmware original do Sansa antes de correr
865o sansapatcher pela primeira vez.
866Veja http://www.rockbox.org/wiki/SansaE200Install
867</translation>
868 </message>
869 <message>
870 <location filename="../base/bootloaderinstallsansa.cpp" line="102"/>
871 <location filename="../base/bootloaderinstallsansa.cpp" line="189"/>
872 <source>Could not open Sansa in R/W mode</source>
873 <translation>Falha na abertura do Sansa em modo de leitura e escrita (R/W)</translation>
874 </message>
875 <message>
876 <location filename="../base/bootloaderinstallsansa.cpp" line="129"/>
877 <source>Successfully installed bootloader</source>
878 <translation>Rotina de arranque instalada com sucesso</translation>
879 </message>
880 <message>
881 <location filename="../base/bootloaderinstallsansa.cpp" line="140"/>
882 <source>Failed to install bootloader</source>
883 <translation>Falha ao instalar rotina de arranque</translation>
884 </message>
885 <message>
886 <location filename="../base/bootloaderinstallsansa.cpp" line="153"/>
887 <source>Bootloader Installation complete.</source>
888 <translation type="unfinished"></translation>
889 </message>
890 <message>
891 <location filename="../base/bootloaderinstallsansa.cpp" line="158"/>
892 <source>Writing log aborted</source>
893 <translation type="unfinished"></translation>
894 </message>
895 <message>
896 <location filename="../base/bootloaderinstallsansa.cpp" line="238"/>
897 <source>Error: could not retrieve device name</source>
898 <translation type="unfinished"></translation>
899 </message>
900 <message>
901 <location filename="../base/bootloaderinstallsansa.cpp" line="254"/>
902 <source>Can&apos;t find Sansa</source>
903 <translation>Não consegue encontrar Sansa</translation>
904 </message>
905 <message>
906 <location filename="../base/bootloaderinstallsansa.cpp" line="259"/>
907 <source>Could not open Sansa</source>
908 <translation>Não consegiu abrir o Sansa</translation>
909 </message>
910 <message>
911 <location filename="../base/bootloaderinstallsansa.cpp" line="264"/>
912 <source>Could not read partition table</source>
913 <translation>Não consegiu ler tabela de partições</translation>
914 </message>
915 <message>
916 <location filename="../base/bootloaderinstallsansa.cpp" line="271"/>
917 <source>Disk is not a Sansa (Error %1), aborting.</source>
918 <translation>Disco não é um Sansa (Erro %1), a abortar.</translation>
919 </message>
920 <message>
921 <location filename="../base/bootloaderinstallsansa.cpp" line="195"/>
922 <source>Successfully removed bootloader</source>
923 <translation>Remoção com sucesso da rotina de arranque</translation>
924 </message>
925 <message>
926 <location filename="../base/bootloaderinstallsansa.cpp" line="202"/>
927 <source>Removing bootloader failed.</source>
928 <translation>Falha na remoção da rotina de arranque.</translation>
929 </message>
930 <message>
931 <location filename="../base/bootloaderinstallsansa.cpp" line="94"/>
932 <source>Installing Rockbox bootloader</source>
933 <translation type="unfinished">Instalando a rotina de arranque do Rockbox</translation>
934 </message>
935 <message>
936 <location filename="../base/bootloaderinstallsansa.cpp" line="111"/>
937 <source>Checking downloaded bootloader</source>
938 <translation type="unfinished"></translation>
939 </message>
940 <message>
941 <location filename="../base/bootloaderinstallsansa.cpp" line="119"/>
942 <source>Bootloader mismatch! Aborting.</source>
943 <translation type="unfinished"></translation>
944 </message>
945 <message>
946 <location filename="../base/bootloaderinstallsansa.cpp" line="170"/>
947 <source>Uninstalling bootloader</source>
948 <translation type="unfinished"></translation>
949 </message>
950</context>
951<context>
952 <name>BootloaderInstallTcc</name>
953 <message>
954 <location filename="../base/bootloaderinstalltcc.cpp" line="33"/>
955 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wiki page on how to obtain the file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
956 <translation type="unfinished"></translation>
957 </message>
958 <message>
959 <location filename="../base/bootloaderinstalltcc.cpp" line="50"/>
960 <source>Downloading bootloader file</source>
961 <translation type="unfinished">Transferindo rotina de arranque</translation>
962 </message>
963 <message>
964 <location filename="../base/bootloaderinstalltcc.cpp" line="82"/>
965 <location filename="../base/bootloaderinstalltcc.cpp" line="99"/>
966 <source>Could not load %1</source>
967 <translation type="unfinished"></translation>
968 </message>
969 <message>
970 <location filename="../base/bootloaderinstalltcc.cpp" line="90"/>
971 <source>Unknown OF file used: %1</source>
972 <translation type="unfinished"></translation>
973 </message>
974 <message>
975 <location filename="../base/bootloaderinstalltcc.cpp" line="104"/>
976 <source>Patching Firmware...</source>
977 <translation type="unfinished"></translation>
978 </message>
979 <message>
980 <location filename="../base/bootloaderinstalltcc.cpp" line="111"/>
981 <source>Could not patch firmware</source>
982 <translation type="unfinished"></translation>
983 </message>
984 <message>
985 <location filename="../base/bootloaderinstalltcc.cpp" line="117"/>
986 <source>Could not open %1 for writing</source>
987 <translation type="unfinished"></translation>
988 </message>
989 <message>
990 <location filename="../base/bootloaderinstalltcc.cpp" line="126"/>
991 <source>Could not write firmware file</source>
992 <translation type="unfinished"></translation>
993 </message>
994 <message>
995 <location filename="../base/bootloaderinstalltcc.cpp" line="131"/>
996 <source>Success: modified firmware file created</source>
997 <translation type="unfinished">Sucesso: ficheiro de firmware modificado criado</translation>
998 </message>
999 <message>
1000 <location filename="../base/bootloaderinstalltcc.cpp" line="151"/>
1001 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
1002 <translation type="unfinished"></translation>
1003 </message>
1004</context>
1005<context>
1006 <name>Changelog</name>
1007 <message>
1008 <location filename="../gui/changelogfrm.ui" line="17"/>
1009 <source>Changelog</source>
1010 <translation type="unfinished"></translation>
1011 </message>
1012 <message>
1013 <location filename="../gui/changelogfrm.ui" line="39"/>
1014 <source>Show on startup</source>
1015 <translation type="unfinished"></translation>
1016 </message>
1017 <message>
1018 <location filename="../gui/changelogfrm.ui" line="46"/>
1019 <source>&amp;Ok</source>
1020 <translation type="unfinished">&amp;Ok</translation>
1021 </message>
1022</context>
1023<context>
1024 <name>Config</name>
1025 <message>
1026 <location filename="../configure.cpp" line="322"/>
1027 <source>Current cache size is %L1 kiB.</source>
1028 <translation>Tamanho actual da cache é %L1 kiB.</translation>
1029 </message>
1030 <message>
1031 <location filename="../configure.cpp" line="340"/>
1032 <source>Showing disabled targets</source>
1033 <translation type="unfinished"></translation>
1034 </message>
1035 <message>
1036 <location filename="../configure.cpp" line="341"/>
1037 <source>You just enabled showing targets that are marked disabled. Disabled targets are not recommended to end users. Please use this option only if you know what you are doing.</source>
1038 <translation type="unfinished"></translation>
1039 </message>
1040 <message>
1041 <location filename="../configure.cpp" line="448"/>
1042 <location filename="../configure.cpp" line="914"/>
1043 <source>TTS error</source>
1044 <translation type="unfinished"></translation>
1045 </message>
1046 <message>
1047 <location filename="../configure.cpp" line="449"/>
1048 <location filename="../configure.cpp" line="915"/>
1049 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1050 <translation type="unfinished"></translation>
1051 </message>
1052 <message>
1053 <location filename="../configure.cpp" line="455"/>
1054 <location filename="../configure.cpp" line="485"/>
1055 <source>Configuration OK</source>
1056 <translation>Configuração OK</translation>
1057 </message>
1058 <message>
1059 <location filename="../configure.cpp" line="461"/>
1060 <location filename="../configure.cpp" line="490"/>
1061 <source>Configuration INVALID</source>
1062 <translation>Configuração INVÁLIDA</translation>
1063 </message>
1064 <message>
1065 <location filename="../configure.cpp" line="529"/>
1066 <source>Proxy Detection</source>
1067 <translation type="unfinished"></translation>
1068 </message>
1069 <message>
1070 <location filename="../configure.cpp" line="530"/>
1071 <source>The System Proxy settings are invalid!
1072Rockbox Utility can&apos;t work with this proxy settings. Make sure the system proxy is set correctly. Note that &quot;proxy auto-config (PAC)&quot; scripts are not supported by Rockbox Utility. If your system uses this you need to use manual proxy settings.</source>
1073 <translation type="unfinished"></translation>
1074 </message>
1075 <message>
1076 <location filename="../configure.cpp" line="643"/>
1077 <source>Set Cache Path</source>
1078 <translation type="unfinished"></translation>
1079 </message>
1080 <message>
1081 <location filename="../configure.cpp" line="665"/>
1082 <source>%1 (%2 GiB of %3 GiB free)</source>
1083 <translation type="unfinished"></translation>
1084 </message>
1085 <message>
1086 <location filename="../configure.cpp" line="739"/>
1087 <source>Multiple devices have been detected. Please disconnect all players but one and try again.</source>
1088 <translation type="unfinished"></translation>
1089 </message>
1090 <message>
1091 <location filename="../configure.cpp" line="742"/>
1092 <source>Detected devices:</source>
1093 <translation type="unfinished"></translation>
1094 </message>
1095 <message>
1096 <location filename="../configure.cpp" line="747"/>
1097 <source>(unknown)</source>
1098 <translation type="unfinished"></translation>
1099 </message>
1100 <message>
1101 <location filename="../configure.cpp" line="749"/>
1102 <source>%1 at %2</source>
1103 <translation type="unfinished"></translation>
1104 </message>
1105 <message>
1106 <location filename="../configure.cpp" line="755"/>
1107 <source>Note: detecting connected devices might be ambiguous. You might have less devices connected than listed. In this case it might not be possible to detect your player unambiguously.</source>
1108 <translation type="unfinished"></translation>
1109 </message>
1110 <message>
1111 <location filename="../configure.cpp" line="759"/>
1112 <location filename="../configure.cpp" line="763"/>
1113 <location filename="../configure.cpp" line="805"/>
1114 <source>Device Detection</source>
1115 <translation type="unfinished"></translation>
1116 </message>
1117 <message>
1118 <location filename="../configure.cpp" line="788"/>
1119 <source>%1 &quot;MacPod&quot; found!
1120Rockbox needs a FAT formatted Ipod (so-called &quot;WinPod&quot;) to run. </source>
1121 <translation type="unfinished"></translation>
1122 </message>
1123 <message>
1124 <source>Fatal error</source>
1125 <translation type="obsolete">Erro fatal</translation>
1126 </message>
1127 <message>
1128 <location filename="../configure.cpp" line="774"/>
1129 <source>Detected an unsupported player:
1130%1
1131Sorry, Rockbox doesn&apos;t run on your player.</source>
1132 <translation type="unfinished"></translation>
1133 </message>
1134 <message>
1135 <location filename="../configure.cpp" line="921"/>
1136 <source>TTS configuration invalid</source>
1137 <translation type="unfinished"></translation>
1138 </message>
1139 <message>
1140 <location filename="../configure.cpp" line="922"/>
1141 <source>TTS configuration invalid.
1142 Please configure TTS engine.</source>
1143 <translation type="unfinished"></translation>
1144 </message>
1145 <message>
1146 <location filename="../configure.cpp" line="927"/>
1147 <source>Could not start TTS engine.</source>
1148 <translation type="unfinished"></translation>
1149 </message>
1150 <message>
1151 <location filename="../configure.cpp" line="928"/>
1152 <source>Could not start TTS engine.
1153</source>
1154 <translation type="unfinished"></translation>
1155 </message>
1156 <message>
1157 <location filename="../configure.cpp" line="929"/>
1158 <location filename="../configure.cpp" line="948"/>
1159 <source>
1160Please configure TTS engine.</source>
1161 <translation type="unfinished"></translation>
1162 </message>
1163 <message>
1164 <location filename="../configure.cpp" line="943"/>
1165 <source>Rockbox Utility Voice Test</source>
1166 <translation type="unfinished"></translation>
1167 </message>
1168 <message>
1169 <location filename="../configure.cpp" line="946"/>
1170 <source>Could not voice test string.</source>
1171 <translation type="unfinished"></translation>
1172 </message>
1173 <message>
1174 <location filename="../configure.cpp" line="947"/>
1175 <source>Could not voice test string.
1176</source>
1177 <translation type="unfinished"></translation>
1178 </message>
1179 <message>
1180 <location filename="../configure.cpp" line="858"/>
1181 <source>Autodetection</source>
1182 <translation>Auto-detecção</translation>
1183 </message>
1184 <message>
1185 <location filename="../configure.cpp" line="780"/>
1186 <source>%1 in MTP mode found!
1187You need to change your player to MSC mode for installation. </source>
1188 <translation type="unfinished"></translation>
1189 </message>
1190 <message>
1191 <location filename="../configure.cpp" line="859"/>
1192 <source>Could not detect a Mountpoint.
1193Select your Mountpoint manually.</source>
1194 <translation>Não consegiu detectar um ponto de montagem.
1195Seleccione um ponto de montagem manualmente.</translation>
1196 </message>
1197 <message>
1198 <location filename="../configure.cpp" line="764"/>
1199 <source>Could not detect a device.
1200Select your device and Mountpoint manually.</source>
1201 <translation>Não consegiu detectar um dispositivo.
1202Seleccione um dispositivo e um ponto de montagem manualmente.</translation>
1203 </message>
1204 <message>
1205 <location filename="../configure.cpp" line="794"/>
1206 <source>The player contains an incompatible filesystem.
1207Make sure you selected the correct mountpoint and the player is set up to use a filesystem compatible with Rockbox.</source>
1208 <translation type="unfinished"></translation>
1209 </message>
1210 <message>
1211 <location filename="../configure.cpp" line="802"/>
1212 <source>An unknown error occured during player detection.</source>
1213 <translation type="unfinished"></translation>
1214 </message>
1215 <message>
1216 <location filename="../configure.cpp" line="869"/>
1217 <source>Really delete cache?</source>
1218 <translation>Eliminar mesmo a cache?</translation>
1219 </message>
1220 <message>
1221 <location filename="../configure.cpp" line="870"/>
1222 <source>Do you really want to delete the cache? Make absolutely sure this setting is correct as it will remove &lt;b&gt;all&lt;/b&gt; files in this folder!</source>
1223 <translation>Quer mesmo eliminar a cache? Verique que esta opção está correcta já que irá remover &lt;b&gt;todos&lt;/b&gt; os ficheiros nesta directoria!</translation>
1224 </message>
1225 <message>
1226 <location filename="../configure.cpp" line="878"/>
1227 <source>Path wrong!</source>
1228 <translation>Caminho incorrecto!</translation>
1229 </message>
1230 <message>
1231 <location filename="../configure.cpp" line="879"/>
1232 <source>The cache path is invalid. Aborting.</source>
1233 <translation>O caminho da cache é inválido. A abortar.</translation>
1234 </message>
1235 <message>
1236 <location filename="../configure.cpp" line="130"/>
1237 <source>The following errors occurred:</source>
1238 <translation type="unfinished"></translation>
1239 </message>
1240 <message>
1241 <location filename="../configure.cpp" line="175"/>
1242 <source>No mountpoint given</source>
1243 <translation type="unfinished"></translation>
1244 </message>
1245 <message>
1246 <location filename="../configure.cpp" line="179"/>
1247 <source>Mountpoint does not exist</source>
1248 <translation type="unfinished"></translation>
1249 </message>
1250 <message>
1251 <location filename="../configure.cpp" line="183"/>
1252 <source>Mountpoint is not a directory.</source>
1253 <translation type="unfinished"></translation>
1254 </message>
1255 <message>
1256 <location filename="../configure.cpp" line="187"/>
1257 <source>Mountpoint is not writeable</source>
1258 <translation type="unfinished"></translation>
1259 </message>
1260 <message>
1261 <location filename="../configure.cpp" line="202"/>
1262 <source>No player selected</source>
1263 <translation type="unfinished"></translation>
1264 </message>
1265 <message>
1266 <location filename="../configure.cpp" line="209"/>
1267 <source>Cache path not writeable. Leave path empty to default to systems temporary path.</source>
1268 <translation type="unfinished"></translation>
1269 </message>
1270 <message>
1271 <location filename="../configure.cpp" line="228"/>
1272 <source>You need to fix the above errors before you can continue.</source>
1273 <translation type="unfinished"></translation>
1274 </message>
1275 <message>
1276 <location filename="../configure.cpp" line="231"/>
1277 <source>Configuration error</source>
1278 <translation type="unfinished">Erro de Configuração</translation>
1279 </message>
1280</context>
1281<context>
1282 <name>ConfigForm</name>
1283 <message>
1284 <location filename="../configurefrm.ui" line="14"/>
1285 <source>Configuration</source>
1286 <translation>Configuração</translation>
1287 </message>
1288 <message>
1289 <location filename="../configurefrm.ui" line="20"/>
1290 <source>Configure Rockbox Utility</source>
1291 <translation>Configurar Rockbox Utility</translation>
1292 </message>
1293 <message>
1294 <location filename="../configurefrm.ui" line="35"/>
1295 <source>&amp;Device</source>
1296 <translation>&amp;Dispositivo</translation>
1297 </message>
1298 <message>
1299 <location filename="../configurefrm.ui" line="41"/>
1300 <source>Select your device in the &amp;filesystem</source>
1301 <translation>Seleccione o seu dispositivo no sistema de &amp;ficheiros</translation>
1302 </message>
1303 <message>
1304 <location filename="../configurefrm.ui" line="319"/>
1305 <source>&amp;Browse</source>
1306 <translation>E&amp;xplorar</translation>
1307 </message>
1308 <message>
1309 <location filename="../configurefrm.ui" line="72"/>
1310 <source>&amp;Select your audio player</source>
1311 <translation>&amp;Seleccione o seu reprodutor de música</translation>
1312 </message>
1313 <message>
1314 <location filename="../configurefrm.ui" line="58"/>
1315 <source>&amp;Refresh</source>
1316 <translation type="unfinished">Actualizar</translation>
1317 </message>
1318 <message>
1319 <location filename="../configurefrm.ui" line="95"/>
1320 <source>Show disabled targets</source>
1321 <translation type="unfinished"></translation>
1322 </message>
1323 <message>
1324 <location filename="../configurefrm.ui" line="114"/>
1325 <source>&amp;Autodetect</source>
1326 <translation>&amp;Auto-detecção</translation>
1327 </message>
1328 <message>
1329 <location filename="../configurefrm.ui" line="136"/>
1330 <source>&amp;Proxy</source>
1331 <translation>&amp;Proxy</translation>
1332 </message>
1333 <message>
1334 <location filename="../configurefrm.ui" line="142"/>
1335 <source>&amp;No Proxy</source>
1336 <translation>Sem &amp;Proxy</translation>
1337 </message>
1338 <message>
1339 <location filename="../configurefrm.ui" line="152"/>
1340 <source>Use S&amp;ystem values</source>
1341 <translation>Usar valores d&amp;o sistema</translation>
1342 </message>
1343 <message>
1344 <location filename="../configurefrm.ui" line="159"/>
1345 <source>&amp;Manual Proxy settings</source>
1346 <translation>Definições &amp;Manuais do Proxy</translation>
1347 </message>
1348 <message>
1349 <location filename="../configurefrm.ui" line="166"/>
1350 <source>Proxy Values</source>
1351 <translation>Valores do Proxy</translation>
1352 </message>
1353 <message>
1354 <location filename="../configurefrm.ui" line="172"/>
1355 <source>&amp;Host:</source>
1356 <translation>Anfi&amp;trião:</translation>
1357 </message>
1358 <message>
1359 <location filename="../configurefrm.ui" line="182"/>
1360 <source>&amp;Port:</source>
1361 <translation>&amp;Porta:</translation>
1362 </message>
1363 <message>
1364 <location filename="../configurefrm.ui" line="199"/>
1365 <source>&amp;Username</source>
1366 <translation>&amp;Utilizador</translation>
1367 </message>
1368 <message>
1369 <location filename="../configurefrm.ui" line="209"/>
1370 <source>Pass&amp;word</source>
1371 <translation>Palavra-c&amp;have</translation>
1372 </message>
1373 <message>
1374 <location filename="../configurefrm.ui" line="219"/>
1375 <source>Show</source>
1376 <translation type="unfinished"></translation>
1377 </message>
1378 <message>
1379 <location filename="../configurefrm.ui" line="260"/>
1380 <source>&amp;Language</source>
1381 <translation>&amp;Linguagem</translation>
1382 </message>
1383 <message>
1384 <location filename="../configurefrm.ui" line="274"/>
1385 <source>Cac&amp;he</source>
1386 <translation>Cac&amp;he</translation>
1387 </message>
1388 <message>
1389 <location filename="../configurefrm.ui" line="277"/>
1390 <source>Download cache settings</source>
1391 <translation>Definições da transferência da cache</translation>
1392 </message>
1393 <message>
1394 <location filename="../configurefrm.ui" line="283"/>
1395 <source>Rockbox Utility uses a local download cache to save network traffic. You can change the path to the cache and use it as local repository by enabling Offline mode.</source>
1396 <translation>Rockbox Utility usa uma cache local para as transferências para poupar tráfego de internet. Pode mudar o caminho para a cache e usá-la como repositório local se activar o Modo Offline.</translation>
1397 </message>
1398 <message>
1399 <location filename="../configurefrm.ui" line="293"/>
1400 <source>Current cache size is %1</source>
1401 <translation>Tamanho actual da cache é %1</translation>
1402 </message>
1403 <message>
1404 <location filename="../configurefrm.ui" line="302"/>
1405 <source>P&amp;ath</source>
1406 <translation>C&amp;aminho</translation>
1407 </message>
1408 <message>
1409 <location filename="../configurefrm.ui" line="312"/>
1410 <source>Entering an invalid folder will reset the path to the systems temporary path.</source>
1411 <translation>Inserção duma directoria inválida irá reiniciar o caminho para o caminho temporário do sistema.</translation>
1412 </message>
1413 <message>
1414 <location filename="../configurefrm.ui" line="334"/>
1415 <source>Disable local &amp;download cache</source>
1416 <translation>Desactivar transferência local de cache</translation>
1417 </message>
1418 <message>
1419 <source>&lt;p&gt;This will try to use all information from the cache, even information about updates. Only use this option if you want to install without network connection. Note: you need to do the same install you want to perform later with network access first to download all required files to the cache.&lt;/p&gt;</source>
1420 <translation type="obsolete">&lt;p&gt;Isto irá tentar usar toda a informação da cache, até informação sobre actualizaçẽos. Só use esta opção se desejar instalar sem conecção de internet. Nota: precisa de fazer primeiro a mesma instalação que deseja efectuar mais tarde com acesso à internet para transferir todos os ficheiros necessários para a cache.&lt;/p&gt;</translation>
1421 </message>
1422 <message>
1423 <source>O&amp;ffline mode</source>
1424 <translation type="obsolete">Modo O&amp;ffline</translation>
1425 </message>
1426 <message>
1427 <location filename="../configurefrm.ui" line="369"/>
1428 <source>Clean cache &amp;now</source>
1429 <translation>Limpar agora a cac&amp;he</translation>
1430 </message>
1431 <message>
1432 <location filename="../configurefrm.ui" line="385"/>
1433 <source>&amp;TTS &amp;&amp; Encoder</source>
1434 <translation>&amp;TTS &amp;&amp; Encoder</translation>
1435 </message>
1436 <message>
1437 <location filename="../configurefrm.ui" line="391"/>
1438 <source>TTS Engine</source>
1439 <translation>Motor TTS</translation>
1440 </message>
1441 <message>
1442 <location filename="../configurefrm.ui" line="397"/>
1443 <source>&amp;Select TTS Engine</source>
1444 <translation>&amp;Seleccione Motor TTS</translation>
1445 </message>
1446 <message>
1447 <location filename="../configurefrm.ui" line="410"/>
1448 <source>Configure TTS Engine</source>
1449 <translation>Configuração do Motor TTS</translation>
1450 </message>
1451 <message>
1452 <location filename="../configurefrm.ui" line="417"/>
1453 <location filename="../configurefrm.ui" line="468"/>
1454 <source>Configuration invalid!</source>
1455 <translation>Configuração inválida!</translation>
1456 </message>
1457 <message>
1458 <location filename="../configurefrm.ui" line="434"/>
1459 <source>Configure &amp;TTS</source>
1460 <translation>Configurar &amp;TTS</translation>
1461 </message>
1462 <message>
1463 <location filename="../configurefrm.ui" line="445"/>
1464 <source>Test TTS</source>
1465 <translation type="unfinished"></translation>
1466 </message>
1467 <message>
1468 <location filename="../configurefrm.ui" line="452"/>
1469 <source>&amp;Use string corrections for TTS</source>
1470 <translation type="unfinished"></translation>
1471 </message>
1472 <message>
1473 <location filename="../configurefrm.ui" line="462"/>
1474 <source>Encoder Engine</source>
1475 <translation>Motor do Codificador</translation>
1476 </message>
1477 <message>
1478 <location filename="../configurefrm.ui" line="485"/>
1479 <source>Configure &amp;Enc</source>
1480 <translation>Configurar &amp;Cod</translation>
1481 </message>
1482 <message>
1483 <location filename="../configurefrm.ui" line="496"/>
1484 <source>encoder name</source>
1485 <translation>nome do codificador</translation>
1486 </message>
1487 <message>
1488 <location filename="../configurefrm.ui" line="536"/>
1489 <source>&amp;Ok</source>
1490 <translation>&amp;Ok</translation>
1491 </message>
1492 <message>
1493 <location filename="../configurefrm.ui" line="547"/>
1494 <source>&amp;Cancel</source>
1495 <translation>&amp;Cancelar</translation>
1496 </message>
1497</context>
1498<context>
1499 <name>Configure</name>
1500 <message>
1501 <location filename="../configure.cpp" line="589"/>
1502 <source>English</source>
1503 <comment>This is the localized language name, i.e. your language.</comment>
1504 <translation>Português (Portugal)</translation>
1505 </message>
1506</context>
1507<context>
1508 <name>CreateVoiceFrm</name>
1509 <message>
1510 <location filename="../createvoicefrm.ui" line="17"/>
1511 <source>Create Voice File</source>
1512 <translation>Criar Ficheiro de Voz</translation>
1513 </message>
1514 <message>
1515 <location filename="../createvoicefrm.ui" line="42"/>
1516 <source>Select the Language you want to generate a voicefile for:</source>
1517 <translation>Seleccione o idioma para o qual deseja gerar um ficheiro de voz:</translation>
1518 </message>
1519 <message>
1520 <location filename="../createvoicefrm.ui" line="55"/>
1521 <source>TTS:</source>
1522 <translation type="unfinished"></translation>
1523 </message>
1524 <message>
1525 <location filename="../createvoicefrm.ui" line="101"/>
1526 <source>Silence threshold</source>
1527 <translation type="unfinished"></translation>
1528 </message>
1529 <message>
1530 <location filename="../createvoicefrm.ui" line="163"/>
1531 <source>Language</source>
1532 <translation type="unfinished"></translation>
1533 </message>
1534 <message>
1535 <location filename="../createvoicefrm.ui" line="49"/>
1536 <source>Generation settings</source>
1537 <translation>Definições de geração</translation>
1538 </message>
1539 <message>
1540 <location filename="../createvoicefrm.ui" line="68"/>
1541 <source>Change</source>
1542 <translation>Alterar</translation>
1543 </message>
1544 <message>
1545 <location filename="../createvoicefrm.ui" line="139"/>
1546 <source>&amp;Install</source>
1547 <translation>&amp;Instalar</translation>
1548 </message>
1549 <message>
1550 <location filename="../createvoicefrm.ui" line="150"/>
1551 <source>&amp;Cancel</source>
1552 <translation>&amp;Cancelar</translation>
1553 </message>
1554 <message>
1555 <location filename="../createvoicefrm.ui" line="88"/>
1556 <source>Wavtrim Threshold</source>
1557 <translation>Limiar do Wavtrim</translation>
1558 </message>
1559</context>
1560<context>
1561 <name>CreateVoiceWindow</name>
1562 <message>
1563 <location filename="../createvoicewindow.cpp" line="100"/>
1564 <source>TTS error</source>
1565 <translation type="unfinished"></translation>
1566 </message>
1567 <message>
1568 <location filename="../createvoicewindow.cpp" line="101"/>
1569 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1570 <translation type="unfinished"></translation>
1571 </message>
1572 <message>
1573 <location filename="../createvoicewindow.cpp" line="105"/>
1574 <location filename="../createvoicewindow.cpp" line="108"/>
1575 <source>Engine: &lt;b&gt;%1&lt;/b&gt;</source>
1576 <translation type="unfinished"></translation>
1577 </message>
1578</context>
1579<context>
1580 <name>EncTtsCfgGui</name>
1581 <message>
1582 <location filename="../encttscfggui.cpp" line="45"/>
1583 <source>Waiting for engine...</source>
1584 <translation type="unfinished"></translation>
1585 </message>
1586 <message>
1587 <location filename="../encttscfggui.cpp" line="95"/>
1588 <source>Ok</source>
1589 <translation type="unfinished"></translation>
1590 </message>
1591 <message>
1592 <location filename="../encttscfggui.cpp" line="98"/>
1593 <source>Cancel</source>
1594 <translation type="unfinished"></translation>
1595 </message>
1596 <message>
1597 <location filename="../encttscfggui.cpp" line="197"/>
1598 <source>Browse</source>
1599 <translation type="unfinished"></translation>
1600 </message>
1601 <message>
1602 <location filename="../encttscfggui.cpp" line="205"/>
1603 <source>Refresh</source>
1604 <translation type="unfinished"></translation>
1605 </message>
1606 <message>
1607 <location filename="../encttscfggui.cpp" line="377"/>
1608 <source>Select executable</source>
1609 <translation type="unfinished"></translation>
1610 </message>
1611</context>
1612<context>
1613 <name>EncoderExe</name>
1614 <message>
1615 <location filename="../base/encoderexe.cpp" line="41"/>
1616 <source>Path to Encoder:</source>
1617 <translation type="unfinished"></translation>
1618 </message>
1619 <message>
1620 <location filename="../base/encoderexe.cpp" line="43"/>
1621 <source>Encoder options:</source>
1622 <translation type="unfinished"></translation>
1623 </message>
1624</context>
1625<context>
1626 <name>EncoderLame</name>
1627 <message>
1628 <location filename="../base/encoderlame.cpp" line="73"/>
1629 <location filename="../base/encoderlame.cpp" line="83"/>
1630 <source>LAME</source>
1631 <translation type="unfinished"></translation>
1632 </message>
1633 <message>
1634 <location filename="../base/encoderlame.cpp" line="75"/>
1635 <source>Volume</source>
1636 <translation type="unfinished"></translation>
1637 </message>
1638 <message>
1639 <location filename="../base/encoderlame.cpp" line="79"/>
1640 <source>Quality</source>
1641 <translation type="unfinished"></translation>
1642 </message>
1643 <message>
1644 <location filename="../base/encoderlame.cpp" line="83"/>
1645 <source>Could not find libmp3lame!</source>
1646 <translation type="unfinished"></translation>
1647 </message>
1648</context>
1649<context>
1650 <name>EncoderRbSpeex</name>
1651 <message>
1652 <location filename="../base/encoderrbspeex.cpp" line="34"/>
1653 <source>Volume:</source>
1654 <translation type="unfinished"></translation>
1655 </message>
1656 <message>
1657 <location filename="../base/encoderrbspeex.cpp" line="36"/>
1658 <source>Quality:</source>
1659 <translation type="unfinished"></translation>
1660 </message>
1661 <message>
1662 <location filename="../base/encoderrbspeex.cpp" line="38"/>
1663 <source>Complexity:</source>
1664 <translation type="unfinished"></translation>
1665 </message>
1666 <message>
1667 <location filename="../base/encoderrbspeex.cpp" line="40"/>
1668 <source>Use Narrowband:</source>
1669 <translation type="unfinished"></translation>
1670 </message>
1671</context>
1672<context>
1673 <name>InfoWidget</name>
1674 <message>
1675 <location filename="../gui/infowidget.cpp" line="30"/>
1676 <location filename="../gui/infowidget.cpp" line="107"/>
1677 <source>File</source>
1678 <translation type="unfinished">Ficheiro</translation>
1679 </message>
1680 <message>
1681 <location filename="../gui/infowidget.cpp" line="30"/>
1682 <location filename="../gui/infowidget.cpp" line="107"/>
1683 <source>Version</source>
1684 <translation type="unfinished">Versão</translation>
1685 </message>
1686</context>
1687<context>
1688 <name>InfoWidgetFrm</name>
1689 <message>
1690 <location filename="../gui/infowidgetfrm.ui" line="14"/>
1691 <source>Info</source>
1692 <translation type="unfinished">Informação</translation>
1693 </message>
1694 <message>
1695 <location filename="../gui/infowidgetfrm.ui" line="20"/>
1696 <source>Currently installed packages.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; if you manually installed packages this might not be correct!</source>
1697 <translation type="unfinished">Pacotes actualmente instalados.&lt;br/&gt;&lt;b&gt;Nota:&lt;/b&gt; se instalou manualmente pacotes, isto pode não estar correcto!</translation>
1698 </message>
1699 <message>
1700 <location filename="../gui/infowidgetfrm.ui" line="34"/>
1701 <source>Package</source>
1702 <translation type="unfinished"></translation>
1703 </message>
1704</context>
1705<context>
1706 <name>InstallTalkFrm</name>
1707 <message>
1708 <location filename="../installtalkfrm.ui" line="17"/>
1709 <source>Install Talk Files</source>
1710 <translation>Instalar Ficheiros de Leitura</translation>
1711 </message>
1712 <message>
1713 <location filename="../installtalkfrm.ui" line="52"/>
1714 <source>Generate for files</source>
1715 <translation type="unfinished"></translation>
1716 </message>
1717 <message>
1718 <location filename="../installtalkfrm.ui" line="78"/>
1719 <source>TTS profile:</source>
1720 <translation>Perfil TTS:</translation>
1721 </message>
1722 <message>
1723 <location filename="../installtalkfrm.ui" line="85"/>
1724 <source>Generate for folders</source>
1725 <translation type="unfinished"></translation>
1726 </message>
1727 <message>
1728 <location filename="../installtalkfrm.ui" line="95"/>
1729 <source>Recurse into folders</source>
1730 <translation type="unfinished"></translation>
1731 </message>
1732 <message>
1733 <location filename="../installtalkfrm.ui" line="111"/>
1734 <source>Change</source>
1735 <translation>Alterar</translation>
1736 </message>
1737 <message>
1738 <location filename="../installtalkfrm.ui" line="118"/>
1739 <source>Ignore files</source>
1740 <translation type="unfinished"></translation>
1741 </message>
1742 <message>
1743 <location filename="../installtalkfrm.ui" line="128"/>
1744 <source>Skip existing</source>
1745 <translation type="unfinished"></translation>
1746 </message>
1747 <message>
1748 <location filename="../installtalkfrm.ui" line="170"/>
1749 <source>Select folders for Talkfile generation (Ctrl for multiselect)</source>
1750 <translation type="unfinished"></translation>
1751 </message>
1752 <message>
1753 <location filename="../installtalkfrm.ui" line="36"/>
1754 <source>Generation options</source>
1755 <translation>Opções de geração</translation>
1756 </message>
1757 <message>
1758 <location filename="../installtalkfrm.ui" line="42"/>
1759 <source>Strip Extensions</source>
1760 <translation>Retirar Extensões</translation>
1761 </message>
1762 <message>
1763 <location filename="../installtalkfrm.ui" line="143"/>
1764 <source>&amp;Install</source>
1765 <translation>&amp;Instalar</translation>
1766 </message>
1767 <message>
1768 <location filename="../installtalkfrm.ui" line="154"/>
1769 <source>&amp;Cancel</source>
1770 <translation>&amp;Cancelar</translation>
1771 </message>
1772</context>
1773<context>
1774 <name>InstallTalkWindow</name>
1775 <message>
1776 <location filename="../installtalkwindow.cpp" line="96"/>
1777 <source>Empty selection</source>
1778 <translation type="unfinished"></translation>
1779 </message>
1780 <message>
1781 <location filename="../installtalkwindow.cpp" line="97"/>
1782 <source>No files or folders selected. Please select files or folders first.</source>
1783 <translation type="unfinished"></translation>
1784 </message>
1785 <message>
1786 <location filename="../installtalkwindow.cpp" line="137"/>
1787 <source>TTS error</source>
1788 <translation type="unfinished"></translation>
1789 </message>
1790 <message>
1791 <location filename="../installtalkwindow.cpp" line="138"/>
1792 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1793 <translation type="unfinished"></translation>
1794 </message>
1795</context>
1796<context>
1797 <name>ManualWidget</name>
1798 <message>
1799 <location filename="../gui/manualwidget.cpp" line="44"/>
1800 <source>&lt;a href=&apos;%1&apos;&gt;PDF Manual&lt;/a&gt;</source>
1801 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Manual PDF&lt;/a&gt;</translation>
1802 </message>
1803 <message>
1804 <location filename="../gui/manualwidget.cpp" line="46"/>
1805 <source>&lt;a href=&apos;%1&apos;&gt;HTML Manual (opens in browser)&lt;/a&gt;</source>
1806 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Manual HTML (abre num navegador de internet)&lt;/a&gt;</translation>
1807 </message>
1808 <message>
1809 <location filename="../gui/manualwidget.cpp" line="50"/>
1810 <source>Select a device for a link to the correct manual</source>
1811 <translation type="unfinished">Seleccione um dispositivo para uma ligação ao manual correcto</translation>
1812 </message>
1813 <message>
1814 <location filename="../gui/manualwidget.cpp" line="51"/>
1815 <source>&lt;a href=&apos;%1&apos;&gt;Manual Overview&lt;/a&gt;</source>
1816 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Visão Geral do Manual&lt;/a&gt;</translation>
1817 </message>
1818 <message>
1819 <location filename="../gui/manualwidget.cpp" line="62"/>
1820 <source>Confirm download</source>
1821 <translation type="unfinished">Confirmar transferência</translation>
1822 </message>
1823 <message>
1824 <location filename="../gui/manualwidget.cpp" line="63"/>
1825 <source>Do you really want to download the manual? The manual will be saved to the root folder of your player.</source>
1826 <translation type="unfinished">Deseja transferir o manual? O manual será guardado na directoria raiz do reprodutor.</translation>
1827 </message>
1828</context>
1829<context>
1830 <name>ManualWidgetFrm</name>
1831 <message>
1832 <location filename="../gui/manualwidgetfrm.ui" line="14"/>
1833 <source>Manual</source>
1834 <translation type="unfinished"></translation>
1835 </message>
1836 <message>
1837 <location filename="../gui/manualwidgetfrm.ui" line="20"/>
1838 <source>Read the manual</source>
1839 <translation type="unfinished">Ler o manual</translation>
1840 </message>
1841 <message>
1842 <location filename="../gui/manualwidgetfrm.ui" line="26"/>
1843 <source>PDF manual</source>
1844 <translation type="unfinished">Manual PDF</translation>
1845 </message>
1846 <message>
1847 <location filename="../gui/manualwidgetfrm.ui" line="39"/>
1848 <source>HTML manual</source>
1849 <translation type="unfinished">Manual HTML</translation>
1850 </message>
1851 <message>
1852 <location filename="../gui/manualwidgetfrm.ui" line="55"/>
1853 <source>Download the manual</source>
1854 <translation type="unfinished">Transferir o manual</translation>
1855 </message>
1856 <message>
1857 <location filename="../gui/manualwidgetfrm.ui" line="63"/>
1858 <source>&amp;PDF version</source>
1859 <translation type="unfinished">Versão &amp;PDF</translation>
1860 </message>
1861 <message>
1862 <location filename="../gui/manualwidgetfrm.ui" line="70"/>
1863 <source>&amp;HTML version (zip file)</source>
1864 <translation type="unfinished">Versão &amp;HTML (ficheiro zip)</translation>
1865 </message>
1866 <message>
1867 <location filename="../gui/manualwidgetfrm.ui" line="92"/>
1868 <source>Down&amp;load</source>
1869 <translation type="unfinished">&amp;Transferir</translation>
1870 </message>
1871</context>
1872<context>
1873 <name>MsPackUtil</name>
1874 <message>
1875 <location filename="../base/mspackutil.cpp" line="101"/>
1876 <source>Creating output path failed</source>
1877 <translation type="unfinished"></translation>
1878 </message>
1879 <message>
1880 <location filename="../base/mspackutil.cpp" line="109"/>
1881 <source>Error during CAB operation</source>
1882 <translation type="unfinished"></translation>
1883 </message>
1884</context>
1885<context>
1886 <name>PreviewFrm</name>
1887 <message>
1888 <location filename="../previewfrm.ui" line="16"/>
1889 <source>Preview</source>
1890 <translation>Pré-Visualização</translation>
1891 </message>
1892</context>
1893<context>
1894 <name>ProgressLoggerFrm</name>
1895 <message>
1896 <location filename="../progressloggerfrm.ui" line="13"/>
1897 <location filename="../progressloggerfrm.ui" line="19"/>
1898 <source>Progress</source>
1899 <translation>Progresso</translation>
1900 </message>
1901 <message>
1902 <location filename="../progressloggerfrm.ui" line="32"/>
1903 <source>progresswindow</source>
1904 <translation>janela de progresso</translation>
1905 </message>
1906 <message>
1907 <location filename="../progressloggerfrm.ui" line="58"/>
1908 <source>Save Log</source>
1909 <translation type="unfinished"></translation>
1910 </message>
1911 <message>
1912 <location filename="../progressloggerfrm.ui" line="82"/>
1913 <source>&amp;Abort</source>
1914 <translation>&amp;Abortar</translation>
1915 </message>
1916</context>
1917<context>
1918 <name>ProgressLoggerGui</name>
1919 <message>
1920 <location filename="../progressloggergui.cpp" line="122"/>
1921 <source>&amp;Ok</source>
1922 <translation>&amp;Ok</translation>
1923 </message>
1924 <message>
1925 <location filename="../progressloggergui.cpp" line="146"/>
1926 <source>Save system trace log</source>
1927 <translation type="unfinished"></translation>
1928 </message>
1929 <message>
1930 <location filename="../progressloggergui.cpp" line="104"/>
1931 <source>&amp;Abort</source>
1932 <translation>&amp;Abortar</translation>
1933 </message>
1934</context>
1935<context>
1936 <name>QObject</name>
1937 <message>
1938 <location filename="../configure.cpp" line="625"/>
1939 <location filename="../main.cpp" line="83"/>
1940 <source>LTR</source>
1941 <extracomment>This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.
1942----------
1943This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.</extracomment>
1944 <translation type="unfinished"></translation>
1945 </message>
1946 <message>
1947 <location filename="../base/system.cpp" line="385"/>
1948 <source>(unknown vendor name) </source>
1949 <translation type="unfinished"></translation>
1950 </message>
1951 <message>
1952 <location filename="../base/system.cpp" line="403"/>
1953 <source>(unknown product name)</source>
1954 <translation type="unfinished"></translation>
1955 </message>
1956 <message>
1957 <location filename="../base/bootloaderinstallhelper.cpp" line="80"/>
1958 <source>Bootloader installation is almost complete. Installation &lt;b&gt;requires&lt;/b&gt; you to perform the following steps manually:</source>
1959 <translation type="unfinished">Instalação da rotina de arranque está quase completa. A instalação &lt;b&gt;necessita&lt;/b&gt; que faça os passos seguintes manualmente:</translation>
1960 </message>
1961 <message>
1962 <location filename="../base/bootloaderinstallhelper.cpp" line="86"/>
1963 <source>&lt;li&gt;Safely remove your player.&lt;/li&gt;</source>
1964 <translation type="unfinished">&lt;li&gt;Remova com segurança o seu reprodutor.&lt;/li&gt;</translation>
1965 </message>
1966 <message>
1967 <location filename="../base/bootloaderinstallhelper.cpp" line="91"/>
1968 <source>&lt;li&gt;Reboot your player into the original firmware.&lt;/li&gt;&lt;li&gt;Perform a firmware upgrade using the update functionality of the original firmware. Please refer to your player&apos;s manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before starting the firmware update process.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1969 <translation type="unfinished"></translation>
1970 </message>
1971 <message>
1972 <location filename="../base/bootloaderinstallhelper.cpp" line="102"/>
1973 <source>&lt;li&gt;Remove any previously inserted microSD card&lt;/li&gt;</source>
1974 <translation type="unfinished"></translation>
1975 </message>
1976 <message>
1977 <location filename="../base/bootloaderinstallhelper.cpp" line="103"/>
1978 <source>&lt;li&gt;Disconnect your player. The player will reboot and perform an update of the original firmware. Please refer to your players manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before disconnecting the player.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1979 <translation type="unfinished"></translation>
1980 </message>
1981 <message>
1982 <location filename="../base/bootloaderinstallhelper.cpp" line="114"/>
1983 <source>&lt;li&gt;Turn the player off&lt;/li&gt;&lt;li&gt;Insert the charger&lt;/li&gt;</source>
1984 <translation type="unfinished">&lt;li&gt;Desligue o reprodutor&lt;/li&gt;&lt;li&gt;Insira o carregador&lt;/li&gt;</translation>
1985 </message>
1986 <message>
1987 <location filename="../base/bootloaderinstallhelper.cpp" line="119"/>
1988 <source>&lt;li&gt;Unplug USB and power adaptors&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to turn the player off&lt;/li&gt;&lt;li&gt;Toggle the battery switch on the player&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to boot into Rockbox&lt;/li&gt;</source>
1989 <translation type="unfinished">&lt;li&gt;Desconecte o USB e carregadores&lt;/li&gt;&lt;li&gt;Pressione &lt;i&gt;Power&lt;/i&gt; para desligar o reprodutor&lt;/li&gt;&lt;li&gt;Alterne o interruptor da bateria no reprodutor&lt;/li&gt;&lt;li&gt;Pressione &lt;i&gt;Power&lt;/i&gt; para arrancar com o Rockbox&lt;/li&gt;</translation>
1990 </message>
1991 <message>
1992 <location filename="../base/bootloaderinstallhelper.cpp" line="125"/>
1993 <source>&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You can safely install other parts first, but the above steps are &lt;b&gt;required&lt;/b&gt; to finish the installation!&lt;/p&gt;</source>
1994 <translation type="unfinished">&lt;p&gt;&lt;b&gt;Nota:&lt;/b&gt; Pode instalar com segurança outras partes primeiro, mas os passos acima são &lt;b&gt;necessários&lt;/b&gt; para terminar a instalação!&lt;/p&gt;</translation>
1995 </message>
1996</context>
1997<context>
1998 <name>QuaZipFile</name>
1999 <message>
2000 <location filename="../quazip/quazipfile.cpp" line="141"/>
2001 <source>ZIP/UNZIP API error %1</source>
2002 <translation type="unfinished"></translation>
2003 </message>
2004</context>
2005<context>
2006 <name>RbUtilQt</name>
2007 <message>
2008 <location filename="../rbutilqt.cpp" line="236"/>
2009 <source>Network error</source>
2010 <translation>Erro de rede</translation>
2011 </message>
2012 <message>
2013 <location filename="../rbutilqt.cpp" line="329"/>
2014 <source>New installation</source>
2015 <translation>Nova instalação</translation>
2016 </message>
2017 <message>
2018 <location filename="../rbutilqt.cpp" line="330"/>
2019 <source>This is a new installation of Rockbox Utility, or a new version. The configuration dialog will now open to allow you to setup the program, or review your settings.</source>
2020 <translation>Esta é uma nova instalação do Rockbox Utility, ou uma nova versão. O diálogo de configuração irá agora abrir para permitir-lhe configurar o programa, ou rever as suas definições.</translation>
2021 </message>
2022 <message>
2023 <location filename="../rbutilqt.cpp" line="337"/>
2024 <location filename="../rbutilqt.cpp" line="642"/>
2025 <source>Configuration error</source>
2026 <translation>Erro de Configuração</translation>
2027 </message>
2028 <message>
2029 <location filename="../rbutilqt.cpp" line="338"/>
2030 <source>Your configuration is invalid. This is most likely due to a changed device path. The configuration dialog will now open to allow you to correct the problem.</source>
2031 <translation>A sua configuração é inválida. Isto é provalvelmente devido a uma mudança do caminho do dispositivo. O diálogo de configuração irá agora abrir para permitir-lhe corrigir o problema.</translation>
2032 </message>
2033 <message>
2034 <location filename="../rbutilqt.cpp" line="224"/>
2035 <source>Downloading build information, please wait ...</source>
2036 <translation type="unfinished"></translation>
2037 </message>
2038 <message>
2039 <location filename="../rbutilqt.cpp" line="235"/>
2040 <source>Can&apos;t get version information!</source>
2041 <translation type="unfinished"></translation>
2042 </message>
2043 <message>
2044 <location filename="../rbutilqt.cpp" line="237"/>
2045 <source>Can&apos;t get version information.
2046Network error: %1. Please check your network and proxy settings.</source>
2047 <translation type="unfinished"></translation>
2048 </message>
2049 <message>
2050 <location filename="../rbutilqt.cpp" line="249"/>
2051 <source>Download build information finished.</source>
2052 <translation type="unfinished"></translation>
2053 </message>
2054 <message>
2055 <location filename="../rbutilqt.cpp" line="450"/>
2056 <source>Confirm Installation</source>
2057 <translation>Confirmar Instalação</translation>
2058 </message>
2059 <message>
2060 <location filename="../rbutilqt.cpp" line="582"/>
2061 <source>Mount point is wrong!</source>
2062 <translation>Ponto de montagem está errado!</translation>
2063 </message>
2064 <message>
2065 <location filename="../rbutilqt.cpp" line="430"/>
2066 <source>No Rockbox installation found</source>
2067 <translation type="unfinished"></translation>
2068 </message>
2069 <message>
2070 <location filename="../rbutilqt.cpp" line="416"/>
2071 <source>Warning</source>
2072 <translation>Aviso</translation>
2073 </message>
2074 <message>
2075 <location filename="../rbutilqt.cpp" line="417"/>
2076 <source>The Application is still downloading Information about new Builds. Please try again shortly.</source>
2077 <translation>A Aplicação está ainda a transferir informação sobre novas compilações. Por favor, tente de novo em breve.</translation>
2078 </message>
2079 <message>
2080 <location filename="../rbutilqt.cpp" line="431"/>
2081 <source>Could not determine the installed Rockbox version. Please install a Rockbox build before installing voice files.</source>
2082 <translation type="unfinished"></translation>
2083 </message>
2084 <message>
2085 <location filename="../rbutilqt.cpp" line="451"/>
2086 <source>Do you really want to install the voice file?</source>
2087 <translation>Deseja instalar o ficheiro de voz?</translation>
2088 </message>
2089 <message>
2090 <location filename="../rbutilqt.cpp" line="512"/>
2091 <source>Confirm Uninstallation</source>
2092 <translation>Confirmar Desinstalação</translation>
2093 </message>
2094 <message>
2095 <location filename="../rbutilqt.cpp" line="513"/>
2096 <source>Do you really want to uninstall the Bootloader?</source>
2097 <translation>Quer mesmo desinstalar a Rotina de Arranque?</translation>
2098 </message>
2099 <message>
2100 <location filename="../rbutilqt.cpp" line="528"/>
2101 <source>No uninstall method for this target known.</source>
2102 <translation type="unfinished"></translation>
2103 </message>
2104 <message>
2105 <location filename="../rbutilqt.cpp" line="542"/>
2106 <source>Rockbox Utility can not uninstall the bootloader on this target. Try a normal firmware update to remove the booloader.</source>
2107 <translation type="unfinished"></translation>
2108 </message>
2109 <message>
2110 <location filename="../rbutilqt.cpp" line="733"/>
2111 <source>New version of Rockbox Utility available.</source>
2112 <translation type="unfinished"></translation>
2113 </message>
2114 <message>
2115 <location filename="../rbutilqt.cpp" line="736"/>
2116 <source>Rockbox Utility is up to date.</source>
2117 <translation type="unfinished"></translation>
2118 </message>
2119 <message>
2120 <location filename="../rbutilqt.cpp" line="568"/>
2121 <source>Confirm installation</source>
2122 <translation>Confirmar instalação</translation>
2123 </message>
2124 <message>
2125 <location filename="../rbutilqt.cpp" line="439"/>
2126 <source>No voice file available</source>
2127 <translation type="unfinished"></translation>
2128 </message>
2129 <message>
2130 <location filename="../rbutilqt.cpp" line="440"/>
2131 <source>The installed version of Rockbox is a development version. Pre-built voices are only available for release versions of Rockbox. Please generate a voice yourself using the &quot;Create voice file&quot; functionality.</source>
2132 <translation type="unfinished"></translation>
2133 </message>
2134 <message>
2135 <location filename="../rbutilqt.cpp" line="550"/>
2136 <source>No Rockbox bootloader found.</source>
2137 <translation type="unfinished"></translation>
2138 </message>
2139 <message>
2140 <location filename="../rbutilqt.cpp" line="569"/>
2141 <source>Do you really want to install Rockbox Utility to your player? After installation you can run it from the players hard drive.</source>
2142 <translation>Deseja instalar o Rockbox Utility no reprodutor? Após a instalação pode corrê-lo do disco rígido do reprodutor.</translation>
2143 </message>
2144 <message>
2145 <location filename="../rbutilqt.cpp" line="578"/>
2146 <source>Installing Rockbox Utility</source>
2147 <translation>Instalando Rockbox Utility</translation>
2148 </message>
2149 <message>
2150 <location filename="../rbutilqt.cpp" line="596"/>
2151 <source>Error installing Rockbox Utility</source>
2152 <translation>Erro ao instalar Rockbox Utility</translation>
2153 </message>
2154 <message>
2155 <location filename="../rbutilqt.cpp" line="600"/>
2156 <source>Installing user configuration</source>
2157 <translation>Instalando a configuração do utilizador</translation>
2158 </message>
2159 <message>
2160 <location filename="../rbutilqt.cpp" line="604"/>
2161 <source>Error installing user configuration</source>
2162 <translation>Erro ao instalar a configuração do utilizador</translation>
2163 </message>
2164 <message>
2165 <location filename="../rbutilqt.cpp" line="608"/>
2166 <source>Successfully installed Rockbox Utility.</source>
2167 <translation>Rockbox Utility instalado com sucesso.</translation>
2168 </message>
2169 <message>
2170 <location filename="../rbutilqt.cpp" line="643"/>
2171 <source>Your configuration is invalid. Please go to the configuration dialog and make sure the selected values are correct.</source>
2172 <translation>A sua configuração é inválida. Por favor, vá ao diálogo de configuração e verifique que os valores inseridos estão correctos.</translation>
2173 </message>
2174 <message>
2175 <location filename="../rbutilqt.cpp" line="664"/>
2176 <source>Checking for update ...</source>
2177 <translation type="unfinished"></translation>
2178 </message>
2179 <message>
2180 <location filename="../rbutilqt.cpp" line="729"/>
2181 <source>RockboxUtility Update available</source>
2182 <translation type="unfinished"></translation>
2183 </message>
2184 <message>
2185 <location filename="../rbutilqt.cpp" line="730"/>
2186 <source>&lt;b&gt;New RockboxUtility Version available.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Download it from here: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</source>
2187 <translation type="unfinished"></translation>
2188 </message>
2189 <message>
2190 <location filename="../rbutilqt.cpp" line="759"/>
2191 <source>Device ejected</source>
2192 <translation type="unfinished"></translation>
2193 </message>
2194 <message>
2195 <location filename="../rbutilqt.cpp" line="760"/>
2196 <source>Device successfully ejected. You may now disconnect the player from the PC.</source>
2197 <translation type="unfinished"></translation>
2198 </message>
2199 <message>
2200 <location filename="../rbutilqt.cpp" line="764"/>
2201 <source>Ejecting failed</source>
2202 <translation type="unfinished"></translation>
2203 </message>
2204 <message>
2205 <location filename="../rbutilqt.cpp" line="765"/>
2206 <source>Ejecting the device failed. Please make sure no programs are accessing files on the device. If ejecting still fails please use your computers eject funtionality.</source>
2207 <translation type="unfinished"></translation>
2208 </message>
2209 <message>
2210 <location filename="../rbutilqt.cpp" line="110"/>
2211 <source>Wine detected!</source>
2212 <translation type="unfinished"></translation>
2213 </message>
2214 <message>
2215 <location filename="../rbutilqt.cpp" line="111"/>
2216 <source>It seems you are trying to run this program under Wine. Please don&apos;t do this, running under Wine will fail. Use the native Linux binary instead.</source>
2217 <translation type="unfinished"></translation>
2218 </message>
2219</context>
2220<context>
2221 <name>RbUtilQtFrm</name>
2222 <message>
2223 <location filename="../rbutilqtfrm.ui" line="14"/>
2224 <source>Rockbox Utility</source>
2225 <translation>Rockbox Utility</translation>
2226 </message>
2227 <message>
2228 <location filename="../rbutilqtfrm.ui" line="31"/>
2229 <source>Device</source>
2230 <translation>Dispositivo</translation>
2231 </message>
2232 <message>
2233 <location filename="../rbutilqtfrm.ui" line="92"/>
2234 <source>&amp;Change</source>
2235 <translation>A&amp;lterar</translation>
2236 </message>
2237 <message>
2238 <location filename="../rbutilqtfrm.ui" line="163"/>
2239 <source>Welcome</source>
2240 <translation>Bem-Vindo</translation>
2241 </message>
2242 <message>
2243 <location filename="../rbutilqtfrm.ui" line="160"/>
2244 <location filename="../rbutilqtfrm.ui" line="658"/>
2245 <source>&amp;Installation</source>
2246 <translation>&amp;Instalação</translation>
2247 </message>
2248 <message>
2249 <location filename="../rbutilqtfrm.ui" line="168"/>
2250 <location filename="../rbutilqtfrm.ui" line="450"/>
2251 <source>&amp;Accessibility</source>
2252 <translation>&amp;Acessibilidade</translation>
2253 </message>
2254 <message>
2255 <location filename="../rbutilqtfrm.ui" line="171"/>
2256 <source>Install accessibility add-ons</source>
2257 <translation>Instalar extensões de acessibilidade</translation>
2258 </message>
2259 <message>
2260 <location filename="../rbutilqtfrm.ui" line="177"/>
2261 <source>Install Voice files</source>
2262 <translation>Instalar Ficheiros de Voz</translation>
2263 </message>
2264 <message>
2265 <location filename="../rbutilqtfrm.ui" line="194"/>
2266 <source>&lt;b&gt;Install Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so if you installed the voice file Rockbox will speak.</source>
2267 <translation>&lt;b&gt;Instalar ficheiro de Voz&lt;/b&gt;&lt;br/&gt;Ficherios de Voz são necessários para fazer o Rockbox ler a interface do utilizador. Falar está activo por omissão, portanto se instalou o ficheiro de voz, o Rockbox irá falar.</translation>
2268 </message>
2269 <message>
2270 <location filename="../rbutilqtfrm.ui" line="204"/>
2271 <source>Install Talk files</source>
2272 <translation>Instalar Ficheiros de Leitura</translation>
2273 </message>
2274 <message>
2275 <location filename="../rbutilqtfrm.ui" line="221"/>
2276 <source>&lt;b&gt;Create Talk Files&lt;/b&gt;&lt;br/&gt;Talkfiles are needed to let Rockbox speak File and Foldernames</source>
2277 <translation>&lt;b&gt;Criar Ficheiros de Leitura&lt;/b&gt;&lt;br/&gt;Ficheiros de Leitura são necessários para deixar o Rockbox ler Ficheiros e nomes de Directorias</translation>
2278 </message>
2279 <message>
2280 <location filename="../rbutilqtfrm.ui" line="254"/>
2281 <source>Create Voice files</source>
2282 <translation>Criar Ficheiros de Voz</translation>
2283 </message>
2284 <message>
2285 <location filename="../rbutilqtfrm.ui" line="271"/>
2286 <source>&lt;b&gt;Create Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so
2287 if you installed the voice file Rockbox will speak.</source>
2288 <translation>&lt;b&gt;Criar ficheiro de Voz&lt;/b&gt;&lt;br/&gt;Ficherios de Voz são necessários para fazer o Rockbox ler a interface do utilizador. Falar está activo por omissão, portanto
2289se instalou o ficheiro de voz, o Rockbox irá falar.</translation>
2290 </message>
2291 <message>
2292 <location filename="../rbutilqtfrm.ui" line="458"/>
2293 <source>&amp;Uninstallation</source>
2294 <translation>Desinstala&amp;ção</translation>
2295 </message>
2296 <message>
2297 <location filename="../rbutilqtfrm.ui" line="286"/>
2298 <location filename="../rbutilqtfrm.ui" line="319"/>
2299 <source>Uninstall Rockbox</source>
2300 <translation>Desinstalar Rockbox</translation>
2301 </message>
2302 <message>
2303 <location filename="../rbutilqtfrm.ui" line="121"/>
2304 <source>mountpoint unknown or invalid</source>
2305 <translation type="unfinished"></translation>
2306 </message>
2307 <message>
2308 <location filename="../rbutilqtfrm.ui" line="114"/>
2309 <source>Mountpoint:</source>
2310 <translation type="unfinished"></translation>
2311 </message>
2312 <message>
2313 <location filename="../rbutilqtfrm.ui" line="72"/>
2314 <source>device unknown or invalid</source>
2315 <translation type="unfinished"></translation>
2316 </message>
2317 <message>
2318 <location filename="../rbutilqtfrm.ui" line="65"/>
2319 <source>Device:</source>
2320 <translation type="unfinished"></translation>
2321 </message>
2322 <message>
2323 <location filename="../rbutilqtfrm.ui" line="283"/>
2324 <source>Backup &amp;&amp; &amp;Uninstallation</source>
2325 <translation type="unfinished"></translation>
2326 </message>
2327 <message>
2328 <location filename="../rbutilqtfrm.ui" line="292"/>
2329 <source>Uninstall Bootloader</source>
2330 <translation>Desinstalar rotina de arranque</translation>
2331 </message>
2332 <message>
2333 <location filename="../rbutilqtfrm.ui" line="309"/>
2334 <source>&lt;b&gt;Remove the bootloader&lt;/b&gt;&lt;br/&gt;After removing the bootloader you won&apos;t be able to start Rockbox.</source>
2335 <translation>&lt;b&gt;Remover a rotina de arranque&lt;/b&gt;&lt;br/&gt;Depois de remover a rotina de arranque não poderá iniciar o Rockbox.</translation>
2336 </message>
2337 <message>
2338 <location filename="../rbutilqtfrm.ui" line="336"/>
2339 <source>&lt;b&gt;Uninstall Rockbox from your audio player.&lt;/b&gt;&lt;br/&gt;This will leave the bootloader in place (you need to remove it manually).</source>
2340 <translation>&lt;b&gt;Desinstalar Rockbox do reprodutor de música.&lt;/b&gt;&lt;br/&gt;Isto irá deixar a rotina de arranque no sítio (terá de removê-la manualmente).</translation>
2341 </message>
2342 <message>
2343 <location filename="../rbutilqtfrm.ui" line="349"/>
2344 <source>Backup</source>
2345 <translation type="unfinished">Cópia de Segurança</translation>
2346 </message>
2347 <message>
2348 <location filename="../rbutilqtfrm.ui" line="366"/>
2349 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup current installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Create a backup by archiving the contents of the Rockbox installation folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2350 <translation type="unfinished"></translation>
2351 </message>
2352 <message>
2353 <location filename="../rbutilqtfrm.ui" line="393"/>
2354 <source>&amp;Manual</source>
2355 <translation>&amp;Manual</translation>
2356 </message>
2357 <message>
2358 <location filename="../rbutilqtfrm.ui" line="396"/>
2359 <source>View and download the manual</source>
2360 <translation>Ver e transferir o manual</translation>
2361 </message>
2362 <message>
2363 <location filename="../rbutilqtfrm.ui" line="401"/>
2364 <source>Inf&amp;o</source>
2365 <translation>Inf&amp;ormação</translation>
2366 </message>
2367 <message>
2368 <location filename="../rbutilqtfrm.ui" line="419"/>
2369 <source>&amp;File</source>
2370 <translation>&amp;Ficheiro</translation>
2371 </message>
2372 <message>
2373 <location filename="../rbutilqtfrm.ui" line="653"/>
2374 <source>System &amp;Trace</source>
2375 <translation type="unfinished"></translation>
2376 </message>
2377 <message>
2378 <location filename="../rbutilqtfrm.ui" line="446"/>
2379 <source>Action&amp;s</source>
2380 <translation>Acçõe&amp;s</translation>
2381 </message>
2382 <message>
2383 <location filename="../rbutilqtfrm.ui" line="474"/>
2384 <source>Empty local download cache</source>
2385 <translation></translation>
2386 </message>
2387 <message>
2388 <location filename="../rbutilqtfrm.ui" line="479"/>
2389 <source>Install Rockbox Utility on player</source>
2390 <translation>Instalar o Rockbox Utility no reprodutor</translation>
2391 </message>
2392 <message>
2393 <location filename="../rbutilqtfrm.ui" line="484"/>
2394 <source>&amp;Configure</source>
2395 <translation>&amp;Configurar</translation>
2396 </message>
2397 <message>
2398 <location filename="../rbutilqtfrm.ui" line="489"/>
2399 <source>E&amp;xit</source>
2400 <translation>Sai&amp;r</translation>
2401 </message>
2402 <message>
2403 <location filename="../rbutilqtfrm.ui" line="492"/>
2404 <source>Ctrl+Q</source>
2405 <translation>Ctrl+Q</translation>
2406 </message>
2407 <message>
2408 <location filename="../rbutilqtfrm.ui" line="497"/>
2409 <source>&amp;About</source>
2410 <translation>S&amp;obre</translation>
2411 </message>
2412 <message>
2413 <location filename="../rbutilqtfrm.ui" line="502"/>
2414 <source>About &amp;Qt</source>
2415 <translation>Sobre &amp;Qt</translation>
2416 </message>
2417 <message>
2418 <location filename="../rbutilqtfrm.ui" line="428"/>
2419 <location filename="../rbutilqtfrm.ui" line="507"/>
2420 <source>&amp;Help</source>
2421 <translation>&amp;Ajuda</translation>
2422 </message>
2423 <message>
2424 <location filename="../rbutilqtfrm.ui" line="103"/>
2425 <source>&amp;Eject</source>
2426 <translation type="unfinished"></translation>
2427 </message>
2428 <message>
2429 <location filename="../rbutilqtfrm.ui" line="432"/>
2430 <source>&amp;Troubleshoot</source>
2431 <translation type="unfinished"></translation>
2432 </message>
2433 <message>
2434 <location filename="../rbutilqtfrm.ui" line="512"/>
2435 <source>Info</source>
2436 <translation>Informação</translation>
2437 </message>
2438 <message>
2439 <location filename="../rbutilqtfrm.ui" line="521"/>
2440 <source>&amp;Complete Installation</source>
2441 <translation>Instalação &amp;Completa</translation>
2442 </message>
2443 <message>
2444 <location filename="../rbutilqtfrm.ui" line="530"/>
2445 <source>&amp;Minimal Installation</source>
2446 <translation>Instalação &amp;Mínima</translation>
2447 </message>
2448 <message>
2449 <location filename="../rbutilqtfrm.ui" line="539"/>
2450 <source>Install &amp;Bootloader</source>
2451 <translation>Instalar Rotina &amp;de Arranque</translation>
2452 </message>
2453 <message>
2454 <location filename="../rbutilqtfrm.ui" line="548"/>
2455 <source>Install &amp;Rockbox</source>
2456 <translation>Instalar &amp;Rockbox</translation>
2457 </message>
2458 <message>
2459 <location filename="../rbutilqtfrm.ui" line="557"/>
2460 <source>Install &amp;Fonts Package</source>
2461 <translation>Instalar pacote de &amp;fontes</translation>
2462 </message>
2463 <message>
2464 <location filename="../rbutilqtfrm.ui" line="566"/>
2465 <source>Install &amp;Themes</source>
2466 <translation>Instalar &amp;temas</translation>
2467 </message>
2468 <message>
2469 <location filename="../rbutilqtfrm.ui" line="575"/>
2470 <source>Install &amp;Game Files</source>
2471 <translation>Instalar Ficheiros de &amp;Jogo</translation>
2472 </message>
2473 <message>
2474 <location filename="../rbutilqtfrm.ui" line="584"/>
2475 <source>&amp;Install Voice File</source>
2476 <translation>&amp;Instalar Ficheiro de Voz</translation>
2477 </message>
2478 <message>
2479 <location filename="../rbutilqtfrm.ui" line="593"/>
2480 <source>Create &amp;Talk Files</source>
2481 <translation>Criar Ficheiros de &amp;Leitura</translation>
2482 </message>
2483 <message>
2484 <location filename="../rbutilqtfrm.ui" line="602"/>
2485 <source>Remove &amp;bootloader</source>
2486 <translation>Remover rotina de arran&amp;que</translation>
2487 </message>
2488 <message>
2489 <location filename="../rbutilqtfrm.ui" line="611"/>
2490 <source>Uninstall &amp;Rockbox</source>
2491 <translation>Desinstalar &amp;Rockbox</translation>
2492 </message>
2493 <message>
2494 <location filename="../rbutilqtfrm.ui" line="616"/>
2495 <source>Read PDF manual</source>
2496 <translation>Ler manual PDF</translation>
2497 </message>
2498 <message>
2499 <location filename="../rbutilqtfrm.ui" line="621"/>
2500 <source>Read HTML manual</source>
2501 <translation>Ler manual HTML</translation>
2502 </message>
2503 <message>
2504 <location filename="../rbutilqtfrm.ui" line="626"/>
2505 <source>Download PDF manual</source>
2506 <translation>Transferir manual PDF</translation>
2507 </message>
2508 <message>
2509 <location filename="../rbutilqtfrm.ui" line="631"/>
2510 <source>Download HTML manual (zip)</source>
2511 <translation>Transferir manual HTML (zip)</translation>
2512 </message>
2513 <message>
2514 <location filename="../rbutilqtfrm.ui" line="640"/>
2515 <source>Create &amp;Voice File</source>
2516 <translation>Criar Ficheiro de &amp;Voz</translation>
2517 </message>
2518 <message>
2519 <location filename="../rbutilqtfrm.ui" line="643"/>
2520 <source>Create Voice File</source>
2521 <translation>Criar Ficheiro de Voz</translation>
2522 </message>
2523 <message>
2524 <location filename="../rbutilqtfrm.ui" line="648"/>
2525 <source>&amp;System Info</source>
2526 <translation>Informação do &amp;sistema</translation>
2527 </message>
2528 <message>
2529 <location filename="../rbutilqtfrm.ui" line="663"/>
2530 <source>Show &amp;Changelog</source>
2531 <translation type="unfinished"></translation>
2532 </message>
2533</context>
2534<context>
2535 <name>SelectiveInstallWidget</name>
2536 <message>
2537 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="20"/>
2538 <source>Selective Installation</source>
2539 <translation type="unfinished"></translation>
2540 </message>
2541 <message>
2542 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="26"/>
2543 <source>Rockbox version to install</source>
2544 <translation type="unfinished"></translation>
2545 </message>
2546 <message>
2547 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="35"/>
2548 <source>Version information not available yet.</source>
2549 <translation type="unfinished"></translation>
2550 </message>
2551 <message>
2552 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="54"/>
2553 <source>Rockbox components to install</source>
2554 <translation type="unfinished"></translation>
2555 </message>
2556 <message>
2557 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="60"/>
2558 <source>&amp;Bootloader</source>
2559 <translation type="unfinished"></translation>
2560 </message>
2561 <message>
2562 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="80"/>
2563 <source>The main Rockbox firmware.</source>
2564 <translation type="unfinished"></translation>
2565 </message>
2566 <message>
2567 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="90"/>
2568 <source>Fonts</source>
2569 <translation type="unfinished"></translation>
2570 </message>
2571 <message>
2572 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="104"/>
2573 <source>&amp;Rockbox</source>
2574 <translation type="unfinished"></translation>
2575 </message>
2576 <message>
2577 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="124"/>
2578 <source>Some game plugins require additional files.</source>
2579 <translation type="unfinished"></translation>
2580 </message>
2581 <message>
2582 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="140"/>
2583 <source>Additional fonts for the User Interface.</source>
2584 <translation type="unfinished"></translation>
2585 </message>
2586 <message>
2587 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="156"/>
2588 <source>The bootloader is required for starting Rockbox. Only necessary for first time install.</source>
2589 <translation type="unfinished"></translation>
2590 </message>
2591 <message>
2592 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="166"/>
2593 <source>Game Files</source>
2594 <translation type="unfinished"></translation>
2595 </message>
2596 <message>
2597 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="177"/>
2598 <source>Customize</source>
2599 <translation type="unfinished"></translation>
2600 </message>
2601 <message>
2602 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="188"/>
2603 <source>Themes</source>
2604 <translation type="unfinished"></translation>
2605 </message>
2606 <message>
2607 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="205"/>
2608 <source>Themes allow adjusting the user interface of Rockbox. Use &quot;Customize&quot; to select themes.</source>
2609 <translation type="unfinished"></translation>
2610 </message>
2611 <message>
2612 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="250"/>
2613 <source>&amp;Install</source>
2614 <translation type="unfinished">&amp;Instalar</translation>
2615 </message>
2616 <message>
2617 <location filename="../gui/selectiveinstallwidget.cpp" line="67"/>
2618 <source>This is the latest stable release available.</source>
2619 <translation type="unfinished"></translation>
2620 </message>
2621 <message>
2622 <location filename="../gui/selectiveinstallwidget.cpp" line="70"/>
2623 <source>The development version is updated on every code change. Last update was on %1</source>
2624 <translation type="unfinished"></translation>
2625 </message>
2626 <message>
2627 <location filename="../gui/selectiveinstallwidget.cpp" line="74"/>
2628 <source>This will eventually become the next Rockbox version. Install it to help testing.</source>
2629 <translation type="unfinished"></translation>
2630 </message>
2631 <message>
2632 <location filename="../gui/selectiveinstallwidget.cpp" line="100"/>
2633 <source>Stable Release (Version %1)</source>
2634 <translation type="unfinished"></translation>
2635 </message>
2636 <message>
2637 <location filename="../gui/selectiveinstallwidget.cpp" line="104"/>
2638 <source>Development Version (Revison %1)</source>
2639 <translation type="unfinished"></translation>
2640 </message>
2641 <message>
2642 <location filename="../gui/selectiveinstallwidget.cpp" line="108"/>
2643 <source>Release Candidate (Revison %1)</source>
2644 <translation type="unfinished"></translation>
2645 </message>
2646 <message>
2647 <location filename="../gui/selectiveinstallwidget.cpp" line="131"/>
2648 <source>The selected player doesn&apos;t need a bootloader.</source>
2649 <translation type="unfinished"></translation>
2650 </message>
2651 <message>
2652 <location filename="../gui/selectiveinstallwidget.cpp" line="136"/>
2653 <source>The bootloader is required for starting Rockbox. Installation of the bootloader is only necessary on first time installation.</source>
2654 <translation type="unfinished"></translation>
2655 </message>
2656 <message>
2657 <location filename="../gui/selectiveinstallwidget.cpp" line="183"/>
2658 <source>Mountpoint is wrong</source>
2659 <translation type="unfinished"></translation>
2660 </message>
2661 <message>
2662 <location filename="../gui/selectiveinstallwidget.cpp" line="239"/>
2663 <source>No install method known.</source>
2664 <translation type="unfinished">Nenhum método de instalação conhecido.</translation>
2665 </message>
2666 <message>
2667 <location filename="../gui/selectiveinstallwidget.cpp" line="266"/>
2668 <source>Bootloader detected</source>
2669 <translation type="unfinished">Rotina de arranque detectada</translation>
2670 </message>
2671 <message>
2672 <location filename="../gui/selectiveinstallwidget.cpp" line="267"/>
2673 <source>Bootloader already installed. Do you want to reinstall the bootloader?</source>
2674 <translation type="unfinished">Rotina de arranque já instalada. Deseja reinstalá-la?</translation>
2675 </message>
2676 <message>
2677 <location filename="../gui/selectiveinstallwidget.cpp" line="271"/>
2678 <source>Bootloader installation skipped</source>
2679 <translation type="unfinished"></translation>
2680 </message>
2681 <message>
2682 <location filename="../gui/selectiveinstallwidget.cpp" line="284"/>
2683 <source>Create Bootloader backup</source>
2684 <translation type="unfinished">Criar cópia de segurança da rotina de arranque</translation>
2685 </message>
2686 <message>
2687 <location filename="../gui/selectiveinstallwidget.cpp" line="285"/>
2688 <source>You can create a backup of the original bootloader file. Press &quot;Yes&quot; to select an output folder on your computer to save the file to. The file will get placed in a new folder &quot;%1&quot; created below the selected folder.
2689Press &quot;No&quot; to skip this step.</source>
2690 <translation type="unfinished">Pde criar uma cópia de segurança da rotina original de arranque. Pressione &quot;Sim&quot; para seleccionar uma directoria de saída no computador para guardar a cópia. O ficheiro será colocado numa nova directoria &quot;%1&quot; criada dentro da directoria seleccionada.
2691Pressione &quot;No&quot; para passar este passo.</translation>
2692 </message>
2693 <message>
2694 <location filename="../gui/selectiveinstallwidget.cpp" line="292"/>
2695 <source>Browse backup folder</source>
2696 <translation type="unfinished">Explorar directoria de cópias de segurança</translation>
2697 </message>
2698 <message>
2699 <location filename="../gui/selectiveinstallwidget.cpp" line="304"/>
2700 <source>Prerequisites</source>
2701 <translation type="unfinished">Pré-requesitos</translation>
2702 </message>
2703 <message>
2704 <location filename="../gui/selectiveinstallwidget.cpp" line="309"/>
2705 <source>Bootloader installation aborted</source>
2706 <translation type="unfinished"></translation>
2707 </message>
2708 <message>
2709 <location filename="../gui/selectiveinstallwidget.cpp" line="319"/>
2710 <source>Bootloader files (%1)</source>
2711 <translation type="unfinished"></translation>
2712 </message>
2713 <message>
2714 <location filename="../gui/selectiveinstallwidget.cpp" line="321"/>
2715 <source>All files (*)</source>
2716 <translation type="unfinished"></translation>
2717 </message>
2718 <message>
2719 <location filename="../gui/selectiveinstallwidget.cpp" line="323"/>
2720 <source>Select firmware file</source>
2721 <translation type="unfinished">Seleccione ficheiro de firmware</translation>
2722 </message>
2723 <message>
2724 <location filename="../gui/selectiveinstallwidget.cpp" line="325"/>
2725 <source>Error opening firmware file</source>
2726 <translation type="unfinished">Erro ao abrir o ficheiro de firmware</translation>
2727 </message>
2728 <message>
2729 <location filename="../gui/selectiveinstallwidget.cpp" line="331"/>
2730 <source>Error reading firmware file</source>
2731 <translation type="unfinished"></translation>
2732 </message>
2733 <message>
2734 <location filename="../gui/selectiveinstallwidget.cpp" line="341"/>
2735 <source>Backup error</source>
2736 <translation type="unfinished">Erro na cópia de segurança</translation>
2737 </message>
2738 <message>
2739 <location filename="../gui/selectiveinstallwidget.cpp" line="342"/>
2740 <source>Could not create backup file. Continue?</source>
2741 <translation type="unfinished">Falha na criação da cópia de segurança. Continuar?</translation>
2742 </message>
2743 <message>
2744 <location filename="../gui/selectiveinstallwidget.cpp" line="366"/>
2745 <source>Manual steps required</source>
2746 <translation type="unfinished">Passos manuais necessários</translation>
2747 </message>
2748 <message>
2749 <location filename="../gui/selectiveinstallwidget.cpp" line="171"/>
2750 <source>Continue with installation?</source>
2751 <translation type="unfinished"></translation>
2752 </message>
2753 <message>
2754 <location filename="../gui/selectiveinstallwidget.cpp" line="172"/>
2755 <source>Really continue?</source>
2756 <translation type="unfinished">Quer mesmo continuar?</translation>
2757 </message>
2758 <message>
2759 <source>Aborted!</source>
2760 <translation type="obsolete">Abortado!</translation>
2761 </message>
2762 <message>
2763 <location filename="../gui/selectiveinstallwidget.cpp" line="490"/>
2764 <source>Your installation doesn&apos;t require game files, skipping.</source>
2765 <translation type="unfinished"></translation>
2766 </message>
2767</context>
2768<context>
2769 <name>ServerInfo</name>
2770 <message>
2771 <location filename="../base/serverinfo.cpp" line="117"/>
2772 <source>Unknown</source>
2773 <translation type="unfinished"></translation>
2774 </message>
2775 <message>
2776 <location filename="../base/serverinfo.cpp" line="121"/>
2777 <source>Unusable</source>
2778 <translation type="unfinished"></translation>
2779 </message>
2780 <message>
2781 <location filename="../base/serverinfo.cpp" line="124"/>
2782 <source>Unstable</source>
2783 <translation type="unfinished"></translation>
2784 </message>
2785 <message>
2786 <location filename="../base/serverinfo.cpp" line="127"/>
2787 <source>Stable</source>
2788 <translation type="unfinished"></translation>
2789 </message>
2790</context>
2791<context>
2792 <name>SysTrace</name>
2793 <message>
2794 <location filename="../systrace.cpp" line="98"/>
2795 <location filename="../systrace.cpp" line="107"/>
2796 <source>Save system trace log</source>
2797 <translation type="unfinished"></translation>
2798 </message>
2799</context>
2800<context>
2801 <name>SysTraceFrm</name>
2802 <message>
2803 <location filename="../systracefrm.ui" line="14"/>
2804 <source>System Trace</source>
2805 <translation type="unfinished"></translation>
2806 </message>
2807 <message>
2808 <location filename="../systracefrm.ui" line="20"/>
2809 <source>System State trace</source>
2810 <translation type="unfinished"></translation>
2811 </message>
2812 <message>
2813 <location filename="../systracefrm.ui" line="46"/>
2814 <source>&amp;Close</source>
2815 <translation type="unfinished"></translation>
2816 </message>
2817 <message>
2818 <location filename="../systracefrm.ui" line="57"/>
2819 <source>&amp;Save</source>
2820 <translation type="unfinished"></translation>
2821 </message>
2822 <message>
2823 <location filename="../systracefrm.ui" line="68"/>
2824 <source>&amp;Refresh</source>
2825 <translation type="unfinished">Actualizar</translation>
2826 </message>
2827 <message>
2828 <location filename="../systracefrm.ui" line="79"/>
2829 <source>Save &amp;previous</source>
2830 <translation type="unfinished"></translation>
2831 </message>
2832</context>
2833<context>
2834 <name>Sysinfo</name>
2835 <message>
2836 <location filename="../sysinfo.cpp" line="45"/>
2837 <source>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</source>
2838 <translation>&lt;b&gt;Sistema Operativo&lt;/b&gt;&lt;br/&gt;</translation>
2839 </message>
2840 <message>
2841 <location filename="../sysinfo.cpp" line="46"/>
2842 <source>&lt;b&gt;Username&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2843 <translation>&lt;b&gt;Utilizador&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2844 </message>
2845 <message>
2846 <location filename="../sysinfo.cpp" line="48"/>
2847 <source>&lt;b&gt;Permissions&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2848 <translation>&lt;b&gt;Permissões&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2849 </message>
2850 <message>
2851 <location filename="../sysinfo.cpp" line="50"/>
2852 <source>&lt;b&gt;Attached USB devices&lt;/b&gt;&lt;br/&gt;</source>
2853 <translation>&lt;b&gt;Dispositivos USB conectados&lt;/b&gt;&lt;br/&gt;</translation>
2854 </message>
2855 <message>
2856 <location filename="../sysinfo.cpp" line="54"/>
2857 <source>VID: %1 PID: %2, %3</source>
2858 <translation>VID: %1 PID: %2, %3</translation>
2859 </message>
2860 <message>
2861 <location filename="../sysinfo.cpp" line="63"/>
2862 <source>Filesystem</source>
2863 <translation>Sistema de Ficheiros</translation>
2864 </message>
2865 <message>
2866 <location filename="../sysinfo.cpp" line="66"/>
2867 <source>Mountpoint</source>
2868 <translation type="unfinished"></translation>
2869 </message>
2870 <message>
2871 <location filename="../sysinfo.cpp" line="66"/>
2872 <source>Label</source>
2873 <translation type="unfinished"></translation>
2874 </message>
2875 <message>
2876 <location filename="../sysinfo.cpp" line="67"/>
2877 <source>Free</source>
2878 <translation type="unfinished"></translation>
2879 </message>
2880 <message>
2881 <location filename="../sysinfo.cpp" line="67"/>
2882 <source>Total</source>
2883 <translation type="unfinished"></translation>
2884 </message>
2885 <message>
2886 <location filename="../sysinfo.cpp" line="68"/>
2887 <source>Cluster Size</source>
2888 <translation type="unfinished"></translation>
2889 </message>
2890 <message>
2891 <location filename="../sysinfo.cpp" line="70"/>
2892 <source>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</source>
2893 <translation type="unfinished"></translation>
2894 </message>
2895</context>
2896<context>
2897 <name>SysinfoFrm</name>
2898 <message>
2899 <location filename="../sysinfofrm.ui" line="13"/>
2900 <source>System Info</source>
2901 <translation>Informação do sistema</translation>
2902 </message>
2903 <message>
2904 <location filename="../sysinfofrm.ui" line="22"/>
2905 <source>&amp;Refresh</source>
2906 <translation>Actualizar</translation>
2907 </message>
2908 <message>
2909 <location filename="../sysinfofrm.ui" line="45"/>
2910 <source>&amp;OK</source>
2911 <translation>&amp;Ok</translation>
2912 </message>
2913</context>
2914<context>
2915 <name>System</name>
2916 <message>
2917 <location filename="../base/system.cpp" line="121"/>
2918 <source>Guest</source>
2919 <translation type="unfinished">Convidado</translation>
2920 </message>
2921 <message>
2922 <location filename="../base/system.cpp" line="124"/>
2923 <source>Admin</source>
2924 <translation type="unfinished">Administrador</translation>
2925 </message>
2926 <message>
2927 <location filename="../base/system.cpp" line="127"/>
2928 <source>User</source>
2929 <translation type="unfinished">Utilizador</translation>
2930 </message>
2931 <message>
2932 <location filename="../base/system.cpp" line="130"/>
2933 <source>Error</source>
2934 <translation type="unfinished">Erro</translation>
2935 </message>
2936 <message>
2937 <location filename="../base/system.cpp" line="278"/>
2938 <location filename="../base/system.cpp" line="323"/>
2939 <source>(no description available)</source>
2940 <translation type="unfinished">(sem descrição disponível)</translation>
2941 </message>
2942</context>
2943<context>
2944 <name>TTSBase</name>
2945 <message>
2946 <location filename="../base/ttsbase.cpp" line="45"/>
2947 <source>Espeak TTS Engine</source>
2948 <translation type="unfinished"></translation>
2949 </message>
2950 <message>
2951 <location filename="../base/ttsbase.cpp" line="47"/>
2952 <source>Flite TTS Engine</source>
2953 <translation type="unfinished"></translation>
2954 </message>
2955 <message>
2956 <location filename="../base/ttsbase.cpp" line="48"/>
2957 <source>Swift TTS Engine</source>
2958 <translation type="unfinished"></translation>
2959 </message>
2960 <message>
2961 <location filename="../base/ttsbase.cpp" line="51"/>
2962 <source>SAPI4 TTS Engine</source>
2963 <translation type="unfinished"></translation>
2964 </message>
2965 <message>
2966 <location filename="../base/ttsbase.cpp" line="53"/>
2967 <source>SAPI5 TTS Engine</source>
2968 <translation type="unfinished"></translation>
2969 </message>
2970 <message>
2971 <location filename="../base/ttsbase.cpp" line="54"/>
2972 <source>MS Speech Platform</source>
2973 <translation type="unfinished"></translation>
2974 </message>
2975 <message>
2976 <location filename="../base/ttsbase.cpp" line="57"/>
2977 <source>Festival TTS Engine</source>
2978 <translation type="unfinished"></translation>
2979 </message>
2980 <message>
2981 <location filename="../base/ttsbase.cpp" line="60"/>
2982 <source>OS X System Engine</source>
2983 <translation type="unfinished"></translation>
2984 </message>
2985</context>
2986<context>
2987 <name>TTSCarbon</name>
2988 <message>
2989 <location filename="../base/ttscarbon.cpp" line="139"/>
2990 <source>Voice:</source>
2991 <translation type="unfinished"></translation>
2992 </message>
2993 <message>
2994 <location filename="../base/ttscarbon.cpp" line="145"/>
2995 <source>Speed (words/min):</source>
2996 <translation type="unfinished"></translation>
2997 </message>
2998 <message>
2999 <location filename="../base/ttscarbon.cpp" line="152"/>
3000 <source>Pitch (0 for default):</source>
3001 <translation type="unfinished"></translation>
3002 </message>
3003 <message>
3004 <location filename="../base/ttscarbon.cpp" line="222"/>
3005 <source>Could not voice string</source>
3006 <translation type="unfinished"></translation>
3007 </message>
3008 <message>
3009 <location filename="../base/ttscarbon.cpp" line="232"/>
3010 <source>Could not convert intermediate file</source>
3011 <translation type="unfinished"></translation>
3012 </message>
3013</context>
3014<context>
3015 <name>TTSExes</name>
3016 <message>
3017 <location filename="../base/ttsexes.cpp" line="78"/>
3018 <source>TTS executable not found</source>
3019 <translation>Executável TTS não encontrado</translation>
3020 </message>
3021 <message>
3022 <location filename="../base/ttsexes.cpp" line="44"/>
3023 <source>Path to TTS engine:</source>
3024 <translation type="unfinished"></translation>
3025 </message>
3026 <message>
3027 <location filename="../base/ttsexes.cpp" line="46"/>
3028 <source>TTS engine options:</source>
3029 <translation type="unfinished"></translation>
3030 </message>
3031</context>
3032<context>
3033 <name>TTSFestival</name>
3034 <message>
3035 <location filename="../base/ttsfestival.cpp" line="207"/>
3036 <source>engine could not voice string</source>
3037 <translation type="unfinished"></translation>
3038 </message>
3039 <message>
3040 <location filename="../base/ttsfestival.cpp" line="290"/>
3041 <source>No description available</source>
3042 <translation type="unfinished"></translation>
3043 </message>
3044 <message>
3045 <location filename="../base/ttsfestival.cpp" line="53"/>
3046 <source>Path to Festival client:</source>
3047 <translation type="unfinished"></translation>
3048 </message>
3049 <message>
3050 <location filename="../base/ttsfestival.cpp" line="58"/>
3051 <source>Voice:</source>
3052 <translation type="unfinished"></translation>
3053 </message>
3054 <message>
3055 <location filename="../base/ttsfestival.cpp" line="67"/>
3056 <source>Voice description:</source>
3057 <translation type="unfinished"></translation>
3058 </message>
3059</context>
3060<context>
3061 <name>TTSSapi</name>
3062 <message>
3063 <location filename="../base/ttssapi.cpp" line="49"/>
3064 <source>Language:</source>
3065 <translation type="unfinished"></translation>
3066 </message>
3067 <message>
3068 <location filename="../base/ttssapi.cpp" line="56"/>
3069 <source>Voice:</source>
3070 <translation type="unfinished"></translation>
3071 </message>
3072 <message>
3073 <location filename="../base/ttssapi.cpp" line="68"/>
3074 <source>Speed:</source>
3075 <translation type="unfinished"></translation>
3076 </message>
3077 <message>
3078 <location filename="../base/ttssapi.cpp" line="71"/>
3079 <source>Options:</source>
3080 <translation type="unfinished"></translation>
3081 </message>
3082 <message>
3083 <location filename="../base/ttssapi.cpp" line="115"/>
3084 <source>Could not copy the SAPI script</source>
3085 <translation type="unfinished"></translation>
3086 </message>
3087 <message>
3088 <location filename="../base/ttssapi.cpp" line="133"/>
3089 <source>Could not start SAPI process</source>
3090 <translation type="unfinished"></translation>
3091 </message>
3092</context>
3093<context>
3094 <name>TalkFileCreator</name>
3095 <message>
3096 <location filename="../base/talkfile.cpp" line="42"/>
3097 <source>Reading Filelist...</source>
3098 <translation>Lendo lista de ficheiros...</translation>
3099 </message>
3100 <message>
3101 <location filename="../base/talkfile.cpp" line="45"/>
3102 <source>Talk file creation aborted</source>
3103 <translation>Criação dos Ficheiros de Leitura abortada</translation>
3104 </message>
3105 <message>
3106 <location filename="../base/talkfile.cpp" line="68"/>
3107 <source>Copying Talkfiles...</source>
3108 <translation type="unfinished"></translation>
3109 </message>
3110 <message>
3111 <location filename="../base/talkfile.cpp" line="240"/>
3112 <source>File copy aborted</source>
3113 <translation type="unfinished"></translation>
3114 </message>
3115 <message>
3116 <location filename="../base/talkfile.cpp" line="280"/>
3117 <source>Cleaning up...</source>
3118 <translation type="unfinished"></translation>
3119 </message>
3120 <message>
3121 <location filename="../base/talkfile.cpp" line="291"/>
3122 <source>Finished</source>
3123 <translation type="unfinished"></translation>
3124 </message>
3125 <message>
3126 <location filename="../base/talkfile.cpp" line="80"/>
3127 <source>Finished creating Talk files</source>
3128 <translation>Terminado a criação dos ficherios de Leitura</translation>
3129 </message>
3130 <message>
3131 <location filename="../base/talkfile.cpp" line="36"/>
3132 <source>Starting Talk file generation for folder %1</source>
3133 <translation type="unfinished"></translation>
3134 </message>
3135 <message>
3136 <location filename="../base/talkfile.cpp" line="259"/>
3137 <source>Copying of %1 to %2 failed</source>
3138 <translation>Cópia de %1 para %2 falhou</translation>
3139 </message>
3140</context>
3141<context>
3142 <name>TalkGenerator</name>
3143 <message>
3144 <location filename="../base/talkgenerator.cpp" line="39"/>
3145 <source>Starting TTS Engine</source>
3146 <translation type="unfinished"></translation>
3147 </message>
3148 <message>
3149 <location filename="../base/talkgenerator.cpp" line="44"/>
3150 <location filename="../base/talkgenerator.cpp" line="51"/>
3151 <source>Init of TTS engine failed</source>
3152 <translation type="unfinished">Falha na inicialização do motor TTS</translation>
3153 </message>
3154 <message>
3155 <location filename="../base/talkgenerator.cpp" line="58"/>
3156 <source>Starting Encoder Engine</source>
3157 <translation type="unfinished"></translation>
3158 </message>
3159 <message>
3160 <location filename="../base/talkgenerator.cpp" line="62"/>
3161 <source>Init of Encoder engine failed</source>
3162 <translation type="unfinished">Falha na inicialização do motor codificador</translation>
3163 </message>
3164 <message>
3165 <location filename="../base/talkgenerator.cpp" line="72"/>
3166 <source>Voicing entries...</source>
3167 <translation type="unfinished">Entradas de vocalização...</translation>
3168 </message>
3169 <message>
3170 <location filename="../base/talkgenerator.cpp" line="87"/>
3171 <source>Encoding files...</source>
3172 <translation type="unfinished">Codificando ficheiros...</translation>
3173 </message>
3174 <message>
3175 <location filename="../base/talkgenerator.cpp" line="126"/>
3176 <source>Voicing aborted</source>
3177 <translation type="unfinished"></translation>
3178 </message>
3179 <message>
3180 <location filename="../base/talkgenerator.cpp" line="162"/>
3181 <location filename="../base/talkgenerator.cpp" line="167"/>
3182 <source>Voicing of %1 failed: %2</source>
3183 <translation type="unfinished"></translation>
3184 </message>
3185 <message>
3186 <location filename="../base/talkgenerator.cpp" line="211"/>
3187 <source>Encoding aborted</source>
3188 <translation type="unfinished"></translation>
3189 </message>
3190 <message>
3191 <location filename="../base/talkgenerator.cpp" line="239"/>
3192 <source>Encoding of %1 failed</source>
3193 <translation type="unfinished">Codificação de %1 falhou</translation>
3194 </message>
3195</context>
3196<context>
3197 <name>ThemeInstallFrm</name>
3198 <message>
3199 <location filename="../themesinstallfrm.ui" line="13"/>
3200 <source>Theme Installation</source>
3201 <translation>Instalação de Tema</translation>
3202 </message>
3203 <message>
3204 <location filename="../themesinstallfrm.ui" line="48"/>
3205 <source>Selected Theme</source>
3206 <translation>Tema Seleccionado</translation>
3207 </message>
3208 <message>
3209 <location filename="../themesinstallfrm.ui" line="73"/>
3210 <source>Description</source>
3211 <translation>Descrição</translation>
3212 </message>
3213 <message>
3214 <location filename="../themesinstallfrm.ui" line="83"/>
3215 <source>Download size:</source>
3216 <translation>Tamanho da transferência:</translation>
3217 </message>
3218 <message>
3219 <location filename="../themesinstallfrm.ui" line="93"/>
3220 <source>Hold Ctrl to select multiple item, Shift for a range</source>
3221 <translation>Pressiona Ctrl para seleccionar múltiplos itens, Shift para um intervalo</translation>
3222 </message>
3223 <message>
3224 <location filename="../themesinstallfrm.ui" line="115"/>
3225 <source>&amp;Install</source>
3226 <translation>&amp;Instalar</translation>
3227 </message>
3228 <message>
3229 <location filename="../themesinstallfrm.ui" line="125"/>
3230 <source>&amp;Cancel</source>
3231 <translation>&amp;Cancelar</translation>
3232 </message>
3233</context>
3234<context>
3235 <name>ThemesInstallWindow</name>
3236 <message>
3237 <location filename="../themesinstallwindow.cpp" line="40"/>
3238 <source>no theme selected</source>
3239 <translation>nehum tema seleccionado</translation>
3240 </message>
3241 <message>
3242 <location filename="../themesinstallwindow.cpp" line="125"/>
3243 <source>Network error: %1.
3244Please check your network and proxy settings.</source>
3245 <translation>Erro de rede:%1
3246Por favor, verifique as suas definições de rede e do proxy.</translation>
3247 </message>
3248 <message>
3249 <location filename="../themesinstallwindow.cpp" line="138"/>
3250 <source>the following error occured:
3251%1</source>
3252 <translation>o erro seguinte ocorreu:
3253%1</translation>
3254 </message>
3255 <message>
3256 <location filename="../themesinstallwindow.cpp" line="144"/>
3257 <source>done.</source>
3258 <translation>completo.</translation>
3259 </message>
3260 <message>
3261 <location filename="../themesinstallwindow.cpp" line="211"/>
3262 <source>fetching details for %1</source>
3263 <translation>transferindo detalhes para %1</translation>
3264 </message>
3265 <message>
3266 <location filename="../themesinstallwindow.cpp" line="214"/>
3267 <source>fetching preview ...</source>
3268 <translation>transferindo pré-visualização ...</translation>
3269 </message>
3270 <message>
3271 <location filename="../themesinstallwindow.cpp" line="227"/>
3272 <source>&lt;b&gt;Author:&lt;/b&gt; %1&lt;hr/&gt;</source>
3273 <translation>&lt;b&gt;Autor:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3274 </message>
3275 <message>
3276 <location filename="../themesinstallwindow.cpp" line="228"/>
3277 <location filename="../themesinstallwindow.cpp" line="230"/>
3278 <source>unknown</source>
3279 <translation>desconhecido</translation>
3280 </message>
3281 <message>
3282 <location filename="../themesinstallwindow.cpp" line="229"/>
3283 <source>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</source>
3284 <translation>&lt;b&gt;Versão:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3285 </message>
3286 <message>
3287 <location filename="../themesinstallwindow.cpp" line="231"/>
3288 <source>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</source>
3289 <translation>&lt;b&gt;Descrição:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3290 </message>
3291 <message>
3292 <location filename="../themesinstallwindow.cpp" line="232"/>
3293 <source>no description</source>
3294 <translation>sem descrição</translation>
3295 </message>
3296 <message>
3297 <location filename="../themesinstallwindow.cpp" line="260"/>
3298 <source>no theme preview</source>
3299 <translation>sem pré-visualização do tema</translation>
3300 </message>
3301 <message>
3302 <location filename="../themesinstallwindow.cpp" line="289"/>
3303 <source>Select</source>
3304 <translation type="unfinished"></translation>
3305 </message>
3306 <message>
3307 <location filename="../themesinstallwindow.cpp" line="296"/>
3308 <source>getting themes information ...</source>
3309 <translation>transferindo informação dos temas ...</translation>
3310 </message>
3311 <message>
3312 <location filename="../themesinstallwindow.cpp" line="326"/>
3313 <source>No themes selected, skipping</source>
3314 <translation type="unfinished"></translation>
3315 </message>
3316 <message>
3317 <location filename="../themesinstallwindow.cpp" line="356"/>
3318 <source>Mount point is wrong!</source>
3319 <translation>Ponto de omntagem está incorrecto!</translation>
3320 </message>
3321 <message>
3322 <location filename="../themesinstallwindow.cpp" line="41"/>
3323 <source>no selection</source>
3324 <translation type="unfinished"></translation>
3325 </message>
3326 <message>
3327 <location filename="../themesinstallwindow.cpp" line="181"/>
3328 <source>Information</source>
3329 <translation type="unfinished"></translation>
3330 </message>
3331 <message numerus="yes">
3332 <location filename="../themesinstallwindow.cpp" line="198"/>
3333 <source>Download size %L1 kiB (%n item(s))</source>
3334 <translation type="unfinished">
3335 <numerusform></numerusform>
3336 <numerusform></numerusform>
3337 </translation>
3338 </message>
3339 <message>
3340 <location filename="../themesinstallwindow.cpp" line="248"/>
3341 <source>Retrieving theme preview failed.
3342HTTP response code: %1</source>
3343 <translation type="unfinished"></translation>
3344 </message>
3345</context>
3346<context>
3347 <name>UninstallFrm</name>
3348 <message>
3349 <location filename="../uninstallfrm.ui" line="16"/>
3350 <source>Uninstall Rockbox</source>
3351 <translation></translation>
3352 </message>
3353 <message>
3354 <location filename="../uninstallfrm.ui" line="35"/>
3355 <source>Please select the Uninstallation Method</source>
3356 <translation>Por favor seleccione o Método de Desinstalação</translation>
3357 </message>
3358 <message>
3359 <location filename="../uninstallfrm.ui" line="45"/>
3360 <source>Uninstallation Method</source>
3361 <translation>Método de desinstalação</translation>
3362 </message>
3363 <message>
3364 <location filename="../uninstallfrm.ui" line="51"/>
3365 <source>Complete Uninstallation</source>
3366 <translation>Desinstalação Completa</translation>
3367 </message>
3368 <message>
3369 <location filename="../uninstallfrm.ui" line="58"/>
3370 <source>Smart Uninstallation</source>
3371 <translation>Desinstalação Inteligente</translation>
3372 </message>
3373 <message>
3374 <location filename="../uninstallfrm.ui" line="68"/>
3375 <source>Please select what you want to uninstall</source>
3376 <translation>Por favor seleccione o que deseja desinstalar</translation>
3377 </message>
3378 <message>
3379 <location filename="../uninstallfrm.ui" line="78"/>
3380 <source>Installed Parts</source>
3381 <translation>Partes Instaladas</translation>
3382 </message>
3383 <message>
3384 <location filename="../uninstallfrm.ui" line="128"/>
3385 <source>&amp;Uninstall</source>
3386 <translation>Deinstala&amp;ção</translation>
3387 </message>
3388 <message>
3389 <location filename="../uninstallfrm.ui" line="138"/>
3390 <source>&amp;Cancel</source>
3391 <translation>&amp;Cancelar</translation>
3392 </message>
3393</context>
3394<context>
3395 <name>Uninstaller</name>
3396 <message>
3397 <location filename="../base/uninstall.cpp" line="32"/>
3398 <location filename="../base/uninstall.cpp" line="43"/>
3399 <source>Starting Uninstallation</source>
3400 <translation>Iniciando Desinstalação</translation>
3401 </message>
3402 <message>
3403 <location filename="../base/uninstall.cpp" line="36"/>
3404 <source>Finished Uninstallation</source>
3405 <translation>Desinstalação terminada</translation>
3406 </message>
3407 <message>
3408 <location filename="../base/uninstall.cpp" line="49"/>
3409 <source>Uninstalling %1...</source>
3410 <translation type="unfinished"></translation>
3411 </message>
3412 <message>
3413 <location filename="../base/uninstall.cpp" line="80"/>
3414 <source>Could not delete %1</source>
3415 <translation type="unfinished"></translation>
3416 </message>
3417 <message>
3418 <location filename="../base/uninstall.cpp" line="109"/>
3419 <source>Uninstallation finished</source>
3420 <translation>Desinstalação terminada</translation>
3421 </message>
3422</context>
3423<context>
3424 <name>Utils</name>
3425 <message>
3426 <location filename="../base/utils.cpp" line="312"/>
3427 <source>&lt;li&gt;Permissions insufficient for bootloader installation.
3428Administrator priviledges are necessary.&lt;/li&gt;</source>
3429 <translation type="unfinished">&lt;li&gt;Permissões insuficientes para a instalação da rotina de arranque
3430Previlégios de administrador são necessários.&lt;/li&gt;</translation>
3431 </message>
3432 <message>
3433 <location filename="../base/utils.cpp" line="324"/>
3434 <source>&lt;li&gt;Target mismatch detected.&lt;br/&gt;Installed target: %1&lt;br/&gt;Selected target: %2.&lt;/li&gt;</source>
3435 <translation type="unfinished"></translation>
3436 </message>
3437 <message>
3438 <location filename="../base/utils.cpp" line="331"/>
3439 <source>Problem detected:</source>
3440 <translation type="unfinished">Problema detectado:</translation>
3441 </message>
3442</context>
3443<context>
3444 <name>VoiceFileCreator</name>
3445 <message>
3446 <location filename="../base/voicefile.cpp" line="43"/>
3447 <source>Starting Voicefile generation</source>
3448 <translation>Iniciando geração dos ficheiros de voz</translation>
3449 </message>
3450 <message>
3451 <location filename="../base/voicefile.cpp" line="90"/>
3452 <source>Extracted voice strings from installation</source>
3453 <translation type="unfinished"></translation>
3454 </message>
3455 <message>
3456 <location filename="../base/voicefile.cpp" line="100"/>
3457 <source>Extracted voice strings incompatible</source>
3458 <translation type="unfinished"></translation>
3459 </message>
3460 <message>
3461 <location filename="../base/voicefile.cpp" line="145"/>
3462 <source>Could not retrieve strings from installation, downloading</source>
3463 <translation type="unfinished"></translation>
3464 </message>
3465 <message>
3466 <location filename="../base/voicefile.cpp" line="171"/>
3467 <source>Downloading voice info...</source>
3468 <translation type="unfinished"></translation>
3469 </message>
3470 <message>
3471 <location filename="../base/voicefile.cpp" line="184"/>
3472 <source>Download error: received HTTP error %1.</source>
3473 <translation>Erro de transferência: recebido erro de HTTP %1.</translation>
3474 </message>
3475 <message>
3476 <location filename="../base/voicefile.cpp" line="191"/>
3477 <source>Cached file used.</source>
3478 <translation>Ficheiro da cache usado.</translation>
3479 </message>
3480 <message>
3481 <location filename="../base/voicefile.cpp" line="194"/>
3482 <source>Download error: %1</source>
3483 <translation>Erro de transferência: %1</translation>
3484 </message>
3485 <message>
3486 <location filename="../base/voicefile.cpp" line="199"/>
3487 <source>Download finished.</source>
3488 <translation>Tranferência terminada.</translation>
3489 </message>
3490 <message>
3491 <location filename="../base/voicefile.cpp" line="212"/>
3492 <source>failed to open downloaded file</source>
3493 <translation>falha ao abrir ficheiro transferido</translation>
3494 </message>
3495 <message>
3496 <location filename="../base/voicefile.cpp" line="218"/>
3497 <source>Reading strings...</source>
3498 <translation type="unfinished"></translation>
3499 </message>
3500 <message>
3501 <location filename="../base/voicefile.cpp" line="297"/>
3502 <source>Creating voicefiles...</source>
3503 <translation type="unfinished"></translation>
3504 </message>
3505 <message>
3506 <location filename="../base/voicefile.cpp" line="342"/>
3507 <source>Cleaning up...</source>
3508 <translation type="unfinished"></translation>
3509 </message>
3510 <message>
3511 <location filename="../base/voicefile.cpp" line="353"/>
3512 <source>Finished</source>
3513 <translation type="unfinished"></translation>
3514 </message>
3515 <message>
3516 <location filename="../base/voicefile.cpp" line="271"/>
3517 <source>The downloaded file was empty!</source>
3518 <translation>O ficheiro transferido estava vazio!</translation>
3519 </message>
3520 <message>
3521 <location filename="../base/voicefile.cpp" line="302"/>
3522 <source>Error opening downloaded file</source>
3523 <translation>Erro ao abrir ficheiro transferido</translation>
3524 </message>
3525 <message>
3526 <location filename="../base/voicefile.cpp" line="313"/>
3527 <source>Error opening output file</source>
3528 <translation>Erro ao abrir o ficheiro de saída</translation>
3529 </message>
3530 <message>
3531 <location filename="../base/voicefile.cpp" line="333"/>
3532 <source>successfully created.</source>
3533 <translation>criado com sucesso.</translation>
3534 </message>
3535 <message>
3536 <location filename="../base/voicefile.cpp" line="56"/>
3537 <source>could not find rockbox-info.txt</source>
3538 <translation type="unfinished"></translation>
3539 </message>
3540</context>
3541<context>
3542 <name>ZipInstaller</name>
3543 <message>
3544 <location filename="../base/zipinstaller.cpp" line="60"/>
3545 <source>done.</source>
3546 <translation>completo.</translation>
3547 </message>
3548 <message>
3549 <location filename="../base/zipinstaller.cpp" line="80"/>
3550 <source>Downloading file %1.%2</source>
3551 <translation>Transferindo ficheiro %1.%2</translation>
3552 </message>
3553 <message>
3554 <location filename="../base/zipinstaller.cpp" line="115"/>
3555 <source>Download error: received HTTP error %1.</source>
3556 <translation>Erro de transferência: recebido erro de HTTP %1.</translation>
3557 </message>
3558 <message>
3559 <location filename="../base/zipinstaller.cpp" line="121"/>
3560 <source>Cached file used.</source>
3561 <translation>Ficheiro de cache usado.</translation>
3562 </message>
3563 <message>
3564 <location filename="../base/zipinstaller.cpp" line="123"/>
3565 <source>Download error: %1</source>
3566 <translation>Erro de transferência: %1</translation>
3567 </message>
3568 <message>
3569 <location filename="../base/zipinstaller.cpp" line="127"/>
3570 <source>Download finished.</source>
3571 <translation>Tranferência terminada.</translation>
3572 </message>
3573 <message>
3574 <location filename="../base/zipinstaller.cpp" line="133"/>
3575 <source>Extracting file.</source>
3576 <translation>Extraindo ficheiro.</translation>
3577 </message>
3578 <message>
3579 <location filename="../base/zipinstaller.cpp" line="153"/>
3580 <source>Extraction failed!</source>
3581 <translation type="unfinished"></translation>
3582 </message>
3583 <message>
3584 <location filename="../base/zipinstaller.cpp" line="146"/>
3585 <source>Not enough disk space! Aborting.</source>
3586 <translation>Sem espaço suficiente em disco! A abortar.</translation>
3587 </message>
3588 <message>
3589 <location filename="../base/zipinstaller.cpp" line="68"/>
3590 <source>Package installation finished successfully.</source>
3591 <translation type="unfinished"></translation>
3592 </message>
3593 <message>
3594 <location filename="../base/zipinstaller.cpp" line="162"/>
3595 <source>Installing file.</source>
3596 <translation>instanlando ficheiro.</translation>
3597 </message>
3598 <message>
3599 <location filename="../base/zipinstaller.cpp" line="173"/>
3600 <source>Installing file failed.</source>
3601 <translation>Falha na instalação do ficheiro.</translation>
3602 </message>
3603 <message>
3604 <location filename="../base/zipinstaller.cpp" line="186"/>
3605 <source>Creating installation log</source>
3606 <translation>Criando registo da instalação</translation>
3607 </message>
3608</context>
3609<context>
3610 <name>ZipUtil</name>
3611 <message>
3612 <location filename="../base/ziputil.cpp" line="125"/>
3613 <source>Creating output path failed</source>
3614 <translation type="unfinished"></translation>
3615 </message>
3616 <message>
3617 <location filename="../base/ziputil.cpp" line="132"/>
3618 <source>Creating output file failed</source>
3619 <translation type="unfinished"></translation>
3620 </message>
3621 <message>
3622 <location filename="../base/ziputil.cpp" line="141"/>
3623 <source>Error during Zip operation</source>
3624 <translation type="unfinished"></translation>
3625 </message>
3626</context>
3627<context>
3628 <name>aboutBox</name>
3629 <message>
3630 <location filename="../aboutbox.ui" line="14"/>
3631 <source>About Rockbox Utility</source>
3632 <translation>Sobre Rockbox Utility</translation>
3633 </message>
3634 <message>
3635 <location filename="../aboutbox.ui" line="32"/>
3636 <source>The Rockbox Utility</source>
3637 <translation>A Rockbox Utility</translation>
3638 </message>
3639 <message utf8="true">
3640 <location filename="../aboutbox.ui" line="54"/>
3641 <source>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</source>
3642 <translation type="unfinished"></translation>
3643 </message>
3644 <message>
3645 <location filename="../aboutbox.ui" line="74"/>
3646 <source>&amp;Credits</source>
3647 <translation>&amp;Créditos</translation>
3648 </message>
3649 <message>
3650 <location filename="../aboutbox.ui" line="106"/>
3651 <source>&amp;License</source>
3652 <translation>&amp;Licença</translation>
3653 </message>
3654 <message>
3655 <location filename="../aboutbox.ui" line="132"/>
3656 <source>&amp;Speex License</source>
3657 <translation type="unfinished"></translation>
3658 </message>
3659 <message>
3660 <location filename="../aboutbox.ui" line="158"/>
3661 <source>&amp;Ok</source>
3662 <translation>&amp;Ok</translation>
3663 </message>
3664</context>
3665</TS>
diff --git a/utils/rbutilqt/lang/rbutil_pt_BR.ts b/utils/rbutilqt/lang/rbutil_pt_BR.ts
new file mode 100644
index 0000000000..c906196125
--- /dev/null
+++ b/utils/rbutilqt/lang/rbutil_pt_BR.ts
@@ -0,0 +1,2969 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE TS>
3<TS version="2.0" language="pt_BR">
4<context>
5 <name>BackupDialog</name>
6 <message>
7 <source>Backup</source>
8 <translation type="unfinished">Cópia de Segurança</translation>
9 </message>
10 <message>
11 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This dialog will create a backup by archiving the contents of the Rockbox installation on the player into a zip file. This will include installed themes and settings stored below the .rockbox folder on the player.&lt;/p&gt;&lt;p&gt;The backup filename will be created based on the installed version. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
12 <translation type="unfinished"></translation>
13 </message>
14 <message>
15 <source>Size: unknown</source>
16 <translation type="unfinished"></translation>
17 </message>
18 <message>
19 <source>Backup to: unknown</source>
20 <translation type="unfinished"></translation>
21 </message>
22 <message>
23 <source>&amp;Change</source>
24 <translation type="unfinished">M&amp;odificar</translation>
25 </message>
26 <message>
27 <source>&amp;Backup</source>
28 <translation type="unfinished"></translation>
29 </message>
30 <message>
31 <source>&amp;Cancel</source>
32 <translation type="unfinished">&amp;Cancelar</translation>
33 </message>
34 <message>
35 <source>Installation size: calculating ...</source>
36 <translation type="unfinished"></translation>
37 </message>
38 <message>
39 <source>Select Backup Filename</source>
40 <translation type="unfinished">Selecione Nome do Arquivo da Cópia de Segurança</translation>
41 </message>
42 <message>
43 <source>Installation size: %L1 %2</source>
44 <translation type="unfinished"></translation>
45 </message>
46 <message>
47 <source>Starting backup ...</source>
48 <translation type="unfinished"></translation>
49 </message>
50 <message>
51 <source>Backup successful.</source>
52 <translation type="unfinished"></translation>
53 </message>
54 <message>
55 <source>Backup failed!</source>
56 <translation type="unfinished">Cópia de segurança falhou!</translation>
57 </message>
58 <message>
59 <source>File exists</source>
60 <translation type="unfinished"></translation>
61 </message>
62 <message>
63 <source>The selected backup file already exists. Overwrite?</source>
64 <translation type="unfinished"></translation>
65 </message>
66</context>
67<context>
68 <name>BootloaderInstallAms</name>
69 <message>
70 <source>Downloading bootloader file</source>
71 <translation>Transferindo arquivo do inicializador</translation>
72 </message>
73 <message>
74 <source>Could not load %1</source>
75 <translation>Não foi possível carregar %1</translation>
76 </message>
77 <message>
78 <source>Patching Firmware...</source>
79 <translation>Aplicando correção no Firmware...</translation>
80 </message>
81 <message>
82 <source>Could not open %1 for writing</source>
83 <translation>Não foi possível abrir %1 para escrita</translation>
84 </message>
85 <message>
86 <source>Could not write firmware file</source>
87 <translation>Não foi possível escrever o arquivo de firmware</translation>
88 </message>
89 <message>
90 <source>Success: modified firmware file created</source>
91 <translation>Sucesso: criado arquivo de firmware modificado</translation>
92 </message>
93 <message>
94 <source>No room to insert bootloader, try another firmware version</source>
95 <translation>Impossível inserir o inicializador, tente outra versão do firmware</translation>
96 </message>
97 <message>
98 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
99 <translation>Para desinstalar, faça uma atualização normal com um firmware original não modificado</translation>
100 </message>
101 <message>
102 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; This file is not present on your player and will disappear automatically after installing it.&lt;br/&gt;&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
103 <translation type="unfinished"></translation>
104 </message>
105</context>
106<context>
107 <name>BootloaderInstallBase</name>
108 <message>
109 <source>Download error: received HTTP error %1.</source>
110 <translation>Erro na transferência: recebeu erro HTTP %1.</translation>
111 </message>
112 <message>
113 <source>Download error: %1</source>
114 <translation>Erro na transferência: %1</translation>
115 </message>
116 <message>
117 <source>Download finished (cache used).</source>
118 <translation>Transferência finalizada (cache usado).</translation>
119 </message>
120 <message>
121 <source>Download finished.</source>
122 <translation>Transferência finalizada.</translation>
123 </message>
124 <message>
125 <source>Creating backup of original firmware file.</source>
126 <translation>Criando cópia de segurança do firmware original.</translation>
127 </message>
128 <message>
129 <source>Creating backup folder failed</source>
130 <translation>Falha ao criar cópia de segurança da pasta</translation>
131 </message>
132 <message>
133 <source>Creating backup copy failed.</source>
134 <translation>Falha ao criar cópia da cópia de segurança.</translation>
135 </message>
136 <message>
137 <source>Backup created.</source>
138 <translation>Cópia de segurança criada.</translation>
139 </message>
140 <message>
141 <source>Creating installation log</source>
142 <translation>Criando registro da instalação</translation>
143 </message>
144 <message>
145 <source>Installation log created</source>
146 <translation>Registro de instalação criado</translation>
147 </message>
148 <message>
149 <source>Waiting for system to remount player</source>
150 <translation>Espere pelo sistema para remontar o reprodutor</translation>
151 </message>
152 <message>
153 <source>Player remounted</source>
154 <translation>Reprodutor remontando</translation>
155 </message>
156 <message>
157 <source>Timeout on remount</source>
158 <translation>Tempo de espera ao remontar</translation>
159 </message>
160 <message>
161 <source>Zip file format detected</source>
162 <translation type="unfinished"></translation>
163 </message>
164 <message>
165 <source>Extracting firmware %1 from archive</source>
166 <translation type="unfinished"></translation>
167 </message>
168 <message>
169 <source>Error extracting firmware from archive</source>
170 <translation type="unfinished"></translation>
171 </message>
172 <message>
173 <source>Could not find firmware in archive</source>
174 <translation type="unfinished"></translation>
175 </message>
176 <message>
177 <source>CAB file format detected</source>
178 <translation type="unfinished"></translation>
179 </message>
180</context>
181<context>
182 <name>BootloaderInstallChinaChip</name>
183 <message>
184 <source>Bootloader installation requires you to provide a firmware file of the original firmware (HXF file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
185 <translation>A instalação do inicializador requer que você forneça um arquivo de firmware do firmware original (arquivo HXF). Você precisa baixar esse arquivo manualmente, devido a motivos legais. Por favor, consulte o &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; e a página wiki do &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; para saber como obter este arquivo.&lt;br/&gt;Pressione Ok para continuar e procure em seu computador pelo arquivo de firmware.</translation>
186 </message>
187 <message>
188 <source>Downloading bootloader file</source>
189 <translation>Transferindo arquivo do inicializador</translation>
190 </message>
191 <message>
192 <source>Could not open firmware file</source>
193 <translation type="unfinished"></translation>
194 </message>
195 <message>
196 <source>Could not open bootloader file</source>
197 <translation type="unfinished"></translation>
198 </message>
199 <message>
200 <source>Could not allocate memory</source>
201 <translation type="unfinished"></translation>
202 </message>
203 <message>
204 <source>Could not load firmware file</source>
205 <translation type="unfinished"></translation>
206 </message>
207 <message>
208 <source>File is not a valid ChinaChip firmware</source>
209 <translation type="unfinished"></translation>
210 </message>
211 <message>
212 <source>Could not find ccpmp.bin in input file</source>
213 <translation type="unfinished"></translation>
214 </message>
215 <message>
216 <source>Could not open backup file for ccpmp.bin</source>
217 <translation type="unfinished"></translation>
218 </message>
219 <message>
220 <source>Could not write backup file for ccpmp.bin</source>
221 <translation type="unfinished"></translation>
222 </message>
223 <message>
224 <source>Could not load bootloader file</source>
225 <translation type="unfinished"></translation>
226 </message>
227 <message>
228 <source>Could not get current time</source>
229 <translation type="unfinished"></translation>
230 </message>
231 <message>
232 <source>Could not open output file</source>
233 <translation type="unfinished"></translation>
234 </message>
235 <message>
236 <source>Could not write output file</source>
237 <translation type="unfinished"></translation>
238 </message>
239 <message>
240 <source>Unexpected error from chinachippatcher</source>
241 <translation type="unfinished"></translation>
242 </message>
243</context>
244<context>
245 <name>BootloaderInstallFile</name>
246 <message>
247 <source>Downloading bootloader</source>
248 <translation>Transferindo inicializador</translation>
249 </message>
250 <message>
251 <source>Installing Rockbox bootloader</source>
252 <translation>Instalando inicializador do Rockbox</translation>
253 </message>
254 <message>
255 <source>Error accessing output folder</source>
256 <translation>Erro ao acessar pasta de saída</translation>
257 </message>
258 <message>
259 <source>Bootloader successful installed</source>
260 <translation>Inicializador instalado com sucesso</translation>
261 </message>
262 <message>
263 <source>Removing Rockbox bootloader</source>
264 <translation>Removendo inicializador do Rockbox</translation>
265 </message>
266 <message>
267 <source>No original firmware file found.</source>
268 <translation>Nenhum firmware original encontrado.</translation>
269 </message>
270 <message>
271 <source>Can&apos;t remove Rockbox bootloader file.</source>
272 <translation>Não é possível remover o arquivo do inicializador do Rockbox.</translation>
273 </message>
274 <message>
275 <source>Can&apos;t restore bootloader file.</source>
276 <translation>Não é possível restaurar o arquivo do inicializador.</translation>
277 </message>
278 <message>
279 <source>Original bootloader restored successfully.</source>
280 <translation>Inicializador original restaurado com sucesso.</translation>
281 </message>
282 <message>
283 <source>A firmware file is already present on player</source>
284 <translation type="unfinished"></translation>
285 </message>
286 <message>
287 <source>Copying modified firmware file failed</source>
288 <translation type="unfinished"></translation>
289 </message>
290</context>
291<context>
292 <name>BootloaderInstallHex</name>
293 <message>
294 <source>Bootloader installation requires you to provide a firmware file of the original firmware (hex file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
295 <translation>A instalação do inicializador requer que você forneça um arquivo contendo o firmware original (arquivo hex). Devido a rasões legais, você precisa transferir esse arquivo por conta própria. Por favor, consulte o &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; e a página wiki do &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; para saber como obter esse arquivo.&lt;br/&gt; Pressione OK para continuar e procure em seu computador por esse arquivo do firmware.</translation>
296 </message>
297 <message>
298 <source>checking MD5 hash of input file ...</source>
299 <translation>verificando o hash MD5 do arquivo de entrada ...</translation>
300 </message>
301 <message>
302 <source>Could not verify original firmware file</source>
303 <translation>Não foi possível verificar o firmware original</translation>
304 </message>
305 <message>
306 <source>Firmware file not recognized.</source>
307 <translation>Arquivo de firmware não reconhecido.</translation>
308 </message>
309 <message>
310 <source>MD5 hash ok</source>
311 <translation>Hash MD5 ok</translation>
312 </message>
313 <message>
314 <source>Firmware file doesn&apos;t match selected player.</source>
315 <translation>Arquivo de firmware não corresponde ao reprodutor selecionado.</translation>
316 </message>
317 <message>
318 <source>Descrambling file</source>
319 <translation>Organizando arquivo</translation>
320 </message>
321 <message>
322 <source>Error in descramble: %1</source>
323 <translation>Erro ao organizar: %1</translation>
324 </message>
325 <message>
326 <source>Downloading bootloader file</source>
327 <translation>Transferindo arquivo do inicializador</translation>
328 </message>
329 <message>
330 <source>Adding bootloader to firmware file</source>
331 <translation>Adicionando o inicializador ao firmware</translation>
332 </message>
333 <message>
334 <source>could not open input file</source>
335 <translation>não foi possível abrir o arquivo de entrada</translation>
336 </message>
337 <message>
338 <source>reading header failed</source>
339 <translation>leitura de cabeçalho falhou</translation>
340 </message>
341 <message>
342 <source>reading firmware failed</source>
343 <translation>leitura de firmware falhou</translation>
344 </message>
345 <message>
346 <source>can&apos;t open bootloader file</source>
347 <translation>Não é possível abrir o arquivo do inicializador</translation>
348 </message>
349 <message>
350 <source>reading bootloader file failed</source>
351 <translation>leitura do arquivo do inicializador falhou</translation>
352 </message>
353 <message>
354 <source>can&apos;t open output file</source>
355 <translation>Não é possível abrir o arquivo de saída</translation>
356 </message>
357 <message>
358 <source>writing output file failed</source>
359 <translation>escrita do arquivo de saída falhou</translation>
360 </message>
361 <message>
362 <source>Error in patching: %1</source>
363 <translation>Erro ao corrigir: %1</translation>
364 </message>
365 <message>
366 <source>Error in scramble: %1</source>
367 <translation>Erro ao misturar: %1</translation>
368 </message>
369 <message>
370 <source>Checking modified firmware file</source>
371 <translation>Verificando o firmware modificado</translation>
372 </message>
373 <message>
374 <source>Error: modified file checksum wrong</source>
375 <translation>Erro: checksum do arquivo modificado incorreto</translation>
376 </message>
377 <message>
378 <source>Success: modified firmware file created</source>
379 <translation>Sucesso: criado arquivo de firmware modificado</translation>
380 </message>
381 <message>
382 <source>Can&apos;t open input file</source>
383 <translation>Não é possível abrir o arquivo de entrada</translation>
384 </message>
385 <message>
386 <source>Can&apos;t open output file</source>
387 <translation>Não é possível abrir o arquivo de saída</translation>
388 </message>
389 <message>
390 <source>invalid file: header length wrong</source>
391 <translation>arquivo inválido: tamanho do cabeçalho incorreto</translation>
392 </message>
393 <message>
394 <source>invalid file: unrecognized header</source>
395 <translation>arquivo inválido: cabeçalho não reconhecido</translation>
396 </message>
397 <message>
398 <source>invalid file: &quot;length&quot; field wrong</source>
399 <translation>arquivo inválido: campo incorreto &quot;length&quot;</translation>
400 </message>
401 <message>
402 <source>invalid file: &quot;length2&quot; field wrong</source>
403 <translation>arquivo inválido: campo incorreto &quot;length2&quot;</translation>
404 </message>
405 <message>
406 <source>invalid file: internal checksum error</source>
407 <translation>arquivo inválido: erro de checksum interno</translation>
408 </message>
409 <message>
410 <source>invalid file: &quot;length3&quot; field wrong</source>
411 <translation>arquivo inválido: campo incorreto &quot;length3&quot;</translation>
412 </message>
413 <message>
414 <source>unknown</source>
415 <translation>desconhecido</translation>
416 </message>
417 <message>
418 <source>Uninstallation not possible, only installation info removed</source>
419 <translation>A desistalação não é possível, apenas a remoção de informação de instalação</translation>
420 </message>
421 <message>
422 <source>A firmware file is already present on player</source>
423 <translation type="unfinished"></translation>
424 </message>
425 <message>
426 <source>Copying modified firmware file failed</source>
427 <translation type="unfinished"></translation>
428 </message>
429</context>
430<context>
431 <name>BootloaderInstallImx</name>
432 <message>
433 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (firmware.sb file). This file will be patched with the Rockbox bootloader and installed to your player. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
434 <translation type="unfinished"></translation>
435 </message>
436 <message>
437 <source>Could not read original firmware file</source>
438 <translation type="unfinished"></translation>
439 </message>
440 <message>
441 <source>Downloading bootloader file</source>
442 <translation type="unfinished">Transferindo arquivo do inicializador</translation>
443 </message>
444 <message>
445 <source>Patching file...</source>
446 <translation type="unfinished"></translation>
447 </message>
448 <message>
449 <source>Patching the original firmware failed</source>
450 <translation type="unfinished"></translation>
451 </message>
452 <message>
453 <source>Succesfully patched firmware file</source>
454 <translation type="unfinished"></translation>
455 </message>
456 <message>
457 <source>Bootloader successful installed</source>
458 <translation type="unfinished">Inicializador instalado com sucesso</translation>
459 </message>
460 <message>
461 <source>Patched bootloader could not be installed</source>
462 <translation type="unfinished"></translation>
463 </message>
464 <message>
465 <source>To uninstall, perform a normal upgrade with an unmodified original firmware.</source>
466 <translation type="unfinished"></translation>
467 </message>
468</context>
469<context>
470 <name>BootloaderInstallIpod</name>
471 <message>
472 <source>Error: can&apos;t allocate buffer memory!</source>
473 <translation>Erro: não é possível alocar memoria buffer!</translation>
474 </message>
475 <message>
476 <source>Downloading bootloader file</source>
477 <translation>Transferindo arquivo do inicializador</translation>
478 </message>
479 <message>
480 <source>Installing Rockbox bootloader</source>
481 <translation>Instalando inicializador do Rockbox</translation>
482 </message>
483 <message>
484 <source>Failed to read firmware directory</source>
485 <translation>Falhou ao ler diretório do firmware</translation>
486 </message>
487 <message>
488 <source>Unknown version number in firmware (%1)</source>
489 <translation>Número de versão desconhecido no firmware (%1)</translation>
490 </message>
491 <message>
492 <source>Could not open Ipod in R/W mode</source>
493 <translation>Não foi possível abrir o Ipod em modo R/W (Leitura/Escrita)</translation>
494 </message>
495 <message>
496 <source>Successfull added bootloader</source>
497 <translation>Inicializador adicionado com sucesso</translation>
498 </message>
499 <message>
500 <source>Failed to add bootloader</source>
501 <translation>Falhou ao adicionar o inicializador</translation>
502 </message>
503 <message>
504 <source>Uninstalling bootloader</source>
505 <translation>Desinstalando o inicializador</translation>
506 </message>
507 <message>
508 <source>No bootloader detected.</source>
509 <translation>Nenhum inicializador detectado.</translation>
510 </message>
511 <message>
512 <source>Successfully removed bootloader</source>
513 <translation>Inicializador removido com sucesso</translation>
514 </message>
515 <message>
516 <source>Removing bootloader failed.</source>
517 <translation>Falhou ao remover o inicializador.</translation>
518 </message>
519 <message>
520 <source>Could not open Ipod</source>
521 <translation>Não foi possível abrir o Ipod</translation>
522 </message>
523 <message>
524 <source>Error reading partition table - possibly not an Ipod</source>
525 <translation>Erro lendo tabela de partição - possivelmente não é um Ipod</translation>
526 </message>
527 <message>
528 <source>No firmware partition on disk</source>
529 <translation>Nenhuma partição de firmware no disco</translation>
530 </message>
531 <message>
532 <source>Warning: This is a MacPod, Rockbox only runs on WinPods.
533See http://www.rockbox.org/wiki/IpodConversionToFAT32</source>
534 <translation>Atenção: Este é um MacPod, O Rockbox roda somente em WinPods.
535Veja http://www.rockbox.org/wiki/IpodConversionToFAT32</translation>
536 </message>
537 <message>
538 <source>Bootloader Installation complete.</source>
539 <translation>Instalação do Inicializador completada.</translation>
540 </message>
541 <message>
542 <source>Writing log aborted</source>
543 <translation>Abortada a escrita do log</translation>
544 </message>
545 <message>
546 <source>Error: no mountpoint specified!</source>
547 <translation>Erro: nenhum ponto de montagem especificado!</translation>
548 </message>
549 <message>
550 <source>Could not open Ipod: permission denied</source>
551 <translation>Não foi possível abrir o Ipod: permissão negada</translation>
552 </message>
553 <message>
554 <source>Error: could not retrieve device name</source>
555 <translation>Erro: não foi possível encontrar o nome do dispositivo</translation>
556 </message>
557</context>
558<context>
559 <name>BootloaderInstallMi4</name>
560 <message>
561 <source>Downloading bootloader</source>
562 <translation>Transferir inicializador</translation>
563 </message>
564 <message>
565 <source>Installing Rockbox bootloader</source>
566 <translation>Instalando inicializador do Rockbox</translation>
567 </message>
568 <message>
569 <source>Bootloader successful installed</source>
570 <translation>Inicializador instalado com sucesso</translation>
571 </message>
572 <message>
573 <source>Checking for Rockbox bootloader</source>
574 <translation>Verificando pelo inicializador do Rockbox</translation>
575 </message>
576 <message>
577 <source>No Rockbox bootloader found</source>
578 <translation>Nenhum inicializador do Rockbox encontrado</translation>
579 </message>
580 <message>
581 <source>Checking for original firmware file</source>
582 <translation>Verificando por arquivo de firmware original</translation>
583 </message>
584 <message>
585 <source>Error finding original firmware file</source>
586 <translation>Erro procurando arquivo de firmware original</translation>
587 </message>
588 <message>
589 <source>Rockbox bootloader successful removed</source>
590 <translation>Inicializador do Rockbox removido com sucesso</translation>
591 </message>
592 <message>
593 <source>A firmware file is already present on player</source>
594 <translation type="unfinished"></translation>
595 </message>
596 <message>
597 <source>Copying modified firmware file failed</source>
598 <translation type="unfinished"></translation>
599 </message>
600</context>
601<context>
602 <name>BootloaderInstallMpio</name>
603 <message>
604 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
605 <translation>A instalação do inicializador requer que você forneça um arquivo de firmware do firmware original (arquivo bin). Você precisa baixar esse arquivo manualmente, devido a motivos legais. Por favor, consulte o &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; e a página wiki do &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; para saber como obter este arquivo.&lt;br/&gt;Pressione Ok para continuar e procure em seu computador pelo arquivo de firmware.</translation>
606 </message>
607 <message>
608 <source>Downloading bootloader file</source>
609 <translation>Transferindo arquivo do inicializador</translation>
610 </message>
611 <message>
612 <source>Could not open the original firmware.</source>
613 <translation>Não foi possível abrir o firmware original.</translation>
614 </message>
615 <message>
616 <source>Could not read the original firmware.</source>
617 <translation>Não foi possível ler o firmware original.</translation>
618 </message>
619 <message>
620 <source>Could not open downloaded bootloader.</source>
621 <translation>Não foi possível transferir o inicializador.</translation>
622 </message>
623 <message>
624 <source>Place for bootloader in OF file not empty.</source>
625 <translation>O espaço para o inicializador no arquivo OF não está vazio.</translation>
626 </message>
627 <message>
628 <source>Could not read the downloaded bootloader.</source>
629 <translation>Não foi possível ler o inicializador transferido.</translation>
630 </message>
631 <message>
632 <source>Bootloader checksum error.</source>
633 <translation>Erro no checksum do inicializador.</translation>
634 </message>
635 <message>
636 <source>Patching original firmware failed: %1</source>
637 <translation>Falhou ao aplicar correção no firmware original: %1</translation>
638 </message>
639 <message>
640 <source>Success: modified firmware file created</source>
641 <translation>Sucesso: criado arquivo de firmware modificado</translation>
642 </message>
643 <message>
644 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
645 <translation>Para desinstalar, faça uma atualização normal com um firmware original não modificado</translation>
646 </message>
647 <message>
648 <source>Loaded firmware file does not look like MPIO original firmware file.</source>
649 <translation>O arquivo de firmware carregado não se parece com um arquivo de firmware MPIO original.</translation>
650 </message>
651 <message>
652 <source>Could not open output file.</source>
653 <translation>Não foi possível abrir o arquivo de saída.</translation>
654 </message>
655 <message>
656 <source>Could not write output file.</source>
657 <translation>Não foi possível escrever o arquivo de saída.</translation>
658 </message>
659 <message>
660 <source>Unknown error number: %1</source>
661 <translation>Erro desconhecido número: %1</translation>
662 </message>
663</context>
664<context>
665 <name>BootloaderInstallSansa</name>
666 <message>
667 <source>Error: can&apos;t allocate buffer memory!</source>
668 <translation>Erro: não é possível alocar memoria buffer!</translation>
669 </message>
670 <message>
671 <source>Searching for Sansa</source>
672 <translation>Procurando por Sansa</translation>
673 </message>
674 <message>
675 <source>Permission for disc access denied!
676This is required to install the bootloader</source>
677 <translation>Permissão de acesso a disco negada!
678Isto é necessário para instalar o inicializador</translation>
679 </message>
680 <message>
681 <source>No Sansa detected!</source>
682 <translation>Nenhum Sansa detectado!</translation>
683 </message>
684 <message>
685 <source>Downloading bootloader file</source>
686 <translation>Transferindo arquivo do inicializador</translation>
687 </message>
688 <message>
689 <source>Installing Rockbox bootloader</source>
690 <translation>Instalando o inicializador do Rockbox</translation>
691 </message>
692 <message>
693 <source>OLD ROCKBOX INSTALLATION DETECTED, ABORTING.
694You must reinstall the original Sansa firmware before running
695sansapatcher for the first time.
696See http://www.rockbox.org/wiki/SansaE200Install
697</source>
698 <translation>DETECTADA INSTALAÇÃO ANTIGA DO ROCKBOX, ABORTANDO.
699Você deve reinstalar o firmware original Sansa antes de executar o
700sansapatcher pela primeira vez.
701Veja http://www.rockbox.org/wiki/SansaE200Install</translation>
702 </message>
703 <message>
704 <source>Could not open Sansa in R/W mode</source>
705 <translation>Não foi possível abrir o Sansa em modo R/W (Leitura/Escrita)</translation>
706 </message>
707 <message>
708 <source>Checking downloaded bootloader</source>
709 <translation>Verificando inicializador transferido</translation>
710 </message>
711 <message>
712 <source>Bootloader mismatch! Aborting.</source>
713 <translation>Inicializador não confere! Abortando.</translation>
714 </message>
715 <message>
716 <source>Successfully installed bootloader</source>
717 <translation>Inicializador instalado com sucesso</translation>
718 </message>
719 <message>
720 <source>Failed to install bootloader</source>
721 <translation>Falhou ao instalar o inicializador</translation>
722 </message>
723 <message>
724 <source>Uninstalling bootloader</source>
725 <translation>Desinstalando o inicializador</translation>
726 </message>
727 <message>
728 <source>Successfully removed bootloader</source>
729 <translation>Inicializador removido com sucesso</translation>
730 </message>
731 <message>
732 <source>Removing bootloader failed.</source>
733 <translation>Falhou ao remover o inicializador.</translation>
734 </message>
735 <message>
736 <source>Can&apos;t find Sansa</source>
737 <translation>Não pode encontrar o Sansa</translation>
738 </message>
739 <message>
740 <source>Could not open Sansa</source>
741 <translation>Não foi possível abrir o Sansa</translation>
742 </message>
743 <message>
744 <source>Could not read partition table</source>
745 <translation>Não foi possível ler a tabela de partição</translation>
746 </message>
747 <message>
748 <source>Disk is not a Sansa (Error %1), aborting.</source>
749 <translation>Disco não é um Sansa (Erro %1), abortando.</translation>
750 </message>
751 <message>
752 <source>Bootloader Installation complete.</source>
753 <translation>Instalação do Inicializador completada.</translation>
754 </message>
755 <message>
756 <source>Writing log aborted</source>
757 <translation>Abortada a escrita do log</translation>
758 </message>
759 <message>
760 <source>Error: could not retrieve device name</source>
761 <translation>Erro: não foi possível encontrar o nome do dispositivo</translation>
762 </message>
763</context>
764<context>
765 <name>BootloaderInstallTcc</name>
766 <message>
767 <source>Downloading bootloader file</source>
768 <translation>Transferindo arquivo do inicializador</translation>
769 </message>
770 <message>
771 <source>Could not load %1</source>
772 <translation>Não foi possível carregar %1</translation>
773 </message>
774 <message>
775 <source>Unknown OF file used: %1</source>
776 <translation>Arquivo OF usado desconhecido: %1</translation>
777 </message>
778 <message>
779 <source>Patching Firmware...</source>
780 <translation>Aplicando correção no Firmware...</translation>
781 </message>
782 <message>
783 <source>Could not open %1 for writing</source>
784 <translation>Não foi possível abrir %1 para escrita</translation>
785 </message>
786 <message>
787 <source>Could not write firmware file</source>
788 <translation>Não foi possível escrever o arquivo de firmware</translation>
789 </message>
790 <message>
791 <source>Success: modified firmware file created</source>
792 <translation>Sucesso: criado arquivo de firmware modificado</translation>
793 </message>
794 <message>
795 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wiki page on how to obtain the file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
796 <translation>A instalação do inicializador requer que você forneça um arquivo de firmware do firmware original (arquivo bin). Você precisa baixar esse arquivo manualmente, devido a motivos legais. Por favor, consulte o &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; e a página wiki do &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; para saber como obter este arquivo.&lt;br/&gt;Pressione Ok para continuar e procure em seu computador pelo arquivo de firmware.</translation>
797 </message>
798 <message>
799 <source>Could not patch firmware</source>
800 <translation>Não foi possível escrever o arquivo de firmware</translation>
801 </message>
802 <message>
803 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
804 <translation>Para desinstalar, faça uma atualização normal com um firmware original não modificado</translation>
805 </message>
806</context>
807<context>
808 <name>Changelog</name>
809 <message>
810 <source>Changelog</source>
811 <translation type="unfinished"></translation>
812 </message>
813 <message>
814 <source>Show on startup</source>
815 <translation type="unfinished"></translation>
816 </message>
817 <message>
818 <source>&amp;Ok</source>
819 <translation type="unfinished">&amp;Ok</translation>
820 </message>
821</context>
822<context>
823 <name>Config</name>
824 <message>
825 <source>The following errors occurred:</source>
826 <translation>Os seguintes erros ocorreram:</translation>
827 </message>
828 <message>
829 <source>No mountpoint given</source>
830 <translation>Não foi fornecido nenhum ponto de montagem</translation>
831 </message>
832 <message>
833 <source>Mountpoint does not exist</source>
834 <translation>O ponto de montagem não existe</translation>
835 </message>
836 <message>
837 <source>Mountpoint is not a directory.</source>
838 <translation>O ponto de montagem não é um diretório.</translation>
839 </message>
840 <message>
841 <source>Mountpoint is not writeable</source>
842 <translation>O ponto de montagem não tem permissão de escrita</translation>
843 </message>
844 <message>
845 <source>No player selected</source>
846 <translation>Nenhum reprodutor selecionado</translation>
847 </message>
848 <message>
849 <source>Cache path not writeable. Leave path empty to default to systems temporary path.</source>
850 <translation>Não se pode escrever no caminho do cache. Deixe o caminho em branco para usar o caminho temporário padrão do sistema.</translation>
851 </message>
852 <message>
853 <source>You need to fix the above errors before you can continue.</source>
854 <translation>Você precisa corrigir os erros acima antes de continuar.</translation>
855 </message>
856 <message>
857 <source>Configuration error</source>
858 <translation>Erro de configuração</translation>
859 </message>
860 <message>
861 <source>Current cache size is %L1 kiB.</source>
862 <translation>O tamanho atual do cache é %L1 kiB.</translation>
863 </message>
864 <message>
865 <source>Configuration OK</source>
866 <translation>Configuração OK</translation>
867 </message>
868 <message>
869 <source>Configuration INVALID</source>
870 <translation>Configuração INVÁLIDA</translation>
871 </message>
872 <message>
873 <source>Fatal error</source>
874 <translation type="obsolete">Erro fatal</translation>
875 </message>
876 <message>
877 <source>Autodetection</source>
878 <translation>Autodetecção</translation>
879 </message>
880 <message>
881 <source>Could not detect a Mountpoint.
882Select your Mountpoint manually.</source>
883 <translation>Não foi possível detectar um Ponto de Montagem.
884Selecione o Ponto de Montagem manualmente.</translation>
885 </message>
886 <message>
887 <source>Could not detect a device.
888Select your device and Mountpoint manually.</source>
889 <translation>Não foi possível detectar um dispositivo.
890Selecione seu dispositivo e Ponto de Montagem manualmente.</translation>
891 </message>
892 <message>
893 <source>Really delete cache?</source>
894 <translation>Realmente apagar o cache?</translation>
895 </message>
896 <message>
897 <source>Do you really want to delete the cache? Make absolutely sure this setting is correct as it will remove &lt;b&gt;all&lt;/b&gt; files in this folder!</source>
898 <translation>Você realmente quer apagar o cache? Tenha certeza absoluta que esta opção está correta já que ela removerá &lt;b&gt;todos&lt;/b&gt; os arquivos nesta pasta!</translation>
899 </message>
900 <message>
901 <source>Path wrong!</source>
902 <translation>Caminho incorreto!</translation>
903 </message>
904 <message>
905 <source>The cache path is invalid. Aborting.</source>
906 <translation>O caminho para o cache é inválido. Abortando.</translation>
907 </message>
908 <message>
909 <source>Detected an unsupported player:
910%1
911Sorry, Rockbox doesn&apos;t run on your player.</source>
912 <translation>Detectado um reprodutor não suportado:
913%1
914Desculpe, o Rockbox não funciona no seu reprodutor.</translation>
915 </message>
916 <message>
917 <source>Fatal: player incompatible</source>
918 <translation type="obsolete">Fatal: reprodutor incompatível</translation>
919 </message>
920 <message>
921 <source>TTS configuration invalid</source>
922 <translation>Configuração TTS inválida</translation>
923 </message>
924 <message>
925 <source>TTS configuration invalid.
926 Please configure TTS engine.</source>
927 <translation>Configuração TTS inválida.
928Por favor, configure o motor TTS.</translation>
929 </message>
930 <message>
931 <source>Could not start TTS engine.</source>
932 <translation>Não foi possível iniciar o motor TTS.</translation>
933 </message>
934 <message>
935 <source>Could not start TTS engine.
936</source>
937 <translation>Não foi possível iniciar o motor TTS.</translation>
938 </message>
939 <message>
940 <source>
941Please configure TTS engine.</source>
942 <translation>
943Por favor, configure o motor TTS.</translation>
944 </message>
945 <message>
946 <source>Rockbox Utility Voice Test</source>
947 <translation>Teste de Voz do Utilitário Rockbox</translation>
948 </message>
949 <message>
950 <source>Could not voice test string.</source>
951 <translation>Não foi possível criar voz para a string de teste.</translation>
952 </message>
953 <message>
954 <source>Could not voice test string.
955</source>
956 <translation>Não foi possível criar voz para a string de teste.</translation>
957 </message>
958 <message>
959 <source>Showing disabled targets</source>
960 <translation>Mostrando alvos desabilitados</translation>
961 </message>
962 <message>
963 <source>You just enabled showing targets that are marked disabled. Disabled targets are not recommended to end users. Please use this option only if you know what you are doing.</source>
964 <translation>Você acaba de habilitar mostrar alvos que estão marcados como desabilitado. Alvos desabilitado não são recomendados para usuários finais. Por favor, use está opção apenas se você sabe o que está fazendo.</translation>
965 </message>
966 <message>
967 <source>Set Cache Path</source>
968 <translation>Definir Caminho do Cache</translation>
969 </message>
970 <message>
971 <source>%1 &quot;MacPod&quot; found!
972Rockbox needs a FAT formatted Ipod (so-called &quot;WinPod&quot;) to run. </source>
973 <translation>%1 encontrado &quot;MacPod&quot;!
974O Rockbox precisa de um Ipod formatado como FAT (chamado de &quot;WinPod&quot;) para funcionar.</translation>
975 </message>
976 <message>
977 <source>Proxy Detection</source>
978 <translation>Detecção de Proxy</translation>
979 </message>
980 <message>
981 <source>The System Proxy settings are invalid!
982Rockbox Utility can&apos;t work with this proxy settings. Make sure the system proxy is set correctly. Note that &quot;proxy auto-config (PAC)&quot; scripts are not supported by Rockbox Utility. If your system uses this you need to use manual proxy settings.</source>
983 <translation>As configurações de Proxy do Sistema são inválidas!
984O Utilitário Rockbox não funciona com estas configurações de proxy. Certifique-se que o proxy do sistema esteja configurado corretamente. Note que scripts &quot;proxy auto-config (PAC)&quot; não são suportados pelo Utilitário Rockbox. Se seu sistema usa um desses scripts você precisa configurar o proxy manualmente.</translation>
985 </message>
986 <message>
987 <source>%1 in MTP mode found!
988You need to change your player to MSC mode for installation. </source>
989 <translation type="unfinished"></translation>
990 </message>
991 <message>
992 <source>TTS error</source>
993 <translation type="unfinished"></translation>
994 </message>
995 <message>
996 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
997 <translation type="unfinished"></translation>
998 </message>
999 <message>
1000 <source>Multiple devices have been detected. Please disconnect all players but one and try again.</source>
1001 <translation type="unfinished"></translation>
1002 </message>
1003 <message>
1004 <source>Detected devices:</source>
1005 <translation type="unfinished"></translation>
1006 </message>
1007 <message>
1008 <source>(unknown)</source>
1009 <translation type="unfinished"></translation>
1010 </message>
1011 <message>
1012 <source>Note: detecting connected devices might be ambiguous. You might have less devices connected than listed. In this case it might not be possible to detect your player unambiguously.</source>
1013 <translation type="unfinished"></translation>
1014 </message>
1015 <message>
1016 <source>Device Detection</source>
1017 <translation type="unfinished"></translation>
1018 </message>
1019 <message>
1020 <source>The player contains an incompatible filesystem.
1021Make sure you selected the correct mountpoint and the player is set up to use a filesystem compatible with Rockbox.</source>
1022 <translation type="unfinished"></translation>
1023 </message>
1024 <message>
1025 <source>An unknown error occured during player detection.</source>
1026 <translation type="unfinished"></translation>
1027 </message>
1028 <message>
1029 <source>%1 (%2 GiB of %3 GiB free)</source>
1030 <translation type="unfinished"></translation>
1031 </message>
1032 <message>
1033 <source>%1 at %2</source>
1034 <translation type="unfinished"></translation>
1035 </message>
1036</context>
1037<context>
1038 <name>ConfigForm</name>
1039 <message>
1040 <source>Configuration</source>
1041 <translation>Configuração</translation>
1042 </message>
1043 <message>
1044 <source>Configure Rockbox Utility</source>
1045 <translation>Configurar Utilitário Rockbox</translation>
1046 </message>
1047 <message>
1048 <source>&amp;Device</source>
1049 <translation>&amp;Dispositivo</translation>
1050 </message>
1051 <message>
1052 <source>Select your device in the &amp;filesystem</source>
1053 <translation>Selecione seu dispositivo no sis&amp;tema de arquivos</translation>
1054 </message>
1055 <message>
1056 <source>&amp;Browse</source>
1057 <translation>&amp;Navegar</translation>
1058 </message>
1059 <message>
1060 <source>&amp;Select your audio player</source>
1061 <translation>&amp;Selecione seu reprodutor de audio</translation>
1062 </message>
1063 <message>
1064 <source>&amp;Autodetect</source>
1065 <translation>&amp;Autodetectar</translation>
1066 </message>
1067 <message>
1068 <source>&amp;Proxy</source>
1069 <translation>&amp;Proxy</translation>
1070 </message>
1071 <message>
1072 <source>&amp;No Proxy</source>
1073 <translation>&amp;Sem Proxy</translation>
1074 </message>
1075 <message>
1076 <source>Use S&amp;ystem values</source>
1077 <translation>Usar valores do s&amp;istema</translation>
1078 </message>
1079 <message>
1080 <source>&amp;Manual Proxy settings</source>
1081 <translation>Configurações de Proxy &amp;manuais</translation>
1082 </message>
1083 <message>
1084 <source>Proxy Values</source>
1085 <translation>Valores de Proxy</translation>
1086 </message>
1087 <message>
1088 <source>&amp;Host:</source>
1089 <translation>&amp;Hospedeiro:</translation>
1090 </message>
1091 <message>
1092 <source>&amp;Port:</source>
1093 <translation>&amp;Porta:</translation>
1094 </message>
1095 <message>
1096 <source>&amp;Username</source>
1097 <translation>&amp;Usuário</translation>
1098 </message>
1099 <message>
1100 <source>Pass&amp;word</source>
1101 <translation>&amp;Senha</translation>
1102 </message>
1103 <message>
1104 <source>&amp;Language</source>
1105 <translation>&amp;Idioma</translation>
1106 </message>
1107 <message>
1108 <source>Cac&amp;he</source>
1109 <translation>Cac&amp;he</translation>
1110 </message>
1111 <message>
1112 <source>Download cache settings</source>
1113 <translation>Configurações de cache de transferência</translation>
1114 </message>
1115 <message>
1116 <source>Rockbox Utility uses a local download cache to save network traffic. You can change the path to the cache and use it as local repository by enabling Offline mode.</source>
1117 <translation>O Utilitário Rockbox usa um cache de transferência local para economizar tráfego de rede. Você pode mudar o caminho para o cache e usá-lo como repositório local habilitando o modo Offline.</translation>
1118 </message>
1119 <message>
1120 <source>Current cache size is %1</source>
1121 <translation>O tamanho atual do cache é %1</translation>
1122 </message>
1123 <message>
1124 <source>P&amp;ath</source>
1125 <translation>C&amp;aminho</translation>
1126 </message>
1127 <message>
1128 <source>Entering an invalid folder will reset the path to the systems temporary path.</source>
1129 <translation>Informando uma pasta inválida irá limpar o caminho para o sistema temporário.</translation>
1130 </message>
1131 <message>
1132 <source>Disable local &amp;download cache</source>
1133 <translation>&amp;Desabilitar cache local de transferência</translation>
1134 </message>
1135 <message>
1136 <source>&lt;p&gt;This will try to use all information from the cache, even information about updates. Only use this option if you want to install without network connection. Note: you need to do the same install you want to perform later with network access first to download all required files to the cache.&lt;/p&gt;</source>
1137 <translation type="obsolete">&lt;p&gt;Isto tentará usar toda a informação do cache, incluindo informação de atualizações. Somente use esta opção se você quer instalar sem uma conecção de rede. Nota: primeiro você precisa fazer a mesma instalação que você quer efetuar posteriormente, com acesso a rede para que sejam transferidos para o cache todos os arquivos necessários.&lt;/p&gt;</translation>
1138 </message>
1139 <message>
1140 <source>O&amp;ffline mode</source>
1141 <translation type="obsolete">Modo o&amp;ffline</translation>
1142 </message>
1143 <message>
1144 <source>Clean cache &amp;now</source>
1145 <translation>Limpar cache a&amp;gora</translation>
1146 </message>
1147 <message>
1148 <source>&amp;TTS &amp;&amp; Encoder</source>
1149 <translation>Codificador &amp;&amp; &amp;TTS</translation>
1150 </message>
1151 <message>
1152 <source>TTS Engine</source>
1153 <translation>Motor TTS</translation>
1154 </message>
1155 <message>
1156 <source>&amp;Select TTS Engine</source>
1157 <translation>&amp;Selecione o Motor TTS</translation>
1158 </message>
1159 <message>
1160 <source>Configure TTS Engine</source>
1161 <translation>Configurar o Motor TTS</translation>
1162 </message>
1163 <message>
1164 <source>Configuration invalid!</source>
1165 <translation>Configuração inválida!</translation>
1166 </message>
1167 <message>
1168 <source>Configure &amp;TTS</source>
1169 <translation>Configurar &amp;TTS</translation>
1170 </message>
1171 <message>
1172 <source>Encoder Engine</source>
1173 <translation>Motor do Codificador</translation>
1174 </message>
1175 <message>
1176 <source>Configure &amp;Enc</source>
1177 <translation>Configurar &amp;Codificador</translation>
1178 </message>
1179 <message>
1180 <source>encoder name</source>
1181 <translation>nome do codificador</translation>
1182 </message>
1183 <message>
1184 <source>&amp;Ok</source>
1185 <translation>&amp;Ok</translation>
1186 </message>
1187 <message>
1188 <source>&amp;Cancel</source>
1189 <translation>&amp;Cancelar</translation>
1190 </message>
1191 <message>
1192 <source>Test TTS</source>
1193 <translation>Testar TTS</translation>
1194 </message>
1195 <message>
1196 <source>Show disabled targets</source>
1197 <translation>Mostrar alvos desabilitados</translation>
1198 </message>
1199 <message>
1200 <source>&amp;Refresh</source>
1201 <translation type="unfinished">&amp;Atualizar</translation>
1202 </message>
1203 <message>
1204 <source>&amp;Use string corrections for TTS</source>
1205 <translation type="unfinished"></translation>
1206 </message>
1207 <message>
1208 <source>Show</source>
1209 <translation type="unfinished"></translation>
1210 </message>
1211</context>
1212<context>
1213 <name>Configure</name>
1214 <message>
1215 <source>English</source>
1216 <comment>This is the localized language name, i.e. your language.</comment>
1217 <translation>Português (Brasil)</translation>
1218 </message>
1219</context>
1220<context>
1221 <name>CreateVoiceFrm</name>
1222 <message>
1223 <source>Create Voice File</source>
1224 <translation>Criar Arquivo de Voz</translation>
1225 </message>
1226 <message>
1227 <source>Select the Language you want to generate a voicefile for:</source>
1228 <translation>Selecione o Idioma para o qual você quer gerar um arquivo de voz:</translation>
1229 </message>
1230 <message>
1231 <source>Language</source>
1232 <translation>Idioma</translation>
1233 </message>
1234 <message>
1235 <source>Generation settings</source>
1236 <translation>Configurações para a geração</translation>
1237 </message>
1238 <message>
1239 <source>Change</source>
1240 <translation>Modificar</translation>
1241 </message>
1242 <message>
1243 <source>&amp;Install</source>
1244 <translation>&amp;Instalar</translation>
1245 </message>
1246 <message>
1247 <source>&amp;Cancel</source>
1248 <translation>&amp;Cancelar</translation>
1249 </message>
1250 <message>
1251 <source>Wavtrim Threshold</source>
1252 <translation>Limiar Wavtrim</translation>
1253 </message>
1254 <message>
1255 <source>TTS:</source>
1256 <translation type="unfinished"></translation>
1257 </message>
1258 <message>
1259 <source>Silence threshold</source>
1260 <translation type="unfinished"></translation>
1261 </message>
1262</context>
1263<context>
1264 <name>CreateVoiceWindow</name>
1265 <message>
1266 <source>Engine: &lt;b&gt;%1&lt;/b&gt;</source>
1267 <translation type="unfinished"></translation>
1268 </message>
1269 <message>
1270 <source>TTS error</source>
1271 <translation type="unfinished"></translation>
1272 </message>
1273 <message>
1274 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1275 <translation type="unfinished"></translation>
1276 </message>
1277</context>
1278<context>
1279 <name>EncTtsCfgGui</name>
1280 <message>
1281 <source></source>
1282 <translation></translation>
1283 </message>
1284 <message>
1285 <source>Waiting for engine...</source>
1286 <translation>Esperando pelo motor...</translation>
1287 </message>
1288 <message>
1289 <source>Ok</source>
1290 <translation>Ok</translation>
1291 </message>
1292 <message>
1293 <source>Cancel</source>
1294 <translation>Cancelar</translation>
1295 </message>
1296 <message>
1297 <source>Browse</source>
1298 <translation>Navegar</translation>
1299 </message>
1300 <message>
1301 <source>Refresh</source>
1302 <translation>Atualizar</translation>
1303 </message>
1304 <message>
1305 <source>Select executable</source>
1306 <translation type="unfinished"></translation>
1307 </message>
1308</context>
1309<context>
1310 <name>EncoderExe</name>
1311 <message>
1312 <source>Path to Encoder:</source>
1313 <translation type="unfinished">Caminho para o Codificador:</translation>
1314 </message>
1315 <message>
1316 <source>Encoder options:</source>
1317 <translation type="unfinished">Opções do codificador:</translation>
1318 </message>
1319</context>
1320<context>
1321 <name>EncoderLame</name>
1322 <message>
1323 <source>LAME</source>
1324 <translation type="unfinished"></translation>
1325 </message>
1326 <message>
1327 <source>Volume</source>
1328 <translation type="unfinished"></translation>
1329 </message>
1330 <message>
1331 <source>Quality</source>
1332 <translation type="unfinished"></translation>
1333 </message>
1334 <message>
1335 <source>Could not find libmp3lame!</source>
1336 <translation type="unfinished"></translation>
1337 </message>
1338</context>
1339<context>
1340 <name>EncoderRbSpeex</name>
1341 <message>
1342 <source>Volume:</source>
1343 <translation type="unfinished">Volume:</translation>
1344 </message>
1345 <message>
1346 <source>Quality:</source>
1347 <translation type="unfinished">Qualidade:</translation>
1348 </message>
1349 <message>
1350 <source>Complexity:</source>
1351 <translation type="unfinished">Complexidade:</translation>
1352 </message>
1353 <message>
1354 <source>Use Narrowband:</source>
1355 <translation type="unfinished">Usar Banda Extreita:</translation>
1356 </message>
1357</context>
1358<context>
1359 <name>InfoWidget</name>
1360 <message>
1361 <source>File</source>
1362 <translation type="unfinished">Arquivo</translation>
1363 </message>
1364 <message>
1365 <source>Version</source>
1366 <translation type="unfinished">Versão</translation>
1367 </message>
1368</context>
1369<context>
1370 <name>InfoWidgetFrm</name>
1371 <message>
1372 <source>Currently installed packages.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; if you manually installed packages this might not be correct!</source>
1373 <translation type="unfinished">Pacotes instalados atualmente.&lt;br/&gt;&lt;b&gt;Nota:&lt;/b&gt; se você instalou pacotes manualmente, isto pode não estar correto!</translation>
1374 </message>
1375 <message>
1376 <source>Info</source>
1377 <translation type="unfinished">Informação</translation>
1378 </message>
1379 <message>
1380 <source>Package</source>
1381 <translation type="unfinished"></translation>
1382 </message>
1383</context>
1384<context>
1385 <name>InstallTalkFrm</name>
1386 <message>
1387 <source>Install Talk Files</source>
1388 <translation>Instalar Arquivos Talk</translation>
1389 </message>
1390 <message>
1391 <source>TTS profile:</source>
1392 <translation>Perfil TTS:</translation>
1393 </message>
1394 <message>
1395 <source>Change</source>
1396 <translation>Modificar</translation>
1397 </message>
1398 <message>
1399 <source>Generation options</source>
1400 <translation>Opções para a geração</translation>
1401 </message>
1402 <message>
1403 <source>Strip Extensions</source>
1404 <translation>Retirar Extensões</translation>
1405 </message>
1406 <message>
1407 <source>&amp;Install</source>
1408 <translation>&amp;Instalar</translation>
1409 </message>
1410 <message>
1411 <source>&amp;Cancel</source>
1412 <translation>&amp;Cancelar</translation>
1413 </message>
1414 <message>
1415 <source>Generate for files</source>
1416 <translation type="unfinished"></translation>
1417 </message>
1418 <message>
1419 <source>Generate for folders</source>
1420 <translation type="unfinished"></translation>
1421 </message>
1422 <message>
1423 <source>Recurse into folders</source>
1424 <translation type="unfinished"></translation>
1425 </message>
1426 <message>
1427 <source>Ignore files</source>
1428 <translation type="unfinished"></translation>
1429 </message>
1430 <message>
1431 <source>Skip existing</source>
1432 <translation type="unfinished"></translation>
1433 </message>
1434 <message>
1435 <source>Select folders for Talkfile generation (Ctrl for multiselect)</source>
1436 <translation type="unfinished"></translation>
1437 </message>
1438</context>
1439<context>
1440 <name>InstallTalkWindow</name>
1441 <message>
1442 <source>Empty selection</source>
1443 <translation type="unfinished"></translation>
1444 </message>
1445 <message>
1446 <source>No files or folders selected. Please select files or folders first.</source>
1447 <translation type="unfinished"></translation>
1448 </message>
1449 <message>
1450 <source>TTS error</source>
1451 <translation type="unfinished"></translation>
1452 </message>
1453 <message>
1454 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1455 <translation type="unfinished"></translation>
1456 </message>
1457</context>
1458<context>
1459 <name>ManualWidget</name>
1460 <message>
1461 <source>&lt;a href=&apos;%1&apos;&gt;PDF Manual&lt;/a&gt;</source>
1462 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Manual PDF&lt;/a&gt;</translation>
1463 </message>
1464 <message>
1465 <source>&lt;a href=&apos;%1&apos;&gt;HTML Manual (opens in browser)&lt;/a&gt;</source>
1466 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Manual HTML (abre em um navegador)&lt;/a&gt;</translation>
1467 </message>
1468 <message>
1469 <source>Select a device for a link to the correct manual</source>
1470 <translation type="unfinished">Selecione um dispositivo para uma ligação ao manual correto</translation>
1471 </message>
1472 <message>
1473 <source>&lt;a href=&apos;%1&apos;&gt;Manual Overview&lt;/a&gt;</source>
1474 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Visão Geral do Manual&lt;/a&gt;</translation>
1475 </message>
1476 <message>
1477 <source>Confirm download</source>
1478 <translation type="unfinished">Confirmar transferência</translation>
1479 </message>
1480 <message>
1481 <source>Do you really want to download the manual? The manual will be saved to the root folder of your player.</source>
1482 <translation type="unfinished">Você realmente quer transferir o manual? O manual será salvo na pasta raiz do reprodutor.</translation>
1483 </message>
1484</context>
1485<context>
1486 <name>ManualWidgetFrm</name>
1487 <message>
1488 <source>Read the manual</source>
1489 <translation type="unfinished">Ler o manual</translation>
1490 </message>
1491 <message>
1492 <source>PDF manual</source>
1493 <translation type="unfinished">Manual PDF</translation>
1494 </message>
1495 <message>
1496 <source>HTML manual</source>
1497 <translation type="unfinished">Manual HTML</translation>
1498 </message>
1499 <message>
1500 <source>Download the manual</source>
1501 <translation type="unfinished">Transferência do manual</translation>
1502 </message>
1503 <message>
1504 <source>&amp;PDF version</source>
1505 <translation type="unfinished">Versão &amp;PDF</translation>
1506 </message>
1507 <message>
1508 <source>&amp;HTML version (zip file)</source>
1509 <translation type="unfinished">Versão &amp;HTML (arquivo zip)</translation>
1510 </message>
1511 <message>
1512 <source>Down&amp;load</source>
1513 <translation type="unfinished">Trans&amp;ferência</translation>
1514 </message>
1515 <message>
1516 <source>Manual</source>
1517 <translation type="unfinished"></translation>
1518 </message>
1519</context>
1520<context>
1521 <name>MsPackUtil</name>
1522 <message>
1523 <source>Creating output path failed</source>
1524 <translation type="unfinished"></translation>
1525 </message>
1526 <message>
1527 <source>Error during CAB operation</source>
1528 <translation type="unfinished"></translation>
1529 </message>
1530</context>
1531<context>
1532 <name>PreviewFrm</name>
1533 <message>
1534 <source>Preview</source>
1535 <translation>Previsão</translation>
1536 </message>
1537</context>
1538<context>
1539 <name>ProgressLoggerFrm</name>
1540 <message>
1541 <source>Progress</source>
1542 <translation>Progresso</translation>
1543 </message>
1544 <message>
1545 <source>progresswindow</source>
1546 <translation>janeladeprogresso</translation>
1547 </message>
1548 <message>
1549 <source>&amp;Abort</source>
1550 <translation>&amp;Abortar</translation>
1551 </message>
1552 <message>
1553 <source>Save Log</source>
1554 <translation>Salvar Log</translation>
1555 </message>
1556</context>
1557<context>
1558 <name>ProgressLoggerGui</name>
1559 <message>
1560 <source>&amp;Abort</source>
1561 <translation>&amp;Abortar</translation>
1562 </message>
1563 <message>
1564 <source>&amp;Ok</source>
1565 <translation>&amp;Ok</translation>
1566 </message>
1567 <message>
1568 <source>Save system trace log</source>
1569 <translation>Salvar trace log do sistema</translation>
1570 </message>
1571</context>
1572<context>
1573 <name>QObject</name>
1574 <message>
1575 <source>LTR</source>
1576 <extracomment>This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.
1577----------
1578This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.</extracomment>
1579 <translation>LTR</translation>
1580 </message>
1581 <message>
1582 <source>(unknown vendor name) </source>
1583 <translation type="unfinished"></translation>
1584 </message>
1585 <message>
1586 <source>(unknown product name)</source>
1587 <translation type="unfinished"></translation>
1588 </message>
1589 <message>
1590 <source>Bootloader installation is almost complete. Installation &lt;b&gt;requires&lt;/b&gt; you to perform the following steps manually:</source>
1591 <translation type="unfinished">A instalação do inicializador está quase completa. A instalação &lt;b&gt;requer&lt;/b&gt; que você execute os seguintes passos manualmente:</translation>
1592 </message>
1593 <message>
1594 <source>&lt;li&gt;Safely remove your player.&lt;/li&gt;</source>
1595 <translation type="unfinished">&lt;li&gt;Remova seu reprodutor de forma segura.&lt;/li&gt;</translation>
1596 </message>
1597 <message>
1598 <source>&lt;li&gt;Reboot your player into the original firmware.&lt;/li&gt;&lt;li&gt;Perform a firmware upgrade using the update functionality of the original firmware. Please refer to your player&apos;s manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before starting the firmware update process.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1599 <translation type="unfinished"></translation>
1600 </message>
1601 <message>
1602 <source>&lt;li&gt;Remove any previously inserted microSD card&lt;/li&gt;</source>
1603 <translation type="unfinished"></translation>
1604 </message>
1605 <message>
1606 <source>&lt;li&gt;Disconnect your player. The player will reboot and perform an update of the original firmware. Please refer to your players manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before disconnecting the player.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1607 <translation type="unfinished"></translation>
1608 </message>
1609 <message>
1610 <source>&lt;li&gt;Turn the player off&lt;/li&gt;&lt;li&gt;Insert the charger&lt;/li&gt;</source>
1611 <translation type="unfinished">&lt;li&gt;Desligue o reprodutor&lt;/li&gt;&lt;li&gt;Insira o carregador&lt;/li&gt;</translation>
1612 </message>
1613 <message>
1614 <source>&lt;li&gt;Unplug USB and power adaptors&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to turn the player off&lt;/li&gt;&lt;li&gt;Toggle the battery switch on the player&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to boot into Rockbox&lt;/li&gt;</source>
1615 <translation type="unfinished">&lt;li&gt;Desconecte os adaptadores USB e de alimentação&lt;/li&gt;&lt;li&gt;Pressione &lt;i&gt;Power&lt;/i&gt; para desligar o reprodutor&lt;/li&gt;&lt;li&gt;Alterne o interruptor da bateria no reprodutor&lt;/li&gt;&lt;li&gt;Pressione &lt;i&gt;Power&lt;/i&gt; para iniciar com o Rockbox&lt;/li&gt;</translation>
1616 </message>
1617 <message>
1618 <source>&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You can safely install other parts first, but the above steps are &lt;b&gt;required&lt;/b&gt; to finish the installation!&lt;/p&gt;</source>
1619 <translation type="unfinished">&lt;p&gt;&lt;b&gt;Nota:&lt;/b&gt; Você pode, de forma segura, instalar outros componentes primeiro, porém, os passos acima são &lt;b&gt;necessários&lt;/b&gt; para se finalizar a instalação!&lt;/p&gt;</translation>
1620 </message>
1621</context>
1622<context>
1623 <name>QuaZipFile</name>
1624 <message>
1625 <source>ZIP/UNZIP API error %1</source>
1626 <translation type="unfinished"></translation>
1627 </message>
1628</context>
1629<context>
1630 <name>RbUtilQt</name>
1631 <message>
1632 <source>Network error</source>
1633 <translation>Erro de rede</translation>
1634 </message>
1635 <message>
1636 <source>New installation</source>
1637 <translation>Nova instalação</translation>
1638 </message>
1639 <message>
1640 <source>This is a new installation of Rockbox Utility, or a new version. The configuration dialog will now open to allow you to setup the program, or review your settings.</source>
1641 <translation>Esta é uma nova instalação do Utilitário Rockbox, ou uma nova versão. A janela de configuração abrirá agora para permitir que você configure o programa, ou revise suas configurações.</translation>
1642 </message>
1643 <message>
1644 <source>Configuration error</source>
1645 <translation>Erro de configuração</translation>
1646 </message>
1647 <message>
1648 <source>Your configuration is invalid. This is most likely due to a changed device path. The configuration dialog will now open to allow you to correct the problem.</source>
1649 <translation>Sua configuração é inválida. Isto é geralmente causado por uma mudança no caminho do dispositivo. A janela de configuração abrirá agora para permitir que você corrija o problema.</translation>
1650 </message>
1651 <message>
1652 <source>Confirm Installation</source>
1653 <translation>Confirmar Instalação</translation>
1654 </message>
1655 <message>
1656 <source>Mount point is wrong!</source>
1657 <translation>O ponto de montagem está incorreto!</translation>
1658 </message>
1659 <message>
1660 <source>Warning</source>
1661 <translation>Atenção</translation>
1662 </message>
1663 <message>
1664 <source>The Application is still downloading Information about new Builds. Please try again shortly.</source>
1665 <translation>A Aplicação ainda está transferindo Informação sobre novas Compilações. Por favor, tente novamente em breve.</translation>
1666 </message>
1667 <message>
1668 <source>Do you really want to install the voice file?</source>
1669 <translation>Você realmente quer instalar o arquivo de voz?</translation>
1670 </message>
1671 <message>
1672 <source>Confirm Uninstallation</source>
1673 <translation>Confirmar Desinstalação</translation>
1674 </message>
1675 <message>
1676 <source>Do you really want to uninstall the Bootloader?</source>
1677 <translation>Você realmente quer desinstalar o Inicializador?</translation>
1678 </message>
1679 <message>
1680 <source>Confirm installation</source>
1681 <translation>Confirmar Instalação</translation>
1682 </message>
1683 <message>
1684 <source>Do you really want to install Rockbox Utility to your player? After installation you can run it from the players hard drive.</source>
1685 <translation>Você realmente quer instalar o Utilitário Rockbox em seu reprodutor? Depois da instalação você pode executá-lo a partir do disco rígido do reprodutor.</translation>
1686 </message>
1687 <message>
1688 <source>Installing Rockbox Utility</source>
1689 <translation>Instalando o Utilitário Rockbox</translation>
1690 </message>
1691 <message>
1692 <source>Error installing Rockbox Utility</source>
1693 <translation>Erro instalando o Utilitário Rockbox</translation>
1694 </message>
1695 <message>
1696 <source>Installing user configuration</source>
1697 <translation>Instalando configuração do usuário</translation>
1698 </message>
1699 <message>
1700 <source>Error installing user configuration</source>
1701 <translation>Erro instalando configuração do usuário</translation>
1702 </message>
1703 <message>
1704 <source>Successfully installed Rockbox Utility.</source>
1705 <translation>Utilitário Rockbox instalado com sucesso.</translation>
1706 </message>
1707 <message>
1708 <source>Your configuration is invalid. Please go to the configuration dialog and make sure the selected values are correct.</source>
1709 <translation>Sua configuração é inválida. Por favor, vá a janela de configuração e certifique-se de selecionar os valores corretos.</translation>
1710 </message>
1711 <message>
1712 <source>Downloading build information, please wait ...</source>
1713 <translation>Baixando informação de compilação, por favor espere...</translation>
1714 </message>
1715 <message>
1716 <source>Can&apos;t get version information!</source>
1717 <translation>Não é possível obter informação da versão!</translation>
1718 </message>
1719 <message>
1720 <source>Download build information finished.</source>
1721 <translation>Baixar informação de compilação finalizada.</translation>
1722 </message>
1723 <message>
1724 <source>RockboxUtility Update available</source>
1725 <translation>Disponível atualização do RockboxUtility</translation>
1726 </message>
1727 <message>
1728 <source>&lt;b&gt;New RockboxUtility Version available.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Download it from here: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</source>
1729 <translation>&lt;b&gt;Nova versão do RockboxUtility disponível.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Baixá-la daqui: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</translation>
1730 </message>
1731 <message>
1732 <source>Wine detected!</source>
1733 <translation>Detectado Wine!</translation>
1734 </message>
1735 <message>
1736 <source>It seems you are trying to run this program under Wine. Please don&apos;t do this, running under Wine will fail. Use the native Linux binary instead.</source>
1737 <translation>Parece que você está tentando rodar este programa sob o Wine. Por favor não faça isso, rodar sob o Wine irá falhar. Ao invés disso, use um Linux nativo.</translation>
1738 </message>
1739 <message>
1740 <source>Can&apos;t get version information.
1741Network error: %1. Please check your network and proxy settings.</source>
1742 <translation>Não é possível obter informação de versão.
1743Erro de rede: %1. Por favor, verifique sua configuração de rede e proxy.</translation>
1744 </message>
1745 <message>
1746 <source>No uninstall method for this target known.</source>
1747 <translation>Não é conhecido método de desistalação deste alvo.</translation>
1748 </message>
1749 <message>
1750 <source>Rockbox Utility can not uninstall the bootloader on this target. Try a normal firmware update to remove the booloader.</source>
1751 <translation>O Utilitário Rockbox não pode desinstalar o inicializador neste alvo. Tente uma atualização normal de firmware para remover o inicializador.</translation>
1752 </message>
1753 <message>
1754 <source>No Rockbox installation found</source>
1755 <translation>Nenhuma instalação do Rockbox encontrada</translation>
1756 </message>
1757 <message>
1758 <source>Could not determine the installed Rockbox version. Please install a Rockbox build before installing voice files.</source>
1759 <translation>Não foi possível determinar a versão do Rockbox instalada. Por favor, instale uma compilação do Rockbox antes de instalar arquivos de voz.</translation>
1760 </message>
1761 <message>
1762 <source>Checking for update ...</source>
1763 <translation>Procurando atualizações...</translation>
1764 </message>
1765 <message>
1766 <source>New version of Rockbox Utility available.</source>
1767 <translation>Nova versão do Utilitário Rockbox disponível.</translation>
1768 </message>
1769 <message>
1770 <source>Rockbox Utility is up to date.</source>
1771 <translation>O Utilitário Rockbox está atualizado.</translation>
1772 </message>
1773 <message>
1774 <source>No voice file available</source>
1775 <translation type="unfinished"></translation>
1776 </message>
1777 <message>
1778 <source>The installed version of Rockbox is a development version. Pre-built voices are only available for release versions of Rockbox. Please generate a voice yourself using the &quot;Create voice file&quot; functionality.</source>
1779 <translation type="unfinished"></translation>
1780 </message>
1781 <message>
1782 <source>No Rockbox bootloader found.</source>
1783 <translation type="unfinished"></translation>
1784 </message>
1785 <message>
1786 <source>Device ejected</source>
1787 <translation type="unfinished"></translation>
1788 </message>
1789 <message>
1790 <source>Device successfully ejected. You may now disconnect the player from the PC.</source>
1791 <translation type="unfinished"></translation>
1792 </message>
1793 <message>
1794 <source>Ejecting failed</source>
1795 <translation type="unfinished"></translation>
1796 </message>
1797 <message>
1798 <source>Ejecting the device failed. Please make sure no programs are accessing files on the device. If ejecting still fails please use your computers eject funtionality.</source>
1799 <translation type="unfinished"></translation>
1800 </message>
1801</context>
1802<context>
1803 <name>RbUtilQtFrm</name>
1804 <message>
1805 <source>Rockbox Utility</source>
1806 <translation>Utilitário Rockbox</translation>
1807 </message>
1808 <message>
1809 <source>Device</source>
1810 <translation>Dispositivo</translation>
1811 </message>
1812 <message>
1813 <source>&amp;Change</source>
1814 <translation>M&amp;odificar</translation>
1815 </message>
1816 <message>
1817 <source>Welcome</source>
1818 <translation>Bem-vindo</translation>
1819 </message>
1820 <message>
1821 <source>&amp;Installation</source>
1822 <translation>Ins&amp;talação</translation>
1823 </message>
1824 <message>
1825 <source>&amp;Accessibility</source>
1826 <translation>Acessi&amp;bilidade</translation>
1827 </message>
1828 <message>
1829 <source>Install accessibility add-ons</source>
1830 <translation>Instalar complementos de acessibilidade</translation>
1831 </message>
1832 <message>
1833 <source>Install Voice files</source>
1834 <translation>Instalar arquivos de Voz</translation>
1835 </message>
1836 <message>
1837 <source>&lt;b&gt;Install Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so if you installed the voice file Rockbox will speak.</source>
1838 <translation>&lt;b&gt;Instalar arquivos de Voz&lt;/b&gt;&lt;br/&gt;Os arquivos de Voz são necessários para que o Rockbox fale a interface do usuário. A fala é habilitada por padrão, logo, se você instalar o arquivo de voz, o Rockbox falará.</translation>
1839 </message>
1840 <message>
1841 <source>Install Talk files</source>
1842 <translation>Instalar arquivos Talk</translation>
1843 </message>
1844 <message>
1845 <source>&lt;b&gt;Create Talk Files&lt;/b&gt;&lt;br/&gt;Talkfiles are needed to let Rockbox speak File and Foldernames</source>
1846 <translation>&lt;b&gt;Criar Arquivos Talk&lt;/b&gt;&lt;br/&gt;Os Arquivos Talk são necessários para permitir ao Rockbox falar os Nomes dos Arquivos e Pasta</translation>
1847 </message>
1848 <message>
1849 <source>Create Voice files</source>
1850 <translation>Criar arquivos de Voz</translation>
1851 </message>
1852 <message>
1853 <source>&lt;b&gt;Create Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so
1854 if you installed the voice file Rockbox will speak.</source>
1855 <translation>&lt;b&gt;Criar arquivo de Voz&lt;/b&gt;&lt;br/&gt;Os arquivos de Voz são necessários para permitir ao Rockbox falar a interface do usuário. A Fala é habilitada por padrão, logo,
1856se você instalar o arquivo de voz, o Rockbox falará.</translation>
1857 </message>
1858 <message>
1859 <source>&amp;Uninstallation</source>
1860 <translation>&amp;Desinstalação</translation>
1861 </message>
1862 <message>
1863 <source>Uninstall Rockbox</source>
1864 <translation>Desinstalar Rockbox</translation>
1865 </message>
1866 <message>
1867 <source>Uninstall Bootloader</source>
1868 <translation>Desinstalar Inicializador</translation>
1869 </message>
1870 <message>
1871 <source>&lt;b&gt;Remove the bootloader&lt;/b&gt;&lt;br/&gt;After removing the bootloader you won&apos;t be able to start Rockbox.</source>
1872 <translation>&lt;b&gt;Remover o inicializador&lt;/b&gt;&lt;br/&gt;Após remover o inicializador você não poderá iniciar o Rockbox.</translation>
1873 </message>
1874 <message>
1875 <source>&lt;b&gt;Uninstall Rockbox from your audio player.&lt;/b&gt;&lt;br/&gt;This will leave the bootloader in place (you need to remove it manually).</source>
1876 <translation>&lt;b&gt;Desinstalar o Rockbox do seu reprodutor de audio.&lt;/b&gt;&lt;br/&gt;Esta opção não remove o inicializador (você deve removê-lo manualmente).</translation>
1877 </message>
1878 <message>
1879 <source>&amp;Manual</source>
1880 <translation>&amp;Manual</translation>
1881 </message>
1882 <message>
1883 <source>View and download the manual</source>
1884 <translation>Visualizar e transferir o manual</translation>
1885 </message>
1886 <message>
1887 <source>Inf&amp;o</source>
1888 <translation>Inf&amp;ormação</translation>
1889 </message>
1890 <message>
1891 <source>&amp;File</source>
1892 <translation>&amp;Arquivo</translation>
1893 </message>
1894 <message>
1895 <source>Action&amp;s</source>
1896 <translation>Açõe&amp;s</translation>
1897 </message>
1898 <message>
1899 <source>Empty local download cache</source>
1900 <translation>Limpar cache de transferência local</translation>
1901 </message>
1902 <message>
1903 <source>Install Rockbox Utility on player</source>
1904 <translation>Instalar Utilitário Rockbox no reprodutor</translation>
1905 </message>
1906 <message>
1907 <source>&amp;Configure</source>
1908 <translation>&amp;Configurar</translation>
1909 </message>
1910 <message>
1911 <source>E&amp;xit</source>
1912 <translation>Sai&amp;r</translation>
1913 </message>
1914 <message>
1915 <source>Ctrl+Q</source>
1916 <translation>Ctrl+Q</translation>
1917 </message>
1918 <message>
1919 <source>&amp;About</source>
1920 <translation>S&amp;obre</translation>
1921 </message>
1922 <message>
1923 <source>About &amp;Qt</source>
1924 <translation>Sobre &amp;Qt</translation>
1925 </message>
1926 <message>
1927 <source>&amp;Help</source>
1928 <translation>A&amp;juda</translation>
1929 </message>
1930 <message>
1931 <source>Info</source>
1932 <translation>Informação</translation>
1933 </message>
1934 <message>
1935 <source>&amp;Complete Installation</source>
1936 <translation>&amp;Instalação Completa</translation>
1937 </message>
1938 <message>
1939 <source>&amp;Minimal Installation</source>
1940 <translation>Instalação &amp;Mínima</translation>
1941 </message>
1942 <message>
1943 <source>Install &amp;Bootloader</source>
1944 <translation>Instalar &amp;Inicializador</translation>
1945 </message>
1946 <message>
1947 <source>Install &amp;Rockbox</source>
1948 <translation>Instalar &amp;Rockbox</translation>
1949 </message>
1950 <message>
1951 <source>Install &amp;Fonts Package</source>
1952 <translation>Instalar Pacotes de &amp;Fontes</translation>
1953 </message>
1954 <message>
1955 <source>Install &amp;Themes</source>
1956 <translation>Instalar &amp;Temas</translation>
1957 </message>
1958 <message>
1959 <source>Install &amp;Game Files</source>
1960 <translation>Instalar Arquivos de &amp;Jogos</translation>
1961 </message>
1962 <message>
1963 <source>&amp;Install Voice File</source>
1964 <translation>&amp;Instalar Arquivo de Voz</translation>
1965 </message>
1966 <message>
1967 <source>Create &amp;Talk Files</source>
1968 <translation>Criar Arquivos &amp;Talk</translation>
1969 </message>
1970 <message>
1971 <source>Remove &amp;bootloader</source>
1972 <translation>Remover &amp;Inicializador</translation>
1973 </message>
1974 <message>
1975 <source>Uninstall &amp;Rockbox</source>
1976 <translation>Desinstalar &amp;Rockbox</translation>
1977 </message>
1978 <message>
1979 <source>Read PDF manual</source>
1980 <translation>Ler Manual PDF</translation>
1981 </message>
1982 <message>
1983 <source>Read HTML manual</source>
1984 <translation>Ler Manual HTML</translation>
1985 </message>
1986 <message>
1987 <source>Download PDF manual</source>
1988 <translation>Transferir manual PDF</translation>
1989 </message>
1990 <message>
1991 <source>Download HTML manual (zip)</source>
1992 <translation>Transferir manual HTML (zip)</translation>
1993 </message>
1994 <message>
1995 <source>Create &amp;Voice File</source>
1996 <translation>Criar Arquivo de &amp;Voz</translation>
1997 </message>
1998 <message>
1999 <source>Create Voice File</source>
2000 <translation>Criar Arquivo de Voz</translation>
2001 </message>
2002 <message>
2003 <source>&amp;System Info</source>
2004 <translation>Informação do &amp;Sistema</translation>
2005 </message>
2006 <message>
2007 <source>&amp;Troubleshoot</source>
2008 <translation>&amp;Relatar Falhas</translation>
2009 </message>
2010 <message>
2011 <source>System &amp;Trace</source>
2012 <translation>&amp;Trace do Sistema</translation>
2013 </message>
2014 <message>
2015 <source>mountpoint unknown or invalid</source>
2016 <translation type="unfinished"></translation>
2017 </message>
2018 <message>
2019 <source>Mountpoint:</source>
2020 <translation type="unfinished"></translation>
2021 </message>
2022 <message>
2023 <source>device unknown or invalid</source>
2024 <translation type="unfinished"></translation>
2025 </message>
2026 <message>
2027 <source>Device:</source>
2028 <translation type="unfinished"></translation>
2029 </message>
2030 <message>
2031 <source>Backup &amp;&amp; &amp;Uninstallation</source>
2032 <translation type="unfinished"></translation>
2033 </message>
2034 <message>
2035 <source>Backup</source>
2036 <translation type="unfinished">Cópia de Segurança</translation>
2037 </message>
2038 <message>
2039 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup current installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Create a backup by archiving the contents of the Rockbox installation folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2040 <translation type="unfinished"></translation>
2041 </message>
2042 <message>
2043 <source>&amp;Eject</source>
2044 <translation type="unfinished"></translation>
2045 </message>
2046 <message>
2047 <source>Show &amp;Changelog</source>
2048 <translation type="unfinished"></translation>
2049 </message>
2050</context>
2051<context>
2052 <name>SelectiveInstallWidget</name>
2053 <message>
2054 <source>Rockbox version to install</source>
2055 <translation type="unfinished"></translation>
2056 </message>
2057 <message>
2058 <source>Version information not available yet.</source>
2059 <translation type="unfinished"></translation>
2060 </message>
2061 <message>
2062 <source>Rockbox components to install</source>
2063 <translation type="unfinished"></translation>
2064 </message>
2065 <message>
2066 <source>&amp;Bootloader</source>
2067 <translation type="unfinished"></translation>
2068 </message>
2069 <message>
2070 <source>The main Rockbox firmware.</source>
2071 <translation type="unfinished"></translation>
2072 </message>
2073 <message>
2074 <source>Fonts</source>
2075 <translation type="unfinished"></translation>
2076 </message>
2077 <message>
2078 <source>&amp;Rockbox</source>
2079 <translation type="unfinished"></translation>
2080 </message>
2081 <message>
2082 <source>Some game plugins require additional files.</source>
2083 <translation type="unfinished"></translation>
2084 </message>
2085 <message>
2086 <source>Additional fonts for the User Interface.</source>
2087 <translation type="unfinished"></translation>
2088 </message>
2089 <message>
2090 <source>The bootloader is required for starting Rockbox. Only necessary for first time install.</source>
2091 <translation type="unfinished"></translation>
2092 </message>
2093 <message>
2094 <source>Game Files</source>
2095 <translation type="unfinished"></translation>
2096 </message>
2097 <message>
2098 <source>Customize</source>
2099 <translation type="unfinished"></translation>
2100 </message>
2101 <message>
2102 <source>Themes</source>
2103 <translation type="unfinished"></translation>
2104 </message>
2105 <message>
2106 <source>Themes allow adjusting the user interface of Rockbox. Use &quot;Customize&quot; to select themes.</source>
2107 <translation type="unfinished"></translation>
2108 </message>
2109 <message>
2110 <source>&amp;Install</source>
2111 <translation type="unfinished">&amp;Instalar</translation>
2112 </message>
2113 <message>
2114 <source>This is the latest stable release available.</source>
2115 <translation type="unfinished"></translation>
2116 </message>
2117 <message>
2118 <source>The development version is updated on every code change. Last update was on %1</source>
2119 <translation type="unfinished"></translation>
2120 </message>
2121 <message>
2122 <source>This will eventually become the next Rockbox version. Install it to help testing.</source>
2123 <translation type="unfinished"></translation>
2124 </message>
2125 <message>
2126 <source>Stable Release (Version %1)</source>
2127 <translation type="unfinished"></translation>
2128 </message>
2129 <message>
2130 <source>Development Version (Revison %1)</source>
2131 <translation type="unfinished"></translation>
2132 </message>
2133 <message>
2134 <source>Release Candidate (Revison %1)</source>
2135 <translation type="unfinished"></translation>
2136 </message>
2137 <message>
2138 <source>The selected player doesn&apos;t need a bootloader.</source>
2139 <translation type="unfinished"></translation>
2140 </message>
2141 <message>
2142 <source>The bootloader is required for starting Rockbox. Installation of the bootloader is only necessary on first time installation.</source>
2143 <translation type="unfinished"></translation>
2144 </message>
2145 <message>
2146 <source>Mountpoint is wrong</source>
2147 <translation type="unfinished"></translation>
2148 </message>
2149 <message>
2150 <source>No install method known.</source>
2151 <translation type="unfinished">Nenhum método de instalação conhecido.</translation>
2152 </message>
2153 <message>
2154 <source>Bootloader detected</source>
2155 <translation type="unfinished">Detectado Inicializador</translation>
2156 </message>
2157 <message>
2158 <source>Bootloader already installed. Do you want to reinstall the bootloader?</source>
2159 <translation type="unfinished">Inicializador já instalado. Você quer reinstalar o inicializador?</translation>
2160 </message>
2161 <message>
2162 <source>Bootloader installation skipped</source>
2163 <translation type="unfinished">Instalação do Inicializador ignorada</translation>
2164 </message>
2165 <message>
2166 <source>Create Bootloader backup</source>
2167 <translation type="unfinished">Criar cópia de segurança do Inicializador</translation>
2168 </message>
2169 <message>
2170 <source>You can create a backup of the original bootloader file. Press &quot;Yes&quot; to select an output folder on your computer to save the file to. The file will get placed in a new folder &quot;%1&quot; created below the selected folder.
2171Press &quot;No&quot; to skip this step.</source>
2172 <translation type="unfinished">Você pode criar uma cópia de segurança do arquivo original do inicializador. Pressione &quot;Sim&quot; para selecionar a pasta de saída no seu computador, onde salvar o arquivo. O arquivo será colocado em uma nova pasta &quot;%1&quot; criada dentro da pasta selecionada.
2173Pressione &quot;Não&quot; para pular esse passo.</translation>
2174 </message>
2175 <message>
2176 <source>Browse backup folder</source>
2177 <translation type="unfinished">Navegar na pasta de cópia de segurança</translation>
2178 </message>
2179 <message>
2180 <source>Prerequisites</source>
2181 <translation type="unfinished">Pré-requisitos</translation>
2182 </message>
2183 <message>
2184 <source>Bootloader installation aborted</source>
2185 <translation type="unfinished">Instalação do Inicializador abortada</translation>
2186 </message>
2187 <message>
2188 <source>Bootloader files (%1)</source>
2189 <translation type="unfinished"></translation>
2190 </message>
2191 <message>
2192 <source>All files (*)</source>
2193 <translation type="unfinished"></translation>
2194 </message>
2195 <message>
2196 <source>Select firmware file</source>
2197 <translation type="unfinished">Selecione o arquivo de firmware</translation>
2198 </message>
2199 <message>
2200 <source>Error opening firmware file</source>
2201 <translation type="unfinished">Erro abrindo arquivo de firmware</translation>
2202 </message>
2203 <message>
2204 <source>Error reading firmware file</source>
2205 <translation type="unfinished"></translation>
2206 </message>
2207 <message>
2208 <source>Backup error</source>
2209 <translation type="unfinished">Erro na cópia de segurança</translation>
2210 </message>
2211 <message>
2212 <source>Could not create backup file. Continue?</source>
2213 <translation type="unfinished">Não foi possível criar o arquivo de cópia de segurança. Continuar?</translation>
2214 </message>
2215 <message>
2216 <source>Manual steps required</source>
2217 <translation type="unfinished">Passo manual requerido</translation>
2218 </message>
2219 <message>
2220 <source>Continue with installation?</source>
2221 <translation type="unfinished"></translation>
2222 </message>
2223 <message>
2224 <source>Really continue?</source>
2225 <translation type="unfinished">Realmente continuar?</translation>
2226 </message>
2227 <message>
2228 <source>Aborted!</source>
2229 <translation type="obsolete">Abortado!</translation>
2230 </message>
2231 <message>
2232 <source>Your installation doesn&apos;t require game files, skipping.</source>
2233 <translation type="unfinished"></translation>
2234 </message>
2235 <message>
2236 <source>Selective Installation</source>
2237 <translation type="unfinished"></translation>
2238 </message>
2239</context>
2240<context>
2241 <name>ServerInfo</name>
2242 <message>
2243 <source>Unknown</source>
2244 <translation>Desconhecido</translation>
2245 </message>
2246 <message>
2247 <source>Unusable</source>
2248 <translation>Inutilizável</translation>
2249 </message>
2250 <message>
2251 <source>Unstable</source>
2252 <translation>Instável</translation>
2253 </message>
2254 <message>
2255 <source>Stable</source>
2256 <translation>Estável</translation>
2257 </message>
2258</context>
2259<context>
2260 <name>SysTrace</name>
2261 <message>
2262 <source>Save system trace log</source>
2263 <translation>Salvar trace log do sistema</translation>
2264 </message>
2265</context>
2266<context>
2267 <name>SysTraceFrm</name>
2268 <message>
2269 <source>System Trace</source>
2270 <translation>Trace do Sistema</translation>
2271 </message>
2272 <message>
2273 <source>System State trace</source>
2274 <translation>Trace do Estado do Sistema</translation>
2275 </message>
2276 <message>
2277 <source>&amp;Close</source>
2278 <translation>Fecha&amp;r</translation>
2279 </message>
2280 <message>
2281 <source>&amp;Save</source>
2282 <translation>&amp;Salvar</translation>
2283 </message>
2284 <message>
2285 <source>&amp;Refresh</source>
2286 <translation>&amp;Atualizar</translation>
2287 </message>
2288 <message>
2289 <source>Save &amp;previous</source>
2290 <translation>Salvar &amp;anterior</translation>
2291 </message>
2292</context>
2293<context>
2294 <name>Sysinfo</name>
2295 <message>
2296 <source>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</source>
2297 <translation>&lt;b&gt;SO&lt;/b&gt;&lt;br/&gt;</translation>
2298 </message>
2299 <message>
2300 <source>&lt;b&gt;Username&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2301 <translation>&lt;b&gt;Usuário&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2302 </message>
2303 <message>
2304 <source>&lt;b&gt;Permissions&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2305 <translation>&lt;b&gt;Permissões&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2306 </message>
2307 <message>
2308 <source>&lt;b&gt;Attached USB devices&lt;/b&gt;&lt;br/&gt;</source>
2309 <translation>&lt;b&gt;Dispositivo USB conectado&lt;/b&gt;&lt;br/&gt;</translation>
2310 </message>
2311 <message>
2312 <source>VID: %1 PID: %2, %3</source>
2313 <translation>VID: %1 PID: %2, %3</translation>
2314 </message>
2315 <message>
2316 <source>Filesystem</source>
2317 <translation>Sistema de arquivos</translation>
2318 </message>
2319 <message>
2320 <source>Mountpoint</source>
2321 <translation type="unfinished"></translation>
2322 </message>
2323 <message>
2324 <source>Label</source>
2325 <translation type="unfinished"></translation>
2326 </message>
2327 <message>
2328 <source>Free</source>
2329 <translation type="unfinished"></translation>
2330 </message>
2331 <message>
2332 <source>Total</source>
2333 <translation type="unfinished"></translation>
2334 </message>
2335 <message>
2336 <source>Cluster Size</source>
2337 <translation type="unfinished"></translation>
2338 </message>
2339 <message>
2340 <source>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</source>
2341 <translation type="unfinished"></translation>
2342 </message>
2343</context>
2344<context>
2345 <name>SysinfoFrm</name>
2346 <message>
2347 <source>System Info</source>
2348 <translation>Informação do Sistema</translation>
2349 </message>
2350 <message>
2351 <source>&amp;Refresh</source>
2352 <translation>&amp;Atualizar</translation>
2353 </message>
2354 <message>
2355 <source>&amp;OK</source>
2356 <translation>&amp;OK</translation>
2357 </message>
2358</context>
2359<context>
2360 <name>System</name>
2361 <message>
2362 <source>Guest</source>
2363 <translation>Convidado</translation>
2364 </message>
2365 <message>
2366 <source>Admin</source>
2367 <translation>Administrador</translation>
2368 </message>
2369 <message>
2370 <source>User</source>
2371 <translation>Usuário</translation>
2372 </message>
2373 <message>
2374 <source>Error</source>
2375 <translation>Erro</translation>
2376 </message>
2377 <message>
2378 <source>(no description available)</source>
2379 <translation>(nenhuma descrição disponível)</translation>
2380 </message>
2381</context>
2382<context>
2383 <name>TTSBase</name>
2384 <message>
2385 <source>Espeak TTS Engine</source>
2386 <translation type="unfinished"></translation>
2387 </message>
2388 <message>
2389 <source>Flite TTS Engine</source>
2390 <translation type="unfinished"></translation>
2391 </message>
2392 <message>
2393 <source>Swift TTS Engine</source>
2394 <translation type="unfinished"></translation>
2395 </message>
2396 <message>
2397 <source>Festival TTS Engine</source>
2398 <translation type="unfinished"></translation>
2399 </message>
2400 <message>
2401 <source>OS X System Engine</source>
2402 <translation type="unfinished"></translation>
2403 </message>
2404 <message>
2405 <source>SAPI4 TTS Engine</source>
2406 <translation type="unfinished"></translation>
2407 </message>
2408 <message>
2409 <source>SAPI5 TTS Engine</source>
2410 <translation type="unfinished"></translation>
2411 </message>
2412 <message>
2413 <source>MS Speech Platform</source>
2414 <translation type="unfinished"></translation>
2415 </message>
2416</context>
2417<context>
2418 <name>TTSCarbon</name>
2419 <message>
2420 <source>Voice:</source>
2421 <translation>Voz:</translation>
2422 </message>
2423 <message>
2424 <source>Speed (words/min):</source>
2425 <translation>Velocidade (palavras/min):</translation>
2426 </message>
2427 <message>
2428 <source>Could not voice string</source>
2429 <translation>Não foi possível criar a string de voz</translation>
2430 </message>
2431 <message>
2432 <source>Could not convert intermediate file</source>
2433 <translation>Não foi possível converter o arquivo intermediário</translation>
2434 </message>
2435 <message>
2436 <source>Pitch (0 for default):</source>
2437 <translation type="unfinished"></translation>
2438 </message>
2439</context>
2440<context>
2441 <name>TTSExes</name>
2442 <message>
2443 <source>Path to TTS engine:</source>
2444 <translation>Caminho para o motor TTS:</translation>
2445 </message>
2446 <message>
2447 <source>TTS engine options:</source>
2448 <translation>Opções do motor TTS:</translation>
2449 </message>
2450 <message>
2451 <source>TTS executable not found</source>
2452 <translation>Executável TTS não encontrado</translation>
2453 </message>
2454</context>
2455<context>
2456 <name>TTSFestival</name>
2457 <message>
2458 <source>Path to Festival client:</source>
2459 <translation>Caminho para o criente Festival:</translation>
2460 </message>
2461 <message>
2462 <source>Voice:</source>
2463 <translation>Voz:</translation>
2464 </message>
2465 <message>
2466 <source>Voice description:</source>
2467 <translation>Descrição de voz:</translation>
2468 </message>
2469 <message>
2470 <source>engine could not voice string</source>
2471 <translation>o motor não pode criar a voz para a string</translation>
2472 </message>
2473 <message>
2474 <source>No description available</source>
2475 <translation>Nenhuma descrição disponível</translation>
2476 </message>
2477</context>
2478<context>
2479 <name>TTSSapi</name>
2480 <message>
2481 <source>Language:</source>
2482 <translation>Idioma:</translation>
2483 </message>
2484 <message>
2485 <source>Voice:</source>
2486 <translation>Voz:</translation>
2487 </message>
2488 <message>
2489 <source>Speed:</source>
2490 <translation>Velocidade:</translation>
2491 </message>
2492 <message>
2493 <source>Options:</source>
2494 <translation>Opções:</translation>
2495 </message>
2496 <message>
2497 <source>Could not copy the SAPI script</source>
2498 <translation type="unfinished"></translation>
2499 </message>
2500 <message>
2501 <source>Could not start SAPI process</source>
2502 <translation type="unfinished"></translation>
2503 </message>
2504</context>
2505<context>
2506 <name>TalkFileCreator</name>
2507 <message>
2508 <source>Reading Filelist...</source>
2509 <translation>Lendo Lista de Arquivos...</translation>
2510 </message>
2511 <message>
2512 <source>Talk file creation aborted</source>
2513 <translation>Criação de arquivo Talk abortada</translation>
2514 </message>
2515 <message>
2516 <source>Finished creating Talk files</source>
2517 <translation>Criação de arquivos Talk finalizada</translation>
2518 </message>
2519 <message>
2520 <source>Copying of %1 to %2 failed</source>
2521 <translation>Cópia de %1 para %2 falhou</translation>
2522 </message>
2523 <message>
2524 <source>Copying Talkfiles...</source>
2525 <translation>Copiando arquivos Talk...</translation>
2526 </message>
2527 <message>
2528 <source>File copy aborted</source>
2529 <translation>Cópia de arquivo abortada</translation>
2530 </message>
2531 <message>
2532 <source>Finished</source>
2533 <translation>Finalizado</translation>
2534 </message>
2535 <message>
2536 <source>Cleaning up...</source>
2537 <translation>Limpando...</translation>
2538 </message>
2539 <message>
2540 <source>Starting Talk file generation for folder %1</source>
2541 <translation type="unfinished"></translation>
2542 </message>
2543</context>
2544<context>
2545 <name>TalkGenerator</name>
2546 <message>
2547 <source>Starting TTS Engine</source>
2548 <translation>Iniciando motor TTS</translation>
2549 </message>
2550 <message>
2551 <source>Init of TTS engine failed</source>
2552 <translation>Falhou ao iniciar o motor TTS</translation>
2553 </message>
2554 <message>
2555 <source>Starting Encoder Engine</source>
2556 <translation>Iniciando Motor Codificador</translation>
2557 </message>
2558 <message>
2559 <source>Init of Encoder engine failed</source>
2560 <translation>Falhou ao iniciar o motor Codificador</translation>
2561 </message>
2562 <message>
2563 <source>Voicing entries...</source>
2564 <translation>Vocalizando entradas...</translation>
2565 </message>
2566 <message>
2567 <source>Encoding files...</source>
2568 <translation>Codificando arquivos...</translation>
2569 </message>
2570 <message>
2571 <source>Voicing aborted</source>
2572 <translation>Vocalização abortada</translation>
2573 </message>
2574 <message>
2575 <source>Voicing of %1 failed: %2</source>
2576 <translation>Vocalização de %1 falhou: %2</translation>
2577 </message>
2578 <message>
2579 <source>Encoding aborted</source>
2580 <translation>Codificação abortada</translation>
2581 </message>
2582 <message>
2583 <source>Encoding of %1 failed</source>
2584 <translation>Codificação de %1 falhou</translation>
2585 </message>
2586</context>
2587<context>
2588 <name>ThemeInstallFrm</name>
2589 <message>
2590 <source>Theme Installation</source>
2591 <translation>Instalação de Tema</translation>
2592 </message>
2593 <message>
2594 <source>Selected Theme</source>
2595 <translation>Tema selecionado</translation>
2596 </message>
2597 <message>
2598 <source>Description</source>
2599 <translation>Descrição</translation>
2600 </message>
2601 <message>
2602 <source>Download size:</source>
2603 <translation>Tamanho:</translation>
2604 </message>
2605 <message>
2606 <source>Hold Ctrl to select multiple item, Shift for a range</source>
2607 <translation>Pressione Ctrl para selecionar múltiplos itens, Shift para um intervalo</translation>
2608 </message>
2609 <message>
2610 <source>&amp;Install</source>
2611 <translation>&amp;Instalar</translation>
2612 </message>
2613 <message>
2614 <source>&amp;Cancel</source>
2615 <translation>&amp;Cancelar</translation>
2616 </message>
2617</context>
2618<context>
2619 <name>ThemesInstallWindow</name>
2620 <message>
2621 <source>no theme selected</source>
2622 <translation>nenhum tema selecionado</translation>
2623 </message>
2624 <message>
2625 <source>no selection</source>
2626 <translation>nenhuma seleção</translation>
2627 </message>
2628 <message>
2629 <source>Network error: %1.
2630Please check your network and proxy settings.</source>
2631 <translation>Erro de rede: %1.
2632Por favor, verifique suas configurações de rede e proxy.</translation>
2633 </message>
2634 <message>
2635 <source>the following error occured:
2636%1</source>
2637 <translation>o seguinte erro ocorreu:
2638%1</translation>
2639 </message>
2640 <message>
2641 <source>done.</source>
2642 <translation>feito.</translation>
2643 </message>
2644 <message>
2645 <source>Information</source>
2646 <translation>Informação</translation>
2647 </message>
2648 <message>
2649 <source>fetching details for %1</source>
2650 <translation>transferindo detalhes para %1</translation>
2651 </message>
2652 <message>
2653 <source>fetching preview ...</source>
2654 <translation>transferindo pré-visualização ...</translation>
2655 </message>
2656 <message>
2657 <source>&lt;b&gt;Author:&lt;/b&gt; %1&lt;hr/&gt;</source>
2658 <translation>&lt;b&gt;Autor:&lt;/b&gt; %1&lt;hr/&gt;</translation>
2659 </message>
2660 <message>
2661 <source>unknown</source>
2662 <translation>desconhecido</translation>
2663 </message>
2664 <message>
2665 <source>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</source>
2666 <translation>&lt;b&gt;Versão:&lt;/b&gt; %1&lt;hr/&gt;</translation>
2667 </message>
2668 <message>
2669 <source>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</source>
2670 <translation>&lt;b&gt;Descrição:&lt;/b&gt; %1&lt;hr/&gt;</translation>
2671 </message>
2672 <message>
2673 <source>no description</source>
2674 <translation>sem descrição</translation>
2675 </message>
2676 <message>
2677 <source>Retrieving theme preview failed.
2678HTTP response code: %1</source>
2679 <translation>Falha ao obter pré-visualização do tema.
2680código de resposta HTTP: %1</translation>
2681 </message>
2682 <message>
2683 <source>no theme preview</source>
2684 <translation>sem pré-visualização do tema</translation>
2685 </message>
2686 <message>
2687 <source>getting themes information ...</source>
2688 <translation>obtendo infomação dos temas ...</translation>
2689 </message>
2690 <message>
2691 <source>Mount point is wrong!</source>
2692 <translation>O ponto de montagem está incorreto!</translation>
2693 </message>
2694 <message numerus="yes">
2695 <source>Download size %L1 kiB (%n item(s))</source>
2696 <translation>
2697 <numerusform>Tamanho %L1 kiB (%n item)</numerusform>
2698 <numerusform>Tamanho %L1 kiB (%n itens)</numerusform>
2699 </translation>
2700 </message>
2701 <message>
2702 <source>Select</source>
2703 <translation type="unfinished"></translation>
2704 </message>
2705 <message>
2706 <source>No themes selected, skipping</source>
2707 <translation type="unfinished"></translation>
2708 </message>
2709</context>
2710<context>
2711 <name>UninstallFrm</name>
2712 <message>
2713 <source>Uninstall Rockbox</source>
2714 <translation>Desinstalar Rockbox</translation>
2715 </message>
2716 <message>
2717 <source>Please select the Uninstallation Method</source>
2718 <translation>Por favor, selecione o Método de Desinstalação</translation>
2719 </message>
2720 <message>
2721 <source>Uninstallation Method</source>
2722 <translation>Método de Desinstalação</translation>
2723 </message>
2724 <message>
2725 <source>Complete Uninstallation</source>
2726 <translation>Desinstalação Completa</translation>
2727 </message>
2728 <message>
2729 <source>Smart Uninstallation</source>
2730 <translation>Desinstalação Inteligente</translation>
2731 </message>
2732 <message>
2733 <source>Please select what you want to uninstall</source>
2734 <translation>Por favor, selecione o que você quer desinstalar</translation>
2735 </message>
2736 <message>
2737 <source>Installed Parts</source>
2738 <translation>Partes Instaladas</translation>
2739 </message>
2740 <message>
2741 <source>&amp;Uninstall</source>
2742 <translation>&amp;Desinstalar</translation>
2743 </message>
2744 <message>
2745 <source>&amp;Cancel</source>
2746 <translation>&amp;Cancelar</translation>
2747 </message>
2748</context>
2749<context>
2750 <name>Uninstaller</name>
2751 <message>
2752 <source>Starting Uninstallation</source>
2753 <translation>Iniciando Desinstalação</translation>
2754 </message>
2755 <message>
2756 <source>Finished Uninstallation</source>
2757 <translation>Desinstalação Finalizada</translation>
2758 </message>
2759 <message>
2760 <source>Uninstallation finished</source>
2761 <translation>Desinstalação finalizada</translation>
2762 </message>
2763 <message>
2764 <source>Uninstalling %1...</source>
2765 <translation>Desinstalando %1...</translation>
2766 </message>
2767 <message>
2768 <source>Could not delete %1</source>
2769 <translation>Não foi possível apagar %1</translation>
2770 </message>
2771</context>
2772<context>
2773 <name>Utils</name>
2774 <message>
2775 <source>&lt;li&gt;Permissions insufficient for bootloader installation.
2776Administrator priviledges are necessary.&lt;/li&gt;</source>
2777 <translation>&lt;li&gt;Permissões insuficientes para a instalação do carregador.
2778É necessário privilégios de administrator.&lt;/li&gt;</translation>
2779 </message>
2780 <message>
2781 <source>Problem detected:</source>
2782 <translation>Problema detectado:</translation>
2783 </message>
2784 <message>
2785 <source>&lt;li&gt;Target mismatch detected.&lt;br/&gt;Installed target: %1&lt;br/&gt;Selected target: %2.&lt;/li&gt;</source>
2786 <translation type="unfinished"></translation>
2787 </message>
2788</context>
2789<context>
2790 <name>VoiceFileCreator</name>
2791 <message>
2792 <source>Starting Voicefile generation</source>
2793 <translation>Iniciando geração do arquivo de voz</translation>
2794 </message>
2795 <message>
2796 <source>could not find rockbox-info.txt</source>
2797 <translation>não foi possível encontrar rockbox-info.txt</translation>
2798 </message>
2799 <message>
2800 <source>Download error: received HTTP error %1.</source>
2801 <translation>Erro de transferência: recebido erro HTTP %1.</translation>
2802 </message>
2803 <message>
2804 <source>Cached file used.</source>
2805 <translation>Arquivo de cache usado.</translation>
2806 </message>
2807 <message>
2808 <source>Download error: %1</source>
2809 <translation>Erro de transferência: %1</translation>
2810 </message>
2811 <message>
2812 <source>Download finished.</source>
2813 <translation>Transferência finalizada.</translation>
2814 </message>
2815 <message>
2816 <source>failed to open downloaded file</source>
2817 <translation>falha ao abrir arquivo transferido</translation>
2818 </message>
2819 <message>
2820 <source>The downloaded file was empty!</source>
2821 <translation>O arquivo transferido estava vazio!</translation>
2822 </message>
2823 <message>
2824 <source>Error opening downloaded file</source>
2825 <translation>Erro abrindo arquivo transferido</translation>
2826 </message>
2827 <message>
2828 <source>Error opening output file</source>
2829 <translation>Erro abrindo arquivo de saída</translation>
2830 </message>
2831 <message>
2832 <source>successfully created.</source>
2833 <translation>criado com sucesso.</translation>
2834 </message>
2835 <message>
2836 <source>Downloading voice info...</source>
2837 <translation>Baixando informação de voz...</translation>
2838 </message>
2839 <message>
2840 <source>Reading strings...</source>
2841 <translation>Lendo strings...</translation>
2842 </message>
2843 <message>
2844 <source>Creating voicefiles...</source>
2845 <translation>Criando arquivos de voz...</translation>
2846 </message>
2847 <message>
2848 <source>Cleaning up...</source>
2849 <translation>Limpando...</translation>
2850 </message>
2851 <message>
2852 <source>Finished</source>
2853 <translation>Finalizado</translation>
2854 </message>
2855 <message>
2856 <source>Extracted voice strings from installation</source>
2857 <translation type="unfinished"></translation>
2858 </message>
2859 <message>
2860 <source>Extracted voice strings incompatible</source>
2861 <translation type="unfinished"></translation>
2862 </message>
2863 <message>
2864 <source>Could not retrieve strings from installation, downloading</source>
2865 <translation type="unfinished"></translation>
2866 </message>
2867</context>
2868<context>
2869 <name>ZipInstaller</name>
2870 <message>
2871 <source>done.</source>
2872 <translation>feito.</translation>
2873 </message>
2874 <message>
2875 <source>Downloading file %1.%2</source>
2876 <translation>Transferindo arquivo %1.%2</translation>
2877 </message>
2878 <message>
2879 <source>Download error: received HTTP error %1.</source>
2880 <translation>Erro de transferência: recebido erro HTTP %1.</translation>
2881 </message>
2882 <message>
2883 <source>Cached file used.</source>
2884 <translation>Arquivo de cache usado.</translation>
2885 </message>
2886 <message>
2887 <source>Download error: %1</source>
2888 <translation>Erro de transferência: %1</translation>
2889 </message>
2890 <message>
2891 <source>Download finished.</source>
2892 <translation>Transferência finalizada.</translation>
2893 </message>
2894 <message>
2895 <source>Extracting file.</source>
2896 <translation>Extraindo arquivo.</translation>
2897 </message>
2898 <message>
2899 <source>Not enough disk space! Aborting.</source>
2900 <translation>Sem espaço em disco suficiente! Abortando.</translation>
2901 </message>
2902 <message>
2903 <source>Installing file.</source>
2904 <translation>Instalando arquivo.</translation>
2905 </message>
2906 <message>
2907 <source>Installing file failed.</source>
2908 <translation>Falhou instalando arquivo.</translation>
2909 </message>
2910 <message>
2911 <source>Creating installation log</source>
2912 <translation>Criando registro da instalação</translation>
2913 </message>
2914 <message>
2915 <source>Extraction failed!</source>
2916 <translation type="unfinished"></translation>
2917 </message>
2918 <message>
2919 <source>Package installation finished successfully.</source>
2920 <translation type="unfinished"></translation>
2921 </message>
2922</context>
2923<context>
2924 <name>ZipUtil</name>
2925 <message>
2926 <source>Creating output path failed</source>
2927 <translation type="unfinished"></translation>
2928 </message>
2929 <message>
2930 <source>Creating output file failed</source>
2931 <translation type="unfinished"></translation>
2932 </message>
2933 <message>
2934 <source>Error during Zip operation</source>
2935 <translation type="unfinished"></translation>
2936 </message>
2937</context>
2938<context>
2939 <name>aboutBox</name>
2940 <message>
2941 <source>About Rockbox Utility</source>
2942 <translation>Sobre o Utilitário Rockbox</translation>
2943 </message>
2944 <message>
2945 <source>The Rockbox Utility</source>
2946 <translation>O Utilitário Rockbox</translation>
2947 </message>
2948 <message>
2949 <source>&amp;Credits</source>
2950 <translation>&amp;Créditos</translation>
2951 </message>
2952 <message>
2953 <source>&amp;License</source>
2954 <translation>&amp;Licença</translation>
2955 </message>
2956 <message>
2957 <source>&amp;Ok</source>
2958 <translation>&amp;Ok</translation>
2959 </message>
2960 <message utf8="true">
2961 <source>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</source>
2962 <translation>Utilitário instalador e de manutenção para o firmware de código aberto de reprodutores digitais de música Rockbox.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</translation>
2963 </message>
2964 <message>
2965 <source>&amp;Speex License</source>
2966 <translation type="unfinished"></translation>
2967 </message>
2968</context>
2969</TS>
diff --git a/utils/rbutilqt/lang/rbutil_ru.ts b/utils/rbutilqt/lang/rbutil_ru.ts
new file mode 100644
index 0000000000..3328065b55
--- /dev/null
+++ b/utils/rbutilqt/lang/rbutil_ru.ts
@@ -0,0 +1,2981 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE TS>
3<TS version="2.0" language="ru">
4<context>
5 <name>BackupDialog</name>
6 <message>
7 <source>Backup</source>
8 <translation>Резервная копия</translation>
9 </message>
10 <message>
11 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This dialog will create a backup by archiving the contents of the Rockbox installation on the player into a zip file. This will include installed themes and settings stored below the .rockbox folder on the player.&lt;/p&gt;&lt;p&gt;The backup filename will be created based on the installed version. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
12 <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Здесь можно создать резервную копию текущей установки Rockbox и упаковать её в ZIP-файл. Это также касается установленных тем и настроек, находящихся в папке .rockbox на Вашем плеере.&lt;/p&gt;&lt;p&gt;Название файла резервной копии будет соответствовать установленной версии прошивки.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
13 </message>
14 <message>
15 <source>Size: unknown</source>
16 <translation>Размер: неизвестен</translation>
17 </message>
18 <message>
19 <source>Backup to: unknown</source>
20 <translation>Создать в: неизвстно</translation>
21 </message>
22 <message>
23 <source>&amp;Change</source>
24 <translation>&amp;Изменить</translation>
25 </message>
26 <message>
27 <source>&amp;Backup</source>
28 <translation>&amp;Создать копию</translation>
29 </message>
30 <message>
31 <source>&amp;Cancel</source>
32 <translation>&amp;Отмена</translation>
33 </message>
34 <message>
35 <source>Installation size: calculating ...</source>
36 <translation>Размер установки: вычисляется...</translation>
37 </message>
38 <message>
39 <source>Select Backup Filename</source>
40 <translation>Выберите название файла резервной копии</translation>
41 </message>
42 <message>
43 <source>Installation size: %L1 %2</source>
44 <translation>Размер установки: %L1 %2</translation>
45 </message>
46 <message>
47 <source>Starting backup ...</source>
48 <translation>Начало копии ...</translation>
49 </message>
50 <message>
51 <source>Backup successful.</source>
52 <translation>Резервная копия удалась.</translation>
53 </message>
54 <message>
55 <source>Backup failed!</source>
56 <translation>Не удалось создать резервную копию!</translation>
57 </message>
58 <message>
59 <source>File exists</source>
60 <translation>Файл уже существует</translation>
61 </message>
62 <message>
63 <source>The selected backup file already exists. Overwrite?</source>
64 <translation>Такой файл уже существует. Заменить?</translation>
65 </message>
66</context>
67<context>
68 <name>BootloaderInstallAms</name>
69 <message>
70 <source>Downloading bootloader file</source>
71 <translation>Скачивается файл загрузчика</translation>
72 </message>
73 <message>
74 <source>Could not load %1</source>
75 <translation>Не удалось загрузить %1</translation>
76 </message>
77 <message>
78 <source>Patching Firmware...</source>
79 <translation>Изменяется прошивка...</translation>
80 </message>
81 <message>
82 <source>Could not open %1 for writing</source>
83 <translation>Не удалось открыть %1 для записи</translation>
84 </message>
85 <message>
86 <source>Could not write firmware file</source>
87 <translation>Сбой записи файла прошивки</translation>
88 </message>
89 <message>
90 <source>Success: modified firmware file created</source>
91 <translation>Изменённая прошивка успешно создана</translation>
92 </message>
93 <message>
94 <source>No room to insert bootloader, try another firmware version</source>
95 <translation>Нет места для записи загрузчика, попробуйте другую версию прошивки</translation>
96 </message>
97 <message>
98 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
99 <translation>Для удаления выполните нормальное обновление с неизменённой фирменной прошивкой</translation>
100 </message>
101 <message>
102 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
103 <translation type="obsolete">Установка загрузчика потребует от вас копию оригинальной прошивки Sandisk\&apos;а (bin файл). Эта прошивка будет пропатчена и затем установлена в ваш плеер вместе с зарузчиком Rockbox\&apos;а. По причинам легальности данного действия вам нужно будет самим скачать загрузчик. Зайдите на &lt;a href=\&apos;http://forums.sandisk.com/sansa/\&apos;&gt;Sansa Forums\&apos;&lt;/a&gt; или обратитесь к &lt;a href=\&apos;http://www.rockbox.org/manual.shtml\&apos;&gt;инструкции&lt;/a&gt; и вики-странице &lt;a href=\&apos;http://www.rockbox.org/wiki/SansaAMS\&apos;&gt;SansaAMS&lt;/a&gt; за помощью с получением файла.&lt;br/&gt;Нажмите ОК чтобы продолжить и выбрать файл прошивки.</translation>
104 </message>
105 <message>
106 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; This file is not present on your player and will disappear automatically after installing it.&lt;br/&gt;&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
107 <translation>Установка загрузчика потребует от вас копию оригинальной прошивки от Sandisk (bin-файл). Эта прошивка будет пропатчена, а затем установлена на ваш плеер вместе с зарузчиком Rockbox\&apos;а. По законным причинам, Вам необходимо скачать файл самостоятельно. Зайдите на &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;форумы Sansa&lt;/a&gt; или читайте &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;инструкцию&lt;/a&gt; и вики-страничку &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; о том, как получить файл.&lt;br/&gt;Нажмите ОК чтобы продолжить и выбрать файл прошивки.</translation>
108 </message>
109</context>
110<context>
111 <name>BootloaderInstallBase</name>
112 <message>
113 <source>Download error: received HTTP error %1.</source>
114 <translation>Ошибка при скачивании: ошибка HTTP %1.</translation>
115 </message>
116 <message>
117 <source>Download error: %1</source>
118 <translation>Ошибка при скачивании: %1</translation>
119 </message>
120 <message>
121 <source>Download finished (cache used).</source>
122 <translation>Скачивание завершено (из кэша).</translation>
123 </message>
124 <message>
125 <source>Download finished.</source>
126 <translation>Скачивание завершено.</translation>
127 </message>
128 <message>
129 <source>Creating backup of original firmware file.</source>
130 <translation>Создаётся резервная копия фирменной прошивки.</translation>
131 </message>
132 <message>
133 <source>Creating backup folder failed</source>
134 <translation>Сбой при попытке создания папки резервной копии</translation>
135 </message>
136 <message>
137 <source>Creating backup copy failed.</source>
138 <translation>Сбой при попытке создания резервной копии.</translation>
139 </message>
140 <message>
141 <source>Backup created.</source>
142 <translation>Резервная копия создана.</translation>
143 </message>
144 <message>
145 <source>Creating installation log</source>
146 <translation>Создаётся журнал установки</translation>
147 </message>
148 <message>
149 <source>Installation log created</source>
150 <translation>Журнал установки создан</translation>
151 </message>
152 <message>
153 <source>Waiting for system to remount player</source>
154 <translation>Ожидание, пока система заново смонтирует плеер</translation>
155 </message>
156 <message>
157 <source>Player remounted</source>
158 <translation>Плеер смонтирован</translation>
159 </message>
160 <message>
161 <source>Timeout on remount</source>
162 <translation>Время ожидания для монтирования истекло</translation>
163 </message>
164 <message>
165 <source>Zip file format detected</source>
166 <translation>Обнаружен формат ZIP</translation>
167 </message>
168 <message>
169 <source>Extracting firmware %1 from archive</source>
170 <translation>Извлекается прошивка %1 из архива</translation>
171 </message>
172 <message>
173 <source>Error extracting firmware from archive</source>
174 <translation>Ошибка при извлечении прошивки</translation>
175 </message>
176 <message>
177 <source>Could not find firmware in archive</source>
178 <translation>Прошивка в архиве не найдена</translation>
179 </message>
180 <message>
181 <source>CAB file format detected</source>
182 <translation>Обнаружен формат CAB</translation>
183 </message>
184</context>
185<context>
186 <name>BootloaderInstallChinaChip</name>
187 <message>
188 <source>Bootloader installation requires you to provide a firmware file of the original firmware (HXF file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
189 <translation>Чтобы установить загрузчик, требуется файл фирменной прошивки (HXF-файл). По законодательным причинам, этот файл вам необходимо скачать самостоятельно. О том, как получить этот файл, смотрите в &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;руководстве по эксплуатации&lt;/a&gt; и на &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;вики-страничке OndaVX747&lt;/a&gt;. &lt;br/&gt; Нажмине на ОК, чтобы продолжить и указать путь к прошивке на Вашем компьютере.</translation>
190 </message>
191 <message>
192 <source>Downloading bootloader file</source>
193 <translation>Скачивается файл загрузчика</translation>
194 </message>
195 <message>
196 <source>Could not open firmware file</source>
197 <translation>Не удалось открыть файл прошивки</translation>
198 </message>
199 <message>
200 <source>Could not open bootloader file</source>
201 <translation>Не удалось открыть файл загрузчика</translation>
202 </message>
203 <message>
204 <source>Could not allocate memory</source>
205 <translation>Не удалось выделить память</translation>
206 </message>
207 <message>
208 <source>Could not load firmware file</source>
209 <translation>Не удалось загрузить файл прошивки</translation>
210 </message>
211 <message>
212 <source>File is not a valid ChinaChip firmware</source>
213 <translation>Файл не является годной прошивкой ChinaChip</translation>
214 </message>
215 <message>
216 <source>Could not find ccpmp.bin in input file</source>
217 <translation>ccpmp.bin во входном файле не найден</translation>
218 </message>
219 <message>
220 <source>Could not open backup file for ccpmp.bin</source>
221 <translation>Не удалось открыть резервную копию для ccpmp.bin</translation>
222 </message>
223 <message>
224 <source>Could not write backup file for ccpmp.bin</source>
225 <translation>Не удалось записать резервную копию для ccpmp.bin</translation>
226 </message>
227 <message>
228 <source>Could not load bootloader file</source>
229 <translation>Не удалось считать файл загрузчика</translation>
230 </message>
231 <message>
232 <source>Could not get current time</source>
233 <translation>Не удалось получить текущее время</translation>
234 </message>
235 <message>
236 <source>Could not open output file</source>
237 <translation>Не удалось открыть выходной файл</translation>
238 </message>
239 <message>
240 <source>Could not write output file</source>
241 <translation>Не удалось записать выходной файл</translation>
242 </message>
243 <message>
244 <source>Unexpected error from chinachippatcher</source>
245 <translation>Неожиданный сбой chinachippatcher</translation>
246 </message>
247</context>
248<context>
249 <name>BootloaderInstallFile</name>
250 <message>
251 <source>Downloading bootloader</source>
252 <translation>Скачивается загрузчик</translation>
253 </message>
254 <message>
255 <source>Installing Rockbox bootloader</source>
256 <translation>Устанавливается загрузчик Rockbox</translation>
257 </message>
258 <message>
259 <source>Error accessing output folder</source>
260 <translation>Ошибка доступа к выходной папке</translation>
261 </message>
262 <message>
263 <source>Removing Rockbox bootloader</source>
264 <translation>Удаляется загрузчик Rockbox</translation>
265 </message>
266 <message>
267 <source>No original firmware file found.</source>
268 <translation>Не найдено фирменной прошивки.</translation>
269 </message>
270 <message>
271 <source>Can&apos;t remove Rockbox bootloader file.</source>
272 <translation>Не удалось удалить файл загрузчика Rockbox.</translation>
273 </message>
274 <message>
275 <source>Can&apos;t restore bootloader file.</source>
276 <translation>Не удалось восстановить файл загрузчика.</translation>
277 </message>
278 <message>
279 <source>Original bootloader restored successfully.</source>
280 <translation>Фирменный загрузчик успешно восстановлен.</translation>
281 </message>
282 <message>
283 <source>Bootloader successful installed</source>
284 <translation>Загрузчик успешно установлен</translation>
285 </message>
286 <message>
287 <source>A firmware file is already present on player</source>
288 <translation>Файл прошивки уже присутствует на плеере</translation>
289 </message>
290 <message>
291 <source>Copying modified firmware file failed</source>
292 <translation>Не удалось скопировать изменённый файл прошивки</translation>
293 </message>
294</context>
295<context>
296 <name>BootloaderInstallHex</name>
297 <message>
298 <source>checking MD5 hash of input file ...</source>
299 <translation>проверка хэша MD5 входного файла ...</translation>
300 </message>
301 <message>
302 <source>Could not verify original firmware file</source>
303 <translation>Не удалось проверить фирменную прошивку</translation>
304 </message>
305 <message>
306 <source>Firmware file not recognized.</source>
307 <translation>Файл прошивки не распознан.</translation>
308 </message>
309 <message>
310 <source>MD5 hash ok</source>
311 <translation>Хэш MD5 проверен</translation>
312 </message>
313 <message>
314 <source>Firmware file doesn&apos;t match selected player.</source>
315 <translation>Прошивка не соответствует указанному плееру.</translation>
316 </message>
317 <message>
318 <source>Descrambling file</source>
319 <translation>Расшифровка файла</translation>
320 </message>
321 <message>
322 <source>Error in descramble: %1</source>
323 <translation>Ошибка при расшифровке: %1</translation>
324 </message>
325 <message>
326 <source>Downloading bootloader file</source>
327 <translation>Скачивается файл загрузчика</translation>
328 </message>
329 <message>
330 <source>Adding bootloader to firmware file</source>
331 <translation>Добавляется загрузчик к прошивке</translation>
332 </message>
333 <message>
334 <source>could not open input file</source>
335 <translation>Не удалось открыть входной файл</translation>
336 </message>
337 <message>
338 <source>reading header failed</source>
339 <translation>Сбой чтения заголовка</translation>
340 </message>
341 <message>
342 <source>reading firmware failed</source>
343 <translation>Сбой чтения прошивки</translation>
344 </message>
345 <message>
346 <source>can&apos;t open bootloader file</source>
347 <translation>Не удалось открыть файл загрузчика</translation>
348 </message>
349 <message>
350 <source>reading bootloader file failed</source>
351 <translation>Сбой чтения файла загрузчика</translation>
352 </message>
353 <message>
354 <source>can&apos;t open output file</source>
355 <translation>Не удалось открыть выходной файл</translation>
356 </message>
357 <message>
358 <source>writing output file failed</source>
359 <translation>Сбой записи выходного файла</translation>
360 </message>
361 <message>
362 <source>Error in patching: %1</source>
363 <translation>Ошибка применения патча: %1</translation>
364 </message>
365 <message>
366 <source>Error in scramble: %1</source>
367 <translation>Ошибка кодирования: %1</translation>
368 </message>
369 <message>
370 <source>Checking modified firmware file</source>
371 <translation>Проверка изменённой прошивки</translation>
372 </message>
373 <message>
374 <source>Error: modified file checksum wrong</source>
375 <translation>Ошибка: неверная контрольная сумма изменённого файла</translation>
376 </message>
377 <message>
378 <source>Success: modified firmware file created</source>
379 <translation>Изменённая прошивка успешно создана</translation>
380 </message>
381 <message>
382 <source>Can&apos;t open input file</source>
383 <translation>Не удалось открыть входной файл</translation>
384 </message>
385 <message>
386 <source>Can&apos;t open output file</source>
387 <translation>Не удалось открыть выходной вайл</translation>
388 </message>
389 <message>
390 <source>invalid file: header length wrong</source>
391 <translation>Неверный файл: неверная длина заголовка</translation>
392 </message>
393 <message>
394 <source>invalid file: unrecognized header</source>
395 <translation>Неверный файл: неопознанный заголовок</translation>
396 </message>
397 <message>
398 <source>invalid file: &quot;length&quot; field wrong</source>
399 <translation>Неверный файл: неверное поле &quot;длина&quot;</translation>
400 </message>
401 <message>
402 <source>invalid file: &quot;length2&quot; field wrong</source>
403 <translation>Неверный файл: неверное поле &quot;длина2&quot;</translation>
404 </message>
405 <message>
406 <source>invalid file: internal checksum error</source>
407 <translation>Неверный файл: ошибка во внутренней контрольной сумме</translation>
408 </message>
409 <message>
410 <source>unknown</source>
411 <translation>неизвестная ошибка</translation>
412 </message>
413 <message>
414 <source>Bootloader installation requires you to provide a firmware file of the original firmware (hex file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
415 <translation>Для установки загрузчика требуется файл прошивки с фирменной прошивкой (hex-файл). По законодательным причинам, вам необходимо скачать этот файл самостоятельно. Как найти этот файл, смотрите в &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;руководстве по экслуатации&lt;/a&gt; и на вики-странице &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt;.&lt;br/&gt;Чтобы продолжить, нажмите на OK и укажите файл прошивки на компьютере.</translation>
416 </message>
417 <message>
418 <source>invalid file: &quot;length3&quot; field wrong</source>
419 <translation>Неверный файл: неверное поле &quot;длина3&quot;</translation>
420 </message>
421 <message>
422 <source>Uninstallation not possible, only installation info removed</source>
423 <translation>Полное удаление невозможно, удалена только информация об установке</translation>
424 </message>
425 <message>
426 <source>A firmware file is already present on player</source>
427 <translation>Файл прошивки уже присутствует на плеере</translation>
428 </message>
429 <message>
430 <source>Copying modified firmware file failed</source>
431 <translation>Не удалось скопировать изменённый файл прошивки</translation>
432 </message>
433</context>
434<context>
435 <name>BootloaderInstallImx</name>
436 <message>
437 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (firmware.sb file). This file will be patched with the Rockbox bootloader and installed to your player. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
438 <translation>Установка загрузчика потребует от вас копию оригинальной прошивки от Sandisk (файл firmware.sb). Эта прошивка будет пропатчена, а затем установлена на ваш плеер вместе с зарузчиком Rockbox. По законным причинам, Вам необходимо скачать файл самостоятельно. Зайдите на &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;форумы Sansa&lt;/a&gt; или читайте вики-страничку &lt;a href=&apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; о том, как получить файл.&lt;br/&gt;Нажмите ОК чтобы продолжить и выбрать файл прошивки.</translation>
439 </message>
440 <message>
441 <source>Could not read original firmware file</source>
442 <translation>Не удалось прочитать фирменную прошивку</translation>
443 </message>
444 <message>
445 <source>Downloading bootloader file</source>
446 <translation>Скачивается файл загрузчика</translation>
447 </message>
448 <message>
449 <source>Patching file...</source>
450 <translation>Изменяется прошивка...</translation>
451 </message>
452 <message>
453 <source>Patching the original firmware failed</source>
454 <translation>Сбой патчирования фирменной прошивки</translation>
455 </message>
456 <message>
457 <source>Succesfully patched firmware file</source>
458 <translation>Прошивка успешно пропатчена</translation>
459 </message>
460 <message>
461 <source>Bootloader successful installed</source>
462 <translation>Загрузчик успешно установлен</translation>
463 </message>
464 <message>
465 <source>Patched bootloader could not be installed</source>
466 <translation>Не удалось установить пропатченный загрузчик</translation>
467 </message>
468 <message>
469 <source>To uninstall, perform a normal upgrade with an unmodified original firmware.</source>
470 <translation>Для удаления выполните нормальное обновление с неизменённой фирменной прошивкой.</translation>
471 </message>
472</context>
473<context>
474 <name>BootloaderInstallIpod</name>
475 <message>
476 <source>Error: can&apos;t allocate buffer memory!</source>
477 <translation>Ошибка: не удалось выделить буферную память!</translation>
478 </message>
479 <message>
480 <source>Downloading bootloader file</source>
481 <translation>Скачивается файл заргузчика</translation>
482 </message>
483 <message>
484 <source>Failed to read firmware directory</source>
485 <translation>Сбой чтения папки микропрограммы</translation>
486 </message>
487 <message>
488 <source>Unknown version number in firmware (%1)</source>
489 <translation>Неизвестный номер версии прошивки (%1)</translation>
490 </message>
491 <message>
492 <source>Could not open Ipod in R/W mode</source>
493 <translation>Не удалось открыть iPod в режиме записи</translation>
494 </message>
495 <message>
496 <source>Failed to add bootloader</source>
497 <translation>Сбой установки загрузчика</translation>
498 </message>
499 <message>
500 <source>No bootloader detected.</source>
501 <translation>Загрузчика не обнаружено.</translation>
502 </message>
503 <message>
504 <source>Successfully removed bootloader</source>
505 <translation>Загрузчик успешно удалён</translation>
506 </message>
507 <message>
508 <source>Removing bootloader failed.</source>
509 <translation>Сбой удаления загрузчика.</translation>
510 </message>
511 <message>
512 <source>Could not open Ipod</source>
513 <translation>Не удалось открыть iPod</translation>
514 </message>
515 <message>
516 <source>No firmware partition on disk</source>
517 <translation>Не найдено раздела прошивки на диске</translation>
518 </message>
519 <message>
520 <source>Installing Rockbox bootloader</source>
521 <translation>Установка загрузчика Rockbox</translation>
522 </message>
523 <message>
524 <source>Uninstalling bootloader</source>
525 <translation>Удаление загрузчика</translation>
526 </message>
527 <message>
528 <source>Error reading partition table - possibly not an Ipod</source>
529 <translation>Сбой чтения таблицы разделов - возможно, это не iPod</translation>
530 </message>
531 <message>
532 <source>Warning: This is a MacPod, Rockbox only runs on WinPods.
533See http://www.rockbox.org/wiki/IpodConversionToFAT32</source>
534 <translation>Предупреждение: это - MacPod, Rockbox работает только на WinPod&apos;ах.
535См. http://www.rockbox.org/wiki/IpodConversionToFAT32</translation>
536 </message>
537 <message>
538 <source>Successfull added bootloader</source>
539 <translation>Загрузчик успешно добавлен</translation>
540 </message>
541 <message>
542 <source>Bootloader Installation complete.</source>
543 <translation>Установка загрузчика завершена.</translation>
544 </message>
545 <message>
546 <source>Writing log aborted</source>
547 <translation>Запись журнала отменена</translation>
548 </message>
549 <message>
550 <source>Error: no mountpoint specified!</source>
551 <translation>Ошибка: не указано точки монтирования!</translation>
552 </message>
553 <message>
554 <source>Could not open Ipod: permission denied</source>
555 <translation>Не удалось открыть iPod: доступ запрещён</translation>
556 </message>
557 <message>
558 <source>Error: could not retrieve device name</source>
559 <translation>Ошибка: не удалось найти название устройства</translation>
560 </message>
561</context>
562<context>
563 <name>BootloaderInstallMi4</name>
564 <message>
565 <source>Downloading bootloader</source>
566 <translation>Скачивается загрузчик</translation>
567 </message>
568 <message>
569 <source>Installing Rockbox bootloader</source>
570 <translation>Устанавливается загрузчик Rockbox</translation>
571 </message>
572 <message>
573 <source>Bootloader successful installed</source>
574 <translation>Загрузчик успешно установлен</translation>
575 </message>
576 <message>
577 <source>Checking for Rockbox bootloader</source>
578 <translation>Проверяется наличие загрузчика Rockbox</translation>
579 </message>
580 <message>
581 <source>No Rockbox bootloader found</source>
582 <translation>Загрузчик Rockbox не найден</translation>
583 </message>
584 <message>
585 <source>Checking for original firmware file</source>
586 <translation>Проверяется наличие фирменной прошивки</translation>
587 </message>
588 <message>
589 <source>Error finding original firmware file</source>
590 <translation>Фирменной прошивки не найдено</translation>
591 </message>
592 <message>
593 <source>Rockbox bootloader successful removed</source>
594 <translation>Загрузчик Rockbox успешно удалён</translation>
595 </message>
596 <message>
597 <source>A firmware file is already present on player</source>
598 <translation>Файл прошивки уже присутствует на плеере</translation>
599 </message>
600 <message>
601 <source>Copying modified firmware file failed</source>
602 <translation>Не удалось скопировать изменённый файл прошивки</translation>
603 </message>
604</context>
605<context>
606 <name>BootloaderInstallMpio</name>
607 <message>
608 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
609 <translation>Для установки загрузчика требуется файл прошивки с фирменной микропрограммой (hex-файл). По законодательным причинам, вам необходимо скачать этот файл самостоятельно. Как найти этот файл, смотрите в &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;руководстве по экслуатации&lt;/a&gt; и на вики-странице &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt;.&lt;br/&gt;Чтобы продолжить, нажмите на OK и укажите файл прошивки на компьютере.</translation>
610 </message>
611 <message>
612 <source>Downloading bootloader file</source>
613 <translation>Скачивается файл загрузчика</translation>
614 </message>
615 <message>
616 <source>Could not open the original firmware.</source>
617 <translation>Не удалось открыть фирменную прошивку.</translation>
618 </message>
619 <message>
620 <source>Could not read the original firmware.</source>
621 <translation>Не удалось прочитать фирменную прошивку.</translation>
622 </message>
623 <message>
624 <source>Could not open downloaded bootloader.</source>
625 <translation>Не удалось открыть скачаный загрузчик.</translation>
626 </message>
627 <message>
628 <source>Place for bootloader in OF file not empty.</source>
629 <translation>Место для загрузчика в фирменной прошивке не пустое.</translation>
630 </message>
631 <message>
632 <source>Could not read the downloaded bootloader.</source>
633 <translation>Не удалось прочитать полученный загрузчик.</translation>
634 </message>
635 <message>
636 <source>Bootloader checksum error.</source>
637 <translation>Ошибка в контрольной сумме загрузчика.</translation>
638 </message>
639 <message>
640 <source>Patching original firmware failed: %1</source>
641 <translation>Сбой патчирования фирменной прошивки: %1</translation>
642 </message>
643 <message>
644 <source>Success: modified firmware file created</source>
645 <translation>Изменённая прошивка успешно создана</translation>
646 </message>
647 <message>
648 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
649 <translation>Для удаления выполните нормальное обновление с неизменённой фирменной прошивкой</translation>
650 </message>
651 <message>
652 <source>Loaded firmware file does not look like MPIO original firmware file.</source>
653 <translation>Загруженная прошивка не похожа на фирменную прошивку MPIO.</translation>
654 </message>
655 <message>
656 <source>Could not open output file.</source>
657 <translation>Не удалось открыть выходной вайл.</translation>
658 </message>
659 <message>
660 <source>Could not write output file.</source>
661 <translation>Сбой записи выходного файла.</translation>
662 </message>
663 <message>
664 <source>Unknown error number: %1</source>
665 <translation>Неизвестная ошибка номер %1</translation>
666 </message>
667</context>
668<context>
669 <name>BootloaderInstallSansa</name>
670 <message>
671 <source>Error: can&apos;t allocate buffer memory!</source>
672 <translation>Ошибка: не удалось выделить буферную память!</translation>
673 </message>
674 <message>
675 <source>Searching for Sansa</source>
676 <translation>Поиск плеера Sansa</translation>
677 </message>
678 <message>
679 <source>Permission for disc access denied!
680This is required to install the bootloader</source>
681 <translation>Доступ к диску отказан!
682Это необходимо для установки загрузчика</translation>
683 </message>
684 <message>
685 <source>No Sansa detected!</source>
686 <translation>Не найдено плеера Sansa!</translation>
687 </message>
688 <message>
689 <source>Downloading bootloader file</source>
690 <translation>Скачивается файл загрузчика</translation>
691 </message>
692 <message>
693 <source>OLD ROCKBOX INSTALLATION DETECTED, ABORTING.
694You must reinstall the original Sansa firmware before running
695sansapatcher for the first time.
696See http://www.rockbox.org/wiki/SansaE200Install
697</source>
698 <translation>ОБНАРУЖЕНА СТАРАЯ УСТАНОВКА ROCKBOX, ОПЕРАЦИЯ ОТМЕНЯЕТСЯ.
699Вам необходимо переустановить фирменную микропрограмму
700вашего плеера перед первым запуском sansapatcher&apos;а.
701См. http://www.rockbox.org/wiki/SansaE200Install</translation>
702 </message>
703 <message>
704 <source>Could not open Sansa in R/W mode</source>
705 <translation>Не удалось открыть плеер в режиме записи</translation>
706 </message>
707 <message>
708 <source>Successfully installed bootloader</source>
709 <translation>Загрузчик успешно установлен</translation>
710 </message>
711 <message>
712 <source>Failed to install bootloader</source>
713 <translation>Сбой при установке загрузчика</translation>
714 </message>
715 <message>
716 <source>Can&apos;t find Sansa</source>
717 <translation>Не удалось найти плеер Sansa</translation>
718 </message>
719 <message>
720 <source>Could not open Sansa</source>
721 <translation>Не удалось открыть плеер Sansa</translation>
722 </message>
723 <message>
724 <source>Could not read partition table</source>
725 <translation>Не удалось прочитать таблицу разделов</translation>
726 </message>
727 <message>
728 <source>Disk is not a Sansa (Error %1), aborting.</source>
729 <translation>Диск не принадлежит плееру Sansa (Ошибка %1), отмена.</translation>
730 </message>
731 <message>
732 <source>Successfully removed bootloader</source>
733 <translation>Загручик успешно удалён</translation>
734 </message>
735 <message>
736 <source>Removing bootloader failed.</source>
737 <translation>Сбой удаления загрузчика.</translation>
738 </message>
739 <message>
740 <source>Installing Rockbox bootloader</source>
741 <translation>Установка загрузчика Rockbox</translation>
742 </message>
743 <message>
744 <source>Checking downloaded bootloader</source>
745 <translation>Проверка скаченного загрузчика</translation>
746 </message>
747 <message>
748 <source>Bootloader mismatch! Aborting.</source>
749 <translation>Загрузчик не соответствует! Отмена.</translation>
750 </message>
751 <message>
752 <source>Uninstalling bootloader</source>
753 <translation>Удаление загрузчика</translation>
754 </message>
755 <message>
756 <source>Bootloader Installation complete.</source>
757 <translation>Установка загрузчика завершена.</translation>
758 </message>
759 <message>
760 <source>Writing log aborted</source>
761 <translation>Запись журнала отменена</translation>
762 </message>
763 <message>
764 <source>Error: could not retrieve device name</source>
765 <translation>Ошибка: не удалось найти имя устройства</translation>
766 </message>
767</context>
768<context>
769 <name>BootloaderInstallTcc</name>
770 <message>
771 <source>Downloading bootloader file</source>
772 <translation>Скачивается файл загрузчика</translation>
773 </message>
774 <message>
775 <source>Could not load %1</source>
776 <translation>Не удалось загрузить %1</translation>
777 </message>
778 <message>
779 <source>Unknown OF file used: %1</source>
780 <translation>Используется неизвестный файл фирменной прошивки: %1</translation>
781 </message>
782 <message>
783 <source>Patching Firmware...</source>
784 <translation>Изменяется прошивка...</translation>
785 </message>
786 <message>
787 <source>Could not open %1 for writing</source>
788 <translation>Не удалось открыть %1 для записи</translation>
789 </message>
790 <message>
791 <source>Could not write firmware file</source>
792 <translation>Сбой записи файла прошиви</translation>
793 </message>
794 <message>
795 <source>Success: modified firmware file created</source>
796 <translation>Изменённый файл прошивки успешно создан</translation>
797 </message>
798 <message>
799 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wiki page on how to obtain the file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
800 <translation>Для установки загрузчика требуется файл прошивки с фирменной микропрограммой (hex-файл). По законодательным причинам, вам необходимо скачать этот файл самостоятельно. Как найти этот файл, смотрите в &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;руководстве по экслуатации&lt;/a&gt; и на вики-странице &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt;.&lt;br/&gt;Чтобы продолжить, нажмите на OK и укажите файл прошивки на компьютере.</translation>
801 </message>
802 <message>
803 <source>Could not patch firmware</source>
804 <translation>Сбой записи файла прошивки</translation>
805 </message>
806 <message>
807 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
808 <translation>Для удаления выполните нормальное обновление с неизменённой фирменной прошивкой</translation>
809 </message>
810</context>
811<context>
812 <name>Changelog</name>
813 <message>
814 <source>Changelog</source>
815 <translation>История изменений</translation>
816 </message>
817 <message>
818 <source>Show on startup</source>
819 <translation>Показать при запуске</translation>
820 </message>
821 <message>
822 <source>&amp;Ok</source>
823 <translation>&amp;OK</translation>
824 </message>
825</context>
826<context>
827 <name>Config</name>
828 <message>
829 <source>Autodetection</source>
830 <translation>Автоопределение</translation>
831 </message>
832 <message>
833 <source>Could not detect a Mountpoint.
834Select your Mountpoint manually.</source>
835 <translation>Не удалось определить точку монтирования
836Укажите её вручную.</translation>
837 </message>
838 <message>
839 <source>Could not detect a device.
840Select your device and Mountpoint manually.</source>
841 <translation>Не удалось определить устройство.
842Укажите устройство и точку монтирования вручную.</translation>
843 </message>
844 <message>
845 <source>Really delete cache?</source>
846 <translation>Удалить кэш?</translation>
847 </message>
848 <message>
849 <source>Do you really want to delete the cache? Make absolutely sure this setting is correct as it will remove &lt;b&gt;all&lt;/b&gt; files in this folder!</source>
850 <translation>Вы дейсвительно хотите удалить кэш? Эта операция удалит &lt;b&gt;все&lt;/b&gt; файлы из этой папки!</translation>
851 </message>
852 <message>
853 <source>Path wrong!</source>
854 <translation>Неверный путь!</translation>
855 </message>
856 <message>
857 <source>The cache path is invalid. Aborting.</source>
858 <translation>Неверный путь кэша. Отмена.</translation>
859 </message>
860 <message>
861 <source>Fatal error</source>
862 <translation type="obsolete">Фатальная ошибка</translation>
863 </message>
864 <message>
865 <source>Current cache size is %L1 kiB.</source>
866 <translation>Текущий размер кэша %L1 КБ.</translation>
867 </message>
868 <message>
869 <source>Configuration OK</source>
870 <translation>Настройки верны</translation>
871 </message>
872 <message>
873 <source>Configuration INVALID</source>
874 <translation>Настройки НЕВЕРНЫ</translation>
875 </message>
876 <message>
877 <source>The following errors occurred:</source>
878 <translation>Обнаружены следующие ошибки:</translation>
879 </message>
880 <message>
881 <source>No mountpoint given</source>
882 <translation>Не указана точка монтирования</translation>
883 </message>
884 <message>
885 <source>Mountpoint does not exist</source>
886 <translation>Точка монтирования не существует</translation>
887 </message>
888 <message>
889 <source>Mountpoint is not a directory.</source>
890 <translation>Указанная точка монтирования не является папкой.</translation>
891 </message>
892 <message>
893 <source>Mountpoint is not writeable</source>
894 <translation>Точка монтирования незаписываема</translation>
895 </message>
896 <message>
897 <source>No player selected</source>
898 <translation>Плеер не выбран</translation>
899 </message>
900 <message>
901 <source>Cache path not writeable. Leave path empty to default to systems temporary path.</source>
902 <translation>Указанный путь кэша незаписываем. Оставьте это поле пустым для использования системного пути по умолчанию.</translation>
903 </message>
904 <message>
905 <source>You need to fix the above errors before you can continue.</source>
906 <translation>Вам необходимо исправить вышеуказанные ошибкм перед тем, как продолжить.</translation>
907 </message>
908 <message>
909 <source>Configuration error</source>
910 <translation>Ошибка в настройках</translation>
911 </message>
912 <message>
913 <source>Detected an unsupported player:
914%1
915Sorry, Rockbox doesn&apos;t run on your player.</source>
916 <translation>Обнаружен неподдерживаемый плеер:
917%1
918К сожалению, Rockbox не работает на этом плеере.</translation>
919 </message>
920 <message>
921 <source>Fatal: player incompatible</source>
922 <translation type="obsolete">Ошибка: плеер несовместим</translation>
923 </message>
924 <message>
925 <source>TTS configuration invalid</source>
926 <translation>Настройки TTS неверны</translation>
927 </message>
928 <message>
929 <source>TTS configuration invalid.
930 Please configure TTS engine.</source>
931 <translation>Настройки TTS неверны.
932 Пожалуйста, настройте движок TTS.</translation>
933 </message>
934 <message>
935 <source>Could not start TTS engine.</source>
936 <translation>Не удалось запустить движок TTS.</translation>
937 </message>
938 <message>
939 <source>Could not start TTS engine.
940</source>
941 <translation>Не удалось запустить движок TTS.
942</translation>
943 </message>
944 <message>
945 <source>
946Please configure TTS engine.</source>
947 <translation>
948Пожалуйста, настройте движок TTS.</translation>
949 </message>
950 <message>
951 <source>Rockbox Utility Voice Test</source>
952 <translation>Проверка голоса</translation>
953 </message>
954 <message>
955 <source>Could not voice test string.</source>
956 <translation>Невозможно озвучить введённый текст.</translation>
957 </message>
958 <message>
959 <source>Showing disabled targets</source>
960 <translation>Отображение отображение неподдерживаемых устройств</translation>
961 </message>
962 <message>
963 <source>You just enabled showing targets that are marked disabled. Disabled targets are not recommended to end users. Please use this option only if you know what you are doing.</source>
964 <translation>Вы только что указали, что хотите видеть в списке устройства, помеченные как официально неподдерживаемые. Таковые не рекомендуются к использованию конечным пользователям. Используйте эту функцию только если знаете, что делаете.</translation>
965 </message>
966 <message>
967 <source>Set Cache Path</source>
968 <translation>Указать путь к кэшу</translation>
969 </message>
970 <message>
971 <source>%1 &quot;MacPod&quot; found!
972Rockbox needs a FAT formatted Ipod (so-called &quot;WinPod&quot;) to run. </source>
973 <translation>%1 является MacPod&apos;ом!
974Для работы, Rockbox нужен iPod форматированный в FAT (так называемый &quot;WinPod&quot;).</translation>
975 </message>
976 <message>
977 <source>Proxy Detection</source>
978 <translation>Определение прокси</translation>
979 </message>
980 <message>
981 <source>The System Proxy settings are invalid!
982Rockbox Utility can&apos;t work with this proxy settings. Make sure the system proxy is set correctly. Note that &quot;proxy auto-config (PAC)&quot; scripts are not supported by Rockbox Utility. If your system uses this you need to use manual proxy settings.</source>
983 <translation>Системные настройки прокси неверны!
984Мастер Rockbox не может работать с этими настройками. Проверьте правильность системных настроек прокси. Учтите, что мастер Rockbox не поддерживает сценарии &quot;proxy auto config&quot; (PAC). Если таковые используются на Вашей системе, вам необходимо использовать ручные настройки.</translation>
985 </message>
986 <message>
987 <source>%1 in MTP mode found!
988You need to change your player to MSC mode for installation. </source>
989 <translation>Найден %1 в режиме MTP!
990Для установки вам нужно сменить режим подключения плеера на MSC.</translation>
991 </message>
992 <message>
993 <source>Until you change this installation will fail!</source>
994 <translation type="obsolete">Пока вы это не измените, установка не пройдёт успешно!</translation>
995 </message>
996 <message>
997 <source>Could not voice test string.
998</source>
999 <translation>Не удалось произнести проверочное предложение.</translation>
1000 </message>
1001 <message>
1002 <source>TTS error</source>
1003 <translation>Ошибка TTS</translation>
1004 </message>
1005 <message>
1006 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1007 <translation>Не удалось инициализироавть выбранный движок. Вы не можете им пользоваться.</translation>
1008 </message>
1009 <message>
1010 <source>Multiple devices have been detected. Please disconnect all players but one and try again.</source>
1011 <translation>Было обнаружено несколько устройств. Отключите все, кроме одного и попробуйте снова.</translation>
1012 </message>
1013 <message>
1014 <source>Detected devices:</source>
1015 <translation>Обнаруженные устройства:</translation>
1016 </message>
1017 <message>
1018 <source>(unknown)</source>
1019 <translation>(неизвестный)</translation>
1020 </message>
1021 <message>
1022 <source>Note: detecting connected devices might be ambiguous. You might have less devices connected than listed. In this case it might not be possible to detect your player unambiguously.</source>
1023 <translation>Примечание: обнаружение подключенных устройств может оказаться двусмысленно. Может быть подключено меньше устройств, чем в списке. В таком случае, Ваш плеер может быть невозможно узнать однозначно.</translation>
1024 </message>
1025 <message>
1026 <source>Device Detection</source>
1027 <translation>Обнаружение устройств</translation>
1028 </message>
1029 <message>
1030 <source>The player contains an incompatible filesystem.
1031Make sure you selected the correct mountpoint and the player is set up to use a filesystem compatible with Rockbox.</source>
1032 <translation>Обнаружена несовместимая файловая система на плеере.
1033Убедитесь в том, что выбрана верная точка монтирования и плеер настроен на использование совместимой с Rockbox файловой системы.</translation>
1034 </message>
1035 <message>
1036 <source>An unknown error occured during player detection.</source>
1037 <translation>Неизвестная ошибка при обнаружении плеера.</translation>
1038 </message>
1039 <message>
1040 <source>%1 (%2 GiB of %3 GiB free)</source>
1041 <translation>%1 (свободны %2 ГиБ из %3 ГиБ)</translation>
1042 </message>
1043 <message>
1044 <source>%1 at %2</source>
1045 <translation>%1 на %2</translation>
1046 </message>
1047</context>
1048<context>
1049 <name>ConfigForm</name>
1050 <message>
1051 <source>Configuration</source>
1052 <translation>Настройки</translation>
1053 </message>
1054 <message>
1055 <source>Configure Rockbox Utility</source>
1056 <translation>Настроить мастера Rockbox</translation>
1057 </message>
1058 <message>
1059 <source>&amp;Device</source>
1060 <translation>&amp;Устройство</translation>
1061 </message>
1062 <message>
1063 <source>Select your device in the &amp;filesystem</source>
1064 <translation>Укажите Ваше устройство в &amp;файловой системе</translation>
1065 </message>
1066 <message>
1067 <source>&amp;Browse</source>
1068 <translation>&amp;Обзор</translation>
1069 </message>
1070 <message>
1071 <source>&amp;Select your audio player</source>
1072 <translation>&amp;Выберите ваш аудио плеер</translation>
1073 </message>
1074 <message>
1075 <source>&amp;Autodetect</source>
1076 <translation>&amp;Автоопределение</translation>
1077 </message>
1078 <message>
1079 <source>&amp;Proxy</source>
1080 <translation>П&amp;рокси</translation>
1081 </message>
1082 <message>
1083 <source>&amp;No Proxy</source>
1084 <translation>&amp;Без прокси</translation>
1085 </message>
1086 <message>
1087 <source>Use S&amp;ystem values</source>
1088 <translation>Использовать с&amp;истемные настройки</translation>
1089 </message>
1090 <message>
1091 <source>&amp;Manual Proxy settings</source>
1092 <translation>&amp;Ручные настройки прокси</translation>
1093 </message>
1094 <message>
1095 <source>Proxy Values</source>
1096 <translation>Параметры прокси</translation>
1097 </message>
1098 <message>
1099 <source>&amp;Host:</source>
1100 <translation>&amp;Хост:</translation>
1101 </message>
1102 <message>
1103 <source>&amp;Port:</source>
1104 <translation>&amp;Порт:</translation>
1105 </message>
1106 <message>
1107 <source>&amp;Username</source>
1108 <translation>&amp;Имя пользователя</translation>
1109 </message>
1110 <message>
1111 <source>Pass&amp;word</source>
1112 <translation>Пар&amp;оль</translation>
1113 </message>
1114 <message>
1115 <source>&amp;Language</source>
1116 <translation>&amp;Язык</translation>
1117 </message>
1118 <message>
1119 <source>Cac&amp;he</source>
1120 <translation>К&amp;эш</translation>
1121 </message>
1122 <message>
1123 <source>Download cache settings</source>
1124 <translation>Настройки кэша загрузок</translation>
1125 </message>
1126 <message>
1127 <source>Rockbox Utility uses a local download cache to save network traffic. You can change the path to the cache and use it as local repository by enabling Offline mode.</source>
1128 <translation>Мастер Rockbox использует локальный кэш скачивания для экономии сетевой передачи. Вы можете изменить путь к кэшу и использовать его как локальное хранилище с помощью автономного режима.</translation>
1129 </message>
1130 <message>
1131 <source>Current cache size is %1</source>
1132 <translation>Текущий размер кэша: %1</translation>
1133 </message>
1134 <message>
1135 <source>P&amp;ath</source>
1136 <translation>&amp;Путь</translation>
1137 </message>
1138 <message>
1139 <source>Entering an invalid folder will reset the path to the systems temporary path.</source>
1140 <translation>Введение неверного пути сбросит путь в значение системной временной папки.</translation>
1141 </message>
1142 <message>
1143 <source>Disable local &amp;download cache</source>
1144 <translation>Отключить локальный кэш &amp;загрузок</translation>
1145 </message>
1146 <message>
1147 <source>&lt;p&gt;This will try to use all information from the cache, even information about updates. Only use this option if you want to install without network connection. Note: you need to do the same install you want to perform later with network access first to download all required files to the cache.&lt;/p&gt;</source>
1148 <translation type="obsolete">&lt;p&gt;Эта функция попытается использовать всю информацию из кэша, даже информацию об обновлениях. Используйте эту возможность только если вы хотите устанавливать без подключения к сети. Примечание: Вам необходимо выполнить такую-же установку, которую вы хотите выполнить потом, пока подключение к сети действует, чтобы загрузить все нужные файлы в кэш.&lt;/p&gt;</translation>
1149 </message>
1150 <message>
1151 <source>O&amp;ffline mode</source>
1152 <translation type="obsolete">Ав&amp;тономный режим</translation>
1153 </message>
1154 <message>
1155 <source>Clean cache &amp;now</source>
1156 <translation>Вычистить кэш &amp;сейчас</translation>
1157 </message>
1158 <message>
1159 <source>&amp;TTS &amp;&amp; Encoder</source>
1160 <translation>&amp;TTS &amp;&amp; Кодировщик</translation>
1161 </message>
1162 <message>
1163 <source>TTS Engine</source>
1164 <translation>Движок TTS</translation>
1165 </message>
1166 <message>
1167 <source>&amp;Select TTS Engine</source>
1168 <translation>&amp;Выберите движок TTS</translation>
1169 </message>
1170 <message>
1171 <source>Encoder Engine</source>
1172 <translation>движок кодирования</translation>
1173 </message>
1174 <message>
1175 <source>&amp;Ok</source>
1176 <translation>&amp;OK</translation>
1177 </message>
1178 <message>
1179 <source>&amp;Cancel</source>
1180 <translation>&amp;Отмена</translation>
1181 </message>
1182 <message>
1183 <source>Configure TTS Engine</source>
1184 <translation>Настроить движок TTS</translation>
1185 </message>
1186 <message>
1187 <source>Configuration invalid!</source>
1188 <translation>Настройка неверна!</translation>
1189 </message>
1190 <message>
1191 <source>Configure &amp;TTS</source>
1192 <translation>Настроить &amp;TTS</translation>
1193 </message>
1194 <message>
1195 <source>Configure &amp;Enc</source>
1196 <translation>Настроить &amp;кодировщик</translation>
1197 </message>
1198 <message>
1199 <source>encoder name</source>
1200 <translation>имя кодировщика</translation>
1201 </message>
1202 <message>
1203 <source>Test TTS</source>
1204 <translation>Проверить TTS</translation>
1205 </message>
1206 <message>
1207 <source>Show disabled targets</source>
1208 <translation>Показывать отключенные устройства</translation>
1209 </message>
1210 <message>
1211 <source>&amp;Refresh</source>
1212 <translation>&amp;Обновить</translation>
1213 </message>
1214 <message>
1215 <source>&amp;Use string corrections for TTS</source>
1216 <translation>&amp;Использовать корекции строк для TTS</translation>
1217 </message>
1218 <message>
1219 <source>Show</source>
1220 <translation>Показать</translation>
1221 </message>
1222</context>
1223<context>
1224 <name>Configure</name>
1225 <message>
1226 <source>English</source>
1227 <comment>This is the localized language name, i.e. your language.</comment>
1228 <translation>Русский</translation>
1229 </message>
1230</context>
1231<context>
1232 <name>CreateVoiceFrm</name>
1233 <message>
1234 <source>Create Voice File</source>
1235 <translation>Создать голосовой файл</translation>
1236 </message>
1237 <message>
1238 <source>Select the Language you want to generate a voicefile for:</source>
1239 <translation>Выберите язык, для которого Вы хотите создать голосовой файл:</translation>
1240 </message>
1241 <message>
1242 <source>Generation settings</source>
1243 <translation>Настройки генерирования</translation>
1244 </message>
1245 <message>
1246 <source>Change</source>
1247 <translation>Изменить</translation>
1248 </message>
1249 <message>
1250 <source>&amp;Install</source>
1251 <translation>&amp;Установить</translation>
1252 </message>
1253 <message>
1254 <source>&amp;Cancel</source>
1255 <translation>&amp;Отмена</translation>
1256 </message>
1257 <message>
1258 <source>Wavtrim Threshold</source>
1259 <translation>Порог Wavtrim</translation>
1260 </message>
1261 <message>
1262 <source>Language</source>
1263 <translation>Язык</translation>
1264 </message>
1265 <message>
1266 <source>TTS:</source>
1267 <translation>TTS:</translation>
1268 </message>
1269 <message>
1270 <source>Silence threshold</source>
1271 <translation>Порог тишины</translation>
1272 </message>
1273</context>
1274<context>
1275 <name>CreateVoiceWindow</name>
1276 <message>
1277 <source>Engine: &lt;b&gt;%1&lt;/b&gt;</source>
1278 <translation>Движок: &lt;b&gt;%1&lt;/b&gt;</translation>
1279 </message>
1280 <message>
1281 <source>TTS error</source>
1282 <translation>Ошибка TTS</translation>
1283 </message>
1284 <message>
1285 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1286 <translation>Не удалось инициализироавть выбранный движок. Вы не можете им пользоваться.</translation>
1287 </message>
1288</context>
1289<context>
1290 <name>EncTtsCfgGui</name>
1291 <message>
1292 <source>Waiting for engine...</source>
1293 <translation>Ожидание движка...</translation>
1294 </message>
1295 <message>
1296 <source>Ok</source>
1297 <translation>OK</translation>
1298 </message>
1299 <message>
1300 <source>Cancel</source>
1301 <translation>Отмена</translation>
1302 </message>
1303 <message>
1304 <source>Browse</source>
1305 <translation>Обзор</translation>
1306 </message>
1307 <message>
1308 <source>Refresh</source>
1309 <translation>Обновить</translation>
1310 </message>
1311 <message>
1312 <source>Select executable</source>
1313 <translation>Выбрать исполняемый файл</translation>
1314 </message>
1315</context>
1316<context>
1317 <name>EncoderExe</name>
1318 <message>
1319 <source>Path to Encoder:</source>
1320 <translation>Путь к кодировщику:</translation>
1321 </message>
1322 <message>
1323 <source>Encoder options:</source>
1324 <translation>Настройки кодировщика:</translation>
1325 </message>
1326</context>
1327<context>
1328 <name>EncoderLame</name>
1329 <message>
1330 <source>LAME</source>
1331 <translation>LAME</translation>
1332 </message>
1333 <message>
1334 <source>Volume</source>
1335 <translation>Громкость</translation>
1336 </message>
1337 <message>
1338 <source>Quality</source>
1339 <translation>Качество</translation>
1340 </message>
1341 <message>
1342 <source>Could not find libmp3lame!</source>
1343 <translation>Не удалось найти libmp3lame!</translation>
1344 </message>
1345</context>
1346<context>
1347 <name>EncoderRbSpeex</name>
1348 <message>
1349 <source>Volume:</source>
1350 <translation>Громкость:</translation>
1351 </message>
1352 <message>
1353 <source>Quality:</source>
1354 <translation>Качество:</translation>
1355 </message>
1356 <message>
1357 <source>Complexity:</source>
1358 <translation>Сложность:</translation>
1359 </message>
1360 <message>
1361 <source>Use Narrowband:</source>
1362 <translation>Узкополосный:</translation>
1363 </message>
1364</context>
1365<context>
1366 <name>InfoWidget</name>
1367 <message>
1368 <source>File</source>
1369 <translation>Файл</translation>
1370 </message>
1371 <message>
1372 <source>Version</source>
1373 <translation>Версия</translation>
1374 </message>
1375</context>
1376<context>
1377 <name>InfoWidgetFrm</name>
1378 <message>
1379 <source>Currently installed packages.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; if you manually installed packages this might not be correct!</source>
1380 <translation>Установленные пакеты.&lt;br/&gt;&lt;b&gt;Примечание:&lt;/b&gt;Если вы установили некоторые пакеты вручную, могут возникнуть несоответствия!</translation>
1381 </message>
1382 <message>
1383 <source>Info</source>
1384 <translation>Сведения</translation>
1385 </message>
1386 <message>
1387 <source>Package</source>
1388 <translation>Пакет</translation>
1389 </message>
1390</context>
1391<context>
1392 <name>InstallTalkFrm</name>
1393 <message>
1394 <source>Install Talk Files</source>
1395 <translation>Установить голосовые файлы</translation>
1396 </message>
1397 <message>
1398 <source>TTS profile:</source>
1399 <translation>Профиль TTS :</translation>
1400 </message>
1401 <message>
1402 <source>Generation options</source>
1403 <translation>Свойства сгенерированого</translation>
1404 </message>
1405 <message>
1406 <source>Strip Extensions</source>
1407 <translation>Отрезать расширения</translation>
1408 </message>
1409 <message>
1410 <source>&amp;Cancel</source>
1411 <translation>&amp;Отмена</translation>
1412 </message>
1413 <message>
1414 <source>&amp;Install</source>
1415 <translation>&amp;Установить</translation>
1416 </message>
1417 <message>
1418 <source>Change</source>
1419 <translation>Изменить</translation>
1420 </message>
1421 <message>
1422 <source>Generate for files</source>
1423 <translation>Генерировать для файлов</translation>
1424 </message>
1425 <message>
1426 <source>Generate for folders</source>
1427 <translation>Генерировать для папок</translation>
1428 </message>
1429 <message>
1430 <source>Recurse into folders</source>
1431 <translation>Рекурсировать в папки</translation>
1432 </message>
1433 <message>
1434 <source>Ignore files</source>
1435 <translation>Игнорировать файлы</translation>
1436 </message>
1437 <message>
1438 <source>Skip existing</source>
1439 <translation>Пропускать существующие</translation>
1440 </message>
1441 <message>
1442 <source>Select folders for Talkfile generation (Ctrl for multiselect)</source>
1443 <translation>Выбрать папки для создания файлов произношения (Ctrl для выбора нескольких)</translation>
1444 </message>
1445</context>
1446<context>
1447 <name>InstallTalkWindow</name>
1448 <message>
1449 <source>Empty selection</source>
1450 <translation>Пусто</translation>
1451 </message>
1452 <message>
1453 <source>No files or folders selected. Please select files or folders first.</source>
1454 <translation>Не выбрано ни одного файла или папки. Сначала выберите файлы и (или) папки.</translation>
1455 </message>
1456 <message>
1457 <source>TTS error</source>
1458 <translation>Ошибка TTS</translation>
1459 </message>
1460 <message>
1461 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1462 <translation>Не удалось инициализироавть выбранный движок. Вы не можете им пользоваться.</translation>
1463 </message>
1464</context>
1465<context>
1466 <name>ManualWidget</name>
1467 <message>
1468 <source>&lt;a href=&apos;%1&apos;&gt;PDF Manual&lt;/a&gt;</source>
1469 <translation>&lt;a href=&apos;%1&apos;&gt;Руководство по эксплуатации в PDF&lt;/a&gt;</translation>
1470 </message>
1471 <message>
1472 <source>&lt;a href=&apos;%1&apos;&gt;HTML Manual (opens in browser)&lt;/a&gt;</source>
1473 <translation>&lt;a href=&apos;%1&apos;&gt;Руководство по эксплуатации в HTML (открывается в обозревателе)&lt;/a&gt;</translation>
1474 </message>
1475 <message>
1476 <source>Select a device for a link to the correct manual</source>
1477 <translation>Выберите устройство, чтобы получить ссылку на соответствующее руководство по эксплуатации</translation>
1478 </message>
1479 <message>
1480 <source>&lt;a href=&apos;%1&apos;&gt;Manual Overview&lt;/a&gt;</source>
1481 <translation>&lt;a href=&apos;%1&apos;&gt;Обзор руководства по эксплуатации&lt;/a&gt;</translation>
1482 </message>
1483 <message>
1484 <source>Confirm download</source>
1485 <translation>Потвердите скачивание</translation>
1486 </message>
1487 <message>
1488 <source>Do you really want to download the manual? The manual will be saved to the root folder of your player.</source>
1489 <translation>Вы действительно хотите скачать руководство по эксплуатации? Оно будет записано в коренную папку Вашего плеера.</translation>
1490 </message>
1491</context>
1492<context>
1493 <name>ManualWidgetFrm</name>
1494 <message>
1495 <source>Read the manual</source>
1496 <translation>Читать руководство по эксплуатации</translation>
1497 </message>
1498 <message>
1499 <source>PDF manual</source>
1500 <translation>Руководство по эксплуатации в PDF</translation>
1501 </message>
1502 <message>
1503 <source>HTML manual</source>
1504 <translation>Руководство по эксплуатации в HTML</translation>
1505 </message>
1506 <message>
1507 <source>Download the manual</source>
1508 <translation>Скачать руководство по эксплуатации</translation>
1509 </message>
1510 <message>
1511 <source>&amp;PDF version</source>
1512 <translation>Версия &amp;PDF</translation>
1513 </message>
1514 <message>
1515 <source>&amp;HTML version (zip file)</source>
1516 <translation>Версия &amp;HTML (.zip-файл)</translation>
1517 </message>
1518 <message>
1519 <source>Down&amp;load</source>
1520 <translation>С&amp;качать</translation>
1521 </message>
1522 <message>
1523 <source>Manual</source>
1524 <translation>Руководство по эксплуатации</translation>
1525 </message>
1526</context>
1527<context>
1528 <name>MsPackUtil</name>
1529 <message>
1530 <source>Creating output path failed</source>
1531 <translation>Ошибка создания выходной папки</translation>
1532 </message>
1533 <message>
1534 <source>Error during CAB operation</source>
1535 <translation>Ошибка при выполнении операции с CAB-пакетом</translation>
1536 </message>
1537</context>
1538<context>
1539 <name>PreviewFrm</name>
1540 <message>
1541 <source>Preview</source>
1542 <translation>Предпросмотр</translation>
1543 </message>
1544</context>
1545<context>
1546 <name>ProgressLoggerFrm</name>
1547 <message>
1548 <source>Progress</source>
1549 <translation>Продвижение</translation>
1550 </message>
1551 <message>
1552 <source>&amp;Abort</source>
1553 <translation>&amp;Отмена</translation>
1554 </message>
1555 <message>
1556 <source>progresswindow</source>
1557 <translation>Окно продвижения</translation>
1558 </message>
1559 <message>
1560 <source>Save Log</source>
1561 <translation>Сохранить журнал</translation>
1562 </message>
1563</context>
1564<context>
1565 <name>ProgressLoggerGui</name>
1566 <message>
1567 <source>&amp;Ok</source>
1568 <translation>&amp;OK</translation>
1569 </message>
1570 <message>
1571 <source>&amp;Abort</source>
1572 <translation>&amp;Отмена</translation>
1573 </message>
1574 <message>
1575 <source>Save system trace log</source>
1576 <translation>Сохранить журнал трассировки системы</translation>
1577 </message>
1578</context>
1579<context>
1580 <name>QObject</name>
1581 <message>
1582 <source>LTR</source>
1583 <extracomment>This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.
1584----------
1585This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.</extracomment>
1586 <translation>LTR</translation>
1587 </message>
1588 <message>
1589 <source>(unknown vendor name) </source>
1590 <translation>(неизвестный поставщик)</translation>
1591 </message>
1592 <message>
1593 <source>(unknown product name)</source>
1594 <translation>(неизвестный продукт)</translation>
1595 </message>
1596 <message>
1597 <source>Bootloader installation is almost complete. Installation &lt;b&gt;requires&lt;/b&gt; you to perform the following steps manually:</source>
1598 <translation>Установка загрузчика почти завершена. Вам &lt;b&gt;протребуется&lt;/b&gt; выполнить следующие операции вручную:</translation>
1599 </message>
1600 <message>
1601 <source>&lt;li&gt;Safely remove your player.&lt;/li&gt;</source>
1602 <translation>&lt;li&gt;Отключить плеер от компьютера с использованием безопасного извлечения.&lt;/li&gt;</translation>
1603 </message>
1604 <message>
1605 <source>&lt;li&gt;Reboot your player into the original firmware.&lt;/li&gt;&lt;li&gt;Perform a firmware upgrade using the update functionality of the original firmware. Please refer to your player&apos;s manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before starting the firmware update process.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1606 <translation>&lt;li&gt;Перезагрузите плеер на фирменную программу.&lt;/li&gt;&lt;li&gt;Обновите программу с помощью функции обновления в фирменной программе. Для подробностей, см. руководство по эксплуатации Вашего плеера.&lt;br/&gt;&lt;b&gt;Важно:&lt;/b&gt; обновление програмного обеспечения является критичной процедурой и не должно быть прервано. &lt;b&gt;Убедитесь в том, что плеер полностью заряжен перед тем, как приступить к обновлению.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;После обновления, перезагрузите плеер.&lt;/li&gt;</translation>
1607 </message>
1608 <message>
1609 <source>&lt;li&gt;Remove any previously inserted microSD card&lt;/li&gt;</source>
1610 <translation>&lt;li&gt;Если в плеере стоит SD-карта, извлеките её&lt;/li&gt;</translation>
1611 </message>
1612 <message>
1613 <source>&lt;li&gt;Disconnect your player. The player will reboot and perform an update of the original firmware. Please refer to your players manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before disconnecting the player.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1614 <translation>&lt;li&gt;Отсоедините плеер, после чего произойдёт перезагрузка и обновится фирменная программа. Для подробностей, см. руковолство по эксплуатации Вашего плеера.&lt;br/&gt;&lt;b&gt;Важно:&lt;/b&gt; обновление програмного обеспечения является критичной процедурой и не должно быть прервано. &lt;b&gt;Убедитесь в том, что плеер полностью заряжен перед тем, как приступить к обновлению.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;После обновления, перезагрузите плеер.&lt;/li&gt;</translation>
1615 </message>
1616 <message>
1617 <source>&lt;li&gt;Turn the player off&lt;/li&gt;&lt;li&gt;Insert the charger&lt;/li&gt;</source>
1618 <translation>&lt;li&gt;Выключить плеер&lt;/li&gt;&lt;li&gt;Подключить зарядное устройство&lt;/li&gt;</translation>
1619 </message>
1620 <message>
1621 <source>&lt;li&gt;Unplug USB and power adaptors&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to turn the player off&lt;/li&gt;&lt;li&gt;Toggle the battery switch on the player&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to boot into Rockbox&lt;/li&gt;</source>
1622 <translation>&lt;li&gt;Отключить плеер от USB и сетевого питания&lt;/li&gt;&lt;li&gt;Выключить плеер&lt;/li&gt;&lt;li&gt;Переключить плеер в режим питания от батареи&lt;/li&gt;&lt;li&gt;Обратно включить плеер для загрузки Rockbox&lt;/li&gt;</translation>
1623 </message>
1624 <message>
1625 <source>&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You can safely install other parts first, but the above steps are &lt;b&gt;required&lt;/b&gt; to finish the installation!&lt;/p&gt;</source>
1626 <translation>&lt;p&gt;&lt;b&gt;Примечание:&lt;/b&gt; Вы можете безопасно устанавливать дополнения, но выше указанные операции &lt;b&gt;обязательны&lt;/b&gt; для завершения установки!&lt;/p&gt;</translation>
1627 </message>
1628</context>
1629<context>
1630 <name>QuaZipFile</name>
1631 <message>
1632 <source>ZIP/UNZIP API error %1</source>
1633 <translation>ошибка ZIP/UNZIP API %1</translation>
1634 </message>
1635</context>
1636<context>
1637 <name>RbUtilQt</name>
1638 <message>
1639 <source>Confirm Installation</source>
1640 <translation>Подтвердите установку</translation>
1641 </message>
1642 <message>
1643 <source>Mount point is wrong!</source>
1644 <translation>Точка монтирования неверная!</translation>
1645 </message>
1646 <message>
1647 <source>Do you really want to install the voice file?</source>
1648 <translation>Вы действительно хотите установить голосовой файл?</translation>
1649 </message>
1650 <message>
1651 <source>Confirm Uninstallation</source>
1652 <translation>Подтвердите удаление</translation>
1653 </message>
1654 <message>
1655 <source>Do you really want to uninstall the Bootloader?</source>
1656 <translation>Вы действительно хотите удалить загрузчик?</translation>
1657 </message>
1658 <message>
1659 <source>Confirm installation</source>
1660 <translation>Подтвердите установку</translation>
1661 </message>
1662 <message>
1663 <source>Do you really want to install Rockbox Utility to your player? After installation you can run it from the players hard drive.</source>
1664 <translation>Вы действительно хотите установить мастера Rockbox на Ваш аудио плеер? Вы сможете потом запустить это с диска или памяти плеера.</translation>
1665 </message>
1666 <message>
1667 <source>Installing Rockbox Utility</source>
1668 <translation>Установка мастера Rockbox</translation>
1669 </message>
1670 <message>
1671 <source>Error installing Rockbox Utility</source>
1672 <translation>Ошибка при установке мастера Rockbox</translation>
1673 </message>
1674 <message>
1675 <source>Installing user configuration</source>
1676 <translation>Установка настроек пользователя</translation>
1677 </message>
1678 <message>
1679 <source>Error installing user configuration</source>
1680 <translation>Ошибка при установке настроек пользователя</translation>
1681 </message>
1682 <message>
1683 <source>Successfully installed Rockbox Utility.</source>
1684 <translation>Мастер Rockbox успешно установлен.</translation>
1685 </message>
1686 <message>
1687 <source>Configuration error</source>
1688 <translation>Ошибка в настройках</translation>
1689 </message>
1690 <message>
1691 <source>Your configuration is invalid. Please go to the configuration dialog and make sure the selected values are correct.</source>
1692 <translation>Ваши настройки недействительны. Проверьте, что ваши настройки правильные в окне настроек.</translation>
1693 </message>
1694 <message>
1695 <source>Warning</source>
1696 <translation>Предупреждение</translation>
1697 </message>
1698 <message>
1699 <source>The Application is still downloading Information about new Builds. Please try again shortly.</source>
1700 <translation>Программа ещё загружает информацию о новых версиях. Попробуйте снова через несколько мгновений.</translation>
1701 </message>
1702 <message>
1703 <source>New installation</source>
1704 <translation>Новая установка</translation>
1705 </message>
1706 <message>
1707 <source>Your configuration is invalid. This is most likely due to a changed device path. The configuration dialog will now open to allow you to correct the problem.</source>
1708 <translation>Ваши настройки негодны. Это скорее всего из-за изменённого пути к устройству. Окно настроек сейчас откроется, чтобы позволить Вам решить проблему.</translation>
1709 </message>
1710 <message>
1711 <source>Network error</source>
1712 <translation>Ошибка сети</translation>
1713 </message>
1714 <message>
1715 <source>Downloading build information, please wait ...</source>
1716 <translation>Скачивается информация о сборке, пожалуйста подождите...</translation>
1717 </message>
1718 <message>
1719 <source>Can&apos;t get version information!</source>
1720 <translation>Не удалось получить информацию о версии!</translation>
1721 </message>
1722 <message>
1723 <source>This is a new installation of Rockbox Utility, or a new version. The configuration dialog will now open to allow you to setup the program, or review your settings.</source>
1724 <translation>Это новая установка или новая версия мастера Rockbox. Диалог настройки сейчас откроется и даст возможность настроить программу или пересмотреть ваши настройки.</translation>
1725 </message>
1726 <message>
1727 <source>Download build information finished.</source>
1728 <translation>Загрузка информации о сборке завершена.</translation>
1729 </message>
1730 <message>
1731 <source>RockboxUtility Update available</source>
1732 <translation>Доступно обновление мастера Rockbox</translation>
1733 </message>
1734 <message>
1735 <source>&lt;b&gt;New RockboxUtility Version available.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Download it from here: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</source>
1736 <translation>Доступна новая версия мастера Rockbox. Скачать можно отсюда: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</translation>
1737 </message>
1738 <message>
1739 <source>Wine detected!</source>
1740 <translation>Обнаружен Wine!</translation>
1741 </message>
1742 <message>
1743 <source>It seems you are trying to run this program under Wine. Please don&apos;t do this, running under Wine will fail. Use the native Linux binary instead.</source>
1744 <translation>Похоже, что вы пытаетесь пользоваться этой программой с помощью Wine. Не делайте этого, это приведёт к сбою. Лучше пользуйтесь нативной программой для Linux.</translation>
1745 </message>
1746 <message>
1747 <source>Can&apos;t get version information.
1748Network error: %1. Please check your network and proxy settings.</source>
1749 <translation>Не удалось получить информацию о версии.
1750Ошибка сети: %1. Проверьте настройки сети и прокси.</translation>
1751 </message>
1752 <message>
1753 <source>No Rockbox installation found</source>
1754 <translation>Не найдено установки Rockbox</translation>
1755 </message>
1756 <message>
1757 <source>Could not determine the installed Rockbox version. Please install a Rockbox build before installing voice files.</source>
1758 <translation>Не удалось определить версию установленного Rockbox. Устанавливайте Rockbox перед установкой голосовых файлов.</translation>
1759 </message>
1760 <message>
1761 <source>No uninstall method for this target known.</source>
1762 <translation>Нет известного способа удаления с этого устройства.</translation>
1763 </message>
1764 <message>
1765 <source>Rockbox Utility can not uninstall the bootloader on this target. Try a normal firmware update to remove the booloader.</source>
1766 <translation>Мастер Rockbox не может удалить загрузчик с этого устройства. Попробуйте нормальное обновление прошивки, чтобы удалить загрузчик.</translation>
1767 </message>
1768 <message>
1769 <source>Checking for update ...</source>
1770 <translation>Проверяется наличие обновления ...</translation>
1771 </message>
1772 <message>
1773 <source>New version of Rockbox Utility available.</source>
1774 <translation>Доступна новая версия мастера Rockbox.</translation>
1775 </message>
1776 <message>
1777 <source>Rockbox Utility is up to date.</source>
1778 <translation>Мастер Rockbox не требует обновления.</translation>
1779 </message>
1780 <message>
1781 <source>No voice file available</source>
1782 <translation>Нет доступного голосового файла</translation>
1783 </message>
1784 <message>
1785 <source>The installed version of Rockbox is a development version. Pre-built voices are only available for release versions of Rockbox. Please generate a voice yourself using the &quot;Create voice file&quot; functionality.</source>
1786 <translation>Установленная версия Rockbox является официально нестабильной. Готовые голоса доступны только для стабильных версий Rockbox. Создайте вручную голосовой файл с помощью кнопки &quot;Создать голосовой файл&quot;.</translation>
1787 </message>
1788 <message>
1789 <source>No Rockbox bootloader found.</source>
1790 <translation>Не найдено загрузчика Rockbox.</translation>
1791 </message>
1792 <message>
1793 <source>Device ejected</source>
1794 <translation>Устройство извлечено</translation>
1795 </message>
1796 <message>
1797 <source>Device successfully ejected. You may now disconnect the player from the PC.</source>
1798 <translation>Устройство успешно извлечено. Теперь можно отсоединить плеер от компьютера.</translation>
1799 </message>
1800 <message>
1801 <source>Ejecting failed</source>
1802 <translation>Не удалось извлечь</translation>
1803 </message>
1804 <message>
1805 <source>Ejecting the device failed. Please make sure no programs are accessing files on the device. If ejecting still fails please use your computers eject funtionality.</source>
1806 <translation>Извлечение не удалось. Убедитесь в том, что на устройстве нет файлов, занятых другими программами. Если извлечь всё равно не получается, пользуйтесь функцией извлечения Вашего компьютера.</translation>
1807 </message>
1808</context>
1809<context>
1810 <name>RbUtilQtFrm</name>
1811 <message>
1812 <source>Rockbox Utility</source>
1813 <translation>Мастер Rockbox</translation>
1814 </message>
1815 <message>
1816 <source>Device</source>
1817 <translation>Устройство</translation>
1818 </message>
1819 <message>
1820 <source>&amp;Change</source>
1821 <translation>&amp;Изменить</translation>
1822 </message>
1823 <message>
1824 <source>Welcome</source>
1825 <translation>Добро пожаловать</translation>
1826 </message>
1827 <message>
1828 <source>&amp;Installation</source>
1829 <translation>&amp;Установка</translation>
1830 </message>
1831 <message>
1832 <source>&amp;Accessibility</source>
1833 <translation>&amp;Специальные возможности</translation>
1834 </message>
1835 <message>
1836 <source>Install accessibility add-ons</source>
1837 <translation>Установить дополнения для специальных возможностей</translation>
1838 </message>
1839 <message>
1840 <source>Install Voice files</source>
1841 <translation>Установить голосовые файлы</translation>
1842 </message>
1843 <message>
1844 <source>Install Talk files</source>
1845 <translation>Установить файлы произношения</translation>
1846 </message>
1847 <message>
1848 <source>&amp;Uninstallation</source>
1849 <translation>&amp;Удаление</translation>
1850 </message>
1851 <message>
1852 <source>Uninstall Rockbox</source>
1853 <translation>Удалить Rockbox</translation>
1854 </message>
1855 <message>
1856 <source>Uninstall Bootloader</source>
1857 <translation>Удалить загрузчик</translation>
1858 </message>
1859 <message>
1860 <source>&amp;Manual</source>
1861 <translation>&amp;Руководство по эксплуатации</translation>
1862 </message>
1863 <message>
1864 <source>View and download the manual</source>
1865 <translation>Смотреть и/или загрузить руководство по эксплуатации</translation>
1866 </message>
1867 <message>
1868 <source>Inf&amp;o</source>
1869 <translation>&amp;Информация</translation>
1870 </message>
1871 <message>
1872 <source>&amp;File</source>
1873 <translation>&amp;Файл</translation>
1874 </message>
1875 <message>
1876 <source>&amp;About</source>
1877 <translation>&amp;О программе</translation>
1878 </message>
1879 <message>
1880 <source>Empty local download cache</source>
1881 <translation>Очистить локальный кэш скачивания</translation>
1882 </message>
1883 <message>
1884 <source>Install Rockbox Utility on player</source>
1885 <translation>Установить мастера Rockbox на плеер</translation>
1886 </message>
1887 <message>
1888 <source>&amp;Configure</source>
1889 <translation>&amp;Настройки</translation>
1890 </message>
1891 <message>
1892 <source>E&amp;xit</source>
1893 <translation>&amp;Выйти</translation>
1894 </message>
1895 <message>
1896 <source>Ctrl+Q</source>
1897 <translation>Ctrl+Q</translation>
1898 </message>
1899 <message>
1900 <source>About &amp;Qt</source>
1901 <translation>О &amp;Qt</translation>
1902 </message>
1903 <message>
1904 <source>&amp;Help</source>
1905 <translation>&amp;Помощь</translation>
1906 </message>
1907 <message>
1908 <source>Action&amp;s</source>
1909 <translation>&amp;Действия</translation>
1910 </message>
1911 <message>
1912 <source>Info</source>
1913 <translation>Информация</translation>
1914 </message>
1915 <message>
1916 <source>Read PDF manual</source>
1917 <translation>Читать руководство по эксплуатации в PDF</translation>
1918 </message>
1919 <message>
1920 <source>Read HTML manual</source>
1921 <translation>Читать руководство по эксплуатации в HTML</translation>
1922 </message>
1923 <message>
1924 <source>Download PDF manual</source>
1925 <translation>Скачать руководство по эксплуатации в PDF</translation>
1926 </message>
1927 <message>
1928 <source>Download HTML manual (zip)</source>
1929 <translation>Скачать руководство по эксплуатации в HTML (zip)</translation>
1930 </message>
1931 <message>
1932 <source>Create Voice files</source>
1933 <translation>Создать голосовые файлы</translation>
1934 </message>
1935 <message>
1936 <source>Create Voice File</source>
1937 <translation>Создать голосовой файл</translation>
1938 </message>
1939 <message>
1940 <source>&lt;b&gt;Install Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so if you installed the voice file Rockbox will speak.</source>
1941 <translation>&lt;b&gt;Установить голосовой файл&lt;/b&gt;&lt;br/&gt;Он нужен, чтобы Rockbox произносил пользовательский интерфейс. Произношение включено по умолчанию, поэтому если Вы установили голосовой файл, Rockbox станет разговаривать.</translation>
1942 </message>
1943 <message>
1944 <source>&lt;b&gt;Create Talk Files&lt;/b&gt;&lt;br/&gt;Talkfiles are needed to let Rockbox speak File and Foldernames</source>
1945 <translation>&lt;b&gt;Создать файлы произношения.&lt;/b&gt;&lt;br/&gt;Они нужны, чтобы Rockbox мог произносить имена файлов и папок</translation>
1946 </message>
1947 <message>
1948 <source>&lt;b&gt;Remove the bootloader&lt;/b&gt;&lt;br/&gt;After removing the bootloader you won&apos;t be able to start Rockbox.</source>
1949 <translation>&lt;b&gt;Удалить загрузчик&lt;/b&gt;&lt;br/&gt;После удаления загрузчика, вы не сможете запустить Rockbox.</translation>
1950 </message>
1951 <message>
1952 <source>&lt;b&gt;Uninstall Rockbox from your audio player.&lt;/b&gt;&lt;br/&gt;This will leave the bootloader in place (you need to remove it manually).</source>
1953 <translation>&lt;b&gt;Удалить Rockbox с Вашего плеера.&lt;/b&gt;&lt;br/&gt;Это оставит загрузчик установленным (его нужно будет удалить вручную).</translation>
1954 </message>
1955 <message>
1956 <source>Install &amp;Bootloader</source>
1957 <translation>Установить &amp;загрузчик</translation>
1958 </message>
1959 <message>
1960 <source>Install &amp;Rockbox</source>
1961 <translation>Установить &amp;Rockbox</translation>
1962 </message>
1963 <message>
1964 <source>Install &amp;Fonts Package</source>
1965 <translation>Установить пакет &amp;шрифтов</translation>
1966 </message>
1967 <message>
1968 <source>Install &amp;Themes</source>
1969 <translation>Установить &amp;темы</translation>
1970 </message>
1971 <message>
1972 <source>Install &amp;Game Files</source>
1973 <translation>Установить игровые &amp;файлы</translation>
1974 </message>
1975 <message>
1976 <source>&amp;Install Voice File</source>
1977 <translation>&amp;Установить голосовой файл</translation>
1978 </message>
1979 <message>
1980 <source>Create &amp;Talk Files</source>
1981 <translation>Установить файлы &amp;произношения</translation>
1982 </message>
1983 <message>
1984 <source>Remove &amp;bootloader</source>
1985 <translation>У&amp;далить загрузчик</translation>
1986 </message>
1987 <message>
1988 <source>Uninstall &amp;Rockbox</source>
1989 <translation>Удалить &amp;Rockbox</translation>
1990 </message>
1991 <message>
1992 <source>Create &amp;Voice File</source>
1993 <translation>&amp;Создать голосовой файл</translation>
1994 </message>
1995 <message>
1996 <source>&amp;System Info</source>
1997 <translation>Информация о &amp;системе</translation>
1998 </message>
1999 <message>
2000 <source>&amp;Complete Installation</source>
2001 <translation>&amp;Полная установка</translation>
2002 </message>
2003 <message>
2004 <source>&amp;Minimal Installation</source>
2005 <translation>&amp;Минимальная установка</translation>
2006 </message>
2007 <message>
2008 <source>&amp;Troubleshoot</source>
2009 <translation>&amp;Устранение неполадок</translation>
2010 </message>
2011 <message>
2012 <source>System &amp;Trace</source>
2013 <translation>&amp;Трассировка системы</translation>
2014 </message>
2015 <message>
2016 <source>&lt;b&gt;Create Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so
2017 if you installed the voice file Rockbox will speak.</source>
2018 <translation>&lt;b&gt;Создать голосовой файл&lt;/b&gt;&lt;br/&gt;Он нужен, чтобы Rockbox произносил пользовательский интерфейс. Произношение включено по умолчанию, поэтому если Вы установили голосовой файл, Rockbox станет разговаривать.</translation>
2019 </message>
2020 <message>
2021 <source>mountpoint unknown or invalid</source>
2022 <translation>точка монтирования неизвестна или неправильна</translation>
2023 </message>
2024 <message>
2025 <source>Mountpoint:</source>
2026 <translation>Точка монтирования:</translation>
2027 </message>
2028 <message>
2029 <source>device unknown or invalid</source>
2030 <translation>устройство неизвестно или неправильно</translation>
2031 </message>
2032 <message>
2033 <source>Device:</source>
2034 <translation>Устройство:</translation>
2035 </message>
2036 <message>
2037 <source>Backup &amp;&amp; &amp;Uninstallation</source>
2038 <translation>Резервная копия и &amp;Удаление</translation>
2039 </message>
2040 <message>
2041 <source>Backup</source>
2042 <translation>Создать резервную копию</translation>
2043 </message>
2044 <message>
2045 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup current installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Create a backup by archiving the contents of the Rockbox installation folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2046 <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Создать резервную копию текущей установки.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Создать копию, архивируя содержимое системной папки Rockbox.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
2047 </message>
2048 <message>
2049 <source>&amp;Eject</source>
2050 <translation>&amp;Извлечь</translation>
2051 </message>
2052 <message>
2053 <source>Show &amp;Changelog</source>
2054 <translation>Показать &amp;историю изменений</translation>
2055 </message>
2056</context>
2057<context>
2058 <name>SelectiveInstallWidget</name>
2059 <message>
2060 <source>Rockbox version to install</source>
2061 <translation>Версия Rockbox для установки</translation>
2062 </message>
2063 <message>
2064 <source>Version information not available yet.</source>
2065 <translation>Сведения о версии пока отсутствуют.</translation>
2066 </message>
2067 <message>
2068 <source>Rockbox components to install</source>
2069 <translation>Части Rockbox для установки</translation>
2070 </message>
2071 <message>
2072 <source>&amp;Bootloader</source>
2073 <translation>&amp;Загрузчик</translation>
2074 </message>
2075 <message>
2076 <source>The main Rockbox firmware.</source>
2077 <translation>Основная программа Rockbox.</translation>
2078 </message>
2079 <message>
2080 <source>Fonts</source>
2081 <translation>Шрифты</translation>
2082 </message>
2083 <message>
2084 <source>&amp;Rockbox</source>
2085 <translation>&amp;Rockbox</translation>
2086 </message>
2087 <message>
2088 <source>Some game plugins require additional files.</source>
2089 <translation>Некоторые игры требуют дополнительных файлов.</translation>
2090 </message>
2091 <message>
2092 <source>Additional fonts for the User Interface.</source>
2093 <translation>Дополнительные шрифты для пользовательского интерфейса.</translation>
2094 </message>
2095 <message>
2096 <source>The bootloader is required for starting Rockbox. Only necessary for first time install.</source>
2097 <translation>Загрузчик требуется для запуска Rockbox. Нужен только для первой установки.</translation>
2098 </message>
2099 <message>
2100 <source>Game Files</source>
2101 <translation>Файлы игр</translation>
2102 </message>
2103 <message>
2104 <source>Customize</source>
2105 <translation>Выбрать</translation>
2106 </message>
2107 <message>
2108 <source>Themes</source>
2109 <translation>Темы</translation>
2110 </message>
2111 <message>
2112 <source>Themes allow adjusting the user interface of Rockbox. Use &quot;Customize&quot; to select themes.</source>
2113 <translation>Темы позволяют изменить пользовательский интерфейс Rockbox. Вы можете их выбрать в списке.</translation>
2114 </message>
2115 <message>
2116 <source>&amp;Install</source>
2117 <translation>&amp;Установить</translation>
2118 </message>
2119 <message>
2120 <source>This is the latest stable release available.</source>
2121 <translation>Это последняя стабильная версия.</translation>
2122 </message>
2123 <message>
2124 <source>The development version is updated on every code change. Last update was on %1</source>
2125 <translation>Разрабатываемая версия обновляется с каждым изменением исходного кода. Дата последнего обновления: %1</translation>
2126 </message>
2127 <message>
2128 <source>This will eventually become the next Rockbox version. Install it to help testing.</source>
2129 <translation>Это станет следующей стабильной версией Rockbox. Устанавливайте для тестирования.</translation>
2130 </message>
2131 <message>
2132 <source>Stable Release (Version %1)</source>
2133 <translation>Стабильная версия (%1)</translation>
2134 </message>
2135 <message>
2136 <source>Development Version (Revison %1)</source>
2137 <translation>Разрабатываемая версия (ревизия %1)</translation>
2138 </message>
2139 <message>
2140 <source>Release Candidate (Revison %1)</source>
2141 <translation>Пробная версия (ревизия %1)</translation>
2142 </message>
2143 <message>
2144 <source>The selected player doesn&apos;t need a bootloader.</source>
2145 <translation>Выбранный плеер не требует загрузчика.</translation>
2146 </message>
2147 <message>
2148 <source>The bootloader is required for starting Rockbox. Installation of the bootloader is only necessary on first time installation.</source>
2149 <translation>Загрузчик требуется для запуска Rockbox. Установка загрузчика требуется только при первой установке.</translation>
2150 </message>
2151 <message>
2152 <source>Mountpoint is wrong</source>
2153 <translation>Точка монтирования неверна</translation>
2154 </message>
2155 <message>
2156 <source>No install method known.</source>
2157 <translation>Нет известного способа установки.</translation>
2158 </message>
2159 <message>
2160 <source>Bootloader detected</source>
2161 <translation>Найден загрузчик</translation>
2162 </message>
2163 <message>
2164 <source>Bootloader already installed. Do you want to reinstall the bootloader?</source>
2165 <translation>Загрузчик уже установлен. Переустановить?</translation>
2166 </message>
2167 <message>
2168 <source>Bootloader installation skipped</source>
2169 <translation>Установка загрузчика пропущена</translation>
2170 </message>
2171 <message>
2172 <source>Create Bootloader backup</source>
2173 <translation>Создать резервную копию загрузчика</translation>
2174 </message>
2175 <message>
2176 <source>You can create a backup of the original bootloader file. Press &quot;Yes&quot; to select an output folder on your computer to save the file to. The file will get placed in a new folder &quot;%1&quot; created below the selected folder.
2177Press &quot;No&quot; to skip this step.</source>
2178 <translation>Вы можете создать резервную копию фирменного файла загрузчика. Нажмите на &quot;Да&quot;, чтобы выбрать выходную папку, в которой будет создана ещё одна папка &quot;%1&quot;, содержащая файл.
2179Нажмите на &quot;Нет&quot;, чтобы пропустить этот шаг.</translation>
2180 </message>
2181 <message>
2182 <source>Browse backup folder</source>
2183 <translation>Обзор папки резервных копий</translation>
2184 </message>
2185 <message>
2186 <source>Prerequisites</source>
2187 <translation>Предварительные требования</translation>
2188 </message>
2189 <message>
2190 <source>Bootloader installation aborted</source>
2191 <translation>Установка загрузчика отменена</translation>
2192 </message>
2193 <message>
2194 <source>Bootloader files (%1)</source>
2195 <translation>Загрузочные файлы (%1)</translation>
2196 </message>
2197 <message>
2198 <source>All files (*)</source>
2199 <translation>Все файлы (*)</translation>
2200 </message>
2201 <message>
2202 <source>Select firmware file</source>
2203 <translation>Выберите файл прошивки</translation>
2204 </message>
2205 <message>
2206 <source>Error opening firmware file</source>
2207 <translation>Ошибка при открытии файла прошивки</translation>
2208 </message>
2209 <message>
2210 <source>Error reading firmware file</source>
2211 <translation>Ошибка при чтении файла прошивки</translation>
2212 </message>
2213 <message>
2214 <source>Backup error</source>
2215 <translation>Ошибка резервной копии</translation>
2216 </message>
2217 <message>
2218 <source>Could not create backup file. Continue?</source>
2219 <translation>Не удалось создать резеврную копию файла. Продолжить?</translation>
2220 </message>
2221 <message>
2222 <source>Manual steps required</source>
2223 <translation>Требуются действия вручную</translation>
2224 </message>
2225 <message>
2226 <source>Continue with installation?</source>
2227 <translation>Продолжить и приступить к установке?</translation>
2228 </message>
2229 <message>
2230 <source>Really continue?</source>
2231 <translatorcomment>:-)</translatorcomment>
2232 <translation>Точно продожить?</translation>
2233 </message>
2234 <message>
2235 <source>Aborted!</source>
2236 <translation type="obsolete">Отменено!</translation>
2237 </message>
2238 <message>
2239 <source>Your installation doesn&apos;t require game files, skipping.</source>
2240 <translation>Ваша установка не требует игровых файлов, шаг пропущен.</translation>
2241 </message>
2242 <message>
2243 <source>Selective Installation</source>
2244 <translation>Выборочная установка</translation>
2245 </message>
2246</context>
2247<context>
2248 <name>ServerInfo</name>
2249 <message>
2250 <source>Unknown</source>
2251 <translation>Неизвестный</translation>
2252 </message>
2253 <message>
2254 <source>Unusable</source>
2255 <translation>Непригодный</translation>
2256 </message>
2257 <message>
2258 <source>Unstable</source>
2259 <translation>Нестабильный</translation>
2260 </message>
2261 <message>
2262 <source>Stable</source>
2263 <translation>Стабильный</translation>
2264 </message>
2265</context>
2266<context>
2267 <name>SysTrace</name>
2268 <message>
2269 <source>Save system trace log</source>
2270 <translation>Сохранить журнал трассировки системы</translation>
2271 </message>
2272</context>
2273<context>
2274 <name>SysTraceFrm</name>
2275 <message>
2276 <source>System Trace</source>
2277 <translation>Трассировка системы</translation>
2278 </message>
2279 <message>
2280 <source>System State trace</source>
2281 <translation>Трассировка состояния системы</translation>
2282 </message>
2283 <message>
2284 <source>&amp;Close</source>
2285 <translation>&amp;Закрыть</translation>
2286 </message>
2287 <message>
2288 <source>&amp;Save</source>
2289 <translation>&amp;Сохранить</translation>
2290 </message>
2291 <message>
2292 <source>&amp;Refresh</source>
2293 <translation>&amp;Обновить</translation>
2294 </message>
2295 <message>
2296 <source>Save &amp;previous</source>
2297 <translation>Сохранить &amp;предыдущий</translation>
2298 </message>
2299</context>
2300<context>
2301 <name>Sysinfo</name>
2302 <message>
2303 <source>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</source>
2304 <translation>&lt;b&gt;ОС&lt;/b&gt;&lt;br/&gt;</translation>
2305 </message>
2306 <message>
2307 <source>&lt;b&gt;Username&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2308 <translation>&lt;b&gt;Имя пользователя&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2309 </message>
2310 <message>
2311 <source>&lt;b&gt;Permissions&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2312 <translation>&lt;b&gt;Полномочия&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</translation>
2313 </message>
2314 <message>
2315 <source>&lt;b&gt;Attached USB devices&lt;/b&gt;&lt;br/&gt;</source>
2316 <translation>&lt;b&gt;Подключенные USB-устройства&lt;/b&gt;&lt;br/&gt;</translation>
2317 </message>
2318 <message>
2319 <source>VID: %1 PID: %2, %3</source>
2320 <translation>VID: %1 PID: %2, %3</translation>
2321 </message>
2322 <message>
2323 <source>Filesystem</source>
2324 <translation>Файловая система</translation>
2325 </message>
2326 <message>
2327 <source>Mountpoint</source>
2328 <translation>Точка монтирования</translation>
2329 </message>
2330 <message>
2331 <source>Label</source>
2332 <translation>Метка</translation>
2333 </message>
2334 <message>
2335 <source>Free</source>
2336 <translation>Свободно</translation>
2337 </message>
2338 <message>
2339 <source>Total</source>
2340 <translation>Всего</translation>
2341 </message>
2342 <message>
2343 <source>Cluster Size</source>
2344 <translation>Размер кластера</translation>
2345 </message>
2346 <message>
2347 <source>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</source>
2348 <translation>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 ГиБ&lt;/td&gt;&lt;td&gt;%3 ГБ&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</translation>
2349 </message>
2350</context>
2351<context>
2352 <name>SysinfoFrm</name>
2353 <message>
2354 <source>System Info</source>
2355 <translation>Информация о системе</translation>
2356 </message>
2357 <message>
2358 <source>&amp;Refresh</source>
2359 <translation>&amp;Обновить</translation>
2360 </message>
2361 <message>
2362 <source>&amp;OK</source>
2363 <translation>&amp;OK</translation>
2364 </message>
2365</context>
2366<context>
2367 <name>System</name>
2368 <message>
2369 <source>Guest</source>
2370 <translation>Гость</translation>
2371 </message>
2372 <message>
2373 <source>Admin</source>
2374 <translation>Администратор</translation>
2375 </message>
2376 <message>
2377 <source>User</source>
2378 <translation>Пользователь</translation>
2379 </message>
2380 <message>
2381 <source>Error</source>
2382 <translation>Ошибка</translation>
2383 </message>
2384 <message>
2385 <source>(no description available)</source>
2386 <translation>(описание недоступно)</translation>
2387 </message>
2388</context>
2389<context>
2390 <name>TTSBase</name>
2391 <message>
2392 <source>Espeak TTS Engine</source>
2393 <translation>Espeak TTS движок</translation>
2394 </message>
2395 <message>
2396 <source>Flite TTS Engine</source>
2397 <translation>Flite TTS движок</translation>
2398 </message>
2399 <message>
2400 <source>Swift TTS Engine</source>
2401 <translation>Swift TTS движок</translation>
2402 </message>
2403 <message>
2404 <source>SAPI TTS Engine</source>
2405 <translation type="obsolete">SAPI TTS движок</translation>
2406 </message>
2407 <message>
2408 <source>Festival TTS Engine</source>
2409 <translation>Festival TTS движок</translation>
2410 </message>
2411 <message>
2412 <source>OS X System Engine</source>
2413 <translation>Системный движок OS X</translation>
2414 </message>
2415 <message>
2416 <source>SAPI4 TTS Engine</source>
2417 <translation>Движок TTS SAPI4</translation>
2418 </message>
2419 <message>
2420 <source>SAPI5 TTS Engine</source>
2421 <translation>Движок TTS SAPI5</translation>
2422 </message>
2423 <message>
2424 <source>MS Speech Platform</source>
2425 <translation>Платформа MS Speech</translation>
2426 </message>
2427</context>
2428<context>
2429 <name>TTSCarbon</name>
2430 <message>
2431 <source>Voice:</source>
2432 <translation>Голос:</translation>
2433 </message>
2434 <message>
2435 <source>Speed (words/min):</source>
2436 <translation>Скорость (слов/мин):</translation>
2437 </message>
2438 <message>
2439 <source>Could not voice string</source>
2440 <translation>Не удалось произнести</translation>
2441 </message>
2442 <message>
2443 <source>Could not convert intermediate file</source>
2444 <translation>Не удалось преобразовать промежуточный файл</translation>
2445 </message>
2446 <message>
2447 <source>Pitch (0 for default):</source>
2448 <translation>Тон (0 по умолчанию) :</translation>
2449 </message>
2450</context>
2451<context>
2452 <name>TTSExes</name>
2453 <message>
2454 <source>TTS executable not found</source>
2455 <translation>Выполняемый файл TTS не найден</translation>
2456 </message>
2457 <message>
2458 <source>Path to TTS engine:</source>
2459 <translation>Путь к мотору TTS:</translation>
2460 </message>
2461 <message>
2462 <source>TTS engine options:</source>
2463 <translation>Настройки мотора TTS:</translation>
2464 </message>
2465</context>
2466<context>
2467 <name>TTSFestival</name>
2468 <message>
2469 <source>engine could not voice string</source>
2470 <translation>мотор не смог озвучить выражение</translation>
2471 </message>
2472 <message>
2473 <source>No description available</source>
2474 <translation>Описание отсутствует</translation>
2475 </message>
2476 <message>
2477 <source>Path to Festival client:</source>
2478 <translation>Путь к клиенту Festival:</translation>
2479 </message>
2480 <message>
2481 <source>Voice:</source>
2482 <translation>Голос:</translation>
2483 </message>
2484 <message>
2485 <source>Voice description:</source>
2486 <translation>Описание голоса:</translation>
2487 </message>
2488</context>
2489<context>
2490 <name>TTSSapi</name>
2491 <message>
2492 <source>Language:</source>
2493 <translation>Язык:</translation>
2494 </message>
2495 <message>
2496 <source>Voice:</source>
2497 <translation>Голос:</translation>
2498 </message>
2499 <message>
2500 <source>Speed:</source>
2501 <translation>Скорость:</translation>
2502 </message>
2503 <message>
2504 <source>Options:</source>
2505 <translation>Настройки:</translation>
2506 </message>
2507 <message>
2508 <source>Could not copy the SAPI script</source>
2509 <translation>Не удалось скопировать SAPI-сценарий</translation>
2510 </message>
2511 <message>
2512 <source>Could not start SAPI process</source>
2513 <translation>Не удалось запустить SAPI-задачу</translation>
2514 </message>
2515</context>
2516<context>
2517 <name>TalkFileCreator</name>
2518 <message>
2519 <source>Talk file creation aborted</source>
2520 <translation>Создание файла произношения отменено</translation>
2521 </message>
2522 <message>
2523 <source>Finished creating Talk files</source>
2524 <translation>Создание файлов произношения завершено</translation>
2525 </message>
2526 <message>
2527 <source>Reading Filelist...</source>
2528 <translation>Чтение списка файлов...</translation>
2529 </message>
2530 <message>
2531 <source>Copying of %1 to %2 failed</source>
2532 <translation>Сбой копирования %1 в %2</translation>
2533 </message>
2534 <message>
2535 <source>Copying Talkfiles...</source>
2536 <translation>Копирую файлы произношения...</translation>
2537 </message>
2538 <message>
2539 <source>File copy aborted</source>
2540 <translation>Копия файлов отменена</translation>
2541 </message>
2542 <message>
2543 <source>Cleaning up...</source>
2544 <translation>Навожу порядок...</translation>
2545 </message>
2546 <message>
2547 <source>Finished</source>
2548 <translation>Всё</translation>
2549 </message>
2550 <message>
2551 <source>Starting Talk file generation for folder %1</source>
2552 <translation>Начинается создание голосового файла для папки %1</translation>
2553 </message>
2554</context>
2555<context>
2556 <name>TalkGenerator</name>
2557 <message>
2558 <source>Starting TTS Engine</source>
2559 <translation>Запуск мотора TTS</translation>
2560 </message>
2561 <message>
2562 <source>Init of TTS engine failed</source>
2563 <translation>Сбой инициализации мотора TTS</translation>
2564 </message>
2565 <message>
2566 <source>Starting Encoder Engine</source>
2567 <translation>Запуск мотора кодировщика</translation>
2568 </message>
2569 <message>
2570 <source>Init of Encoder engine failed</source>
2571 <translation>Сбой инициализации мотора кодировщика</translation>
2572 </message>
2573 <message>
2574 <source>Voicing entries...</source>
2575 <translation>Озвучивание вводов...</translation>
2576 </message>
2577 <message>
2578 <source>Encoding files...</source>
2579 <translation>Кодировка файлов...</translation>
2580 </message>
2581 <message>
2582 <source>Voicing aborted</source>
2583 <translation>Озвучивание отменено</translation>
2584 </message>
2585 <message>
2586 <source>Voicing of %1 failed: %2</source>
2587 <translation>Сбой озвучивания %1 : %2</translation>
2588 </message>
2589 <message>
2590 <source>Encoding aborted</source>
2591 <translation>Кодировка отменена</translation>
2592 </message>
2593 <message>
2594 <source>Encoding of %1 failed</source>
2595 <translation>Сбой кодировки %1</translation>
2596 </message>
2597</context>
2598<context>
2599 <name>ThemeInstallFrm</name>
2600 <message>
2601 <source>Theme Installation</source>
2602 <translation>Установка тем</translation>
2603 </message>
2604 <message>
2605 <source>Selected Theme</source>
2606 <translation>Выбранная тема</translation>
2607 </message>
2608 <message>
2609 <source>Description</source>
2610 <translation>Описание</translation>
2611 </message>
2612 <message>
2613 <source>Download size:</source>
2614 <translation>Объём скачивания :</translation>
2615 </message>
2616 <message>
2617 <source>&amp;Cancel</source>
2618 <translation>&amp;Отмена</translation>
2619 </message>
2620 <message>
2621 <source>&amp;Install</source>
2622 <translation>&amp;Установить</translation>
2623 </message>
2624 <message>
2625 <source>Hold Ctrl to select multiple item, Shift for a range</source>
2626 <translation>Нажать и держать Ctrl для выделения нескольких элеметнов, Shift для выделения ряда элементов</translation>
2627 </message>
2628</context>
2629<context>
2630 <name>ThemesInstallWindow</name>
2631 <message>
2632 <source>no theme selected</source>
2633 <translation>Тема не выделена</translation>
2634 </message>
2635 <message>
2636 <source>Network error: %1.
2637Please check your network and proxy settings.</source>
2638 <translation>Ошибка сети: %1.
2639Проверьте настройки сети и прокси.</translation>
2640 </message>
2641 <message>
2642 <source>the following error occured:
2643%1</source>
2644 <translation>Произошла следующая ошибка :
2645%1</translation>
2646 </message>
2647 <message>
2648 <source>done.</source>
2649 <translation>выполнено.</translation>
2650 </message>
2651 <message>
2652 <source>fetching details for %1</source>
2653 <translation>получаю подробности о %1</translation>
2654 </message>
2655 <message>
2656 <source>fetching preview ...</source>
2657 <translation>Получаю предпросмотр ...</translation>
2658 </message>
2659 <message>
2660 <source>&lt;b&gt;Author:&lt;/b&gt; %1&lt;hr/&gt;</source>
2661 <translation>&lt;b&gt;Автор :&lt;/b&gt; %1&lt;hr/&gt;</translation>
2662 </message>
2663 <message>
2664 <source>unknown</source>
2665 <translation>неизвестный</translation>
2666 </message>
2667 <message>
2668 <source>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</source>
2669 <translation>&lt;b&gt;Версия :&lt;/b&gt; %1&lt;hr/&gt;</translation>
2670 </message>
2671 <message>
2672 <source>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</source>
2673 <translation>&lt;b&gt;Описание:&lt;/b&gt; %1&lt;hr/&gt;</translation>
2674 </message>
2675 <message>
2676 <source>no description</source>
2677 <translation>нет описания</translation>
2678 </message>
2679 <message>
2680 <source>no theme preview</source>
2681 <translation>предпросмотр недоступен</translation>
2682 </message>
2683 <message>
2684 <source>getting themes information ...</source>
2685 <translation>получаю информацию о темах ...</translation>
2686 </message>
2687 <message>
2688 <source>Mount point is wrong!</source>
2689 <translation>Неправильная точка монтирования!</translation>
2690 </message>
2691 <message>
2692 <source>no selection</source>
2693 <translation>нет выделения</translation>
2694 </message>
2695 <message>
2696 <source>Information</source>
2697 <translation>Информация</translation>
2698 </message>
2699 <message numerus="yes">
2700 <source>Download size %L1 kiB (%n item(s))</source>
2701 <translation>
2702 <numerusform>Размер загрузки %L1 КиБ (%n штука)</numerusform>
2703 <numerusform>Размер загрузки %L1 КиБ (%n штуки)</numerusform>
2704 <numerusform>Размер загрузки %L1 КиБ (%n штук)</numerusform>
2705 </translation>
2706 </message>
2707 <message>
2708 <source>Retrieving theme preview failed.
2709HTTP response code: %1</source>
2710 <translation>Сбой при получении предпросмотра темы.
2711Код ответа HTTP : %1</translation>
2712 </message>
2713 <message>
2714 <source>Select</source>
2715 <translation>Выбрать</translation>
2716 </message>
2717 <message>
2718 <source>No themes selected, skipping</source>
2719 <translation>Не выбрано ни одной темы, этап пропускается</translation>
2720 </message>
2721</context>
2722<context>
2723 <name>UninstallFrm</name>
2724 <message>
2725 <source>Uninstall Rockbox</source>
2726 <translation>Удалить Rockbox</translation>
2727 </message>
2728 <message>
2729 <source>Please select the Uninstallation Method</source>
2730 <translation>Выберите способ удаления</translation>
2731 </message>
2732 <message>
2733 <source>Uninstallation Method</source>
2734 <translation>Способ удаления</translation>
2735 </message>
2736 <message>
2737 <source>Complete Uninstallation</source>
2738 <translation>Полное удаление</translation>
2739 </message>
2740 <message>
2741 <source>Smart Uninstallation</source>
2742 <translation>Выборочное удаление</translation>
2743 </message>
2744 <message>
2745 <source>Please select what you want to uninstall</source>
2746 <translation>Выберите, что вы желаете удалить</translation>
2747 </message>
2748 <message>
2749 <source>Installed Parts</source>
2750 <translation>Установленные части</translation>
2751 </message>
2752 <message>
2753 <source>&amp;Cancel</source>
2754 <translation>&amp;Отмена</translation>
2755 </message>
2756 <message>
2757 <source>&amp;Uninstall</source>
2758 <translation>&amp;Удалить</translation>
2759 </message>
2760</context>
2761<context>
2762 <name>Uninstaller</name>
2763 <message>
2764 <source>Starting Uninstallation</source>
2765 <translation>Начало удаления</translation>
2766 </message>
2767 <message>
2768 <source>Finished Uninstallation</source>
2769 <translation>Удаление завершено</translation>
2770 </message>
2771 <message>
2772 <source>Uninstallation finished</source>
2773 <translation>Удаление завершено</translation>
2774 </message>
2775 <message>
2776 <source>Uninstalling %1...</source>
2777 <translation>Удаляется %1...</translation>
2778 </message>
2779 <message>
2780 <source>Could not delete %1</source>
2781 <translation>Не удалось удалить %1</translation>
2782 </message>
2783</context>
2784<context>
2785 <name>Utils</name>
2786 <message>
2787 <source>&lt;li&gt;Permissions insufficient for bootloader installation.
2788Administrator priviledges are necessary.&lt;/li&gt;</source>
2789 <translation>&lt;li&gt;Недостаточные полномочия для установки загрузчика.
2790Нужны полномочия администратора.&lt;/li&gt;</translation>
2791 </message>
2792 <message>
2793 <source>Problem detected:</source>
2794 <translation>Обнаружена проблема:</translation>
2795 </message>
2796 <message>
2797 <source>&lt;li&gt;Target mismatch detected.&lt;br/&gt;Installed target: %1&lt;br/&gt;Selected target: %2.&lt;/li&gt;</source>
2798 <translation>&lt;li&gt;Обнаруженно несовпадение устройств.&lt;br/&gt;Установленное устройство: %1&lt;br/&gt;Выбранное устройство : %2.&lt;/li&gt;</translation>
2799 </message>
2800</context>
2801<context>
2802 <name>VoiceFileCreator</name>
2803 <message>
2804 <source>Starting Voicefile generation</source>
2805 <translation>Начинаю вырабатывание голосового файла</translation>
2806 </message>
2807 <message>
2808 <source>Download error: received HTTP error %1.</source>
2809 <translation>Ошибка скачивания : получена ошибка HTTP %1.</translation>
2810 </message>
2811 <message>
2812 <source>Cached file used.</source>
2813 <translation>Использован файл из кэша.</translation>
2814 </message>
2815 <message>
2816 <source>Download error: %1</source>
2817 <translation>Ошибка скачивания : %1</translation>
2818 </message>
2819 <message>
2820 <source>Download finished.</source>
2821 <translation>Скачивание завершено.</translation>
2822 </message>
2823 <message>
2824 <source>failed to open downloaded file</source>
2825 <translation>Сбой при открытии скаченного файла</translation>
2826 </message>
2827 <message>
2828 <source>The downloaded file was empty!</source>
2829 <translation>Скачаный файл пуст!</translation>
2830 </message>
2831 <message>
2832 <source>Error opening downloaded file</source>
2833 <translation>Сбой при открытии скаченного файла</translation>
2834 </message>
2835 <message>
2836 <source>Error opening output file</source>
2837 <translation>Сбой при открытии выводного файла</translation>
2838 </message>
2839 <message>
2840 <source>successfully created.</source>
2841 <translation>успешно создано.</translation>
2842 </message>
2843 <message>
2844 <source>could not find rockbox-info.txt</source>
2845 <translation>Не удалось найти rockbox-info.txt</translation>
2846 </message>
2847 <message>
2848 <source>Downloading voice info...</source>
2849 <translation>Получаю информацию о голосе...</translation>
2850 </message>
2851 <message>
2852 <source>Reading strings...</source>
2853 <translation>Читаются значения...</translation>
2854 </message>
2855 <message>
2856 <source>Creating voicefiles...</source>
2857 <translation>Создаются голосовые файлы...</translation>
2858 </message>
2859 <message>
2860 <source>Cleaning up...</source>
2861 <translation>Навожу порядок...</translation>
2862 </message>
2863 <message>
2864 <source>Finished</source>
2865 <translation>Всё</translation>
2866 </message>
2867 <message>
2868 <source>Extracted voice strings from installation</source>
2869 <translation>Извлечены голосовые произношения</translation>
2870 </message>
2871 <message>
2872 <source>Extracted voice strings incompatible</source>
2873 <translation>Извлечённые произношения несовместимы</translation>
2874 </message>
2875 <message>
2876 <source>Could not retrieve strings from installation, downloading</source>
2877 <translation>Не удалось найти произношения в установке, скачиваются</translation>
2878 </message>
2879</context>
2880<context>
2881 <name>ZipInstaller</name>
2882 <message>
2883 <source>done.</source>
2884 <translation>выполнено.</translation>
2885 </message>
2886 <message>
2887 <source>Downloading file %1.%2</source>
2888 <translation>Скачивается файл %1.%2</translation>
2889 </message>
2890 <message>
2891 <source>Download error: received HTTP error %1.</source>
2892 <translation>Сбой скачивания. Ошибка HTTP %1.</translation>
2893 </message>
2894 <message>
2895 <source>Cached file used.</source>
2896 <translation>Используется файл из кэша.</translation>
2897 </message>
2898 <message>
2899 <source>Download error: %1</source>
2900 <translation>Сбой скачивания: %1</translation>
2901 </message>
2902 <message>
2903 <source>Download finished.</source>
2904 <translation>Скачивание завершено.</translation>
2905 </message>
2906 <message>
2907 <source>Extracting file.</source>
2908 <translation>Извлечение файла.</translation>
2909 </message>
2910 <message>
2911 <source>Installing file.</source>
2912 <translation>Установка файла.</translation>
2913 </message>
2914 <message>
2915 <source>Installing file failed.</source>
2916 <translation>Сбой установки файла.</translation>
2917 </message>
2918 <message>
2919 <source>Creating installation log</source>
2920 <translation>Создаю журнал установки</translation>
2921 </message>
2922 <message>
2923 <source>Not enough disk space! Aborting.</source>
2924 <translation>Не достаточно дискового пространства! Отмена.</translation>
2925 </message>
2926 <message>
2927 <source>Extraction failed!</source>
2928 <translation>Ошибка распаковки!</translation>
2929 </message>
2930 <message>
2931 <source>Package installation finished successfully.</source>
2932 <translation>Установка файла успешно завершена.</translation>
2933 </message>
2934</context>
2935<context>
2936 <name>ZipUtil</name>
2937 <message>
2938 <source>Creating output path failed</source>
2939 <translation>Ошибка создания выходной папки</translation>
2940 </message>
2941 <message>
2942 <source>Creating output file failed</source>
2943 <translation>Ошибка создания выходного файла</translation>
2944 </message>
2945 <message>
2946 <source>Error during Zip operation</source>
2947 <translation>Ошибка при выполнении операции с ZIP-пакетом</translation>
2948 </message>
2949</context>
2950<context>
2951 <name>aboutBox</name>
2952 <message>
2953 <source>About Rockbox Utility</source>
2954 <translation>О мастере Rockbox</translation>
2955 </message>
2956 <message>
2957 <source>The Rockbox Utility</source>
2958 <translation>Мастер Rockbox</translation>
2959 </message>
2960 <message>
2961 <source>&amp;Credits</source>
2962 <translation>&amp;Благодарности</translation>
2963 </message>
2964 <message>
2965 <source>&amp;License</source>
2966 <translation>&amp;Лицензия</translation>
2967 </message>
2968 <message>
2969 <source>&amp;Ok</source>
2970 <translation>&amp;OK</translation>
2971 </message>
2972 <message utf8="true">
2973 <source>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</source>
2974 <translation>Мастер установки и управления Rockbox, микропрограммы с открытым исходным кодом для цифровых аудиоплееров.&lt;br/&gt;© Команда Rockbox.&lt;br/&gt;Раздаётся по лицензии GNU General Public License v2.&lt;br/&gt;Используются иконки из &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;проекта Tango&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</translation>
2975 </message>
2976 <message>
2977 <source>&amp;Speex License</source>
2978 <translation>&amp;Лицензия Speex</translation>
2979 </message>
2980</context>
2981</TS>
diff --git a/utils/rbutilqt/lang/rbutil_tr.ts b/utils/rbutilqt/lang/rbutil_tr.ts
new file mode 100644
index 0000000000..bb93e62ff2
--- /dev/null
+++ b/utils/rbutilqt/lang/rbutil_tr.ts
@@ -0,0 +1,4731 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE TS>
3<TS version="2.0" language="tr">
4<context>
5 <name>BackupDialog</name>
6 <message>
7 <location filename="../gui/backupdialogfrm.ui" line="+17"/>
8 <location line="+26"/>
9 <source>Backup</source>
10 <translation type="unfinished"></translation>
11 </message>
12 <message>
13 <location line="-10"/>
14 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This dialog will create a backup by archiving the contents of the Rockbox installation on the player into a zip file. This will include installed themes and settings stored below the .rockbox folder on the player.&lt;/p&gt;&lt;p&gt;The backup filename will be created based on the installed version. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
15 <translation type="unfinished"></translation>
16 </message>
17 <message>
18 <location line="+16"/>
19 <source>Size: unknown</source>
20 <translation type="unfinished"></translation>
21 </message>
22 <message>
23 <location line="+7"/>
24 <source>Backup to: unknown</source>
25 <translation type="unfinished"></translation>
26 </message>
27 <message>
28 <location line="+20"/>
29 <source>&amp;Change</source>
30 <translation type="unfinished">&amp;Değiştir</translation>
31 </message>
32 <message>
33 <location line="+40"/>
34 <source>&amp;Backup</source>
35 <translation type="unfinished"></translation>
36 </message>
37 <message>
38 <location line="+11"/>
39 <source>&amp;Cancel</source>
40 <translation type="unfinished">&amp;İptal</translation>
41 </message>
42 <message>
43 <location filename="../gui/backupdialog.cpp" line="+70"/>
44 <source>Installation size: calculating ...</source>
45 <translation type="unfinished"></translation>
46 </message>
47 <message>
48 <location line="+19"/>
49 <source>Select Backup Filename</source>
50 <translation type="unfinished"></translation>
51 </message>
52 <message>
53 <location line="+20"/>
54 <source>Installation size: %L1 %2</source>
55 <translation type="unfinished"></translation>
56 </message>
57 <message>
58 <location line="+7"/>
59 <source>File exists</source>
60 <translation type="unfinished"></translation>
61 </message>
62 <message>
63 <location line="+1"/>
64 <source>The selected backup file already exists. Overwrite?</source>
65 <translation type="unfinished"></translation>
66 </message>
67 <message>
68 <location line="+8"/>
69 <source>Starting backup ...</source>
70 <translation type="unfinished"></translation>
71 </message>
72 <message>
73 <location line="+19"/>
74 <source>Backup successful.</source>
75 <translation type="unfinished"></translation>
76 </message>
77 <message>
78 <location line="+3"/>
79 <source>Backup failed!</source>
80 <translation type="unfinished"></translation>
81 </message>
82</context>
83<context>
84 <name>BootloaderInstallAms</name>
85 <message>
86 <location filename="../base/bootloaderinstallams.cpp" line="+33"/>
87 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; This file is not present on your player and will disappear automatically after installing it.&lt;br/&gt;&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
88 <translation type="unfinished"></translation>
89 </message>
90 <message>
91 <location line="+25"/>
92 <source>Downloading bootloader file</source>
93 <translation type="unfinished"></translation>
94 </message>
95 <message>
96 <location line="+42"/>
97 <location line="+13"/>
98 <source>Could not load %1</source>
99 <translation type="unfinished"></translation>
100 </message>
101 <message>
102 <location line="+14"/>
103 <source>No room to insert bootloader, try another firmware version</source>
104 <translation type="unfinished"></translation>
105 </message>
106 <message>
107 <location line="+10"/>
108 <source>Patching Firmware...</source>
109 <translation type="unfinished"></translation>
110 </message>
111 <message>
112 <location line="+11"/>
113 <source>Could not open %1 for writing</source>
114 <translation type="unfinished"></translation>
115 </message>
116 <message>
117 <location line="+13"/>
118 <source>Could not write firmware file</source>
119 <translation type="unfinished"></translation>
120 </message>
121 <message>
122 <location line="+16"/>
123 <source>Success: modified firmware file created</source>
124 <translation type="unfinished"></translation>
125 </message>
126 <message>
127 <location line="+8"/>
128 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
129 <translation type="unfinished"></translation>
130 </message>
131</context>
132<context>
133 <name>BootloaderInstallBase</name>
134 <message>
135 <location filename="../base/bootloaderinstallbase.cpp" line="+78"/>
136 <source>Download error: received HTTP error %1.</source>
137 <translation type="unfinished">İndirme hatası: HTTP %1 hatası.</translation>
138 </message>
139 <message>
140 <location line="+6"/>
141 <source>Download error: %1</source>
142 <translation type="unfinished">İndirme hatası: %1</translation>
143 </message>
144 <message>
145 <location line="+6"/>
146 <source>Download finished (cache used).</source>
147 <translation type="unfinished"></translation>
148 </message>
149 <message>
150 <location line="+2"/>
151 <source>Download finished.</source>
152 <translation type="unfinished">İndirme işlemi tamamlandı.</translation>
153 </message>
154 <message>
155 <location line="+21"/>
156 <source>Creating backup of original firmware file.</source>
157 <translation type="unfinished"></translation>
158 </message>
159 <message>
160 <location line="+2"/>
161 <source>Creating backup folder failed</source>
162 <translation type="unfinished"></translation>
163 </message>
164 <message>
165 <location line="+6"/>
166 <source>Creating backup copy failed.</source>
167 <translation type="unfinished"></translation>
168 </message>
169 <message>
170 <location line="+3"/>
171 <source>Backup created.</source>
172 <translation type="unfinished"></translation>
173 </message>
174 <message>
175 <location line="+13"/>
176 <source>Creating installation log</source>
177 <translation type="unfinished">Kurulum kayıt dosyası yaratılıyor</translation>
178 </message>
179 <message>
180 <location line="+12"/>
181 <source>Installation log created</source>
182 <translation type="unfinished"></translation>
183 </message>
184 <message>
185 <location line="+10"/>
186 <source>Waiting for system to remount player</source>
187 <translation type="unfinished"></translation>
188 </message>
189 <message>
190 <location line="+30"/>
191 <source>Player remounted</source>
192 <translation type="unfinished"></translation>
193 </message>
194 <message>
195 <location line="+5"/>
196 <source>Timeout on remount</source>
197 <translation type="unfinished"></translation>
198 </message>
199 <message>
200 <location line="+32"/>
201 <source>Zip file format detected</source>
202 <translation type="unfinished"></translation>
203 </message>
204 <message>
205 <location line="+12"/>
206 <source>CAB file format detected</source>
207 <translation type="unfinished"></translation>
208 </message>
209 <message>
210 <location line="+21"/>
211 <source>Extracting firmware %1 from archive</source>
212 <translation type="unfinished"></translation>
213 </message>
214 <message>
215 <location line="+7"/>
216 <source>Error extracting firmware from archive</source>
217 <translation type="unfinished"></translation>
218 </message>
219 <message>
220 <location line="+9"/>
221 <source>Could not find firmware in archive</source>
222 <translation type="unfinished"></translation>
223 </message>
224</context>
225<context>
226 <name>BootloaderInstallChinaChip</name>
227 <message>
228 <location filename="../base/bootloaderinstallchinachip.cpp" line="+33"/>
229 <source>Bootloader installation requires you to provide a firmware file of the original firmware (HXF file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
230 <translation type="unfinished"></translation>
231 </message>
232 <message>
233 <location line="+17"/>
234 <source>Downloading bootloader file</source>
235 <translation type="unfinished"></translation>
236 </message>
237 <message>
238 <location line="+25"/>
239 <source>Could not open firmware file</source>
240 <translation type="unfinished"></translation>
241 </message>
242 <message>
243 <location line="+3"/>
244 <source>Could not open bootloader file</source>
245 <translation type="unfinished"></translation>
246 </message>
247 <message>
248 <location line="+3"/>
249 <source>Could not allocate memory</source>
250 <translation type="unfinished"></translation>
251 </message>
252 <message>
253 <location line="+3"/>
254 <source>Could not load firmware file</source>
255 <translation type="unfinished"></translation>
256 </message>
257 <message>
258 <location line="+3"/>
259 <source>File is not a valid ChinaChip firmware</source>
260 <translation type="unfinished"></translation>
261 </message>
262 <message>
263 <location line="+3"/>
264 <source>Could not find ccpmp.bin in input file</source>
265 <translation type="unfinished"></translation>
266 </message>
267 <message>
268 <location line="+3"/>
269 <source>Could not open backup file for ccpmp.bin</source>
270 <translation type="unfinished"></translation>
271 </message>
272 <message>
273 <location line="+3"/>
274 <source>Could not write backup file for ccpmp.bin</source>
275 <translation type="unfinished"></translation>
276 </message>
277 <message>
278 <location line="+3"/>
279 <source>Could not load bootloader file</source>
280 <translation type="unfinished"></translation>
281 </message>
282 <message>
283 <location line="+3"/>
284 <source>Could not get current time</source>
285 <translation type="unfinished"></translation>
286 </message>
287 <message>
288 <location line="+3"/>
289 <source>Could not open output file</source>
290 <translation type="unfinished"></translation>
291 </message>
292 <message>
293 <location line="+3"/>
294 <source>Could not write output file</source>
295 <translation type="unfinished"></translation>
296 </message>
297 <message>
298 <location line="+3"/>
299 <source>Unexpected error from chinachippatcher</source>
300 <translation type="unfinished"></translation>
301 </message>
302</context>
303<context>
304 <name>BootloaderInstallFile</name>
305 <message>
306 <location filename="../base/bootloaderinstallfile.cpp" line="+34"/>
307 <source>Downloading bootloader</source>
308 <translation type="unfinished"></translation>
309 </message>
310 <message>
311 <location line="+9"/>
312 <source>Installing Rockbox bootloader</source>
313 <translation type="unfinished"></translation>
314 </message>
315 <message>
316 <location line="+32"/>
317 <source>Error accessing output folder</source>
318 <translation type="unfinished"></translation>
319 </message>
320 <message>
321 <location line="+14"/>
322 <source>A firmware file is already present on player</source>
323 <translation type="unfinished"></translation>
324 </message>
325 <message>
326 <location line="+5"/>
327 <source>Bootloader successful installed</source>
328 <translation type="unfinished"></translation>
329 </message>
330 <message>
331 <location line="+3"/>
332 <source>Copying modified firmware file failed</source>
333 <translation type="unfinished"></translation>
334 </message>
335 <message>
336 <location line="+14"/>
337 <source>Removing Rockbox bootloader</source>
338 <translation type="unfinished"></translation>
339 </message>
340 <message>
341 <location line="+4"/>
342 <source>No original firmware file found.</source>
343 <translation type="unfinished"></translation>
344 </message>
345 <message>
346 <location line="+6"/>
347 <source>Can&apos;t remove Rockbox bootloader file.</source>
348 <translation type="unfinished"></translation>
349 </message>
350 <message>
351 <location line="+5"/>
352 <source>Can&apos;t restore bootloader file.</source>
353 <translation type="unfinished"></translation>
354 </message>
355 <message>
356 <location line="+4"/>
357 <source>Original bootloader restored successfully.</source>
358 <translation type="unfinished"></translation>
359 </message>
360</context>
361<context>
362 <name>BootloaderInstallHex</name>
363 <message>
364 <location filename="../base/bootloaderinstallhex.cpp" line="+50"/>
365 <source>Bootloader installation requires you to provide a firmware file of the original firmware (hex file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
366 <translation type="unfinished"></translation>
367 </message>
368 <message>
369 <location line="+19"/>
370 <source>checking MD5 hash of input file ...</source>
371 <translation type="unfinished"></translation>
372 </message>
373 <message>
374 <location line="+11"/>
375 <source>Could not verify original firmware file</source>
376 <translation type="unfinished"></translation>
377 </message>
378 <message>
379 <location line="+15"/>
380 <source>Firmware file not recognized.</source>
381 <translation type="unfinished"></translation>
382 </message>
383 <message>
384 <location line="+4"/>
385 <source>MD5 hash ok</source>
386 <translation type="unfinished"></translation>
387 </message>
388 <message>
389 <location line="+7"/>
390 <source>Firmware file doesn&apos;t match selected player.</source>
391 <translation type="unfinished"></translation>
392 </message>
393 <message>
394 <location line="+5"/>
395 <source>Descrambling file</source>
396 <translation type="unfinished"></translation>
397 </message>
398 <message>
399 <location line="+8"/>
400 <source>Error in descramble: %1</source>
401 <translation type="unfinished"></translation>
402 </message>
403 <message>
404 <location line="+5"/>
405 <source>Downloading bootloader file</source>
406 <translation type="unfinished"></translation>
407 </message>
408 <message>
409 <location line="+10"/>
410 <source>Adding bootloader to firmware file</source>
411 <translation type="unfinished"></translation>
412 </message>
413 <message>
414 <location line="+38"/>
415 <source>could not open input file</source>
416 <translation type="unfinished"></translation>
417 </message>
418 <message>
419 <location line="+1"/>
420 <source>reading header failed</source>
421 <translation type="unfinished"></translation>
422 </message>
423 <message>
424 <location line="+1"/>
425 <source>reading firmware failed</source>
426 <translation type="unfinished"></translation>
427 </message>
428 <message>
429 <location line="+1"/>
430 <source>can&apos;t open bootloader file</source>
431 <translation type="unfinished"></translation>
432 </message>
433 <message>
434 <location line="+1"/>
435 <source>reading bootloader file failed</source>
436 <translation type="unfinished"></translation>
437 </message>
438 <message>
439 <location line="+1"/>
440 <source>can&apos;t open output file</source>
441 <translation type="unfinished"></translation>
442 </message>
443 <message>
444 <location line="+1"/>
445 <source>writing output file failed</source>
446 <translation type="unfinished"></translation>
447 </message>
448 <message>
449 <location line="+2"/>
450 <source>Error in patching: %1</source>
451 <translation type="unfinished"></translation>
452 </message>
453 <message>
454 <location line="+11"/>
455 <source>Error in scramble: %1</source>
456 <translation type="unfinished"></translation>
457 </message>
458 <message>
459 <location line="+15"/>
460 <source>Checking modified firmware file</source>
461 <translation type="unfinished"></translation>
462 </message>
463 <message>
464 <location line="+2"/>
465 <source>Error: modified file checksum wrong</source>
466 <translation type="unfinished"></translation>
467 </message>
468 <message>
469 <location line="+7"/>
470 <source>A firmware file is already present on player</source>
471 <translation type="unfinished"></translation>
472 </message>
473 <message>
474 <location line="+5"/>
475 <source>Success: modified firmware file created</source>
476 <translation type="unfinished"></translation>
477 </message>
478 <message>
479 <location line="+3"/>
480 <source>Copying modified firmware file failed</source>
481 <translation type="unfinished"></translation>
482 </message>
483 <message>
484 <location line="+14"/>
485 <source>Uninstallation not possible, only installation info removed</source>
486 <translation type="unfinished"></translation>
487 </message>
488 <message>
489 <location line="+21"/>
490 <source>Can&apos;t open input file</source>
491 <translation type="unfinished"></translation>
492 </message>
493 <message>
494 <location line="+1"/>
495 <source>Can&apos;t open output file</source>
496 <translation type="unfinished"></translation>
497 </message>
498 <message>
499 <location line="+1"/>
500 <source>invalid file: header length wrong</source>
501 <translation type="unfinished"></translation>
502 </message>
503 <message>
504 <location line="+1"/>
505 <source>invalid file: unrecognized header</source>
506 <translation type="unfinished"></translation>
507 </message>
508 <message>
509 <location line="+1"/>
510 <source>invalid file: &quot;length&quot; field wrong</source>
511 <translation type="unfinished"></translation>
512 </message>
513 <message>
514 <location line="+1"/>
515 <source>invalid file: &quot;length2&quot; field wrong</source>
516 <translation type="unfinished"></translation>
517 </message>
518 <message>
519 <location line="+1"/>
520 <source>invalid file: internal checksum error</source>
521 <translation type="unfinished"></translation>
522 </message>
523 <message>
524 <location line="+1"/>
525 <source>invalid file: &quot;length3&quot; field wrong</source>
526 <translation type="unfinished"></translation>
527 </message>
528 <message>
529 <location line="+1"/>
530 <source>unknown</source>
531 <translation type="unfinished">bilinmiyor</translation>
532 </message>
533</context>
534<context>
535 <name>BootloaderInstallImx</name>
536 <message>
537 <location filename="../base/bootloaderinstallimx.cpp" line="+72"/>
538 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (firmware.sb file). This file will be patched with the Rockbox bootloader and installed to your player. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
539 <translation type="unfinished"></translation>
540 </message>
541 <message>
542 <location line="+22"/>
543 <source>Could not read original firmware file</source>
544 <translation type="unfinished"></translation>
545 </message>
546 <message>
547 <location line="+6"/>
548 <source>Downloading bootloader file</source>
549 <translation type="unfinished"></translation>
550 </message>
551 <message>
552 <location line="+10"/>
553 <source>Patching file...</source>
554 <translation type="unfinished"></translation>
555 </message>
556 <message>
557 <location line="+27"/>
558 <source>Patching the original firmware failed</source>
559 <translation type="unfinished"></translation>
560 </message>
561 <message>
562 <location line="+6"/>
563 <source>Succesfully patched firmware file</source>
564 <translation type="unfinished"></translation>
565 </message>
566 <message>
567 <location line="+15"/>
568 <source>Bootloader successful installed</source>
569 <translation type="unfinished"></translation>
570 </message>
571 <message>
572 <location line="+6"/>
573 <source>Patched bootloader could not be installed</source>
574 <translation type="unfinished"></translation>
575 </message>
576 <message>
577 <location line="+11"/>
578 <source>To uninstall, perform a normal upgrade with an unmodified original firmware.</source>
579 <translation type="unfinished"></translation>
580 </message>
581</context>
582<context>
583 <name>BootloaderInstallIpod</name>
584 <message>
585 <location filename="../base/bootloaderinstallipod.cpp" line="+49"/>
586 <source>Error: can&apos;t allocate buffer memory!</source>
587 <translation type="unfinished"></translation>
588 </message>
589 <message>
590 <location line="+15"/>
591 <location line="+87"/>
592 <source>Failed to read firmware directory</source>
593 <translation type="unfinished">Bellenim (firmware) dizini okunamadı</translation>
594 </message>
595 <message>
596 <location line="-82"/>
597 <location line="+87"/>
598 <source>Unknown version number in firmware (%1)</source>
599 <translation type="unfinished">Bilinmeyen bellenim (firmware) sürüm numarası (%1)</translation>
600 </message>
601 <message>
602 <location line="-81"/>
603 <source>Warning: This is a MacPod, Rockbox only runs on WinPods.
604See http://www.rockbox.org/wiki/IpodConversionToFAT32</source>
605 <translation type="unfinished"></translation>
606 </message>
607 <message>
608 <location line="+5"/>
609 <source>Downloading bootloader file</source>
610 <translation type="unfinished"></translation>
611 </message>
612 <message>
613 <location line="+10"/>
614 <source>Installing Rockbox bootloader</source>
615 <translation type="unfinished"></translation>
616 </message>
617 <message>
618 <location line="+4"/>
619 <location line="+69"/>
620 <source>Could not open Ipod in R/W mode</source>
621 <translation type="unfinished"></translation>
622 </message>
623 <message>
624 <location line="-59"/>
625 <source>Successfull added bootloader</source>
626 <translation type="unfinished"></translation>
627 </message>
628 <message>
629 <location line="+11"/>
630 <source>Failed to add bootloader</source>
631 <translation type="unfinished"></translation>
632 </message>
633 <message>
634 <location line="+12"/>
635 <source>Bootloader Installation complete.</source>
636 <translation type="unfinished"></translation>
637 </message>
638 <message>
639 <location line="+5"/>
640 <source>Writing log aborted</source>
641 <translation type="unfinished"></translation>
642 </message>
643 <message>
644 <location line="+10"/>
645 <source>Uninstalling bootloader</source>
646 <translation type="unfinished"></translation>
647 </message>
648 <message>
649 <location line="+27"/>
650 <source>No bootloader detected.</source>
651 <translation type="unfinished">Herhangi bir önyükleyici algılanamadı.</translation>
652 </message>
653 <message>
654 <location line="+6"/>
655 <source>Successfully removed bootloader</source>
656 <translation type="unfinished"></translation>
657 </message>
658 <message>
659 <location line="+7"/>
660 <source>Removing bootloader failed.</source>
661 <translation type="unfinished"></translation>
662 </message>
663 <message>
664 <location line="+46"/>
665 <source>Error: could not retrieve device name</source>
666 <translation type="unfinished"></translation>
667 </message>
668 <message>
669 <location line="+16"/>
670 <source>Error: no mountpoint specified!</source>
671 <translation type="unfinished"></translation>
672 </message>
673 <message>
674 <location line="+5"/>
675 <source>Could not open Ipod: permission denied</source>
676 <translation type="unfinished"></translation>
677 </message>
678 <message>
679 <location line="+4"/>
680 <source>Could not open Ipod</source>
681 <translation type="unfinished"></translation>
682 </message>
683 <message>
684 <location line="+5"/>
685 <source>Error reading partition table - possibly not an Ipod</source>
686 <translation type="unfinished"></translation>
687 </message>
688 <message>
689 <location line="+6"/>
690 <source>No firmware partition on disk</source>
691 <translation type="unfinished"></translation>
692 </message>
693</context>
694<context>
695 <name>BootloaderInstallMi4</name>
696 <message>
697 <location filename="../base/bootloaderinstallmi4.cpp" line="+34"/>
698 <source>Downloading bootloader</source>
699 <translation type="unfinished"></translation>
700 </message>
701 <message>
702 <location line="+9"/>
703 <source>Installing Rockbox bootloader</source>
704 <translation type="unfinished"></translation>
705 </message>
706 <message>
707 <location line="+23"/>
708 <source>A firmware file is already present on player</source>
709 <translation type="unfinished"></translation>
710 </message>
711 <message>
712 <location line="+5"/>
713 <location line="+8"/>
714 <source>Bootloader successful installed</source>
715 <translation type="unfinished"></translation>
716 </message>
717 <message>
718 <location line="-5"/>
719 <source>Copying modified firmware file failed</source>
720 <translation type="unfinished"></translation>
721 </message>
722 <message>
723 <location line="+17"/>
724 <source>Checking for Rockbox bootloader</source>
725 <translation type="unfinished"></translation>
726 </message>
727 <message>
728 <location line="+2"/>
729 <source>No Rockbox bootloader found</source>
730 <translation type="unfinished"></translation>
731 </message>
732 <message>
733 <location line="+5"/>
734 <source>Checking for original firmware file</source>
735 <translation type="unfinished"></translation>
736 </message>
737 <message>
738 <location line="+5"/>
739 <source>Error finding original firmware file</source>
740 <translation type="unfinished"></translation>
741 </message>
742 <message>
743 <location line="+10"/>
744 <source>Rockbox bootloader successful removed</source>
745 <translation type="unfinished"></translation>
746 </message>
747</context>
748<context>
749 <name>BootloaderInstallMpio</name>
750 <message>
751 <location filename="../base/bootloaderinstallmpio.cpp" line="+34"/>
752 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
753 <translation type="unfinished"></translation>
754 </message>
755 <message>
756 <location line="+19"/>
757 <source>Downloading bootloader file</source>
758 <translation type="unfinished"></translation>
759 </message>
760 <message>
761 <location line="+27"/>
762 <source>Could not open the original firmware.</source>
763 <translation type="unfinished"></translation>
764 </message>
765 <message>
766 <location line="+3"/>
767 <source>Could not read the original firmware.</source>
768 <translation type="unfinished"></translation>
769 </message>
770 <message>
771 <location line="+3"/>
772 <source>Loaded firmware file does not look like MPIO original firmware file.</source>
773 <translation type="unfinished"></translation>
774 </message>
775 <message>
776 <location line="+3"/>
777 <source>Could not open downloaded bootloader.</source>
778 <translation type="unfinished"></translation>
779 </message>
780 <message>
781 <location line="+3"/>
782 <source>Place for bootloader in OF file not empty.</source>
783 <translation type="unfinished"></translation>
784 </message>
785 <message>
786 <location line="+3"/>
787 <source>Could not read the downloaded bootloader.</source>
788 <translation type="unfinished"></translation>
789 </message>
790 <message>
791 <location line="+3"/>
792 <source>Bootloader checksum error.</source>
793 <translation type="unfinished"></translation>
794 </message>
795 <message>
796 <location line="+3"/>
797 <source>Could not open output file.</source>
798 <translation type="unfinished"></translation>
799 </message>
800 <message>
801 <location line="+3"/>
802 <source>Could not write output file.</source>
803 <translation type="unfinished"></translation>
804 </message>
805 <message>
806 <location line="+3"/>
807 <source>Unknown error number: %1</source>
808 <translation type="unfinished"></translation>
809 </message>
810 <message>
811 <location line="+5"/>
812 <source>Patching original firmware failed: %1</source>
813 <translation type="unfinished"></translation>
814 </message>
815 <message>
816 <location line="+7"/>
817 <source>Success: modified firmware file created</source>
818 <translation type="unfinished"></translation>
819 </message>
820 <message>
821 <location line="+8"/>
822 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
823 <translation type="unfinished"></translation>
824 </message>
825</context>
826<context>
827 <name>BootloaderInstallSansa</name>
828 <message>
829 <location filename="../base/bootloaderinstallsansa.cpp" line="+50"/>
830 <source>Error: can&apos;t allocate buffer memory!</source>
831 <translation type="unfinished"></translation>
832 </message>
833 <message>
834 <location line="+5"/>
835 <source>Searching for Sansa</source>
836 <translation type="unfinished"></translation>
837 </message>
838 <message>
839 <location line="+4"/>
840 <source>Permission for disc access denied!
841This is required to install the bootloader</source>
842 <translation type="unfinished"></translation>
843 </message>
844 <message>
845 <location line="+7"/>
846 <source>No Sansa detected!</source>
847 <translation type="unfinished"></translation>
848 </message>
849 <message>
850 <location line="+5"/>
851 <location line="+108"/>
852 <source>OLD ROCKBOX INSTALLATION DETECTED, ABORTING.
853You must reinstall the original Sansa firmware before running
854sansapatcher for the first time.
855See http://www.rockbox.org/wiki/SansaE200Install
856</source>
857 <translation type="unfinished"></translation>
858 </message>
859 <message>
860 <location line="-100"/>
861 <source>Downloading bootloader file</source>
862 <translation type="unfinished"></translation>
863 </message>
864 <message>
865 <location line="+15"/>
866 <source>Installing Rockbox bootloader</source>
867 <translation type="unfinished"></translation>
868 </message>
869 <message>
870 <location line="+8"/>
871 <location line="+87"/>
872 <source>Could not open Sansa in R/W mode</source>
873 <translation type="unfinished"></translation>
874 </message>
875 <message>
876 <location line="-78"/>
877 <source>Checking downloaded bootloader</source>
878 <translation type="unfinished"></translation>
879 </message>
880 <message>
881 <location line="+8"/>
882 <source>Bootloader mismatch! Aborting.</source>
883 <translation type="unfinished"></translation>
884 </message>
885 <message>
886 <location line="+10"/>
887 <source>Successfully installed bootloader</source>
888 <translation type="unfinished"></translation>
889 </message>
890 <message>
891 <location line="+11"/>
892 <source>Failed to install bootloader</source>
893 <translation type="unfinished"></translation>
894 </message>
895 <message>
896 <location line="+13"/>
897 <source>Bootloader Installation complete.</source>
898 <translation type="unfinished"></translation>
899 </message>
900 <message>
901 <location line="+5"/>
902 <source>Writing log aborted</source>
903 <translation type="unfinished"></translation>
904 </message>
905 <message>
906 <location line="+12"/>
907 <source>Uninstalling bootloader</source>
908 <translation type="unfinished"></translation>
909 </message>
910 <message>
911 <location line="+25"/>
912 <source>Successfully removed bootloader</source>
913 <translation type="unfinished"></translation>
914 </message>
915 <message>
916 <location line="+7"/>
917 <source>Removing bootloader failed.</source>
918 <translation type="unfinished"></translation>
919 </message>
920 <message>
921 <location line="+36"/>
922 <source>Error: could not retrieve device name</source>
923 <translation type="unfinished"></translation>
924 </message>
925 <message>
926 <location line="+16"/>
927 <source>Can&apos;t find Sansa</source>
928 <translation type="unfinished"></translation>
929 </message>
930 <message>
931 <location line="+5"/>
932 <source>Could not open Sansa</source>
933 <translation type="unfinished"></translation>
934 </message>
935 <message>
936 <location line="+5"/>
937 <source>Could not read partition table</source>
938 <translation type="unfinished"></translation>
939 </message>
940 <message>
941 <location line="+7"/>
942 <source>Disk is not a Sansa (Error %1), aborting.</source>
943 <translation type="unfinished"></translation>
944 </message>
945</context>
946<context>
947 <name>BootloaderInstallTcc</name>
948 <message>
949 <location filename="../base/bootloaderinstalltcc.cpp" line="+33"/>
950 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wiki page on how to obtain the file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
951 <translation type="unfinished"></translation>
952 </message>
953 <message>
954 <location line="+17"/>
955 <source>Downloading bootloader file</source>
956 <translation type="unfinished"></translation>
957 </message>
958 <message>
959 <location line="+32"/>
960 <location line="+17"/>
961 <source>Could not load %1</source>
962 <translation type="unfinished"></translation>
963 </message>
964 <message>
965 <location line="-9"/>
966 <source>Unknown OF file used: %1</source>
967 <translation type="unfinished"></translation>
968 </message>
969 <message>
970 <location line="+14"/>
971 <source>Patching Firmware...</source>
972 <translation type="unfinished"></translation>
973 </message>
974 <message>
975 <location line="+7"/>
976 <source>Could not patch firmware</source>
977 <translation type="unfinished"></translation>
978 </message>
979 <message>
980 <location line="+6"/>
981 <source>Could not open %1 for writing</source>
982 <translation type="unfinished"></translation>
983 </message>
984 <message>
985 <location line="+9"/>
986 <source>Could not write firmware file</source>
987 <translation type="unfinished"></translation>
988 </message>
989 <message>
990 <location line="+5"/>
991 <source>Success: modified firmware file created</source>
992 <translation type="unfinished"></translation>
993 </message>
994 <message>
995 <location line="+20"/>
996 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
997 <translation type="unfinished"></translation>
998 </message>
999</context>
1000<context>
1001 <name>BootloaderInstaller</name>
1002 <message>
1003 <source>Starting bootloader installation</source>
1004 <translation type="obsolete">Önyükleyici kurulumu başlatılıyor</translation>
1005 </message>
1006 <message>
1007 <source>unsupported install Method</source>
1008 <translation type="obsolete">desteklenmeyen kurulum yöntemi</translation>
1009 </message>
1010 <message>
1011 <source>Starting bootloader uninstallation</source>
1012 <translation type="obsolete">Önyükleyici kaldırma işlemi başlatılıyor</translation>
1013 </message>
1014 <message>
1015 <source>No uninstallation possible</source>
1016 <translation type="obsolete">Uygun kaldırma işlemi bulunmamaktadır</translation>
1017 </message>
1018 <message>
1019 <source>Download error: received HTTP error %1.</source>
1020 <translation type="obsolete">İndirme hatası: HTTP %1 hatası.</translation>
1021 </message>
1022 <message>
1023 <source>Download error: %1</source>
1024 <translation type="obsolete">İndirme hatası: %1</translation>
1025 </message>
1026 <message>
1027 <source>Download finished.</source>
1028 <translation type="obsolete">İndirme işlemi tamamlandı.</translation>
1029 </message>
1030 <message>
1031 <source>Network error: %1. Please check your network and proxy settings.</source>
1032 <translation type="obsolete">Ağ hatası: %1. Lütfen ağ ve vekil sunucu ayarlarınızı kontrol ediniz.</translation>
1033 </message>
1034 <message>
1035 <source>Creating installation log</source>
1036 <translation type="obsolete">Kurulum kayıt dosyası yaratılıyor</translation>
1037 </message>
1038 <message>
1039 <source>Editing installation log</source>
1040 <translation type="obsolete">Kurulum kayıt dosyası düzenleniyor</translation>
1041 </message>
1042 <message>
1043 <source>Downloading file %1.%2</source>
1044 <translation type="obsolete">Dosya indiriliyor %1.%2</translation>
1045 </message>
1046 <message>
1047 <source>Could not find the Original Firmware at: %1</source>
1048 <translation type="obsolete">Orijinal bellenim (firmware) bulunamadı: %1</translation>
1049 </message>
1050 <message>
1051 <source>Could not remove the Firmware at: %1</source>
1052 <translation type="obsolete">Bellenim (firmware) kaldırılamadı: %1</translation>
1053 </message>
1054 <message>
1055 <source>Could not copy the Firmware from: %1 to %2</source>
1056 <translation type="obsolete">Bellenim (firmware) kopyalanamadı: %1 den %2 ye</translation>
1057 </message>
1058 <message>
1059 <source>Finishing bootloader install</source>
1060 <translation type="obsolete">Önyükleyici kurulumu sonlandırılıyor</translation>
1061 </message>
1062 <message>
1063 <source>Could not find the Firmware at: %1</source>
1064 <translation type="obsolete">Bellenim (firmware) bulunamadı: %1</translation>
1065 </message>
1066 <message>
1067 <source>Could not rename: %1 to %2</source>
1068 <translation type="obsolete">Yeniden adlandırma işlemi başarısız: %1 den %2 ye</translation>
1069 </message>
1070 <message>
1071 <source>Could not copy: %1 to %2</source>
1072 <translation type="obsolete">Kopyalama işlemi başarısız: %1 den %2 ye</translation>
1073 </message>
1074 <message>
1075 <source>Bootloader install finished successfully.</source>
1076 <translation type="obsolete">Önyükleyici kurulumu başarıyla tamamlandı.</translation>
1077 </message>
1078 <message>
1079 <source>To finish the Bootloader installation, follow the steps below.</source>
1080 <translation type="obsolete">Önyükleyici kurulumunu tamamlamak için aşağıdaki adımları izleyin.</translation>
1081 </message>
1082 <message>
1083 <source>1. Eject/Unmount your Device.</source>
1084 <translation type="obsolete">1. Aygıtı Çıkarın/Aygıtın Bağlantısını kesin.</translation>
1085 </message>
1086 <message>
1087 <source>2. Unplug USB and any Power adapters.</source>
1088 <translation type="obsolete">2. USB ve güç kablolarının bağlantısını kesin.</translation>
1089 </message>
1090 <message>
1091 <source>3. Hold POWER to turn the Device off.</source>
1092 <translation type="obsolete">POWER (güç) düğmesine basılı tutarak aygıtı kapatın.</translation>
1093 </message>
1094 <message>
1095 <source>4. Toggle the Battery switch on the Device.</source>
1096 <translation type="obsolete">4. Aygıtın pil anahtarını açın.</translation>
1097 </message>
1098 <message>
1099 <source>5. Hold POWER to boot the Rockbox bootloader.</source>
1100 <translation type="obsolete">5. POWER (güç) düğmesine basarak Rockbox önyükleyicisini başlatın.</translation>
1101 </message>
1102 <message>
1103 <source>2. Turn you Device OFF.</source>
1104 <translation type="obsolete">2. Aygıtı kapatın.</translation>
1105 </message>
1106 <message>
1107 <source>3. Insert Charger.</source>
1108 <translation type="obsolete">3. Aygıtın şarjını bağlayın.</translation>
1109 </message>
1110 <message>
1111 <source>Firmware does not exist: %1</source>
1112 <translation type="obsolete">Bellenim (firmware) mevcut değil: %1</translation>
1113 </message>
1114 <message>
1115 <source>Original Firmware does not exist: %1</source>
1116 <translation type="obsolete">Orijinal bellenim (firmware) mevcut değil: %1</translation>
1117 </message>
1118 <message>
1119 <source>Searching for ipods</source>
1120 <translation type="obsolete">iPod&apos;lar aranıyor</translation>
1121 </message>
1122 <message>
1123 <source>No Ipods found</source>
1124 <translation type="obsolete">Herhangi bir iPod bulunamadı</translation>
1125 </message>
1126 <message>
1127 <source>Too many Ipods found</source>
1128 <translation type="obsolete">Çok sayıda iPod bulundu</translation>
1129 </message>
1130 <message>
1131 <source>could not open ipod</source>
1132 <translation type="obsolete">iPod açılamadı</translation>
1133 </message>
1134 <message>
1135 <source>could not read partitiontable</source>
1136 <translation type="obsolete">bölümlendirme tablosu okunamadı</translation>
1137 </message>
1138 <message>
1139 <source>No partition 0 on disk</source>
1140 <translation type="obsolete">Diskte 0 bölümü mevcut değil</translation>
1141 </message>
1142 <message>
1143 <source>[INFO] Part Start Sector End Sector Size (MB) Type
1144</source>
1145 <translation type="obsolete">[BİLGİ] Bölüm Başlangıç sektörü Bitiş sektörü Boyut (MB) Tür
1146</translation>
1147 </message>
1148 <message>
1149 <source>[INFO] %1 %2 %3 %4 %5 (%6)</source>
1150 <translation type="obsolete">[BİLGİ] %1 %2 %3 %4 %5 (%6)</translation>
1151 </message>
1152 <message>
1153 <source>Failed to read firmware directory</source>
1154 <translation type="obsolete">Bellenim (firmware) dizini okunamadı</translation>
1155 </message>
1156 <message>
1157 <source>Unknown version number in firmware (%1)</source>
1158 <translation type="obsolete">Bilinmeyen bellenim (firmware) sürüm numarası (%1)</translation>
1159 </message>
1160 <message>
1161 <source>Warning this is a MacPod, Rockbox doesnt work on this. Convert it to WinPod
1162See http://www.rockbox.org/wiki/IpodConversionToFAT32</source>
1163 <translation type="obsolete">iPod&apos;unuz Macintosh&apos;a göre biçimlendirilmiş. Rockbox&apos;ın çalışabilmesi için iPod&apos;un FAT32 türünde biçimlendirilmiş olması gerekmektedir.
1164Ayrıntılı bilgi için: http://www.rockbox.org/wiki/IpodConversionToFAT32</translation>
1165 </message>
1166 <message>
1167 <source>Could not open Ipod in RW mode</source>
1168 <translation type="obsolete">iPod RW modunda açılamadı</translation>
1169 </message>
1170 <message>
1171 <source>No bootloader detected.</source>
1172 <translation type="obsolete">Herhangi bir önyükleyici algılanamadı.</translation>
1173 </message>
1174 <message>
1175 <source>Successfully removed Bootloader</source>
1176 <translation type="obsolete">Önyükleyici başarıyla kaldırıldı</translation>
1177 </message>
1178 <message>
1179 <source>--delete-bootloader failed.</source>
1180 <translation type="obsolete">--delete-bootloader (önyükleyici silme komutu) başarısız.</translation>
1181 </message>
1182 <message>
1183 <source>Successfully added Bootloader</source>
1184 <translation type="obsolete">Önyükleyici başarıyla eklendi</translation>
1185 </message>
1186 <message>
1187 <source>failed to add Bootloader</source>
1188 <translation type="obsolete">Önyükleyici ekleme işlemi başarısız</translation>
1189 </message>
1190 <message>
1191 <source>Searching for sansas</source>
1192 <translation type="obsolete">Sansa&apos;lar aranıyor</translation>
1193 </message>
1194 <message>
1195 <source>No Sansa found</source>
1196 <translation type="obsolete">Herhangi bir Sansa bulunamadı</translation>
1197 </message>
1198 <message>
1199 <source>Too many Sansas found</source>
1200 <translation type="obsolete">Çok sayıda Sansa bulundu</translation>
1201 </message>
1202 <message>
1203 <source>could not open Sansa</source>
1204 <translation type="obsolete">Sansa açılamadı</translation>
1205 </message>
1206 <message>
1207 <source>Disk is not a Sansa (%1), aborting.</source>
1208 <translation type="obsolete">Disk bir Sansa değil (%1), işlem durduruluyor.</translation>
1209 </message>
1210 <message>
1211 <source>********************************************
1212OLD ROCKBOX INSTALLATION DETECTED, ABORTING.
1213You must reinstall the original Sansa firmware before running
1214sansapatcher for the first time.
1215See http://www.rockbox.org/twiki/bin/view/Main/SansaE200Install
1216*********************************************
1217</source>
1218 <translation type="obsolete">********************************************
1219ESKİ BİR ROCKBOX KURULUMU ALGILANDI, İŞLEM DURDURULUYOR.
1220Sansa yamalayıcısını çalıştırmak için orijinal Sansa bellenimini (firmware)
1221tekrar kurmanız gerekmektedir.
1222Ayrıntılı bilgi için: http://www.rockbox.org/twiki/bin/view/Main/SansaE200Install
1223*********************************************
1224</translation>
1225 </message>
1226 <message>
1227 <source>Could not open Sansa in RW mode</source>
1228 <translation type="obsolete">Sansa RW modunda açılamadı</translation>
1229 </message>
1230 <message>
1231 <source>Could not MD5Sum original firmware</source>
1232 <translation type="obsolete">Orijinal bellenimin (firmware) MD5Sum doğrulaması başarısız</translation>
1233 </message>
1234 <message>
1235 <source>Could not detect firmware type</source>
1236 <translation type="obsolete">Bellenim (firmware) türü algılanamadı</translation>
1237 </message>
1238 <message>
1239 <source>Error in descramble</source>
1240 <translation type="obsolete">Sinyali çözümlemede hata</translation>
1241 </message>
1242 <message>
1243 <source>Error in patching</source>
1244 <translation type="obsolete">Yamalama işleminde hata</translation>
1245 </message>
1246 <message>
1247 <source>Error in scramble</source>
1248 <translation type="obsolete">Sinyali değiştirmede hata</translation>
1249 </message>
1250 <message>
1251 <source>Error in checksumming</source>
1252 <translation type="obsolete">Doğrulama başarısız</translation>
1253 </message>
1254 <message>
1255 <source>2. Boot into the original Firmware.</source>
1256 <translation type="obsolete">2. Orijinal bellenimle (firmware) başlatın.</translation>
1257 </message>
1258 <message>
1259 <source>3. Use the Firmware flash option in the Original Firmware.</source>
1260 <translation type="obsolete">3. Orijinal bellenimdeki (firmware) firmware flash seçeneğini kullanın.</translation>
1261 </message>
1262 <message>
1263 <source>4. Reboot.</source>
1264 <translation type="obsolete">4. Yeniden başlatın.</translation>
1265 </message>
1266</context>
1267<context>
1268 <name>BrowseDirtreeFrm</name>
1269 <message>
1270 <source>Find Directory</source>
1271 <translation type="obsolete">Dizini Bul</translation>
1272 </message>
1273 <message>
1274 <source>Browse to the destination folder</source>
1275 <translation type="obsolete">Hedef dizini seçin</translation>
1276 </message>
1277 <message>
1278 <source>&amp;Ok</source>
1279 <translation type="obsolete">&amp;Tamam</translation>
1280 </message>
1281 <message>
1282 <source>&amp;Cancel</source>
1283 <translation type="obsolete">&amp;İptal</translation>
1284 </message>
1285</context>
1286<context>
1287 <name>BrowseOFFrm</name>
1288 <message>
1289 <source>Find original Firmware</source>
1290 <translation type="obsolete">Orijinal bellenimi (firmware) bul</translation>
1291 </message>
1292 <message>
1293 <source>Browse for a downloaded copy of the original firmware</source>
1294 <translation type="obsolete">İndirilmiş orijinal bellenimin (firmware) kopyasına göz at</translation>
1295 </message>
1296 <message>
1297 <source>Browse</source>
1298 <translation type="obsolete">Göz At</translation>
1299 </message>
1300 <message>
1301 <source>&amp;Ok</source>
1302 <translation type="obsolete">&amp;Tamam</translation>
1303 </message>
1304 <message>
1305 <source>&amp;Cancel</source>
1306 <translation type="obsolete">&amp;İptal</translation>
1307 </message>
1308</context>
1309<context>
1310 <name>Changelog</name>
1311 <message>
1312 <location filename="../gui/changelogfrm.ui" line="+17"/>
1313 <source>Changelog</source>
1314 <translation type="unfinished"></translation>
1315 </message>
1316 <message>
1317 <location line="+22"/>
1318 <source>Show on startup</source>
1319 <translation type="unfinished"></translation>
1320 </message>
1321 <message>
1322 <location line="+7"/>
1323 <source>&amp;Ok</source>
1324 <translation type="unfinished">&amp;Tamam</translation>
1325 </message>
1326</context>
1327<context>
1328 <name>Config</name>
1329 <message>
1330 <source> (%1)</source>
1331 <translation type="obsolete"> (%1)</translation>
1332 </message>
1333 <message>
1334 <source>Language changed</source>
1335 <translation type="obsolete">Dil değiştirildi</translation>
1336 </message>
1337 <message>
1338 <source>You need to restart the application for the changed language to take effect.</source>
1339 <translation type="obsolete">Seçilen dilin etkin olması için uygulamayı yeniden başlatmalısınız.</translation>
1340 </message>
1341 <message>
1342 <location filename="../configure.cpp" line="+322"/>
1343 <source>Current cache size is %L1 kiB.</source>
1344 <translation>Mevcut önbellek boyutu %L1 KB.</translation>
1345 </message>
1346 <message>
1347 <source>Select your device</source>
1348 <translation type="obsolete">Aygıtınızı seçin</translation>
1349 </message>
1350 <message>
1351 <source>Sansa e200 in MTP mode found!
1352You need to change your player to MSC mode for installation. </source>
1353 <translation type="obsolete">MTP modunda bir Sansa e200 bulundu!
1354Kurulum için aygıtı MSC moduna almalısınız. </translation>
1355 </message>
1356 <message>
1357 <source>H10 20GB in MTP mode found!
1358You need to change your player to UMS mode for installation. </source>
1359 <translation type="obsolete">MTP modunda bir H10 20GB bulundu!
1360Kurulum için aygıtı UMS moduna almalısınız. </translation>
1361 </message>
1362 <message>
1363 <source>Unless you changed this installation will fail!</source>
1364 <translation type="obsolete">Değiştirmezseniz kurulum gerçekleştirilemez!</translation>
1365 </message>
1366 <message>
1367 <source>Fatal error</source>
1368 <translation type="obsolete">Önemli hata</translation>
1369 </message>
1370 <message>
1371 <location line="+536"/>
1372 <source>Autodetection</source>
1373 <translation>Otomatik algılama</translation>
1374 </message>
1375 <message>
1376 <location line="+1"/>
1377 <source>Could not detect a Mountpoint.
1378Select your Mountpoint manually.</source>
1379 <translation>Herhangi bir bağlama noktası algılanamadı.
1380Bağlama noktasını kendiniz seçiniz.</translation>
1381 </message>
1382 <message>
1383 <location line="-95"/>
1384 <source>Could not detect a device.
1385Select your device and Mountpoint manually.</source>
1386 <translation>Herhangi bir aygıt algılanamadı.
1387Aygıtınızı ve bağlama noktasını kendiniz seçiniz.</translation>
1388 </message>
1389 <message>
1390 <location line="-634"/>
1391 <source>The following errors occurred:</source>
1392 <translation type="unfinished"></translation>
1393 </message>
1394 <message>
1395 <location line="+45"/>
1396 <source>No mountpoint given</source>
1397 <translation type="unfinished"></translation>
1398 </message>
1399 <message>
1400 <location line="+4"/>
1401 <source>Mountpoint does not exist</source>
1402 <translation type="unfinished"></translation>
1403 </message>
1404 <message>
1405 <location line="+4"/>
1406 <source>Mountpoint is not a directory.</source>
1407 <translation type="unfinished"></translation>
1408 </message>
1409 <message>
1410 <location line="+4"/>
1411 <source>Mountpoint is not writeable</source>
1412 <translation type="unfinished"></translation>
1413 </message>
1414 <message>
1415 <location line="+15"/>
1416 <source>No player selected</source>
1417 <translation type="unfinished"></translation>
1418 </message>
1419 <message>
1420 <location line="+7"/>
1421 <source>Cache path not writeable. Leave path empty to default to systems temporary path.</source>
1422 <translation type="unfinished"></translation>
1423 </message>
1424 <message>
1425 <location line="+19"/>
1426 <source>You need to fix the above errors before you can continue.</source>
1427 <translation type="unfinished"></translation>
1428 </message>
1429 <message>
1430 <location line="+3"/>
1431 <source>Configuration error</source>
1432 <translation type="unfinished">Yapılandırma hatası</translation>
1433 </message>
1434 <message>
1435 <location line="+109"/>
1436 <source>Showing disabled targets</source>
1437 <translation type="unfinished"></translation>
1438 </message>
1439 <message>
1440 <location line="+1"/>
1441 <source>You just enabled showing targets that are marked disabled. Disabled targets are not recommended to end users. Please use this option only if you know what you are doing.</source>
1442 <translation type="unfinished"></translation>
1443 </message>
1444 <message>
1445 <location line="+107"/>
1446 <location line="+466"/>
1447 <source>TTS error</source>
1448 <translation type="unfinished"></translation>
1449 </message>
1450 <message>
1451 <location line="-465"/>
1452 <location line="+466"/>
1453 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1454 <translation type="unfinished"></translation>
1455 </message>
1456 <message>
1457 <location line="-460"/>
1458 <location line="+30"/>
1459 <source>Configuration OK</source>
1460 <translation type="unfinished"></translation>
1461 </message>
1462 <message>
1463 <location line="-24"/>
1464 <location line="+29"/>
1465 <source>Configuration INVALID</source>
1466 <translation type="unfinished"></translation>
1467 </message>
1468 <message>
1469 <location line="+39"/>
1470 <source>Proxy Detection</source>
1471 <translation type="unfinished"></translation>
1472 </message>
1473 <message>
1474 <location line="+1"/>
1475 <source>The System Proxy settings are invalid!
1476Rockbox Utility can&apos;t work with this proxy settings. Make sure the system proxy is set correctly. Note that &quot;proxy auto-config (PAC)&quot; scripts are not supported by Rockbox Utility. If your system uses this you need to use manual proxy settings.</source>
1477 <translation type="unfinished"></translation>
1478 </message>
1479 <message>
1480 <location line="+113"/>
1481 <source>Set Cache Path</source>
1482 <translation type="unfinished"></translation>
1483 </message>
1484 <message>
1485 <location line="+22"/>
1486 <source>%1 (%2 GiB of %3 GiB free)</source>
1487 <translation type="unfinished"></translation>
1488 </message>
1489 <message>
1490 <location line="+74"/>
1491 <source>Multiple devices have been detected. Please disconnect all players but one and try again.</source>
1492 <translation type="unfinished"></translation>
1493 </message>
1494 <message>
1495 <location line="+3"/>
1496 <source>Detected devices:</source>
1497 <translation type="unfinished"></translation>
1498 </message>
1499 <message>
1500 <location line="+5"/>
1501 <source>(unknown)</source>
1502 <translation type="unfinished"></translation>
1503 </message>
1504 <message>
1505 <location line="+2"/>
1506 <source>%1 at %2</source>
1507 <translation type="unfinished"></translation>
1508 </message>
1509 <message>
1510 <location line="+6"/>
1511 <source>Note: detecting connected devices might be ambiguous. You might have less devices connected than listed. In this case it might not be possible to detect your player unambiguously.</source>
1512 <translation type="unfinished"></translation>
1513 </message>
1514 <message>
1515 <location line="+4"/>
1516 <location line="+4"/>
1517 <location line="+42"/>
1518 <source>Device Detection</source>
1519 <translation type="unfinished"></translation>
1520 </message>
1521 <message>
1522 <location line="-31"/>
1523 <source>Detected an unsupported player:
1524%1
1525Sorry, Rockbox doesn&apos;t run on your player.</source>
1526 <translation type="unfinished"></translation>
1527 </message>
1528 <message>
1529 <location line="+6"/>
1530 <source>%1 in MTP mode found!
1531You need to change your player to MSC mode for installation. </source>
1532 <translation type="unfinished"></translation>
1533 </message>
1534 <message>
1535 <location line="+8"/>
1536 <source>%1 &quot;MacPod&quot; found!
1537Rockbox needs a FAT formatted Ipod (so-called &quot;WinPod&quot;) to run. </source>
1538 <translation type="unfinished"></translation>
1539 </message>
1540 <message>
1541 <location line="+6"/>
1542 <source>The player contains an incompatible filesystem.
1543Make sure you selected the correct mountpoint and the player is set up to use a filesystem compatible with Rockbox.</source>
1544 <translation type="unfinished"></translation>
1545 </message>
1546 <message>
1547 <location line="+8"/>
1548 <source>An unknown error occured during player detection.</source>
1549 <translation type="unfinished"></translation>
1550 </message>
1551 <message>
1552 <location line="+67"/>
1553 <source>Really delete cache?</source>
1554 <translation>Önbelleği silmek istediğinizden emin misiniz?</translation>
1555 </message>
1556 <message>
1557 <location line="+1"/>
1558 <source>Do you really want to delete the cache? Make absolutely sure this setting is correct as it will remove &lt;b&gt;all&lt;/b&gt; files in this folder!</source>
1559 <translation>Önbelleği silmeyi onaylıyor musunuz? Bu seçenek ilgili dizindeki &lt;b&gt;tüm&lt;/b&gt; dosyaları silecek!</translation>
1560 </message>
1561 <message>
1562 <location line="+8"/>
1563 <source>Path wrong!</source>
1564 <translation>Konum hatalı!</translation>
1565 </message>
1566 <message>
1567 <location line="+1"/>
1568 <source>The cache path is invalid. Aborting.</source>
1569 <translation>Önbellek konumu geçersiz. İşlem durduruluyor.</translation>
1570 </message>
1571 <message>
1572 <location line="+42"/>
1573 <source>TTS configuration invalid</source>
1574 <translation type="unfinished"></translation>
1575 </message>
1576 <message>
1577 <location line="+1"/>
1578 <source>TTS configuration invalid.
1579 Please configure TTS engine.</source>
1580 <translation type="unfinished"></translation>
1581 </message>
1582 <message>
1583 <location line="+5"/>
1584 <source>Could not start TTS engine.</source>
1585 <translation type="unfinished"></translation>
1586 </message>
1587 <message>
1588 <location line="+1"/>
1589 <source>Could not start TTS engine.
1590</source>
1591 <translation type="unfinished"></translation>
1592 </message>
1593 <message>
1594 <location line="+1"/>
1595 <location line="+19"/>
1596 <source>
1597Please configure TTS engine.</source>
1598 <translation type="unfinished"></translation>
1599 </message>
1600 <message>
1601 <location line="-5"/>
1602 <source>Rockbox Utility Voice Test</source>
1603 <translation type="unfinished"></translation>
1604 </message>
1605 <message>
1606 <location line="+3"/>
1607 <source>Could not voice test string.</source>
1608 <translation type="unfinished"></translation>
1609 </message>
1610 <message>
1611 <location line="+1"/>
1612 <source>Could not voice test string.
1613</source>
1614 <translation type="unfinished"></translation>
1615 </message>
1616</context>
1617<context>
1618 <name>ConfigForm</name>
1619 <message>
1620 <location filename="../configurefrm.ui" line="+14"/>
1621 <source>Configuration</source>
1622 <translation>Yapılandırma</translation>
1623 </message>
1624 <message>
1625 <location line="+6"/>
1626 <source>Configure Rockbox Utility</source>
1627 <translation>Rockbox Aracını Yapılandır</translation>
1628 </message>
1629 <message>
1630 <location line="+15"/>
1631 <source>&amp;Device</source>
1632 <translation>&amp;Aygıt</translation>
1633 </message>
1634 <message>
1635 <location line="+6"/>
1636 <source>Select your device in the &amp;filesystem</source>
1637 <translation>Aygıtınızı &amp;dosya sisteminde seçin</translation>
1638 </message>
1639 <message>
1640 <location line="+17"/>
1641 <source>&amp;Refresh</source>
1642 <translation type="unfinished"></translation>
1643 </message>
1644 <message>
1645 <location line="+37"/>
1646 <source>Show disabled targets</source>
1647 <translation type="unfinished"></translation>
1648 </message>
1649 <message>
1650 <location line="+224"/>
1651 <source>&amp;Browse</source>
1652 <translation>&amp;Göz At</translation>
1653 </message>
1654 <message>
1655 <location line="-247"/>
1656 <source>&amp;Select your audio player</source>
1657 <translation>&amp;Ses oynatıcınızı seçin</translation>
1658 </message>
1659 <message>
1660 <source>1</source>
1661 <translation type="obsolete">1</translation>
1662 </message>
1663 <message>
1664 <location line="+42"/>
1665 <source>&amp;Autodetect</source>
1666 <translation>&amp;Otomatik Algılama</translation>
1667 </message>
1668 <message>
1669 <location line="+22"/>
1670 <source>&amp;Proxy</source>
1671 <translation>&amp;Vekil Sunucu</translation>
1672 </message>
1673 <message>
1674 <location line="+6"/>
1675 <source>&amp;No Proxy</source>
1676 <translation>Vekil Sunucu &amp;Yok</translation>
1677 </message>
1678 <message>
1679 <location line="+10"/>
1680 <source>Use S&amp;ystem values</source>
1681 <translation>S&amp;istem değerlerini kullan</translation>
1682 </message>
1683 <message>
1684 <location line="+7"/>
1685 <source>&amp;Manual Proxy settings</source>
1686 <translation>Vekil Sunucu &amp;ayarları</translation>
1687 </message>
1688 <message>
1689 <location line="+7"/>
1690 <source>Proxy Values</source>
1691 <translation>Vekil Sunucu Değerleri</translation>
1692 </message>
1693 <message>
1694 <location line="+6"/>
1695 <source>&amp;Host:</source>
1696 <translation>S&amp;unucu:</translation>
1697 </message>
1698 <message>
1699 <location line="+10"/>
1700 <source>&amp;Port:</source>
1701 <translation>&amp;Port:</translation>
1702 </message>
1703 <message>
1704 <location line="+17"/>
1705 <source>&amp;Username</source>
1706 <translation>&amp;Kullanıcı Adı</translation>
1707 </message>
1708 <message>
1709 <location line="+10"/>
1710 <source>Pass&amp;word</source>
1711 <translation>Pa&amp;rola</translation>
1712 </message>
1713 <message>
1714 <location line="+10"/>
1715 <source>Show</source>
1716 <translation type="unfinished"></translation>
1717 </message>
1718 <message>
1719 <location line="+41"/>
1720 <source>&amp;Language</source>
1721 <translation>&amp;Dil</translation>
1722 </message>
1723 <message>
1724 <location line="+14"/>
1725 <source>Cac&amp;he</source>
1726 <translation>&amp;Önbellek</translation>
1727 </message>
1728 <message>
1729 <location line="+3"/>
1730 <source>Download cache settings</source>
1731 <translation>İndirme önbelleği ayarları</translation>
1732 </message>
1733 <message>
1734 <location line="+6"/>
1735 <source>Rockbox Utility uses a local download cache to save network traffic. You can change the path to the cache and use it as local repository by enabling Offline mode.</source>
1736 <translation>Rockbox Aracı ağ trafiğini azaltmak için indirme önbelleği kullanır. Bu önbelleğin konumunu değiştirebilirsiniz ve önbelleği Çevrimdışı modu seçerek yerel depo gibi kullanabilirsiniz.</translation>
1737 </message>
1738 <message>
1739 <location line="+10"/>
1740 <source>Current cache size is %1</source>
1741 <translation>Mevcut önbellek boyutu %1</translation>
1742 </message>
1743 <message>
1744 <location line="+9"/>
1745 <source>P&amp;ath</source>
1746 <translation>&amp;Konum</translation>
1747 </message>
1748 <message>
1749 <location line="+10"/>
1750 <source>Entering an invalid folder will reset the path to the systems temporary path.</source>
1751 <translation>Geçersiz bir dizin girmek konumu sistemin geçici konumuna getirir.</translation>
1752 </message>
1753 <message>
1754 <location line="+22"/>
1755 <source>Disable local &amp;download cache</source>
1756 <translation>Yerel &amp;indirme önbelleğini kapat</translation>
1757 </message>
1758 <message>
1759 <location line="+63"/>
1760 <source>&amp;Select TTS Engine</source>
1761 <translation type="unfinished"></translation>
1762 </message>
1763 <message>
1764 <location line="+13"/>
1765 <source>Configure TTS Engine</source>
1766 <translation type="unfinished"></translation>
1767 </message>
1768 <message>
1769 <location line="+7"/>
1770 <location line="+51"/>
1771 <source>Configuration invalid!</source>
1772 <translation type="unfinished"></translation>
1773 </message>
1774 <message>
1775 <location line="-34"/>
1776 <source>Configure &amp;TTS</source>
1777 <translation type="unfinished"></translation>
1778 </message>
1779 <message>
1780 <location line="+11"/>
1781 <source>Test TTS</source>
1782 <translation type="unfinished"></translation>
1783 </message>
1784 <message>
1785 <location line="+7"/>
1786 <source>&amp;Use string corrections for TTS</source>
1787 <translation type="unfinished"></translation>
1788 </message>
1789 <message>
1790 <location line="+33"/>
1791 <source>Configure &amp;Enc</source>
1792 <translation type="unfinished"></translation>
1793 </message>
1794 <message>
1795 <location line="+11"/>
1796 <source>encoder name</source>
1797 <translation type="unfinished"></translation>
1798 </message>
1799 <message>
1800 <source>This will try to use all information from the cache, even information about updates. Only use this option if you want to install without network connection. Note: you need to do the same install you want to perform later with network access first to download all required files to the cache.</source>
1801 <translation type="obsolete">Bu seçenek, güncellemeler dahil tüm bilgilerin önbellekten alınmasını sağlar. Bu seçeneği sadece ağ bağlantısı olmadan kurulum yapmak için kullanın. Not: Daha sonra ağ bağlantısıyla aynı kurulumu yapmak için gerekli tüm dosyaları önbelleğe indirmeniz gerekmektedir.</translation>
1802 </message>
1803 <message>
1804 <source>O&amp;ffline mode</source>
1805 <translation type="obsolete">&amp;Çevrimdışı modu</translation>
1806 </message>
1807 <message>
1808 <location line="-127"/>
1809 <source>Clean cache &amp;now</source>
1810 <translation>Önbelleği &amp;temizle</translation>
1811 </message>
1812 <message>
1813 <location line="+16"/>
1814 <source>&amp;TTS &amp;&amp; Encoder</source>
1815 <translation>&amp;TTS &amp;&amp; Kodlayıcı</translation>
1816 </message>
1817 <message>
1818 <location line="+6"/>
1819 <source>TTS Engine</source>
1820 <translation>TTS Motoru</translation>
1821 </message>
1822 <message>
1823 <source>&amp;Select TTS profile</source>
1824 <translation type="obsolete">TTS &amp;Profilini seçin</translation>
1825 </message>
1826 <message>
1827 <source>TTS executable</source>
1828 <translation type="obsolete">TTS çalıştırılabilir dosyası</translation>
1829 </message>
1830 <message>
1831 <source>TTS Options</source>
1832 <translation type="obsolete">TTS Seçenekleri</translation>
1833 </message>
1834 <message>
1835 <source>TTS Language</source>
1836 <translation type="obsolete">TTS Dili</translation>
1837 </message>
1838 <message>
1839 <location line="+71"/>
1840 <source>Encoder Engine</source>
1841 <translation>Kodlayıcı Motoru</translation>
1842 </message>
1843 <message>
1844 <source>Select &amp;encoder profile</source>
1845 <translation type="obsolete">Kod&amp;layıcı profilini seçin</translation>
1846 </message>
1847 <message>
1848 <source>Encoder executable</source>
1849 <translation type="obsolete">Kodlayıcı çalıştırılabilir dosyası</translation>
1850 </message>
1851 <message>
1852 <source>B&amp;rowse</source>
1853 <translation type="obsolete">&amp;Göz At</translation>
1854 </message>
1855 <message>
1856 <source>Encoder options</source>
1857 <translation type="obsolete">Kodlayıcı Seçenekleri</translation>
1858 </message>
1859 <message>
1860 <location line="+74"/>
1861 <source>&amp;Ok</source>
1862 <translation>&amp;Tamam</translation>
1863 </message>
1864 <message>
1865 <location line="+11"/>
1866 <source>&amp;Cancel</source>
1867 <translation>&amp;İptal</translation>
1868 </message>
1869</context>
1870<context>
1871 <name>Configure</name>
1872 <message>
1873 <source>English</source>
1874 <translation type="obsolete">Türkçe</translation>
1875 </message>
1876 <message>
1877 <location filename="../configure.cpp" line="-358"/>
1878 <source>English</source>
1879 <comment>This is the localized language name, i.e. your language.</comment>
1880 <translation type="unfinished">Türkçe</translation>
1881 </message>
1882</context>
1883<context>
1884 <name>CreateVoiceFrm</name>
1885 <message>
1886 <location filename="../createvoicefrm.ui" line="+17"/>
1887 <source>Create Voice File</source>
1888 <translation type="unfinished"></translation>
1889 </message>
1890 <message>
1891 <location line="+25"/>
1892 <source>Select the Language you want to generate a voicefile for:</source>
1893 <translation type="unfinished"></translation>
1894 </message>
1895 <message>
1896 <location line="+7"/>
1897 <source>Generation settings</source>
1898 <translation type="unfinished">Oluşturma ayarları</translation>
1899 </message>
1900 <message>
1901 <location line="+6"/>
1902 <source>TTS:</source>
1903 <translation type="unfinished"></translation>
1904 </message>
1905 <message>
1906 <location line="+13"/>
1907 <source>Change</source>
1908 <translation type="unfinished"></translation>
1909 </message>
1910 <message>
1911 <location line="+20"/>
1912 <source>Wavtrim Threshold</source>
1913 <translation type="unfinished"></translation>
1914 </message>
1915 <message>
1916 <location line="+13"/>
1917 <source>Silence threshold</source>
1918 <translation type="unfinished"></translation>
1919 </message>
1920 <message>
1921 <location line="+38"/>
1922 <source>&amp;Install</source>
1923 <translation type="unfinished">&amp;Yükle</translation>
1924 </message>
1925 <message>
1926 <location line="+11"/>
1927 <source>&amp;Cancel</source>
1928 <translation type="unfinished">&amp;İptal</translation>
1929 </message>
1930 <message>
1931 <location line="+13"/>
1932 <source>Language</source>
1933 <translation type="unfinished"></translation>
1934 </message>
1935</context>
1936<context>
1937 <name>CreateVoiceWindow</name>
1938 <message>
1939 <location filename="../createvoicewindow.cpp" line="+100"/>
1940 <source>TTS error</source>
1941 <translation type="unfinished"></translation>
1942 </message>
1943 <message>
1944 <location line="+1"/>
1945 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1946 <translation type="unfinished"></translation>
1947 </message>
1948 <message>
1949 <location line="+4"/>
1950 <location line="+3"/>
1951 <source>Engine: &lt;b&gt;%1&lt;/b&gt;</source>
1952 <translation type="unfinished"></translation>
1953 </message>
1954</context>
1955<context>
1956 <name>EncTtsCfgGui</name>
1957 <message>
1958 <location filename="../encttscfggui.cpp" line="+45"/>
1959 <source>Waiting for engine...</source>
1960 <translation type="unfinished"></translation>
1961 </message>
1962 <message>
1963 <location line="+50"/>
1964 <source>Ok</source>
1965 <translation type="unfinished"></translation>
1966 </message>
1967 <message>
1968 <location line="+3"/>
1969 <source>Cancel</source>
1970 <translation type="unfinished"></translation>
1971 </message>
1972 <message>
1973 <location line="+99"/>
1974 <source>Browse</source>
1975 <translation type="unfinished">Göz At</translation>
1976 </message>
1977 <message>
1978 <location line="+8"/>
1979 <source>Refresh</source>
1980 <translation type="unfinished"></translation>
1981 </message>
1982 <message>
1983 <location line="+172"/>
1984 <source>Select executable</source>
1985 <translation type="unfinished"></translation>
1986 </message>
1987</context>
1988<context>
1989 <name>EncoderExe</name>
1990 <message>
1991 <location filename="../base/encoderexe.cpp" line="+41"/>
1992 <source>Path to Encoder:</source>
1993 <translation type="unfinished"></translation>
1994 </message>
1995 <message>
1996 <location line="+2"/>
1997 <source>Encoder options:</source>
1998 <translation type="unfinished"></translation>
1999 </message>
2000</context>
2001<context>
2002 <name>EncoderLame</name>
2003 <message>
2004 <location filename="../base/encoderlame.cpp" line="+73"/>
2005 <location line="+10"/>
2006 <source>LAME</source>
2007 <translation type="unfinished"></translation>
2008 </message>
2009 <message>
2010 <location line="-8"/>
2011 <source>Volume</source>
2012 <translation type="unfinished"></translation>
2013 </message>
2014 <message>
2015 <location line="+4"/>
2016 <source>Quality</source>
2017 <translation type="unfinished"></translation>
2018 </message>
2019 <message>
2020 <location line="+4"/>
2021 <source>Could not find libmp3lame!</source>
2022 <translation type="unfinished"></translation>
2023 </message>
2024</context>
2025<context>
2026 <name>EncoderRbSpeex</name>
2027 <message>
2028 <location filename="../base/encoderrbspeex.cpp" line="+34"/>
2029 <source>Volume:</source>
2030 <translation type="unfinished"></translation>
2031 </message>
2032 <message>
2033 <location line="+2"/>
2034 <source>Quality:</source>
2035 <translation type="unfinished"></translation>
2036 </message>
2037 <message>
2038 <location line="+2"/>
2039 <source>Complexity:</source>
2040 <translation type="unfinished"></translation>
2041 </message>
2042 <message>
2043 <location line="+2"/>
2044 <source>Use Narrowband:</source>
2045 <translation type="unfinished"></translation>
2046 </message>
2047</context>
2048<context>
2049 <name>InfoWidget</name>
2050 <message>
2051 <location filename="../gui/infowidget.cpp" line="+30"/>
2052 <location line="+77"/>
2053 <source>File</source>
2054 <translation type="unfinished">Dosya</translation>
2055 </message>
2056 <message>
2057 <location line="-77"/>
2058 <location line="+77"/>
2059 <source>Version</source>
2060 <translation type="unfinished">Sürüm</translation>
2061 </message>
2062</context>
2063<context>
2064 <name>InfoWidgetFrm</name>
2065 <message>
2066 <location filename="../gui/infowidgetfrm.ui" line="+14"/>
2067 <source>Info</source>
2068 <translation type="unfinished">Bilgi</translation>
2069 </message>
2070 <message>
2071 <location line="+6"/>
2072 <source>Currently installed packages.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; if you manually installed packages this might not be correct!</source>
2073 <translation type="unfinished"></translation>
2074 </message>
2075 <message>
2076 <location line="+14"/>
2077 <source>Package</source>
2078 <translation type="unfinished"></translation>
2079 </message>
2080</context>
2081<context>
2082 <name>Install</name>
2083 <message>
2084 <source>Mount point is wrong!</source>
2085 <translation type="obsolete">Bağlama noktası hatalı!</translation>
2086 </message>
2087 <message>
2088 <source>This is the absolute up to the minute Rockbox built. A current build will get updated every time a change is made. Latest version is r%1 (%2).</source>
2089 <translation type="obsolete">En güncel Rockbox inşasıdır. Mevcut inşa bir değişiklik yapıldığında güncellenir. Son sürüm r%1 (%2) dir.</translation>
2090 </message>
2091 <message>
2092 <source>&lt;b&gt;Note:&lt;/b&gt; This option will always download a fresh copy. &lt;b&gt;This is the recommended version.&lt;/b&gt;</source>
2093 <translation type="obsolete">&lt;b&gt;Not:&lt;/b&gt; Bu seçenek her zaman yeni bir kopyayı indirir. &lt;b&gt;Önerilen yöntem budur.&lt;/b&gt;</translation>
2094 </message>
2095 <message>
2096 <source>&lt;b&gt;Note:&lt;/b&gt; This option will always download a fresh copy.</source>
2097 <translation type="obsolete">&lt;b&gt;Not:&lt;/b&gt; Bu seçenek her zaman yeni bir kopyayı indirir.</translation>
2098 </message>
2099 <message>
2100 <source>This is the last released version of Rockbox.</source>
2101 <translation type="obsolete">Bu Rockbox&apos;ın kararlı en son sürümüdür.</translation>
2102 </message>
2103 <message>
2104 <source>&lt;b&gt;Note:&lt;/b&gt;The lastest released version is %1. &lt;b&gt;This is the recommended version.&lt;/b&gt;</source>
2105 <translation type="obsolete">&lt;b&gt;Not:&lt;/b&gt; Son sürüm %1 dir. &lt;b&gt;Önerilen sürüm budur.&lt;/b&gt;</translation>
2106 </message>
2107 <message>
2108 <source>These are automatically built each day from the current development source code. This generally has more features than the last stable release but may be much less stable. Features may change regularly.</source>
2109 <translation type="obsolete">Mevcut kaynak koddan her gün otomatik inşa edilir. Genellikle son sürümden daha fazla özellik barındırmasına rağmen daha az kararlı olabilir. Özellikler sürekli değişmektedir.</translation>
2110 </message>
2111 <message>
2112 <source>&lt;b&gt;Note:&lt;/b&gt; archived version is r%1 (%2).</source>
2113 <translation type="obsolete">&lt;b&gt;Not:&lt;/b&gt; arşivlenen sürüm r%1 (%2) dir.</translation>
2114 </message>
2115</context>
2116<context>
2117 <name>InstallFrm</name>
2118 <message>
2119 <source>Install Rockbox</source>
2120 <translation type="obsolete">Rockbox&apos;u Yükle</translation>
2121 </message>
2122 <message>
2123 <source>Please select the Rockbox version you want to install on your player:</source>
2124 <translation type="obsolete">Lütfen aygıtınıza kuracağınız Rockbox sürümünü seçin:</translation>
2125 </message>
2126 <message>
2127 <source>Version</source>
2128 <translation type="obsolete">Sürüm</translation>
2129 </message>
2130 <message>
2131 <source>Rockbox &amp;stable</source>
2132 <translation type="obsolete">Rockbox &amp;kararlı sürüm</translation>
2133 </message>
2134 <message>
2135 <source>&amp;Archived Build</source>
2136 <translation type="obsolete">&amp;Arşivlenmiş İnşa</translation>
2137 </message>
2138 <message>
2139 <source>&amp;Current Build</source>
2140 <translation type="obsolete">&amp;Mevcut İnşa</translation>
2141 </message>
2142 <message>
2143 <source>Details</source>
2144 <translation type="obsolete">Ayrıntılar</translation>
2145 </message>
2146 <message>
2147 <source>Details about the selected version</source>
2148 <translation type="obsolete">Seçili sürümün ayrıntıları</translation>
2149 </message>
2150 <message>
2151 <source>Note</source>
2152 <translation type="obsolete">Not</translation>
2153 </message>
2154 <message>
2155 <source>Rockbox Utility stores copies of Rockbox it has downloaded on the local hard disk to save network traffic. If your local copy is no longer working, tick this box to download a fresh copy.</source>
2156 <translation type="obsolete">Rockbox Aracı ağ trafiğini azaltmak için Rockbox kopyalarını yerel diskinizde saklar. Eğer yerel kopya çalışmıyorsa, yeni bir kopya indirmek için bu kutucuğu işaretleyin.</translation>
2157 </message>
2158 <message>
2159 <source>&amp;Don&apos;t use locally cached copy</source>
2160 <translation type="obsolete">Yerel &amp;kopyayı kullanma</translation>
2161 </message>
2162 <message>
2163 <source>&amp;Install</source>
2164 <translation type="obsolete">&amp;Yükle</translation>
2165 </message>
2166 <message>
2167 <source>&amp;Cancel</source>
2168 <translation type="obsolete">&amp;İptal</translation>
2169 </message>
2170</context>
2171<context>
2172 <name>InstallProgressFrm</name>
2173 <message>
2174 <source>Progress</source>
2175 <translation type="obsolete">İlerleme</translation>
2176 </message>
2177 <message>
2178 <source>&amp;Abort</source>
2179 <translation type="obsolete">&amp;Durdur</translation>
2180 </message>
2181</context>
2182<context>
2183 <name>InstallTalkFrm</name>
2184 <message>
2185 <location filename="../installtalkfrm.ui" line="+17"/>
2186 <source>Install Talk Files</source>
2187 <translation>Konuşma dosyalarını indir</translation>
2188 </message>
2189 <message>
2190 <source>Select the Folder to generate Talkfiles for.</source>
2191 <translation type="obsolete">Konuşma dosyalarının yazılacağı dizini seçin.</translation>
2192 </message>
2193 <message>
2194 <source>&amp;Browse</source>
2195 <translation type="obsolete">&amp;Göz At</translation>
2196 </message>
2197 <message>
2198 <source>Generation settings</source>
2199 <translation type="obsolete">Oluşturma ayarları</translation>
2200 </message>
2201 <message>
2202 <source>Encoder profile:</source>
2203 <translation type="obsolete">Kodlayıcı profili:</translation>
2204 </message>
2205 <message>
2206 <location line="+61"/>
2207 <source>TTS profile:</source>
2208 <translation>TTS profili:</translation>
2209 </message>
2210 <message>
2211 <location line="-42"/>
2212 <source>Generation options</source>
2213 <translation>Oluşturma seçenekleri</translation>
2214 </message>
2215 <message>
2216 <source>Overwrite Wavefiles</source>
2217 <translation type="obsolete">Wave dosyalarının üzerine yaz</translation>
2218 </message>
2219 <message>
2220 <source>Remove Wavefiles</source>
2221 <translation type="obsolete">Wave dosyalarını kaldır</translation>
2222 </message>
2223 <message>
2224 <source>Run recursive</source>
2225 <translation type="obsolete">Özyinelemeli çalıştır</translation>
2226 </message>
2227 <message>
2228 <location line="+6"/>
2229 <source>Strip Extensions</source>
2230 <translation>Uzantıları kaldır</translation>
2231 </message>
2232 <message>
2233 <source>Overwrite Talkfiles</source>
2234 <translation type="obsolete">Konuşma dosyalarının üzerine yaz</translation>
2235 </message>
2236 <message>
2237 <source>Generate .talk files for Folders</source>
2238 <translation type="obsolete">Dizinler için .talk dosyaları üret</translation>
2239 </message>
2240 <message>
2241 <source>Generate .talk files for Files</source>
2242 <translation type="obsolete">Dosyalar için .talk dosyaları üret</translation>
2243 </message>
2244 <message>
2245 <location line="+10"/>
2246 <source>Generate for files</source>
2247 <translation type="unfinished"></translation>
2248 </message>
2249 <message>
2250 <location line="+33"/>
2251 <source>Generate for folders</source>
2252 <translation type="unfinished"></translation>
2253 </message>
2254 <message>
2255 <location line="+10"/>
2256 <source>Recurse into folders</source>
2257 <translation type="unfinished"></translation>
2258 </message>
2259 <message>
2260 <location line="+16"/>
2261 <source>Change</source>
2262 <translation type="unfinished"></translation>
2263 </message>
2264 <message>
2265 <location line="+7"/>
2266 <source>Ignore files</source>
2267 <translation type="unfinished"></translation>
2268 </message>
2269 <message>
2270 <location line="+10"/>
2271 <source>Skip existing</source>
2272 <translation type="unfinished"></translation>
2273 </message>
2274 <message>
2275 <location line="+15"/>
2276 <source>&amp;Install</source>
2277 <translation>&amp;Yükle</translation>
2278 </message>
2279 <message>
2280 <location line="+11"/>
2281 <source>&amp;Cancel</source>
2282 <translation>&amp;İptal</translation>
2283 </message>
2284 <message>
2285 <location line="+16"/>
2286 <source>Select folders for Talkfile generation (Ctrl for multiselect)</source>
2287 <translation type="unfinished"></translation>
2288 </message>
2289</context>
2290<context>
2291 <name>InstallTalkWindow</name>
2292 <message>
2293 <source>The Folder to Talk is wrong!</source>
2294 <translation type="obsolete">Konuşma dizini hatalı!</translation>
2295 </message>
2296 <message>
2297 <source>Path to Encoder is wrong!</source>
2298 <translation type="obsolete">Kodlayıcı konumu hatalı!</translation>
2299 </message>
2300 <message>
2301 <source>Path to TTS is wrong!</source>
2302 <translation type="obsolete">TTS konumu hatalı!</translation>
2303 </message>
2304 <message>
2305 <source>TTS Profile: &lt;b&gt;%1&lt;/b&gt;</source>
2306 <translation type="obsolete">TTS Profili: &lt;b&gt;%1&lt;/b&gt;</translation>
2307 </message>
2308 <message>
2309 <source>Invalid TTS profile!</source>
2310 <translation type="obsolete">Geçersiz TTS Profili!</translation>
2311 </message>
2312 <message>
2313 <source>Encoder Profile: &lt;b&gt;%1&lt;/b&gt;</source>
2314 <translation type="obsolete">Kodlayıcı Profili: &lt;b&gt;%1&lt;/b&gt;</translation>
2315 </message>
2316 <message>
2317 <source>Invalid encoder profile!</source>
2318 <translation type="obsolete">Geçersiz kodlayıcı profili!</translation>
2319 </message>
2320 <message>
2321 <location filename="../installtalkwindow.cpp" line="+96"/>
2322 <source>Empty selection</source>
2323 <translation type="unfinished"></translation>
2324 </message>
2325 <message>
2326 <location line="+1"/>
2327 <source>No files or folders selected. Please select files or folders first.</source>
2328 <translation type="unfinished"></translation>
2329 </message>
2330 <message>
2331 <location line="+40"/>
2332 <source>TTS error</source>
2333 <translation type="unfinished"></translation>
2334 </message>
2335 <message>
2336 <location line="+1"/>
2337 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
2338 <translation type="unfinished"></translation>
2339 </message>
2340</context>
2341<context>
2342 <name>ManualWidget</name>
2343 <message>
2344 <location filename="../gui/manualwidget.cpp" line="+44"/>
2345 <source>&lt;a href=&apos;%1&apos;&gt;PDF Manual&lt;/a&gt;</source>
2346 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Kılavuz (PDF)&lt;/a&gt;</translation>
2347 </message>
2348 <message>
2349 <location line="+2"/>
2350 <source>&lt;a href=&apos;%1&apos;&gt;HTML Manual (opens in browser)&lt;/a&gt;</source>
2351 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Kılavuz (HTML) -- tarayıcıda açılır&lt;/a&gt;</translation>
2352 </message>
2353 <message>
2354 <location line="+4"/>
2355 <source>Select a device for a link to the correct manual</source>
2356 <translation type="unfinished">Uygun kılavuz için aygıt seçiniz</translation>
2357 </message>
2358 <message>
2359 <location line="+1"/>
2360 <source>&lt;a href=&apos;%1&apos;&gt;Manual Overview&lt;/a&gt;</source>
2361 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;Kılavuz Genel Açıklaması&lt;/a&gt;</translation>
2362 </message>
2363 <message>
2364 <location line="+11"/>
2365 <source>Confirm download</source>
2366 <translation type="unfinished">İndirme işlemini onayla</translation>
2367 </message>
2368 <message>
2369 <location line="+1"/>
2370 <source>Do you really want to download the manual? The manual will be saved to the root folder of your player.</source>
2371 <translation type="unfinished">Kılavuzu indirmek istiyor musunuz? Aygıtınızın bulunduğu konuma kaydedilecektir.</translation>
2372 </message>
2373</context>
2374<context>
2375 <name>ManualWidgetFrm</name>
2376 <message>
2377 <location filename="../gui/manualwidgetfrm.ui" line="+14"/>
2378 <source>Manual</source>
2379 <translation type="unfinished"></translation>
2380 </message>
2381 <message>
2382 <location line="+6"/>
2383 <source>Read the manual</source>
2384 <translation type="unfinished">Kılavuzu oku</translation>
2385 </message>
2386 <message>
2387 <location line="+6"/>
2388 <source>PDF manual</source>
2389 <translation type="unfinished">Kılavuz (PDF)</translation>
2390 </message>
2391 <message>
2392 <location line="+13"/>
2393 <source>HTML manual</source>
2394 <translation type="unfinished">Kılavuz (HTML)</translation>
2395 </message>
2396 <message>
2397 <location line="+16"/>
2398 <source>Download the manual</source>
2399 <translation type="unfinished">Kılavuzu indir</translation>
2400 </message>
2401 <message>
2402 <location line="+8"/>
2403 <source>&amp;PDF version</source>
2404 <translation type="unfinished">&amp;PDF formatı</translation>
2405 </message>
2406 <message>
2407 <location line="+7"/>
2408 <source>&amp;HTML version (zip file)</source>
2409 <translation type="unfinished">&amp;HTML formatı (zip dosyası)</translation>
2410 </message>
2411 <message>
2412 <location line="+22"/>
2413 <source>Down&amp;load</source>
2414 <translation type="unfinished">&amp;İndir</translation>
2415 </message>
2416</context>
2417<context>
2418 <name>MsPackUtil</name>
2419 <message>
2420 <location filename="../base/mspackutil.cpp" line="+101"/>
2421 <source>Creating output path failed</source>
2422 <translation type="unfinished"></translation>
2423 </message>
2424 <message>
2425 <location line="+8"/>
2426 <source>Error during CAB operation</source>
2427 <translation type="unfinished"></translation>
2428 </message>
2429</context>
2430<context>
2431 <name>PreviewFrm</name>
2432 <message>
2433 <location filename="../previewfrm.ui" line="+16"/>
2434 <source>Preview</source>
2435 <translation>Önizleme</translation>
2436 </message>
2437</context>
2438<context>
2439 <name>ProgressLoggerFrm</name>
2440 <message>
2441 <location filename="../progressloggerfrm.ui" line="+13"/>
2442 <location line="+6"/>
2443 <source>Progress</source>
2444 <translation type="unfinished">İlerleme</translation>
2445 </message>
2446 <message>
2447 <location line="+13"/>
2448 <source>progresswindow</source>
2449 <translation type="unfinished"></translation>
2450 </message>
2451 <message>
2452 <location line="+26"/>
2453 <source>Save Log</source>
2454 <translation type="unfinished"></translation>
2455 </message>
2456 <message>
2457 <location line="+24"/>
2458 <source>&amp;Abort</source>
2459 <translation type="unfinished">&amp;Durdur</translation>
2460 </message>
2461</context>
2462<context>
2463 <name>ProgressLoggerGui</name>
2464 <message>
2465 <location filename="../progressloggergui.cpp" line="+122"/>
2466 <source>&amp;Ok</source>
2467 <translation>&amp;Tamam</translation>
2468 </message>
2469 <message>
2470 <location line="+24"/>
2471 <source>Save system trace log</source>
2472 <translation type="unfinished"></translation>
2473 </message>
2474 <message>
2475 <location line="-42"/>
2476 <source>&amp;Abort</source>
2477 <translation>&amp;Durdur</translation>
2478 </message>
2479</context>
2480<context>
2481 <name>QObject</name>
2482 <message>
2483 <location filename="../base/bootloaderinstallhelper.cpp" line="+80"/>
2484 <source>Bootloader installation is almost complete. Installation &lt;b&gt;requires&lt;/b&gt; you to perform the following steps manually:</source>
2485 <translation type="unfinished"></translation>
2486 </message>
2487 <message>
2488 <location line="+6"/>
2489 <source>&lt;li&gt;Safely remove your player.&lt;/li&gt;</source>
2490 <translation type="unfinished"></translation>
2491 </message>
2492 <message>
2493 <location line="+5"/>
2494 <source>&lt;li&gt;Reboot your player into the original firmware.&lt;/li&gt;&lt;li&gt;Perform a firmware upgrade using the update functionality of the original firmware. Please refer to your player&apos;s manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before starting the firmware update process.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
2495 <translation type="unfinished"></translation>
2496 </message>
2497 <message>
2498 <location line="+11"/>
2499 <source>&lt;li&gt;Remove any previously inserted microSD card&lt;/li&gt;</source>
2500 <translation type="unfinished"></translation>
2501 </message>
2502 <message>
2503 <location line="+1"/>
2504 <source>&lt;li&gt;Disconnect your player. The player will reboot and perform an update of the original firmware. Please refer to your players manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before disconnecting the player.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
2505 <translation type="unfinished"></translation>
2506 </message>
2507 <message>
2508 <location line="+11"/>
2509 <source>&lt;li&gt;Turn the player off&lt;/li&gt;&lt;li&gt;Insert the charger&lt;/li&gt;</source>
2510 <translation type="unfinished"></translation>
2511 </message>
2512 <message>
2513 <location line="+5"/>
2514 <source>&lt;li&gt;Unplug USB and power adaptors&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to turn the player off&lt;/li&gt;&lt;li&gt;Toggle the battery switch on the player&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to boot into Rockbox&lt;/li&gt;</source>
2515 <translation type="unfinished"></translation>
2516 </message>
2517 <message>
2518 <location line="+6"/>
2519 <source>&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You can safely install other parts first, but the above steps are &lt;b&gt;required&lt;/b&gt; to finish the installation!&lt;/p&gt;</source>
2520 <translation type="unfinished"></translation>
2521 </message>
2522 <message>
2523 <location filename="../base/system.cpp" line="+385"/>
2524 <source>(unknown vendor name) </source>
2525 <translation type="unfinished"></translation>
2526 </message>
2527 <message>
2528 <location line="+18"/>
2529 <source>(unknown product name)</source>
2530 <translation type="unfinished"></translation>
2531 </message>
2532 <message>
2533 <location filename="../configure.cpp" line="+36"/>
2534 <location filename="../main.cpp" line="+83"/>
2535 <source>LTR</source>
2536 <extracomment>This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.
2537----------
2538This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.</extracomment>
2539 <translation type="unfinished"></translation>
2540 </message>
2541</context>
2542<context>
2543 <name>QuaZipFile</name>
2544 <message>
2545 <location filename="../quazip/quazipfile.cpp" line="+141"/>
2546 <source>ZIP/UNZIP API error %1</source>
2547 <translation type="unfinished"></translation>
2548 </message>
2549</context>
2550<context>
2551 <name>RbUtilQt</name>
2552 <message>
2553 <source>File</source>
2554 <translation type="obsolete">Dosya</translation>
2555 </message>
2556 <message>
2557 <source>Version</source>
2558 <translation type="obsolete">Sürüm</translation>
2559 </message>
2560 <message>
2561 <location filename="../rbutilqt.cpp" line="+337"/>
2562 <location line="+305"/>
2563 <source>Configuration error</source>
2564 <translation>Yapılandırma hatası</translation>
2565 </message>
2566 <message>
2567 <source>Your configuration is invalid. This is most likely due to a new installation of Rockbox Utility or a changed device path. The configuation dialog will now open to allow you correcting the problem.</source>
2568 <translation type="obsolete">Yapılandırmanız geçersiz. Bunun nedeni yeni bir Rockbox Aracı kullanmanız ya da aygıtınızın yolunu değiştirmeniz olabilir. Bu problemi düzeltmeniz için şimdi yapılandırma ekranı açılacaktır.</translation>
2569 </message>
2570 <message>
2571 <source>Network error: %1. Please check your network and proxy settings.</source>
2572 <translation type="obsolete">Ağ hatası: %1. Lütfen ağ ve vekil sunucu ayarlarınızı kontrol ediniz.</translation>
2573 </message>
2574 <message>
2575 <source>&lt;b&gt;%1 %2&lt;/b&gt; at &lt;b&gt;%3&lt;/b&gt;</source>
2576 <translation type="obsolete">&lt;b&gt;%1 %2&lt;/b&gt; Bağlantı Noktası: &lt;b&gt;%3&lt;/b&gt;</translation>
2577 </message>
2578 <message>
2579 <source>&lt;a href=&apos;%1&apos;&gt;PDF Manual&lt;/a&gt;</source>
2580 <translation type="obsolete">&lt;a href=&apos;%1&apos;&gt;Kılavuz (PDF)&lt;/a&gt;</translation>
2581 </message>
2582 <message>
2583 <source>&lt;a href=&apos;%1&apos;&gt;HTML Manual (opens in browser)&lt;/a&gt;</source>
2584 <translation type="obsolete">&lt;a href=&apos;%1&apos;&gt;Kılavuz (HTML) -- tarayıcıda açılır&lt;/a&gt;</translation>
2585 </message>
2586 <message>
2587 <source>Select a device for a link to the correct manual</source>
2588 <translation type="obsolete">Uygun kılavuz için aygıt seçiniz</translation>
2589 </message>
2590 <message>
2591 <source>&lt;a href=&apos;%1&apos;&gt;Manual Overview&lt;/a&gt;</source>
2592 <translation type="obsolete">&lt;a href=&apos;%1&apos;&gt;Kılavuz Genel Açıklaması&lt;/a&gt;</translation>
2593 </message>
2594 <message>
2595 <location line="-192"/>
2596 <source>Confirm Installation</source>
2597 <translation>Kurulumu onayla</translation>
2598 </message>
2599 <message>
2600 <source>Do you really want to make a complete Installation?</source>
2601 <translation type="obsolete">Tüm bileşenleri yüklemek istediğinize emin misiniz?</translation>
2602 </message>
2603 <message>
2604 <source>Do you really want to make a small Installation?</source>
2605 <translation type="obsolete">Mini kurulum yapmak istediğinize emin misiniz?</translation>
2606 </message>
2607 <message>
2608 <location line="+132"/>
2609 <source>Mount point is wrong!</source>
2610 <translation>Bağlama noktası hatalı!</translation>
2611 </message>
2612 <message>
2613 <source>Do you really want to install the Bootloader?</source>
2614 <translation type="obsolete">Önyükleyiciyi kurmak istediğinizden emin misiniz?</translation>
2615 </message>
2616 <message>
2617 <source>Could not get the bootloader info file!</source>
2618 <translation type="obsolete">Önyükleyici bilgi dosyası alınamadı!</translation>
2619 </message>
2620 <message>
2621 <source>Bootloader Installation</source>
2622 <translation type="obsolete">Önyükleyici Kurulumu</translation>
2623 </message>
2624 <message>
2625 <source>The bootloader is already installed and up to date.
2626Do want to replace the current bootloader?</source>
2627 <translation type="obsolete">Önyükleyici daha önce kurulmuş ve güncel.
2628Mevcut önyükleyiciyi değiştirmek istiyor musunuz?</translation>
2629 </message>
2630 <message>
2631 <source>Bootloader installation skipped!</source>
2632 <translation type="obsolete">Önyükleyici kurulumu atlandı!</translation>
2633 </message>
2634 <message>
2635 <source>Original Firmware Path is wrong!</source>
2636 <translation type="obsolete">Orijinal bellenim (firmware) konumu hatalı!</translation>
2637 </message>
2638 <message>
2639 <source>Original Firmware selection Canceled!</source>
2640 <translation type="obsolete">Orijinal bellenim (firmware) seçimi iptal edildi!</translation>
2641 </message>
2642 <message>
2643 <source>Do you really want to install the fonts package?</source>
2644 <translation type="obsolete">Yazı tipi paketini kurmak istediğinizden emin misiniz?</translation>
2645 </message>
2646 <message>
2647 <location line="-131"/>
2648 <source>Do you really want to install the voice file?</source>
2649 <translation>Seslendirme dosyasını yüklemek istediğinizden emin misiniz?</translation>
2650 </message>
2651 <message>
2652 <source>Error</source>
2653 <translation type="obsolete">Hata</translation>
2654 </message>
2655 <message>
2656 <source>Your device doesn&apos;t have a doom plugin. Aborting.</source>
2657 <translation type="obsolete">Aygıtınızda doom eklentisi bulunmamaktadır. İşlem durduruluyor.</translation>
2658 </message>
2659 <message>
2660 <source>Do you really want to install the game addon files?</source>
2661 <translation type="obsolete">Oyun eklenti dosyalarını yüklemek istediğinizden emin misiniz?</translation>
2662 </message>
2663 <message>
2664 <location line="+61"/>
2665 <source>Confirm Uninstallation</source>
2666 <translation>Kaldırma işlemini onayla</translation>
2667 </message>
2668 <message>
2669 <location line="+1"/>
2670 <source>Do you really want to uninstall the Bootloader?</source>
2671 <translation>Önyükleyiciyi kaldırmak istediğinizden emin misiniz?</translation>
2672 </message>
2673 <message>
2674 <source>Confirm download</source>
2675 <translation type="obsolete">İndirme işlemini onayla</translation>
2676 </message>
2677 <message>
2678 <source>Do you really want to download the manual? The manual will be saved to the root folder of your player.</source>
2679 <translation type="obsolete">Kılavuzu indirmek istiyor musunuz? Aygıtınızın bulunduğu konuma kaydedilecektir.</translation>
2680 </message>
2681 <message>
2682 <location line="-403"/>
2683 <source>Wine detected!</source>
2684 <translation type="unfinished"></translation>
2685 </message>
2686 <message>
2687 <location line="+1"/>
2688 <source>It seems you are trying to run this program under Wine. Please don&apos;t do this, running under Wine will fail. Use the native Linux binary instead.</source>
2689 <translation type="unfinished"></translation>
2690 </message>
2691 <message>
2692 <location line="+113"/>
2693 <source>Downloading build information, please wait ...</source>
2694 <translation type="unfinished"></translation>
2695 </message>
2696 <message>
2697 <location line="+11"/>
2698 <source>Can&apos;t get version information!</source>
2699 <translation type="unfinished"></translation>
2700 </message>
2701 <message>
2702 <location line="+1"/>
2703 <source>Network error</source>
2704 <translation type="unfinished"></translation>
2705 </message>
2706 <message>
2707 <location line="+1"/>
2708 <source>Can&apos;t get version information.
2709Network error: %1. Please check your network and proxy settings.</source>
2710 <translation type="unfinished"></translation>
2711 </message>
2712 <message>
2713 <location line="+12"/>
2714 <source>Download build information finished.</source>
2715 <translation type="unfinished"></translation>
2716 </message>
2717 <message>
2718 <location line="+80"/>
2719 <source>New installation</source>
2720 <translation type="unfinished"></translation>
2721 </message>
2722 <message>
2723 <location line="+1"/>
2724 <source>This is a new installation of Rockbox Utility, or a new version. The configuration dialog will now open to allow you to setup the program, or review your settings.</source>
2725 <translation type="unfinished"></translation>
2726 </message>
2727 <message>
2728 <location line="+8"/>
2729 <source>Your configuration is invalid. This is most likely due to a changed device path. The configuration dialog will now open to allow you to correct the problem.</source>
2730 <translation type="unfinished"></translation>
2731 </message>
2732 <message>
2733 <location line="+78"/>
2734 <source>Warning</source>
2735 <translation type="unfinished"></translation>
2736 </message>
2737 <message>
2738 <location line="+1"/>
2739 <source>The Application is still downloading Information about new Builds. Please try again shortly.</source>
2740 <translation type="unfinished"></translation>
2741 </message>
2742 <message>
2743 <location line="+13"/>
2744 <source>No Rockbox installation found</source>
2745 <translation type="unfinished"></translation>
2746 </message>
2747 <message>
2748 <location line="+1"/>
2749 <source>Could not determine the installed Rockbox version. Please install a Rockbox build before installing voice files.</source>
2750 <translation type="unfinished"></translation>
2751 </message>
2752 <message>
2753 <location line="+8"/>
2754 <source>No voice file available</source>
2755 <translation type="unfinished"></translation>
2756 </message>
2757 <message>
2758 <location line="+1"/>
2759 <source>The installed version of Rockbox is a development version. Pre-built voices are only available for release versions of Rockbox. Please generate a voice yourself using the &quot;Create voice file&quot; functionality.</source>
2760 <translation type="unfinished"></translation>
2761 </message>
2762 <message>
2763 <location line="+88"/>
2764 <source>No uninstall method for this target known.</source>
2765 <translation type="unfinished"></translation>
2766 </message>
2767 <message>
2768 <location line="+14"/>
2769 <source>Rockbox Utility can not uninstall the bootloader on this target. Try a normal firmware update to remove the booloader.</source>
2770 <translation type="unfinished"></translation>
2771 </message>
2772 <message>
2773 <location line="+187"/>
2774 <source>RockboxUtility Update available</source>
2775 <translation type="unfinished"></translation>
2776 </message>
2777 <message>
2778 <location line="+1"/>
2779 <source>&lt;b&gt;New RockboxUtility Version available.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Download it from here: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</source>
2780 <translation type="unfinished"></translation>
2781 </message>
2782 <message>
2783 <location line="-180"/>
2784 <source>No Rockbox bootloader found.</source>
2785 <translation type="unfinished"></translation>
2786 </message>
2787 <message>
2788 <location line="+18"/>
2789 <source>Confirm installation</source>
2790 <translation>Kurulumu onayla</translation>
2791 </message>
2792 <message>
2793 <location line="+1"/>
2794 <source>Do you really want to install Rockbox Utility to your player? After installation you can run it from the players hard drive.</source>
2795 <translation>Rockbox Aracını aygıtınıza kurmak istediğinizden emin misiniz? Kurulum sonrası aygıtınızın diskinden çalıştırabilirsiniz.</translation>
2796 </message>
2797 <message>
2798 <location line="+9"/>
2799 <source>Installing Rockbox Utility</source>
2800 <translation>Rockbox Aracı Kuruluyor</translation>
2801 </message>
2802 <message>
2803 <location line="+18"/>
2804 <source>Error installing Rockbox Utility</source>
2805 <translation>Rockbox Aracı kurulumunda hata</translation>
2806 </message>
2807 <message>
2808 <location line="+4"/>
2809 <source>Installing user configuration</source>
2810 <translation>Kullanıcı yapılandırması yükleniyor</translation>
2811 </message>
2812 <message>
2813 <location line="+4"/>
2814 <source>Error installing user configuration</source>
2815 <translation>Kullanıcı yapılandırması yükleme işleminde hata</translation>
2816 </message>
2817 <message>
2818 <location line="+4"/>
2819 <source>Successfully installed Rockbox Utility.</source>
2820 <translation>Rockbox Aracı başarıyla kuruldu.</translation>
2821 </message>
2822 <message>
2823 <location line="+35"/>
2824 <source>Your configuration is invalid. Please go to the configuration dialog and make sure the selected values are correct.</source>
2825 <translation>Yapılandırmanız geçersiz. Yapılandırma ekranına giderek seçilen değerlerin doğruluğundan emin olun.</translation>
2826 </message>
2827 <message>
2828 <location line="+21"/>
2829 <source>Checking for update ...</source>
2830 <translation type="unfinished"></translation>
2831 </message>
2832 <message>
2833 <location line="+69"/>
2834 <source>New version of Rockbox Utility available.</source>
2835 <translation type="unfinished"></translation>
2836 </message>
2837 <message>
2838 <location line="+3"/>
2839 <source>Rockbox Utility is up to date.</source>
2840 <translation type="unfinished"></translation>
2841 </message>
2842 <message>
2843 <location line="+23"/>
2844 <source>Device ejected</source>
2845 <translation type="unfinished"></translation>
2846 </message>
2847 <message>
2848 <location line="+1"/>
2849 <source>Device successfully ejected. You may now disconnect the player from the PC.</source>
2850 <translation type="unfinished"></translation>
2851 </message>
2852 <message>
2853 <location line="+4"/>
2854 <source>Ejecting failed</source>
2855 <translation type="unfinished"></translation>
2856 </message>
2857 <message>
2858 <location line="+1"/>
2859 <source>Ejecting the device failed. Please make sure no programs are accessing files on the device. If ejecting still fails please use your computers eject funtionality.</source>
2860 <translation type="unfinished"></translation>
2861 </message>
2862</context>
2863<context>
2864 <name>RbUtilQtFrm</name>
2865 <message>
2866 <location filename="../rbutilqtfrm.ui" line="+14"/>
2867 <source>Rockbox Utility</source>
2868 <translation>Rockbox Aracı</translation>
2869 </message>
2870 <message>
2871 <location line="+17"/>
2872 <source>Device</source>
2873 <translation>Aygıt</translation>
2874 </message>
2875 <message>
2876 <source>Selected device:</source>
2877 <translation type="obsolete">Seçili Aygıt:</translation>
2878 </message>
2879 <message>
2880 <source>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
2881p, li { white-space: pre-wrap; }
2882&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
2883&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;none&lt;/span&gt; at &lt;span style=&quot; font-weight:600;&quot;&gt;unknown&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2884 <translation type="obsolete">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
2885p, li { white-space: pre-wrap; }
2886&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
2887&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;bilinmeyen&lt;/span&gt; Bağlantı Noktası: &lt;span style=&quot; font-weight:600;&quot;&gt;bilinmeyen&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
2888 </message>
2889 <message>
2890 <location line="+61"/>
2891 <source>&amp;Change</source>
2892 <translation>&amp;Değiştir</translation>
2893 </message>
2894 <message>
2895 <source>&amp;Quick Start</source>
2896 <translation type="obsolete">&amp;Hızlı Başlangıç</translation>
2897 </message>
2898 <message>
2899 <location line="+71"/>
2900 <source>Welcome</source>
2901 <translation>Hoş Geldiniz</translation>
2902 </message>
2903 <message>
2904 <source>Complete Installation</source>
2905 <translation type="obsolete">Tam Kurulum</translation>
2906 </message>
2907 <message>
2908 <source>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
2909p, li { white-space: pre-wrap; }
2910&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
2911&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Complete Installation&lt;/span&gt;&lt;/p&gt;
2912&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;This installs the bootloader, a current build and the extras package. This is the recommended method for new installations.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2913 <translation type="obsolete">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
2914p, li { white-space: pre-wrap; }
2915&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
2916&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Tam Kurulum&lt;/span&gt;&lt;/p&gt;
2917&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Bu seçenek, önyükleyiciyi, mevcut inşayı ve ekstra paketleri kurar. Yeni kurulumlar için önerilen yöntemdir.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
2918 </message>
2919 <message>
2920 <source>Small Installation</source>
2921 <translation type="obsolete">Mini Kurulum</translation>
2922 </message>
2923 <message>
2924 <source>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
2925p, li { white-space: pre-wrap; }
2926&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
2927&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Small installation&lt;/span&gt;&lt;/p&gt;
2928&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;This installs bootloader and the current build of Rockbox. If you don&apos;t want the extras package, choose this option.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2929 <translation type="obsolete">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
2930p, li { white-space: pre-wrap; }
2931&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Mini Kurulum&lt;/span&gt;&lt;/p&gt;
2932&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Bu seçenek, önyükleyiciyi ve mevcut inşayı kurar. Ekstra paketleri kurmak istemiyorsanız bu yöntemi seçin.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
2933 </message>
2934 <message>
2935 <location line="-3"/>
2936 <location line="+498"/>
2937 <source>&amp;Installation</source>
2938 <translation>&amp;Kurulum</translation>
2939 </message>
2940 <message>
2941 <source>Basic Rockbox installation</source>
2942 <translation type="obsolete">Temel Rockbox kurulumu</translation>
2943 </message>
2944 <message>
2945 <source>Install Bootloader</source>
2946 <translation type="obsolete">Önyükleyiciyi Kur</translation>
2947 </message>
2948 <message>
2949 <source>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
2950p, li { white-space: pre-wrap; }
2951&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
2952&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Install the bootloader&lt;/span&gt;&lt;/p&gt;
2953&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Before Rockbox can be run on your audio player, you may have to install a bootloader. This is only necessary the first time Rockbox is installed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2954 <translation type="obsolete">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
2955p, li { white-space: pre-wrap; }
2956&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
2957&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Önyükleyiciyi Kur&lt;/span&gt;&lt;/p&gt;
2958&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Ses oynatıcınızda Rockbox&apos;ın çalışabilmesi için öncelikle önyükleyicinin kurulması gerekmektedır. Bu sadece Rockbox&apos;ın ilk kurulumunda gereklidir.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
2959 </message>
2960 <message>
2961 <source>Install Rockbox</source>
2962 <translation type="obsolete">Rockbox&apos;ı Kur</translation>
2963 </message>
2964 <message>
2965 <source>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
2966p, li { white-space: pre-wrap; }
2967&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;&quot;&gt;
2968&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Install Rockbox&lt;/span&gt; on your audio player&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2969 <translation type="obsolete">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
2970p, li { white-space: pre-wrap; }
2971&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;&quot;&gt;
2972&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Rockbox&apos;ı Kur&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
2973 </message>
2974 <message>
2975 <source>&amp;Extras</source>
2976 <translation type="obsolete">&amp;Ekstralar</translation>
2977 </message>
2978 <message>
2979 <source>Install extras for Rockbox</source>
2980 <translation type="obsolete">Rockbox için ekstraları kur</translation>
2981 </message>
2982 <message>
2983 <source>Install Fonts package</source>
2984 <translation type="obsolete">Yazı Tipi Paketini Kur</translation>
2985 </message>
2986 <message>
2987 <source>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
2988p, li { white-space: pre-wrap; }
2989&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
2990&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Fonts Package&lt;/span&gt;&lt;/p&gt;
2991&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The Fonts Package contains a couple of commonly used fonts. Installation is highly recommended.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2992 <translation type="obsolete">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
2993p, li { white-space: pre-wrap; }
2994&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
2995&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Yazı Tipi Paketi&lt;/span&gt;&lt;/p&gt;
2996&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Yazı tipi paketi sıkça kullanılan birçok yazı tipini barındırır. Bu paketi kurmanız şiddetle önerilir.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
2997 </message>
2998 <message>
2999 <source>Install themes</source>
3000 <translation type="obsolete">Temaları yükle</translation>
3001 </message>
3002 <message>
3003 <source>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
3004p, li { white-space: pre-wrap; }
3005&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
3006&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Install Themes&lt;/span&gt;&lt;/p&gt;
3007&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Rockbox&apos; look can be customized by themes. You can choose and install several officially distributed themes.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
3008 <translation type="obsolete">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
3009p, li { white-space: pre-wrap; }
3010&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
3011&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Temaları Kur&lt;/span&gt;&lt;/p&gt;
3012&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Rockbox&apos;ın görünümü temalarla kişiselleştirilebilir. Temaları seçip yükleyebilirsiniz.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
3013 </message>
3014 <message>
3015 <source>Install game files</source>
3016 <translation type="obsolete">Oyun Dosyalarını Yükle</translation>
3017 </message>
3018 <message>
3019 <source>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
3020p, li { white-space: pre-wrap; }
3021&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
3022&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Install Game Files&lt;/span&gt;&lt;/p&gt;
3023&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;&quot;&gt;&lt;span style=&quot; font-weight:400;&quot;&gt;Doom needs a base wad file to run.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
3024 <translation type="obsolete">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
3025p, li { white-space: pre-wrap; }
3026&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
3027&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Oyun Dosyalarını Yükle&lt;/span&gt;&lt;/p&gt;
3028&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;&quot;&gt;&lt;span style=&quot; font-weight:400;&quot;&gt;Doom temel bir wad dosyasına ihtiyaç duyar.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
3029 </message>
3030 <message>
3031 <location line="-490"/>
3032 <location line="+282"/>
3033 <source>&amp;Accessibility</source>
3034 <translation>&amp;Erişilebilirlik</translation>
3035 </message>
3036 <message>
3037 <location line="-279"/>
3038 <source>Install accessibility add-ons</source>
3039 <translation>Erişilebilirlik eklentilerini yükle</translation>
3040 </message>
3041 <message>
3042 <location line="+6"/>
3043 <source>Install Voice files</source>
3044 <translation>Seslendirme Dosyalarını Yükle</translation>
3045 </message>
3046 <message>
3047 <source>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
3048p, li { white-space: pre-wrap; }
3049&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
3050&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Install Voice file&lt;/span&gt;&lt;/p&gt;
3051&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so if you installed the voice file Rockbox will speak.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
3052 <translation type="obsolete">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
3053p, li { white-space: pre-wrap; }
3054&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
3055&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Seslendirme Dosyasını Yükle&lt;/span&gt;&lt;/p&gt;
3056&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Seslendirme dosyası kullanıcı arayüzünün seslendirilmesi için gereklidir. Seslendirme özelliği öntanımlı olarak açıktır, eğer seslendirme dosyasını yüklerseniz, Rockbox&apos;ınız konuşur.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
3057 </message>
3058 <message>
3059 <location line="+27"/>
3060 <source>Install Talk files</source>
3061 <translation>Konuşma Dosyalarını Yükle</translation>
3062 </message>
3063 <message>
3064 <source>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
3065p, li { white-space: pre-wrap; }
3066&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
3067&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Create Talk Files&lt;/span&gt;&lt;/p&gt;
3068&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;&quot;&gt;&lt;span style=&quot; font-weight:400;&quot;&gt;Talkfiles are needed to let Rockbox speak File and Foldernames&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
3069 <translation type="obsolete">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
3070p, li { white-space: pre-wrap; }
3071&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
3072&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Konuşma Dosyalarını Oluştur&lt;/span&gt;&lt;/p&gt;
3073&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;&quot;&gt;&lt;span style=&quot; font-weight:400;&quot;&gt;Konuşma dosyaları Rockbox&apos;ın dosya ve dizin isimlerini seslendirmesi için gereklidir.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
3074 </message>
3075 <message>
3076 <location line="+254"/>
3077 <source>&amp;Uninstallation</source>
3078 <translation>&amp;Kaldırma</translation>
3079 </message>
3080 <message>
3081 <location line="-172"/>
3082 <location line="+33"/>
3083 <source>Uninstall Rockbox</source>
3084 <translation>Rockbox&apos;ı Kaldır</translation>
3085 </message>
3086 <message>
3087 <location line="-254"/>
3088 <source>Device:</source>
3089 <translation type="unfinished"></translation>
3090 </message>
3091 <message>
3092 <location line="+7"/>
3093 <source>device unknown or invalid</source>
3094 <translation type="unfinished"></translation>
3095 </message>
3096 <message>
3097 <location line="+31"/>
3098 <source>&amp;Eject</source>
3099 <translation type="unfinished"></translation>
3100 </message>
3101 <message>
3102 <location line="+11"/>
3103 <source>Mountpoint:</source>
3104 <translation type="unfinished"></translation>
3105 </message>
3106 <message>
3107 <location line="+7"/>
3108 <source>mountpoint unknown or invalid</source>
3109 <translation type="unfinished"></translation>
3110 </message>
3111 <message>
3112 <location line="+73"/>
3113 <source>&lt;b&gt;Install Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so if you installed the voice file Rockbox will speak.</source>
3114 <translation type="unfinished"></translation>
3115 </message>
3116 <message>
3117 <location line="+27"/>
3118 <source>&lt;b&gt;Create Talk Files&lt;/b&gt;&lt;br/&gt;Talkfiles are needed to let Rockbox speak File and Foldernames</source>
3119 <translation type="unfinished"></translation>
3120 </message>
3121 <message>
3122 <location line="+33"/>
3123 <source>Create Voice files</source>
3124 <translation type="unfinished"></translation>
3125 </message>
3126 <message>
3127 <location line="+17"/>
3128 <source>&lt;b&gt;Create Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so
3129 if you installed the voice file Rockbox will speak.</source>
3130 <translation type="unfinished"></translation>
3131 </message>
3132 <message>
3133 <location line="+12"/>
3134 <source>Backup &amp;&amp; &amp;Uninstallation</source>
3135 <translation type="unfinished"></translation>
3136 </message>
3137 <message>
3138 <location line="+9"/>
3139 <source>Uninstall Bootloader</source>
3140 <translation>Önyükleyiciyi Kaldır</translation>
3141 </message>
3142 <message>
3143 <location line="+140"/>
3144 <source>&amp;Troubleshoot</source>
3145 <translation type="unfinished"></translation>
3146 </message>
3147 <message>
3148 <location line="+89"/>
3149 <source>&amp;Complete Installation</source>
3150 <translation type="unfinished"></translation>
3151 </message>
3152 <message>
3153 <location line="+9"/>
3154 <source>&amp;Minimal Installation</source>
3155 <translation type="unfinished"></translation>
3156 </message>
3157 <message>
3158 <location line="+9"/>
3159 <source>Install &amp;Bootloader</source>
3160 <translation type="unfinished"></translation>
3161 </message>
3162 <message>
3163 <location line="+9"/>
3164 <source>Install &amp;Rockbox</source>
3165 <translation type="unfinished"></translation>
3166 </message>
3167 <message>
3168 <location line="+9"/>
3169 <source>Install &amp;Fonts Package</source>
3170 <translation type="unfinished"></translation>
3171 </message>
3172 <message>
3173 <location line="+9"/>
3174 <source>Install &amp;Themes</source>
3175 <translation type="unfinished"></translation>
3176 </message>
3177 <message>
3178 <location line="+9"/>
3179 <source>Install &amp;Game Files</source>
3180 <translation type="unfinished"></translation>
3181 </message>
3182 <message>
3183 <location line="+9"/>
3184 <source>&amp;Install Voice File</source>
3185 <translation type="unfinished"></translation>
3186 </message>
3187 <message>
3188 <location line="+9"/>
3189 <source>Create &amp;Talk Files</source>
3190 <translation type="unfinished"></translation>
3191 </message>
3192 <message>
3193 <location line="+9"/>
3194 <source>Remove &amp;bootloader</source>
3195 <translation type="unfinished"></translation>
3196 </message>
3197 <message>
3198 <location line="+9"/>
3199 <source>Uninstall &amp;Rockbox</source>
3200 <translation type="unfinished"></translation>
3201 </message>
3202 <message>
3203 <location line="+29"/>
3204 <source>Create &amp;Voice File</source>
3205 <translation type="unfinished"></translation>
3206 </message>
3207 <message>
3208 <location line="+3"/>
3209 <source>Create Voice File</source>
3210 <translation type="unfinished"></translation>
3211 </message>
3212 <message>
3213 <location line="+5"/>
3214 <source>&amp;System Info</source>
3215 <translation type="unfinished"></translation>
3216 </message>
3217 <message>
3218 <location line="+5"/>
3219 <source>System &amp;Trace</source>
3220 <translation type="unfinished"></translation>
3221 </message>
3222 <message>
3223 <location line="+10"/>
3224 <source>Show &amp;Changelog</source>
3225 <translation type="unfinished"></translation>
3226 </message>
3227 <message>
3228 <source>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
3229p, li { white-space: pre-wrap; }
3230&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
3231&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Remove the bootloader&lt;/span&gt;&lt;/p&gt;
3232&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;After removing the bootloader you won&apos;t be able to start Rockbox.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
3233 <translation type="obsolete">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
3234p, li { white-space: pre-wrap; }
3235&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
3236&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Önyükleyiciyi Kaldır&lt;/span&gt;&lt;/p&gt;
3237&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Önyükleyiciyi kaldırdıktan sonra Rockbox&apos;ı başlatamazsınız.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
3238 </message>
3239 <message>
3240 <source>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
3241p, li { white-space: pre-wrap; }
3242&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
3243&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Uninstall Rockbox&lt;/span&gt; from your audio player.&lt;/p&gt;
3244&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;This will leave the bootloader in place (you need to remove it manually).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
3245 <translation type="obsolete">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
3246p, li { white-space: pre-wrap; }
3247&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
3248&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Rockbox&apos;ı Kaldır&lt;/span&gt;&lt;/p&gt;
3249&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Önyükleyiciniz kaldırılmayacaktır, isterseniz daha sonra kendiniz kaldırabilirsiniz.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
3250 </message>
3251 <message>
3252 <location line="-270"/>
3253 <source>&amp;Manual</source>
3254 <translation>&amp;Kılavuz</translation>
3255 </message>
3256 <message>
3257 <location line="+3"/>
3258 <source>View and download the manual</source>
3259 <translation>Kılavuzu göster ve indir</translation>
3260 </message>
3261 <message>
3262 <source>Read the manual</source>
3263 <translation type="obsolete">Kılavuzu oku</translation>
3264 </message>
3265 <message>
3266 <source>PDF manual</source>
3267 <translation type="obsolete">Kılavuz (PDF)</translation>
3268 </message>
3269 <message>
3270 <source>HTML manual</source>
3271 <translation type="obsolete">Kılavuz (HTML)</translation>
3272 </message>
3273 <message>
3274 <source>Download the manual</source>
3275 <translation type="obsolete">Kılavuzu indir</translation>
3276 </message>
3277 <message>
3278 <source>&amp;PDF version</source>
3279 <translation type="obsolete">&amp;PDF formatı</translation>
3280 </message>
3281 <message>
3282 <source>&amp;HTML version (zip file)</source>
3283 <translation type="obsolete">&amp;HTML formatı (zip dosyası)</translation>
3284 </message>
3285 <message>
3286 <source>Down&amp;load</source>
3287 <translation type="obsolete">&amp;İndir</translation>
3288 </message>
3289 <message>
3290 <location line="+5"/>
3291 <source>Inf&amp;o</source>
3292 <translation>&amp;Bilgi</translation>
3293 </message>
3294 <message>
3295 <source>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
3296p, li { white-space: pre-wrap; }
3297&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
3298&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Currently installed packages.&lt;/p&gt;
3299&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note&lt;/span&gt;: if you manually installed packages this might not be correct!&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
3300 <translation type="obsolete">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;p, li { white-space: pre-wrap; }&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Yüklenmiş paketler.&lt;/p&gt;&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Not&lt;/span&gt;: Paketleri kendiniz kurduysanız, bu bilgiler doğru olmayabilir!&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
3301 </message>
3302 <message>
3303 <source>1</source>
3304 <translation type="obsolete">1</translation>
3305 </message>
3306 <message>
3307 <location line="+18"/>
3308 <source>&amp;File</source>
3309 <translation>&amp;Dosya</translation>
3310 </message>
3311 <message>
3312 <location line="+78"/>
3313 <source>&amp;About</source>
3314 <translation>&amp;Hakkında</translation>
3315 </message>
3316 <message>
3317 <location line="-51"/>
3318 <source>Action&amp;s</source>
3319 <translation>İ&amp;şlemler</translation>
3320 </message>
3321 <message>
3322 <source>Installation</source>
3323 <translation type="obsolete">Kurulum</translation>
3324 </message>
3325 <message>
3326 <source>Quick Start</source>
3327 <translation type="obsolete">Hızlı Başlangıç</translation>
3328 </message>
3329 <message>
3330 <source>Extras</source>
3331 <translation type="obsolete">Ekstralar</translation>
3332 </message>
3333 <message>
3334 <source>Accessibility</source>
3335 <translation type="obsolete">Erişilebilirlik</translation>
3336 </message>
3337 <message>
3338 <source>Uninstallation</source>
3339 <translation type="obsolete">Kaldırma</translation>
3340 </message>
3341 <message>
3342 <location line="+28"/>
3343 <source>Empty local download cache</source>
3344 <translation>Yerel indirme önbelleği boş</translation>
3345 </message>
3346 <message>
3347 <location line="+5"/>
3348 <source>Install Rockbox Utility on player</source>
3349 <translation>Rockbox Aracını Kur</translation>
3350 </message>
3351 <message>
3352 <location line="+5"/>
3353 <source>&amp;Configure</source>
3354 <translation>&amp;Yapılandır</translation>
3355 </message>
3356 <message>
3357 <location line="+5"/>
3358 <source>E&amp;xit</source>
3359 <translation>&amp;Çıkış</translation>
3360 </message>
3361 <message>
3362 <location line="+3"/>
3363 <source>Ctrl+Q</source>
3364 <translation>Ctrl+Q</translation>
3365 </message>
3366 <message>
3367 <location line="+10"/>
3368 <source>About &amp;Qt</source>
3369 <translation>&amp;Qt Hakkında</translation>
3370 </message>
3371 <message>
3372 <location line="-74"/>
3373 <location line="+79"/>
3374 <source>&amp;Help</source>
3375 <translation>&amp;Yardım</translation>
3376 </message>
3377 <message>
3378 <location line="-198"/>
3379 <source>&lt;b&gt;Remove the bootloader&lt;/b&gt;&lt;br/&gt;After removing the bootloader you won&apos;t be able to start Rockbox.</source>
3380 <translation type="unfinished"></translation>
3381 </message>
3382 <message>
3383 <location line="+27"/>
3384 <source>&lt;b&gt;Uninstall Rockbox from your audio player.&lt;/b&gt;&lt;br/&gt;This will leave the bootloader in place (you need to remove it manually).</source>
3385 <translation type="unfinished"></translation>
3386 </message>
3387 <message>
3388 <location line="+13"/>
3389 <source>Backup</source>
3390 <translation type="unfinished"></translation>
3391 </message>
3392 <message>
3393 <location line="+17"/>
3394 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup current installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Create a backup by archiving the contents of the Rockbox installation folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
3395 <translation type="unfinished"></translation>
3396 </message>
3397 <message>
3398 <location line="+146"/>
3399 <source>Info</source>
3400 <translation>Bilgi</translation>
3401 </message>
3402 <message>
3403 <source>Fonts Package</source>
3404 <translation type="obsolete">Yazı Tipi Paketi</translation>
3405 </message>
3406 <message>
3407 <source>Install Themes</source>
3408 <translation type="obsolete">Temaları Yükle</translation>
3409 </message>
3410 <message>
3411 <source>Install Game Files</source>
3412 <translation type="obsolete">Oyun Dosyalarını Yükle</translation>
3413 </message>
3414 <message>
3415 <source>Install Voice File</source>
3416 <translation type="obsolete">Seslendirme Dosyasını Yükle</translation>
3417 </message>
3418 <message>
3419 <source>Create Talk Files</source>
3420 <translation type="obsolete">Konuşma Dosyaları Oluştur</translation>
3421 </message>
3422 <message>
3423 <source>Remove bootloader</source>
3424 <translation type="obsolete">Önyükleyiciyi Kaldır</translation>
3425 </message>
3426 <message>
3427 <location line="+104"/>
3428 <source>Read PDF manual</source>
3429 <translation> Kılavuzu (PDF) oku</translation>
3430 </message>
3431 <message>
3432 <location line="+5"/>
3433 <source>Read HTML manual</source>
3434 <translation>Kılavuzu (HTML) oku</translation>
3435 </message>
3436 <message>
3437 <location line="+5"/>
3438 <source>Download PDF manual</source>
3439 <translation>Kılavuzu (PDF) indir</translation>
3440 </message>
3441 <message>
3442 <location line="+5"/>
3443 <source>Download HTML manual (zip)</source>
3444 <translation>Kılavuzu (HTML zip) indir</translation>
3445 </message>
3446</context>
3447<context>
3448 <name>SelectiveInstallWidget</name>
3449 <message>
3450 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="+20"/>
3451 <source>Selective Installation</source>
3452 <translation type="unfinished"></translation>
3453 </message>
3454 <message>
3455 <location line="+6"/>
3456 <source>Rockbox version to install</source>
3457 <translation type="unfinished"></translation>
3458 </message>
3459 <message>
3460 <location line="+9"/>
3461 <source>Version information not available yet.</source>
3462 <translation type="unfinished"></translation>
3463 </message>
3464 <message>
3465 <location line="+19"/>
3466 <source>Rockbox components to install</source>
3467 <translation type="unfinished"></translation>
3468 </message>
3469 <message>
3470 <location line="+6"/>
3471 <source>&amp;Bootloader</source>
3472 <translation type="unfinished"></translation>
3473 </message>
3474 <message>
3475 <location line="+20"/>
3476 <source>The main Rockbox firmware.</source>
3477 <translation type="unfinished"></translation>
3478 </message>
3479 <message>
3480 <location line="+10"/>
3481 <source>Fonts</source>
3482 <translation type="unfinished"></translation>
3483 </message>
3484 <message>
3485 <location line="+14"/>
3486 <source>&amp;Rockbox</source>
3487 <translation type="unfinished"></translation>
3488 </message>
3489 <message>
3490 <location line="+20"/>
3491 <source>Some game plugins require additional files.</source>
3492 <translation type="unfinished"></translation>
3493 </message>
3494 <message>
3495 <location line="+16"/>
3496 <source>Additional fonts for the User Interface.</source>
3497 <translation type="unfinished"></translation>
3498 </message>
3499 <message>
3500 <location line="+16"/>
3501 <source>The bootloader is required for starting Rockbox. Only necessary for first time install.</source>
3502 <translation type="unfinished"></translation>
3503 </message>
3504 <message>
3505 <location line="+10"/>
3506 <source>Game Files</source>
3507 <translation type="unfinished"></translation>
3508 </message>
3509 <message>
3510 <location line="+11"/>
3511 <source>Customize</source>
3512 <translation type="unfinished"></translation>
3513 </message>
3514 <message>
3515 <location line="+11"/>
3516 <source>Themes</source>
3517 <translation type="unfinished"></translation>
3518 </message>
3519 <message>
3520 <location line="+17"/>
3521 <source>Themes allow adjusting the user interface of Rockbox. Use &quot;Customize&quot; to select themes.</source>
3522 <translation type="unfinished"></translation>
3523 </message>
3524 <message>
3525 <location line="+45"/>
3526 <source>&amp;Install</source>
3527 <translation type="unfinished">&amp;Yükle</translation>
3528 </message>
3529 <message>
3530 <location filename="../gui/selectiveinstallwidget.cpp" line="+67"/>
3531 <source>This is the latest stable release available.</source>
3532 <translation type="unfinished"></translation>
3533 </message>
3534 <message>
3535 <location line="+3"/>
3536 <source>The development version is updated on every code change. Last update was on %1</source>
3537 <translation type="unfinished"></translation>
3538 </message>
3539 <message>
3540 <location line="+4"/>
3541 <source>This will eventually become the next Rockbox version. Install it to help testing.</source>
3542 <translation type="unfinished"></translation>
3543 </message>
3544 <message>
3545 <location line="+26"/>
3546 <source>Stable Release (Version %1)</source>
3547 <translation type="unfinished"></translation>
3548 </message>
3549 <message>
3550 <location line="+4"/>
3551 <source>Development Version (Revison %1)</source>
3552 <translation type="unfinished"></translation>
3553 </message>
3554 <message>
3555 <location line="+4"/>
3556 <source>Release Candidate (Revison %1)</source>
3557 <translation type="unfinished"></translation>
3558 </message>
3559 <message>
3560 <location line="+23"/>
3561 <source>The selected player doesn&apos;t need a bootloader.</source>
3562 <translation type="unfinished"></translation>
3563 </message>
3564 <message>
3565 <location line="+5"/>
3566 <source>The bootloader is required for starting Rockbox. Installation of the bootloader is only necessary on first time installation.</source>
3567 <translation type="unfinished"></translation>
3568 </message>
3569 <message>
3570 <location line="+35"/>
3571 <source>Continue with installation?</source>
3572 <translation type="unfinished"></translation>
3573 </message>
3574 <message>
3575 <location line="+1"/>
3576 <source>Really continue?</source>
3577 <translation type="unfinished"></translation>
3578 </message>
3579 <message>
3580 <location line="+11"/>
3581 <source>Mountpoint is wrong</source>
3582 <translation type="unfinished"></translation>
3583 </message>
3584 <message>
3585 <location line="+56"/>
3586 <source>No install method known.</source>
3587 <translation type="unfinished"></translation>
3588 </message>
3589 <message>
3590 <location line="+27"/>
3591 <source>Bootloader detected</source>
3592 <translation type="unfinished"></translation>
3593 </message>
3594 <message>
3595 <location line="+1"/>
3596 <source>Bootloader already installed. Do you want to reinstall the bootloader?</source>
3597 <translation type="unfinished"></translation>
3598 </message>
3599 <message>
3600 <location line="+4"/>
3601 <source>Bootloader installation skipped</source>
3602 <translation type="unfinished"></translation>
3603 </message>
3604 <message>
3605 <location line="+13"/>
3606 <source>Create Bootloader backup</source>
3607 <translation type="unfinished"></translation>
3608 </message>
3609 <message>
3610 <location line="+1"/>
3611 <source>You can create a backup of the original bootloader file. Press &quot;Yes&quot; to select an output folder on your computer to save the file to. The file will get placed in a new folder &quot;%1&quot; created below the selected folder.
3612Press &quot;No&quot; to skip this step.</source>
3613 <translation type="unfinished"></translation>
3614 </message>
3615 <message>
3616 <location line="+7"/>
3617 <source>Browse backup folder</source>
3618 <translation type="unfinished"></translation>
3619 </message>
3620 <message>
3621 <location line="+12"/>
3622 <source>Prerequisites</source>
3623 <translation type="unfinished"></translation>
3624 </message>
3625 <message>
3626 <location line="+5"/>
3627 <source>Bootloader installation aborted</source>
3628 <translation type="unfinished"></translation>
3629 </message>
3630 <message>
3631 <location line="+10"/>
3632 <source>Bootloader files (%1)</source>
3633 <translation type="unfinished"></translation>
3634 </message>
3635 <message>
3636 <location line="+2"/>
3637 <source>All files (*)</source>
3638 <translation type="unfinished"></translation>
3639 </message>
3640 <message>
3641 <location line="+2"/>
3642 <source>Select firmware file</source>
3643 <translation type="unfinished"></translation>
3644 </message>
3645 <message>
3646 <location line="+2"/>
3647 <source>Error opening firmware file</source>
3648 <translation type="unfinished"></translation>
3649 </message>
3650 <message>
3651 <location line="+6"/>
3652 <source>Error reading firmware file</source>
3653 <translation type="unfinished"></translation>
3654 </message>
3655 <message>
3656 <location line="+10"/>
3657 <source>Backup error</source>
3658 <translation type="unfinished"></translation>
3659 </message>
3660 <message>
3661 <location line="+1"/>
3662 <source>Could not create backup file. Continue?</source>
3663 <translation type="unfinished"></translation>
3664 </message>
3665 <message>
3666 <location line="+24"/>
3667 <source>Manual steps required</source>
3668 <translation type="unfinished"></translation>
3669 </message>
3670 <message>
3671 <location line="+124"/>
3672 <source>Your installation doesn&apos;t require game files, skipping.</source>
3673 <translation type="unfinished"></translation>
3674 </message>
3675</context>
3676<context>
3677 <name>ServerInfo</name>
3678 <message>
3679 <location filename="../base/serverinfo.cpp" line="+117"/>
3680 <source>Unknown</source>
3681 <translation type="unfinished"></translation>
3682 </message>
3683 <message>
3684 <location line="+4"/>
3685 <source>Unusable</source>
3686 <translation type="unfinished"></translation>
3687 </message>
3688 <message>
3689 <location line="+3"/>
3690 <source>Unstable</source>
3691 <translation type="unfinished"></translation>
3692 </message>
3693 <message>
3694 <location line="+3"/>
3695 <source>Stable</source>
3696 <translation type="unfinished"></translation>
3697 </message>
3698</context>
3699<context>
3700 <name>SysTrace</name>
3701 <message>
3702 <location filename="../systrace.cpp" line="+98"/>
3703 <location line="+9"/>
3704 <source>Save system trace log</source>
3705 <translation type="unfinished"></translation>
3706 </message>
3707</context>
3708<context>
3709 <name>SysTraceFrm</name>
3710 <message>
3711 <location filename="../systracefrm.ui" line="+14"/>
3712 <source>System Trace</source>
3713 <translation type="unfinished"></translation>
3714 </message>
3715 <message>
3716 <location line="+6"/>
3717 <source>System State trace</source>
3718 <translation type="unfinished"></translation>
3719 </message>
3720 <message>
3721 <location line="+26"/>
3722 <source>&amp;Close</source>
3723 <translation type="unfinished"></translation>
3724 </message>
3725 <message>
3726 <location line="+11"/>
3727 <source>&amp;Save</source>
3728 <translation type="unfinished"></translation>
3729 </message>
3730 <message>
3731 <location line="+11"/>
3732 <source>&amp;Refresh</source>
3733 <translation type="unfinished"></translation>
3734 </message>
3735 <message>
3736 <location line="+11"/>
3737 <source>Save &amp;previous</source>
3738 <translation type="unfinished"></translation>
3739 </message>
3740</context>
3741<context>
3742 <name>Sysinfo</name>
3743 <message>
3744 <location filename="../sysinfo.cpp" line="+45"/>
3745 <source>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</source>
3746 <translation type="unfinished"></translation>
3747 </message>
3748 <message>
3749 <location line="+1"/>
3750 <source>&lt;b&gt;Username&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
3751 <translation type="unfinished"></translation>
3752 </message>
3753 <message>
3754 <location line="+2"/>
3755 <source>&lt;b&gt;Permissions&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
3756 <translation type="unfinished"></translation>
3757 </message>
3758 <message>
3759 <location line="+2"/>
3760 <source>&lt;b&gt;Attached USB devices&lt;/b&gt;&lt;br/&gt;</source>
3761 <translation type="unfinished"></translation>
3762 </message>
3763 <message>
3764 <location line="+4"/>
3765 <source>VID: %1 PID: %2, %3</source>
3766 <translation type="unfinished"></translation>
3767 </message>
3768 <message>
3769 <location line="+9"/>
3770 <source>Filesystem</source>
3771 <translation type="unfinished"></translation>
3772 </message>
3773 <message>
3774 <location line="+3"/>
3775 <source>Mountpoint</source>
3776 <translation type="unfinished"></translation>
3777 </message>
3778 <message>
3779 <location line="+0"/>
3780 <source>Label</source>
3781 <translation type="unfinished"></translation>
3782 </message>
3783 <message>
3784 <location line="+1"/>
3785 <source>Free</source>
3786 <translation type="unfinished"></translation>
3787 </message>
3788 <message>
3789 <location line="+0"/>
3790 <source>Total</source>
3791 <translation type="unfinished"></translation>
3792 </message>
3793 <message>
3794 <location line="+1"/>
3795 <source>Cluster Size</source>
3796 <translation type="unfinished"></translation>
3797 </message>
3798 <message>
3799 <location line="+2"/>
3800 <source>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</source>
3801 <translation type="unfinished"></translation>
3802 </message>
3803</context>
3804<context>
3805 <name>SysinfoFrm</name>
3806 <message>
3807 <location filename="../sysinfofrm.ui" line="+13"/>
3808 <source>System Info</source>
3809 <translation type="unfinished"></translation>
3810 </message>
3811 <message>
3812 <location line="+9"/>
3813 <source>&amp;Refresh</source>
3814 <translation type="unfinished"></translation>
3815 </message>
3816 <message>
3817 <location line="+23"/>
3818 <source>&amp;OK</source>
3819 <translation type="unfinished"></translation>
3820 </message>
3821</context>
3822<context>
3823 <name>System</name>
3824 <message>
3825 <location filename="../base/system.cpp" line="-282"/>
3826 <source>Guest</source>
3827 <translation type="unfinished"></translation>
3828 </message>
3829 <message>
3830 <location line="+3"/>
3831 <source>Admin</source>
3832 <translation type="unfinished"></translation>
3833 </message>
3834 <message>
3835 <location line="+3"/>
3836 <source>User</source>
3837 <translation type="unfinished"></translation>
3838 </message>
3839 <message>
3840 <location line="+3"/>
3841 <source>Error</source>
3842 <translation type="unfinished">Hata</translation>
3843 </message>
3844 <message>
3845 <location line="+148"/>
3846 <location line="+45"/>
3847 <source>(no description available)</source>
3848 <translation type="unfinished"></translation>
3849 </message>
3850</context>
3851<context>
3852 <name>TTSBase</name>
3853 <message>
3854 <location filename="../base/ttsbase.cpp" line="+45"/>
3855 <source>Espeak TTS Engine</source>
3856 <translation type="unfinished"></translation>
3857 </message>
3858 <message>
3859 <location line="+2"/>
3860 <source>Flite TTS Engine</source>
3861 <translation type="unfinished"></translation>
3862 </message>
3863 <message>
3864 <location line="+1"/>
3865 <source>Swift TTS Engine</source>
3866 <translation type="unfinished"></translation>
3867 </message>
3868 <message>
3869 <location line="+3"/>
3870 <source>SAPI4 TTS Engine</source>
3871 <translation type="unfinished"></translation>
3872 </message>
3873 <message>
3874 <location line="+2"/>
3875 <source>SAPI5 TTS Engine</source>
3876 <translation type="unfinished"></translation>
3877 </message>
3878 <message>
3879 <location line="+1"/>
3880 <source>MS Speech Platform</source>
3881 <translation type="unfinished"></translation>
3882 </message>
3883 <message>
3884 <location line="+3"/>
3885 <source>Festival TTS Engine</source>
3886 <translation type="unfinished"></translation>
3887 </message>
3888 <message>
3889 <location line="+3"/>
3890 <source>OS X System Engine</source>
3891 <translation type="unfinished"></translation>
3892 </message>
3893</context>
3894<context>
3895 <name>TTSCarbon</name>
3896 <message>
3897 <location filename="../base/ttscarbon.cpp" line="+139"/>
3898 <source>Voice:</source>
3899 <translation type="unfinished"></translation>
3900 </message>
3901 <message>
3902 <location line="+6"/>
3903 <source>Speed (words/min):</source>
3904 <translation type="unfinished"></translation>
3905 </message>
3906 <message>
3907 <location line="+7"/>
3908 <source>Pitch (0 for default):</source>
3909 <translation type="unfinished"></translation>
3910 </message>
3911 <message>
3912 <location line="+70"/>
3913 <source>Could not voice string</source>
3914 <translation type="unfinished"></translation>
3915 </message>
3916 <message>
3917 <location line="+10"/>
3918 <source>Could not convert intermediate file</source>
3919 <translation type="unfinished"></translation>
3920 </message>
3921</context>
3922<context>
3923 <name>TTSExes</name>
3924 <message>
3925 <location filename="../base/ttsexes.cpp" line="+44"/>
3926 <source>Path to TTS engine:</source>
3927 <translation type="unfinished"></translation>
3928 </message>
3929 <message>
3930 <location line="+2"/>
3931 <source>TTS engine options:</source>
3932 <translation type="unfinished"></translation>
3933 </message>
3934 <message>
3935 <location line="+32"/>
3936 <source>TTS executable not found</source>
3937 <translation type="unfinished"></translation>
3938 </message>
3939</context>
3940<context>
3941 <name>TTSFestival</name>
3942 <message>
3943 <location filename="../base/ttsfestival.cpp" line="+53"/>
3944 <source>Path to Festival client:</source>
3945 <translation type="unfinished"></translation>
3946 </message>
3947 <message>
3948 <location line="+5"/>
3949 <source>Voice:</source>
3950 <translation type="unfinished"></translation>
3951 </message>
3952 <message>
3953 <location line="+9"/>
3954 <source>Voice description:</source>
3955 <translation type="unfinished"></translation>
3956 </message>
3957 <message>
3958 <location line="+140"/>
3959 <source>engine could not voice string</source>
3960 <translation type="unfinished"></translation>
3961 </message>
3962 <message>
3963 <location line="+83"/>
3964 <source>No description available</source>
3965 <translation type="unfinished"></translation>
3966 </message>
3967</context>
3968<context>
3969 <name>TTSSapi</name>
3970 <message>
3971 <location filename="../base/ttssapi.cpp" line="+49"/>
3972 <source>Language:</source>
3973 <translation type="unfinished"></translation>
3974 </message>
3975 <message>
3976 <location line="+7"/>
3977 <source>Voice:</source>
3978 <translation type="unfinished"></translation>
3979 </message>
3980 <message>
3981 <location line="+12"/>
3982 <source>Speed:</source>
3983 <translation type="unfinished"></translation>
3984 </message>
3985 <message>
3986 <location line="+3"/>
3987 <source>Options:</source>
3988 <translation type="unfinished"></translation>
3989 </message>
3990 <message>
3991 <location line="+44"/>
3992 <source>Could not copy the SAPI script</source>
3993 <translation type="unfinished"></translation>
3994 </message>
3995 <message>
3996 <location line="+18"/>
3997 <source>Could not start SAPI process</source>
3998 <translation type="unfinished"></translation>
3999 </message>
4000</context>
4001<context>
4002 <name>TalkFileCreator</name>
4003 <message>
4004 <location filename="../base/talkfile.cpp" line="+36"/>
4005 <source>Starting Talk file generation for folder %1</source>
4006 <translation type="unfinished"></translation>
4007 </message>
4008 <message>
4009 <location line="+6"/>
4010 <source>Reading Filelist...</source>
4011 <translation type="unfinished"></translation>
4012 </message>
4013 <message>
4014 <location line="+3"/>
4015 <source>Talk file creation aborted</source>
4016 <translation type="unfinished"></translation>
4017 </message>
4018 <message>
4019 <location line="+23"/>
4020 <source>Copying Talkfiles...</source>
4021 <translation type="unfinished"></translation>
4022 </message>
4023 <message>
4024 <location line="+12"/>
4025 <source>Finished creating Talk files</source>
4026 <translation type="unfinished"></translation>
4027 </message>
4028 <message>
4029 <location line="+160"/>
4030 <source>File copy aborted</source>
4031 <translation type="unfinished"></translation>
4032 </message>
4033 <message>
4034 <location line="+19"/>
4035 <source>Copying of %1 to %2 failed</source>
4036 <translation type="unfinished"></translation>
4037 </message>
4038 <message>
4039 <location line="+21"/>
4040 <source>Cleaning up...</source>
4041 <translation type="unfinished"></translation>
4042 </message>
4043 <message>
4044 <location line="+11"/>
4045 <source>Finished</source>
4046 <translation type="unfinished"></translation>
4047 </message>
4048</context>
4049<context>
4050 <name>TalkGenerator</name>
4051 <message>
4052 <location filename="../base/talkgenerator.cpp" line="+39"/>
4053 <source>Starting TTS Engine</source>
4054 <translation type="unfinished"></translation>
4055 </message>
4056 <message>
4057 <location line="+5"/>
4058 <location line="+7"/>
4059 <source>Init of TTS engine failed</source>
4060 <translation type="unfinished"></translation>
4061 </message>
4062 <message>
4063 <location line="+7"/>
4064 <source>Starting Encoder Engine</source>
4065 <translation type="unfinished"></translation>
4066 </message>
4067 <message>
4068 <location line="+4"/>
4069 <source>Init of Encoder engine failed</source>
4070 <translation type="unfinished"></translation>
4071 </message>
4072 <message>
4073 <location line="+10"/>
4074 <source>Voicing entries...</source>
4075 <translation type="unfinished"></translation>
4076 </message>
4077 <message>
4078 <location line="+15"/>
4079 <source>Encoding files...</source>
4080 <translation type="unfinished"></translation>
4081 </message>
4082 <message>
4083 <location line="+39"/>
4084 <source>Voicing aborted</source>
4085 <translation type="unfinished"></translation>
4086 </message>
4087 <message>
4088 <location line="+36"/>
4089 <location line="+5"/>
4090 <source>Voicing of %1 failed: %2</source>
4091 <translation type="unfinished"></translation>
4092 </message>
4093 <message>
4094 <location line="+44"/>
4095 <source>Encoding aborted</source>
4096 <translation type="unfinished"></translation>
4097 </message>
4098 <message>
4099 <location line="+28"/>
4100 <source>Encoding of %1 failed</source>
4101 <translation type="unfinished"></translation>
4102 </message>
4103</context>
4104<context>
4105 <name>ThemeInstallFrm</name>
4106 <message>
4107 <location filename="../themesinstallfrm.ui" line="+13"/>
4108 <source>Theme Installation</source>
4109 <translation>Tema Kurulumu</translation>
4110 </message>
4111 <message>
4112 <location line="+35"/>
4113 <source>Selected Theme</source>
4114 <translation>Seçili Tema</translation>
4115 </message>
4116 <message>
4117 <location line="+25"/>
4118 <source>Description</source>
4119 <translation>Açıklama</translation>
4120 </message>
4121 <message>
4122 <location line="+10"/>
4123 <source>Download size:</source>
4124 <translation>İndirme boyutu:</translation>
4125 </message>
4126 <message>
4127 <location line="+10"/>
4128 <source>Hold Ctrl to select multiple item, Shift for a range</source>
4129 <translation type="unfinished"></translation>
4130 </message>
4131 <message>
4132 <location line="+22"/>
4133 <source>&amp;Install</source>
4134 <translation>&amp;Yükle</translation>
4135 </message>
4136 <message>
4137 <source>Install &amp;All</source>
4138 <translation type="obsolete">&amp;Hepsini Yükle</translation>
4139 </message>
4140 <message>
4141 <location line="+10"/>
4142 <source>&amp;Cancel</source>
4143 <translation>&amp;İptal</translation>
4144 </message>
4145</context>
4146<context>
4147 <name>ThemesInstallWindow</name>
4148 <message>
4149 <location filename="../themesinstallwindow.cpp" line="+40"/>
4150 <source>no theme selected</source>
4151 <translation>tema seçilmedi</translation>
4152 </message>
4153 <message>
4154 <location line="+1"/>
4155 <source>no selection</source>
4156 <translation type="unfinished"></translation>
4157 </message>
4158 <message>
4159 <location line="+84"/>
4160 <source>Network error: %1.
4161Please check your network and proxy settings.</source>
4162 <translation>Ağ hatası: %1.
4163Lütfen ağ ve vekil sunucu ayarlarınızı kontrol ediniz.</translation>
4164 </message>
4165 <message>
4166 <location line="+13"/>
4167 <source>the following error occured:
4168%1</source>
4169 <translation>oluşan hata:
4170%1</translation>
4171 </message>
4172 <message>
4173 <location line="+6"/>
4174 <source>done.</source>
4175 <translation>tamamlandı.</translation>
4176 </message>
4177 <message>
4178 <location line="+37"/>
4179 <source>Information</source>
4180 <translation type="unfinished"></translation>
4181 </message>
4182 <message numerus="yes">
4183 <location line="+17"/>
4184 <source>Download size %L1 kiB (%n item(s))</source>
4185 <translation type="unfinished">
4186 <numerusform></numerusform>
4187 </translation>
4188 </message>
4189 <message>
4190 <location line="+13"/>
4191 <source>fetching details for %1</source>
4192 <translation>%1 in bilgileri alınıyor</translation>
4193 </message>
4194 <message>
4195 <location line="+3"/>
4196 <source>fetching preview ...</source>
4197 <translation>önizleme getiriliyor ...</translation>
4198 </message>
4199 <message>
4200 <source>Download size %L1 kiB</source>
4201 <translation type="obsolete">İndirme boyutu %L1 KB</translation>
4202 </message>
4203 <message>
4204 <location line="+13"/>
4205 <source>&lt;b&gt;Author:&lt;/b&gt; %1&lt;hr/&gt;</source>
4206 <translation>&lt;b&gt;Sahibi:&lt;/b&gt; %1&lt;hr/&gt;</translation>
4207 </message>
4208 <message>
4209 <location line="+1"/>
4210 <location line="+2"/>
4211 <source>unknown</source>
4212 <translation>bilinmiyor</translation>
4213 </message>
4214 <message>
4215 <location line="-1"/>
4216 <source>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</source>
4217 <translation>&lt;b&gt;Sürüm:&lt;/b&gt; %1&lt;hr/&gt;</translation>
4218 </message>
4219 <message>
4220 <location line="+2"/>
4221 <source>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</source>
4222 <translation>&lt;b&gt;Açıklama:&lt;/b&gt; %1&lt;hr/&gt;</translation>
4223 </message>
4224 <message>
4225 <location line="+1"/>
4226 <source>no description</source>
4227 <translation>açıklama yok</translation>
4228 </message>
4229 <message>
4230 <location line="+16"/>
4231 <source>Retrieving theme preview failed.
4232HTTP response code: %1</source>
4233 <translation type="unfinished"></translation>
4234 </message>
4235 <message>
4236 <location line="+12"/>
4237 <source>no theme preview</source>
4238 <translation>tema önizlemesi yok</translation>
4239 </message>
4240 <message>
4241 <location line="+29"/>
4242 <source>Select</source>
4243 <translation type="unfinished"></translation>
4244 </message>
4245 <message>
4246 <location line="+7"/>
4247 <source>getting themes information ...</source>
4248 <translation>temaların bilgileri alınıyor ...</translation>
4249 </message>
4250 <message>
4251 <location line="+30"/>
4252 <source>No themes selected, skipping</source>
4253 <translation type="unfinished"></translation>
4254 </message>
4255 <message>
4256 <location line="+30"/>
4257 <source>Mount point is wrong!</source>
4258 <translation>Bağlama noktası hatalı!</translation>
4259 </message>
4260</context>
4261<context>
4262 <name>UnZip</name>
4263 <message>
4264 <source>ZIP operation completed successfully.</source>
4265 <translation type="obsolete">ZIP işlemi başarıyla tamamlandı.</translation>
4266 </message>
4267 <message>
4268 <source>Failed to initialize or load zlib library.</source>
4269 <translation type="obsolete">zlib kütüphanesi yüklenemedi.</translation>
4270 </message>
4271 <message>
4272 <source>zlib library error.</source>
4273 <translation type="obsolete">zlib kütüphane hatası.</translation>
4274 </message>
4275 <message>
4276 <source>Unable to create or open file.</source>
4277 <translation type="obsolete">Dosya oluşturulamadı veya açılamadı.</translation>
4278 </message>
4279 <message>
4280 <source>Partially corrupted archive. Some files might be extracted.</source>
4281 <translation type="obsolete">Kısmi bozuk arşiv. Bazı dosyalar açılmış olabilir.</translation>
4282 </message>
4283 <message>
4284 <source>Corrupted archive.</source>
4285 <translation type="obsolete">Bozuk arşiv.</translation>
4286 </message>
4287 <message>
4288 <source>Wrong password.</source>
4289 <translation type="obsolete">Yanlış parola.</translation>
4290 </message>
4291 <message>
4292 <source>No archive has been created yet.</source>
4293 <translation type="obsolete">Henüz herhangi bir arşiv dosyası oluşturulmadı.</translation>
4294 </message>
4295 <message>
4296 <source>File or directory does not exist.</source>
4297 <translation type="obsolete">Dosya veya dizin mevcut değil.</translation>
4298 </message>
4299 <message>
4300 <source>File read error.</source>
4301 <translation type="obsolete">Dosya okuma hatası.</translation>
4302 </message>
4303 <message>
4304 <source>File write error.</source>
4305 <translation type="obsolete">Dosyaya yazma hatası.</translation>
4306 </message>
4307 <message>
4308 <source>File seek error.</source>
4309 <translation type="obsolete">Dosya konumlandırma hatası.</translation>
4310 </message>
4311 <message>
4312 <source>Unable to create a directory.</source>
4313 <translation type="obsolete">Dizin oluşturulamadı.</translation>
4314 </message>
4315 <message>
4316 <source>Invalid device.</source>
4317 <translation type="obsolete">Geçersiz aygıt.</translation>
4318 </message>
4319 <message>
4320 <source>Invalid or incompatible zip archive.</source>
4321 <translation type="obsolete">Bozuk veya tamamlanmamış arşiv dosyası.</translation>
4322 </message>
4323 <message>
4324 <source>Inconsistent headers. Archive might be corrupted.</source>
4325 <translation type="obsolete">Tutarsız başlıklar. Arşiv bozulmuş olabilir.</translation>
4326 </message>
4327 <message>
4328 <source>Unknown error.</source>
4329 <translation type="obsolete">Bilinmeyen hata.</translation>
4330 </message>
4331</context>
4332<context>
4333 <name>UninstallFrm</name>
4334 <message>
4335 <location filename="../uninstallfrm.ui" line="+16"/>
4336 <source>Uninstall Rockbox</source>
4337 <translation>Rockbox&apos;ı Kaldır</translation>
4338 </message>
4339 <message>
4340 <source>Please select the Uninstallation Methodl</source>
4341 <translation type="obsolete">Lütfen kaldırma yöntemini seçiniz</translation>
4342 </message>
4343 <message>
4344 <location line="+19"/>
4345 <source>Please select the Uninstallation Method</source>
4346 <translation type="unfinished"></translation>
4347 </message>
4348 <message>
4349 <location line="+10"/>
4350 <source>Uninstallation Method</source>
4351 <translation>Kaldırma Yöntemi</translation>
4352 </message>
4353 <message>
4354 <location line="+6"/>
4355 <source>Complete Uninstallation</source>
4356 <translation>Tümünü Kaldır</translation>
4357 </message>
4358 <message>
4359 <location line="+7"/>
4360 <source>Smart Uninstallation</source>
4361 <translation>Özel </translation>
4362 </message>
4363 <message>
4364 <location line="+10"/>
4365 <source>Please select what you want to uninstall</source>
4366 <translation>Lütfen neyi kaldırmak istediğinizi seçiniz</translation>
4367 </message>
4368 <message>
4369 <location line="+10"/>
4370 <source>Installed Parts</source>
4371 <translation>Kurulmuş Bileşenler</translation>
4372 </message>
4373 <message>
4374 <location line="+50"/>
4375 <source>&amp;Uninstall</source>
4376 <translation>&amp;Kaldır</translation>
4377 </message>
4378 <message>
4379 <location line="+10"/>
4380 <source>&amp;Cancel</source>
4381 <translation>&amp;İptal</translation>
4382 </message>
4383</context>
4384<context>
4385 <name>Uninstaller</name>
4386 <message>
4387 <location filename="../base/uninstall.cpp" line="+32"/>
4388 <location line="+11"/>
4389 <source>Starting Uninstallation</source>
4390 <translation>Kaldırma İşlemi Başlatılıyor</translation>
4391 </message>
4392 <message>
4393 <location line="-7"/>
4394 <source>Finished Uninstallation</source>
4395 <translation>Kaldırma İşlemi Tamamlandı</translation>
4396 </message>
4397 <message>
4398 <location line="+13"/>
4399 <source>Uninstalling %1...</source>
4400 <translation type="unfinished"></translation>
4401 </message>
4402 <message>
4403 <location line="+31"/>
4404 <source>Could not delete %1</source>
4405 <translation type="unfinished"></translation>
4406 </message>
4407 <message>
4408 <source>Uninstalling </source>
4409 <translation type="obsolete">Kaldırılıyor </translation>
4410 </message>
4411 <message>
4412 <source>Could not delete: </source>
4413 <translation type="obsolete">Silinemedi: </translation>
4414 </message>
4415 <message>
4416 <location line="+29"/>
4417 <source>Uninstallation finished</source>
4418 <translation>Kaldırma işlemi tamamlandı</translation>
4419 </message>
4420</context>
4421<context>
4422 <name>Utils</name>
4423 <message>
4424 <location filename="../base/utils.cpp" line="+312"/>
4425 <source>&lt;li&gt;Permissions insufficient for bootloader installation.
4426Administrator priviledges are necessary.&lt;/li&gt;</source>
4427 <translation type="unfinished"></translation>
4428 </message>
4429 <message>
4430 <location line="+12"/>
4431 <source>&lt;li&gt;Target mismatch detected.&lt;br/&gt;Installed target: %1&lt;br/&gt;Selected target: %2.&lt;/li&gt;</source>
4432 <translation type="unfinished"></translation>
4433 </message>
4434 <message>
4435 <location line="+7"/>
4436 <source>Problem detected:</source>
4437 <translation type="unfinished"></translation>
4438 </message>
4439</context>
4440<context>
4441 <name>VoiceFileCreator</name>
4442 <message>
4443 <location filename="../base/voicefile.cpp" line="+43"/>
4444 <source>Starting Voicefile generation</source>
4445 <translation type="unfinished"></translation>
4446 </message>
4447 <message>
4448 <location line="+13"/>
4449 <source>could not find rockbox-info.txt</source>
4450 <translation type="unfinished"></translation>
4451 </message>
4452 <message>
4453 <location line="+34"/>
4454 <source>Extracted voice strings from installation</source>
4455 <translation type="unfinished"></translation>
4456 </message>
4457 <message>
4458 <location line="+10"/>
4459 <source>Extracted voice strings incompatible</source>
4460 <translation type="unfinished"></translation>
4461 </message>
4462 <message>
4463 <location line="+45"/>
4464 <source>Could not retrieve strings from installation, downloading</source>
4465 <translation type="unfinished"></translation>
4466 </message>
4467 <message>
4468 <location line="+26"/>
4469 <source>Downloading voice info...</source>
4470 <translation type="unfinished"></translation>
4471 </message>
4472 <message>
4473 <location line="+13"/>
4474 <source>Download error: received HTTP error %1.</source>
4475 <translation type="unfinished">İndirme hatası: HTTP %1 hatası.</translation>
4476 </message>
4477 <message>
4478 <location line="+7"/>
4479 <source>Cached file used.</source>
4480 <translation type="unfinished">Önbellekteki dosya kullanıldı.</translation>
4481 </message>
4482 <message>
4483 <location line="+3"/>
4484 <source>Download error: %1</source>
4485 <translation type="unfinished">İndirme hatası: %1</translation>
4486 </message>
4487 <message>
4488 <location line="+5"/>
4489 <source>Download finished.</source>
4490 <translation type="unfinished">İndirme işlemi tamamlandı.</translation>
4491 </message>
4492 <message>
4493 <location line="+13"/>
4494 <source>failed to open downloaded file</source>
4495 <translation type="unfinished"></translation>
4496 </message>
4497 <message>
4498 <location line="+6"/>
4499 <source>Reading strings...</source>
4500 <translation type="unfinished"></translation>
4501 </message>
4502 <message>
4503 <location line="+53"/>
4504 <source>The downloaded file was empty!</source>
4505 <translation type="unfinished"></translation>
4506 </message>
4507 <message>
4508 <location line="+26"/>
4509 <source>Creating voicefiles...</source>
4510 <translation type="unfinished"></translation>
4511 </message>
4512 <message>
4513 <location line="+5"/>
4514 <source>Error opening downloaded file</source>
4515 <translation type="unfinished"></translation>
4516 </message>
4517 <message>
4518 <location line="+11"/>
4519 <source>Error opening output file</source>
4520 <translation type="unfinished"></translation>
4521 </message>
4522 <message>
4523 <location line="+20"/>
4524 <source>successfully created.</source>
4525 <translation type="unfinished"></translation>
4526 </message>
4527 <message>
4528 <location line="+9"/>
4529 <source>Cleaning up...</source>
4530 <translation type="unfinished"></translation>
4531 </message>
4532 <message>
4533 <location line="+11"/>
4534 <source>Finished</source>
4535 <translation type="unfinished"></translation>
4536 </message>
4537</context>
4538<context>
4539 <name>Zip</name>
4540 <message>
4541 <source>ZIP operation completed successfully.</source>
4542 <translation type="obsolete">ZIP işlemi başarıyla tamamlandı.</translation>
4543 </message>
4544 <message>
4545 <source>Failed to initialize or load zlib library.</source>
4546 <translation type="obsolete">zlib kütüphanesi yüklenemedi.</translation>
4547 </message>
4548 <message>
4549 <source>zlib library error.</source>
4550 <translation type="obsolete">zlib kütüphane hatası.</translation>
4551 </message>
4552 <message>
4553 <source>Unable to create or open file.</source>
4554 <translation type="obsolete">Dosya oluşturulamadı veya açılamadı.</translation>
4555 </message>
4556 <message>
4557 <source>No archive has been created yet.</source>
4558 <translation type="obsolete">Henüz herhangi bir arşiv dosyası oluşturulmadı.</translation>
4559 </message>
4560 <message>
4561 <source>File or directory does not exist.</source>
4562 <translation type="obsolete">Dosya veya dizin mevcut değil.</translation>
4563 </message>
4564 <message>
4565 <source>File read error.</source>
4566 <translation type="obsolete">Dosya okuma hatası.</translation>
4567 </message>
4568 <message>
4569 <source>File write error.</source>
4570 <translation type="obsolete">Dosyaya yazma hatası.</translation>
4571 </message>
4572 <message>
4573 <source>File seek error.</source>
4574 <translation type="obsolete">Dosya konumlandırma hatası.</translation>
4575 </message>
4576 <message>
4577 <source>Unknown error.</source>
4578 <translation type="obsolete">Bilinmeyen hata.</translation>
4579 </message>
4580</context>
4581<context>
4582 <name>ZipInstaller</name>
4583 <message>
4584 <location filename="../base/zipinstaller.cpp" line="+60"/>
4585 <source>done.</source>
4586 <translation>tamamlandı.</translation>
4587 </message>
4588 <message>
4589 <source>Installation finished successfully.</source>
4590 <translation type="obsolete">Yükleme başarıyla tamamlandı.</translation>
4591 </message>
4592 <message>
4593 <location line="+8"/>
4594 <source>Package installation finished successfully.</source>
4595 <translation type="unfinished"></translation>
4596 </message>
4597 <message>
4598 <location line="+12"/>
4599 <source>Downloading file %1.%2</source>
4600 <translation>Dosya indiriliyor %1.%2</translation>
4601 </message>
4602 <message>
4603 <location line="+35"/>
4604 <source>Download error: received HTTP error %1.</source>
4605 <translation>İndirme hatası: HTTP %1 hatası.</translation>
4606 </message>
4607 <message>
4608 <location line="+6"/>
4609 <source>Cached file used.</source>
4610 <translation>Önbellekteki dosya kullanıldı.</translation>
4611 </message>
4612 <message>
4613 <location line="+2"/>
4614 <source>Download error: %1</source>
4615 <translation>İndirme hatası: %1</translation>
4616 </message>
4617 <message>
4618 <location line="+4"/>
4619 <source>Download finished.</source>
4620 <translation>İndirme işlemi tamamlandı.</translation>
4621 </message>
4622 <message>
4623 <location line="+6"/>
4624 <source>Extracting file.</source>
4625 <translation>Dosya çıkarılıyor.</translation>
4626 </message>
4627 <message>
4628 <location line="+13"/>
4629 <source>Not enough disk space! Aborting.</source>
4630 <translation type="unfinished"></translation>
4631 </message>
4632 <message>
4633 <location line="+7"/>
4634 <source>Extraction failed!</source>
4635 <translation type="unfinished"></translation>
4636 </message>
4637 <message>
4638 <source>Opening archive failed: %1.</source>
4639 <translation type="obsolete">Arşiv açılamadı: %1.</translation>
4640 </message>
4641 <message>
4642 <source>Extracting failed: %1.</source>
4643 <translation type="obsolete">Arşivden çıkarma işlemi başarısız: %1.</translation>
4644 </message>
4645 <message>
4646 <location line="+9"/>
4647 <source>Installing file.</source>
4648 <translation>Dosya yükleniyor.</translation>
4649 </message>
4650 <message>
4651 <location line="+11"/>
4652 <source>Installing file failed.</source>
4653 <translation>Dosya yükleme işlemi başarısız.</translation>
4654 </message>
4655 <message>
4656 <location line="+13"/>
4657 <source>Creating installation log</source>
4658 <translation>Kurulum kayıt dosyası yaratılıyor</translation>
4659 </message>
4660</context>
4661<context>
4662 <name>ZipUtil</name>
4663 <message>
4664 <location filename="../base/ziputil.cpp" line="+125"/>
4665 <source>Creating output path failed</source>
4666 <translation type="unfinished"></translation>
4667 </message>
4668 <message>
4669 <location line="+7"/>
4670 <source>Creating output file failed</source>
4671 <translation type="unfinished"></translation>
4672 </message>
4673 <message>
4674 <location line="+9"/>
4675 <source>Error during Zip operation</source>
4676 <translation type="unfinished"></translation>
4677 </message>
4678</context>
4679<context>
4680 <name>aboutBox</name>
4681 <message>
4682 <location filename="../aboutbox.ui" line="+14"/>
4683 <source>About Rockbox Utility</source>
4684 <translation>Rockbox Aracı Hakkında</translation>
4685 </message>
4686 <message>
4687 <location line="+18"/>
4688 <source>The Rockbox Utility</source>
4689 <translation>Rockbox Aracı</translation>
4690 </message>
4691 <message>
4692 <source>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.
4693
4694© 2005 - 2007 The Rockbox Team.
4695Released under the GNU General Public License v2.</source>
4696 <translation type="obsolete">Rockbox açık kaynak ses oynatıcısı bellenimi (firmware) yükleme aracı.
4697
4698© 2005 - 2007 Rockbox Takımı.
4699GNU Genel Kamu Lisansı v2 altında dağıtılmaktadır.</translation>
4700 </message>
4701 <message>
4702 <source>http://www.rockbox.org</source>
4703 <translation type="obsolete">http://www.rockbox.org</translation>
4704 </message>
4705 <message utf8="true">
4706 <location line="+22"/>
4707 <source>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</source>
4708 <translation type="unfinished"></translation>
4709 </message>
4710 <message>
4711 <location line="+20"/>
4712 <source>&amp;Credits</source>
4713 <translation>&amp;Hazırlayanlar</translation>
4714 </message>
4715 <message>
4716 <location line="+32"/>
4717 <source>&amp;License</source>
4718 <translation>&amp;Lisans</translation>
4719 </message>
4720 <message>
4721 <location line="+26"/>
4722 <source>&amp;Speex License</source>
4723 <translation type="unfinished"></translation>
4724 </message>
4725 <message>
4726 <location line="+26"/>
4727 <source>&amp;Ok</source>
4728 <translation>&amp;Tamam</translation>
4729 </message>
4730</context>
4731</TS>
diff --git a/utils/rbutilqt/lang/rbutil_zh_CN.ts b/utils/rbutilqt/lang/rbutil_zh_CN.ts
new file mode 100644
index 0000000000..06b562abe5
--- /dev/null
+++ b/utils/rbutilqt/lang/rbutil_zh_CN.ts
@@ -0,0 +1,3647 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE TS>
3<TS version="2.0">
4<context>
5 <name>BackupDialog</name>
6 <message>
7 <location filename="../gui/backupdialogfrm.ui" line="17"/>
8 <location filename="../gui/backupdialogfrm.ui" line="43"/>
9 <source>Backup</source>
10 <translation type="unfinished"></translation>
11 </message>
12 <message>
13 <location filename="../gui/backupdialogfrm.ui" line="33"/>
14 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This dialog will create a backup by archiving the contents of the Rockbox installation on the player into a zip file. This will include installed themes and settings stored below the .rockbox folder on the player.&lt;/p&gt;&lt;p&gt;The backup filename will be created based on the installed version. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
15 <translation type="unfinished"></translation>
16 </message>
17 <message>
18 <location filename="../gui/backupdialogfrm.ui" line="49"/>
19 <source>Size: unknown</source>
20 <translation type="unfinished"></translation>
21 </message>
22 <message>
23 <location filename="../gui/backupdialogfrm.ui" line="56"/>
24 <source>Backup to: unknown</source>
25 <translation type="unfinished"></translation>
26 </message>
27 <message>
28 <location filename="../gui/backupdialogfrm.ui" line="76"/>
29 <source>&amp;Change</source>
30 <translation type="unfinished">&amp;更改</translation>
31 </message>
32 <message>
33 <location filename="../gui/backupdialogfrm.ui" line="116"/>
34 <source>&amp;Backup</source>
35 <translation type="unfinished"></translation>
36 </message>
37 <message>
38 <location filename="../gui/backupdialogfrm.ui" line="127"/>
39 <source>&amp;Cancel</source>
40 <translation type="unfinished">&amp;取消</translation>
41 </message>
42 <message>
43 <location filename="../gui/backupdialog.cpp" line="70"/>
44 <source>Installation size: calculating ...</source>
45 <translation type="unfinished"></translation>
46 </message>
47 <message>
48 <location filename="../gui/backupdialog.cpp" line="89"/>
49 <source>Select Backup Filename</source>
50 <translation type="unfinished"></translation>
51 </message>
52 <message>
53 <location filename="../gui/backupdialog.cpp" line="109"/>
54 <source>Installation size: %L1 %2</source>
55 <translation type="unfinished"></translation>
56 </message>
57 <message>
58 <location filename="../gui/backupdialog.cpp" line="116"/>
59 <source>File exists</source>
60 <translation type="unfinished"></translation>
61 </message>
62 <message>
63 <location filename="../gui/backupdialog.cpp" line="117"/>
64 <source>The selected backup file already exists. Overwrite?</source>
65 <translation type="unfinished"></translation>
66 </message>
67 <message>
68 <location filename="../gui/backupdialog.cpp" line="125"/>
69 <source>Starting backup ...</source>
70 <translation type="unfinished"></translation>
71 </message>
72 <message>
73 <location filename="../gui/backupdialog.cpp" line="144"/>
74 <source>Backup successful.</source>
75 <translation type="unfinished"></translation>
76 </message>
77 <message>
78 <location filename="../gui/backupdialog.cpp" line="147"/>
79 <source>Backup failed!</source>
80 <translation type="unfinished"></translation>
81 </message>
82</context>
83<context>
84 <name>BootloaderInstallAms</name>
85 <message>
86 <location filename="../base/bootloaderinstallams.cpp" line="33"/>
87 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; This file is not present on your player and will disappear automatically after installing it.&lt;br/&gt;&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
88 <translation type="unfinished"></translation>
89 </message>
90 <message>
91 <location filename="../base/bootloaderinstallams.cpp" line="58"/>
92 <source>Downloading bootloader file</source>
93 <translation type="unfinished"></translation>
94 </message>
95 <message>
96 <location filename="../base/bootloaderinstallams.cpp" line="100"/>
97 <location filename="../base/bootloaderinstallams.cpp" line="113"/>
98 <source>Could not load %1</source>
99 <translation type="unfinished"></translation>
100 </message>
101 <message>
102 <location filename="../base/bootloaderinstallams.cpp" line="127"/>
103 <source>No room to insert bootloader, try another firmware version</source>
104 <translation type="unfinished"></translation>
105 </message>
106 <message>
107 <location filename="../base/bootloaderinstallams.cpp" line="137"/>
108 <source>Patching Firmware...</source>
109 <translation type="unfinished"></translation>
110 </message>
111 <message>
112 <location filename="../base/bootloaderinstallams.cpp" line="148"/>
113 <source>Could not open %1 for writing</source>
114 <translation type="unfinished"></translation>
115 </message>
116 <message>
117 <location filename="../base/bootloaderinstallams.cpp" line="161"/>
118 <source>Could not write firmware file</source>
119 <translation type="unfinished"></translation>
120 </message>
121 <message>
122 <location filename="../base/bootloaderinstallams.cpp" line="177"/>
123 <source>Success: modified firmware file created</source>
124 <translation type="unfinished"></translation>
125 </message>
126 <message>
127 <location filename="../base/bootloaderinstallams.cpp" line="185"/>
128 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
129 <translation type="unfinished"></translation>
130 </message>
131</context>
132<context>
133 <name>BootloaderInstallBase</name>
134 <message>
135 <location filename="../base/bootloaderinstallbase.cpp" line="78"/>
136 <source>Download error: received HTTP error %1.</source>
137 <translation type="unfinished">下载错误: 接到 HTTP 错误 %1. </translation>
138 </message>
139 <message>
140 <location filename="../base/bootloaderinstallbase.cpp" line="84"/>
141 <source>Download error: %1</source>
142 <translation type="unfinished">下载错误: %1</translation>
143 </message>
144 <message>
145 <location filename="../base/bootloaderinstallbase.cpp" line="90"/>
146 <source>Download finished (cache used).</source>
147 <translation type="unfinished"></translation>
148 </message>
149 <message>
150 <location filename="../base/bootloaderinstallbase.cpp" line="92"/>
151 <source>Download finished.</source>
152 <translation type="unfinished">完成下载.</translation>
153 </message>
154 <message>
155 <location filename="../base/bootloaderinstallbase.cpp" line="113"/>
156 <source>Creating backup of original firmware file.</source>
157 <translation type="unfinished"></translation>
158 </message>
159 <message>
160 <location filename="../base/bootloaderinstallbase.cpp" line="115"/>
161 <source>Creating backup folder failed</source>
162 <translation type="unfinished"></translation>
163 </message>
164 <message>
165 <location filename="../base/bootloaderinstallbase.cpp" line="121"/>
166 <source>Creating backup copy failed.</source>
167 <translation type="unfinished"></translation>
168 </message>
169 <message>
170 <location filename="../base/bootloaderinstallbase.cpp" line="124"/>
171 <source>Backup created.</source>
172 <translation type="unfinished"></translation>
173 </message>
174 <message>
175 <location filename="../base/bootloaderinstallbase.cpp" line="137"/>
176 <source>Creating installation log</source>
177 <translation type="unfinished">正在建立安装日志</translation>
178 </message>
179 <message>
180 <location filename="../base/bootloaderinstallbase.cpp" line="226"/>
181 <source>Zip file format detected</source>
182 <translation type="unfinished"></translation>
183 </message>
184 <message>
185 <location filename="../base/bootloaderinstallbase.cpp" line="238"/>
186 <source>CAB file format detected</source>
187 <translation type="unfinished"></translation>
188 </message>
189 <message>
190 <location filename="../base/bootloaderinstallbase.cpp" line="259"/>
191 <source>Extracting firmware %1 from archive</source>
192 <translation type="unfinished"></translation>
193 </message>
194 <message>
195 <location filename="../base/bootloaderinstallbase.cpp" line="266"/>
196 <source>Error extracting firmware from archive</source>
197 <translation type="unfinished"></translation>
198 </message>
199 <message>
200 <location filename="../base/bootloaderinstallbase.cpp" line="275"/>
201 <source>Could not find firmware in archive</source>
202 <translation type="unfinished"></translation>
203 </message>
204 <message>
205 <location filename="../base/bootloaderinstallbase.cpp" line="159"/>
206 <source>Waiting for system to remount player</source>
207 <translation type="unfinished"></translation>
208 </message>
209 <message>
210 <location filename="../base/bootloaderinstallbase.cpp" line="189"/>
211 <source>Player remounted</source>
212 <translation type="unfinished"></translation>
213 </message>
214 <message>
215 <location filename="../base/bootloaderinstallbase.cpp" line="194"/>
216 <source>Timeout on remount</source>
217 <translation type="unfinished"></translation>
218 </message>
219 <message>
220 <location filename="../base/bootloaderinstallbase.cpp" line="149"/>
221 <source>Installation log created</source>
222 <translation type="unfinished"></translation>
223 </message>
224</context>
225<context>
226 <name>BootloaderInstallChinaChip</name>
227 <message>
228 <location filename="../base/bootloaderinstallchinachip.cpp" line="33"/>
229 <source>Bootloader installation requires you to provide a firmware file of the original firmware (HXF file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
230 <translation type="unfinished"></translation>
231 </message>
232 <message>
233 <location filename="../base/bootloaderinstallchinachip.cpp" line="50"/>
234 <source>Downloading bootloader file</source>
235 <translation type="unfinished"></translation>
236 </message>
237 <message>
238 <location filename="../base/bootloaderinstallchinachip.cpp" line="75"/>
239 <source>Could not open firmware file</source>
240 <translation type="unfinished"></translation>
241 </message>
242 <message>
243 <location filename="../base/bootloaderinstallchinachip.cpp" line="78"/>
244 <source>Could not open bootloader file</source>
245 <translation type="unfinished"></translation>
246 </message>
247 <message>
248 <location filename="../base/bootloaderinstallchinachip.cpp" line="81"/>
249 <source>Could not allocate memory</source>
250 <translation type="unfinished"></translation>
251 </message>
252 <message>
253 <location filename="../base/bootloaderinstallchinachip.cpp" line="84"/>
254 <source>Could not load firmware file</source>
255 <translation type="unfinished"></translation>
256 </message>
257 <message>
258 <location filename="../base/bootloaderinstallchinachip.cpp" line="87"/>
259 <source>File is not a valid ChinaChip firmware</source>
260 <translation type="unfinished"></translation>
261 </message>
262 <message>
263 <location filename="../base/bootloaderinstallchinachip.cpp" line="90"/>
264 <source>Could not find ccpmp.bin in input file</source>
265 <translation type="unfinished"></translation>
266 </message>
267 <message>
268 <location filename="../base/bootloaderinstallchinachip.cpp" line="93"/>
269 <source>Could not open backup file for ccpmp.bin</source>
270 <translation type="unfinished"></translation>
271 </message>
272 <message>
273 <location filename="../base/bootloaderinstallchinachip.cpp" line="96"/>
274 <source>Could not write backup file for ccpmp.bin</source>
275 <translation type="unfinished"></translation>
276 </message>
277 <message>
278 <location filename="../base/bootloaderinstallchinachip.cpp" line="99"/>
279 <source>Could not load bootloader file</source>
280 <translation type="unfinished"></translation>
281 </message>
282 <message>
283 <location filename="../base/bootloaderinstallchinachip.cpp" line="102"/>
284 <source>Could not get current time</source>
285 <translation type="unfinished"></translation>
286 </message>
287 <message>
288 <location filename="../base/bootloaderinstallchinachip.cpp" line="105"/>
289 <source>Could not open output file</source>
290 <translation type="unfinished"></translation>
291 </message>
292 <message>
293 <location filename="../base/bootloaderinstallchinachip.cpp" line="108"/>
294 <source>Could not write output file</source>
295 <translation type="unfinished"></translation>
296 </message>
297 <message>
298 <location filename="../base/bootloaderinstallchinachip.cpp" line="111"/>
299 <source>Unexpected error from chinachippatcher</source>
300 <translation type="unfinished"></translation>
301 </message>
302</context>
303<context>
304 <name>BootloaderInstallFile</name>
305 <message>
306 <location filename="../base/bootloaderinstallfile.cpp" line="34"/>
307 <source>Downloading bootloader</source>
308 <translation type="unfinished"></translation>
309 </message>
310 <message>
311 <location filename="../base/bootloaderinstallfile.cpp" line="43"/>
312 <source>Installing Rockbox bootloader</source>
313 <translation type="unfinished"></translation>
314 </message>
315 <message>
316 <location filename="../base/bootloaderinstallfile.cpp" line="75"/>
317 <source>Error accessing output folder</source>
318 <translation type="unfinished"></translation>
319 </message>
320 <message>
321 <location filename="../base/bootloaderinstallfile.cpp" line="89"/>
322 <source>A firmware file is already present on player</source>
323 <translation type="unfinished"></translation>
324 </message>
325 <message>
326 <location filename="../base/bootloaderinstallfile.cpp" line="94"/>
327 <source>Bootloader successful installed</source>
328 <translation type="unfinished"></translation>
329 </message>
330 <message>
331 <location filename="../base/bootloaderinstallfile.cpp" line="97"/>
332 <source>Copying modified firmware file failed</source>
333 <translation type="unfinished"></translation>
334 </message>
335 <message>
336 <location filename="../base/bootloaderinstallfile.cpp" line="111"/>
337 <source>Removing Rockbox bootloader</source>
338 <translation type="unfinished"></translation>
339 </message>
340 <message>
341 <location filename="../base/bootloaderinstallfile.cpp" line="115"/>
342 <source>No original firmware file found.</source>
343 <translation type="unfinished"></translation>
344 </message>
345 <message>
346 <location filename="../base/bootloaderinstallfile.cpp" line="121"/>
347 <source>Can&apos;t remove Rockbox bootloader file.</source>
348 <translation type="unfinished"></translation>
349 </message>
350 <message>
351 <location filename="../base/bootloaderinstallfile.cpp" line="126"/>
352 <source>Can&apos;t restore bootloader file.</source>
353 <translation type="unfinished"></translation>
354 </message>
355 <message>
356 <location filename="../base/bootloaderinstallfile.cpp" line="130"/>
357 <source>Original bootloader restored successfully.</source>
358 <translation type="unfinished"></translation>
359 </message>
360</context>
361<context>
362 <name>BootloaderInstallHex</name>
363 <message>
364 <location filename="../base/bootloaderinstallhex.cpp" line="69"/>
365 <source>checking MD5 hash of input file ...</source>
366 <translation type="unfinished"></translation>
367 </message>
368 <message>
369 <location filename="../base/bootloaderinstallhex.cpp" line="80"/>
370 <source>Could not verify original firmware file</source>
371 <translation type="unfinished"></translation>
372 </message>
373 <message>
374 <location filename="../base/bootloaderinstallhex.cpp" line="95"/>
375 <source>Firmware file not recognized.</source>
376 <translation type="unfinished"></translation>
377 </message>
378 <message>
379 <location filename="../base/bootloaderinstallhex.cpp" line="99"/>
380 <source>MD5 hash ok</source>
381 <translation type="unfinished"></translation>
382 </message>
383 <message>
384 <location filename="../base/bootloaderinstallhex.cpp" line="106"/>
385 <source>Firmware file doesn&apos;t match selected player.</source>
386 <translation type="unfinished"></translation>
387 </message>
388 <message>
389 <location filename="../base/bootloaderinstallhex.cpp" line="111"/>
390 <source>Descrambling file</source>
391 <translation type="unfinished"></translation>
392 </message>
393 <message>
394 <location filename="../base/bootloaderinstallhex.cpp" line="119"/>
395 <source>Error in descramble: %1</source>
396 <translation type="unfinished"></translation>
397 </message>
398 <message>
399 <location filename="../base/bootloaderinstallhex.cpp" line="124"/>
400 <source>Downloading bootloader file</source>
401 <translation type="unfinished"></translation>
402 </message>
403 <message>
404 <location filename="../base/bootloaderinstallhex.cpp" line="134"/>
405 <source>Adding bootloader to firmware file</source>
406 <translation type="unfinished"></translation>
407 </message>
408 <message>
409 <location filename="../base/bootloaderinstallhex.cpp" line="172"/>
410 <source>could not open input file</source>
411 <translation type="unfinished"></translation>
412 </message>
413 <message>
414 <location filename="../base/bootloaderinstallhex.cpp" line="173"/>
415 <source>reading header failed</source>
416 <translation type="unfinished"></translation>
417 </message>
418 <message>
419 <location filename="../base/bootloaderinstallhex.cpp" line="174"/>
420 <source>reading firmware failed</source>
421 <translation type="unfinished"></translation>
422 </message>
423 <message>
424 <location filename="../base/bootloaderinstallhex.cpp" line="175"/>
425 <source>can&apos;t open bootloader file</source>
426 <translation type="unfinished"></translation>
427 </message>
428 <message>
429 <location filename="../base/bootloaderinstallhex.cpp" line="176"/>
430 <source>reading bootloader file failed</source>
431 <translation type="unfinished"></translation>
432 </message>
433 <message>
434 <location filename="../base/bootloaderinstallhex.cpp" line="177"/>
435 <source>can&apos;t open output file</source>
436 <translation type="unfinished"></translation>
437 </message>
438 <message>
439 <location filename="../base/bootloaderinstallhex.cpp" line="178"/>
440 <source>writing output file failed</source>
441 <translation type="unfinished"></translation>
442 </message>
443 <message>
444 <location filename="../base/bootloaderinstallhex.cpp" line="180"/>
445 <source>Error in patching: %1</source>
446 <translation type="unfinished"></translation>
447 </message>
448 <message>
449 <location filename="../base/bootloaderinstallhex.cpp" line="191"/>
450 <source>Error in scramble: %1</source>
451 <translation type="unfinished"></translation>
452 </message>
453 <message>
454 <location filename="../base/bootloaderinstallhex.cpp" line="206"/>
455 <source>Checking modified firmware file</source>
456 <translation type="unfinished"></translation>
457 </message>
458 <message>
459 <location filename="../base/bootloaderinstallhex.cpp" line="208"/>
460 <source>Error: modified file checksum wrong</source>
461 <translation type="unfinished"></translation>
462 </message>
463 <message>
464 <location filename="../base/bootloaderinstallhex.cpp" line="215"/>
465 <source>A firmware file is already present on player</source>
466 <translation type="unfinished"></translation>
467 </message>
468 <message>
469 <location filename="../base/bootloaderinstallhex.cpp" line="220"/>
470 <source>Success: modified firmware file created</source>
471 <translation type="unfinished"></translation>
472 </message>
473 <message>
474 <location filename="../base/bootloaderinstallhex.cpp" line="223"/>
475 <source>Copying modified firmware file failed</source>
476 <translation type="unfinished"></translation>
477 </message>
478 <message>
479 <location filename="../base/bootloaderinstallhex.cpp" line="237"/>
480 <source>Uninstallation not possible, only installation info removed</source>
481 <translation type="unfinished"></translation>
482 </message>
483 <message>
484 <location filename="../base/bootloaderinstallhex.cpp" line="258"/>
485 <source>Can&apos;t open input file</source>
486 <translation type="unfinished"></translation>
487 </message>
488 <message>
489 <location filename="../base/bootloaderinstallhex.cpp" line="259"/>
490 <source>Can&apos;t open output file</source>
491 <translation type="unfinished"></translation>
492 </message>
493 <message>
494 <location filename="../base/bootloaderinstallhex.cpp" line="260"/>
495 <source>invalid file: header length wrong</source>
496 <translation type="unfinished"></translation>
497 </message>
498 <message>
499 <location filename="../base/bootloaderinstallhex.cpp" line="261"/>
500 <source>invalid file: unrecognized header</source>
501 <translation type="unfinished"></translation>
502 </message>
503 <message>
504 <location filename="../base/bootloaderinstallhex.cpp" line="262"/>
505 <source>invalid file: &quot;length&quot; field wrong</source>
506 <translation type="unfinished"></translation>
507 </message>
508 <message>
509 <location filename="../base/bootloaderinstallhex.cpp" line="263"/>
510 <source>invalid file: &quot;length2&quot; field wrong</source>
511 <translation type="unfinished"></translation>
512 </message>
513 <message>
514 <location filename="../base/bootloaderinstallhex.cpp" line="264"/>
515 <source>invalid file: internal checksum error</source>
516 <translation type="unfinished"></translation>
517 </message>
518 <message>
519 <location filename="../base/bootloaderinstallhex.cpp" line="265"/>
520 <source>invalid file: &quot;length3&quot; field wrong</source>
521 <translation type="unfinished"></translation>
522 </message>
523 <message>
524 <location filename="../base/bootloaderinstallhex.cpp" line="266"/>
525 <source>unknown</source>
526 <translation type="unfinished">不明</translation>
527 </message>
528 <message>
529 <location filename="../base/bootloaderinstallhex.cpp" line="50"/>
530 <source>Bootloader installation requires you to provide a firmware file of the original firmware (hex file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
531 <translation type="unfinished"></translation>
532 </message>
533</context>
534<context>
535 <name>BootloaderInstallImx</name>
536 <message>
537 <location filename="../base/bootloaderinstallimx.cpp" line="72"/>
538 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (firmware.sb file). This file will be patched with the Rockbox bootloader and installed to your player. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
539 <translation type="unfinished"></translation>
540 </message>
541 <message>
542 <location filename="../base/bootloaderinstallimx.cpp" line="94"/>
543 <source>Could not read original firmware file</source>
544 <translation type="unfinished"></translation>
545 </message>
546 <message>
547 <location filename="../base/bootloaderinstallimx.cpp" line="100"/>
548 <source>Downloading bootloader file</source>
549 <translation type="unfinished"></translation>
550 </message>
551 <message>
552 <location filename="../base/bootloaderinstallimx.cpp" line="110"/>
553 <source>Patching file...</source>
554 <translation type="unfinished"></translation>
555 </message>
556 <message>
557 <location filename="../base/bootloaderinstallimx.cpp" line="137"/>
558 <source>Patching the original firmware failed</source>
559 <translation type="unfinished"></translation>
560 </message>
561 <message>
562 <location filename="../base/bootloaderinstallimx.cpp" line="143"/>
563 <source>Succesfully patched firmware file</source>
564 <translation type="unfinished"></translation>
565 </message>
566 <message>
567 <location filename="../base/bootloaderinstallimx.cpp" line="158"/>
568 <source>Bootloader successful installed</source>
569 <translation type="unfinished"></translation>
570 </message>
571 <message>
572 <location filename="../base/bootloaderinstallimx.cpp" line="164"/>
573 <source>Patched bootloader could not be installed</source>
574 <translation type="unfinished"></translation>
575 </message>
576 <message>
577 <location filename="../base/bootloaderinstallimx.cpp" line="175"/>
578 <source>To uninstall, perform a normal upgrade with an unmodified original firmware.</source>
579 <translation type="unfinished"></translation>
580 </message>
581</context>
582<context>
583 <name>BootloaderInstallIpod</name>
584 <message>
585 <location filename="../base/bootloaderinstallipod.cpp" line="49"/>
586 <source>Error: can&apos;t allocate buffer memory!</source>
587 <translation type="unfinished"></translation>
588 </message>
589 <message>
590 <location filename="../base/bootloaderinstallipod.cpp" line="80"/>
591 <source>Downloading bootloader file</source>
592 <translation type="unfinished"></translation>
593 </message>
594 <message>
595 <location filename="../base/bootloaderinstallipod.cpp" line="64"/>
596 <location filename="../base/bootloaderinstallipod.cpp" line="151"/>
597 <source>Failed to read firmware directory</source>
598 <translation type="unfinished">读不了固件文件夹</translation>
599 </message>
600 <message>
601 <location filename="../base/bootloaderinstallipod.cpp" line="69"/>
602 <location filename="../base/bootloaderinstallipod.cpp" line="156"/>
603 <source>Unknown version number in firmware (%1)</source>
604 <translation type="unfinished">固件版本不明 (%1)</translation>
605 </message>
606 <message>
607 <location filename="../base/bootloaderinstallipod.cpp" line="75"/>
608 <source>Warning: This is a MacPod, Rockbox only runs on WinPods.
609See http://www.rockbox.org/wiki/IpodConversionToFAT32</source>
610 <translation type="unfinished"></translation>
611 </message>
612 <message>
613 <location filename="../base/bootloaderinstallipod.cpp" line="94"/>
614 <location filename="../base/bootloaderinstallipod.cpp" line="163"/>
615 <source>Could not open Ipod in R/W mode</source>
616 <translation type="unfinished"></translation>
617 </message>
618 <message>
619 <location filename="../base/bootloaderinstallipod.cpp" line="104"/>
620 <source>Successfull added bootloader</source>
621 <translation type="unfinished"></translation>
622 </message>
623 <message>
624 <location filename="../base/bootloaderinstallipod.cpp" line="115"/>
625 <source>Failed to add bootloader</source>
626 <translation type="unfinished"></translation>
627 </message>
628 <message>
629 <location filename="../base/bootloaderinstallipod.cpp" line="127"/>
630 <source>Bootloader Installation complete.</source>
631 <translation type="unfinished"></translation>
632 </message>
633 <message>
634 <location filename="../base/bootloaderinstallipod.cpp" line="132"/>
635 <source>Writing log aborted</source>
636 <translation type="unfinished"></translation>
637 </message>
638 <message>
639 <location filename="../base/bootloaderinstallipod.cpp" line="169"/>
640 <source>No bootloader detected.</source>
641 <translation type="unfinished">找不到启动程序.</translation>
642 </message>
643 <message>
644 <location filename="../base/bootloaderinstallipod.cpp" line="175"/>
645 <source>Successfully removed bootloader</source>
646 <translation type="unfinished"></translation>
647 </message>
648 <message>
649 <location filename="../base/bootloaderinstallipod.cpp" line="182"/>
650 <source>Removing bootloader failed.</source>
651 <translation type="unfinished"></translation>
652 </message>
653 <message>
654 <location filename="../base/bootloaderinstallipod.cpp" line="228"/>
655 <source>Error: could not retrieve device name</source>
656 <translation type="unfinished"></translation>
657 </message>
658 <message>
659 <location filename="../base/bootloaderinstallipod.cpp" line="244"/>
660 <source>Error: no mountpoint specified!</source>
661 <translation type="unfinished"></translation>
662 </message>
663 <message>
664 <location filename="../base/bootloaderinstallipod.cpp" line="249"/>
665 <source>Could not open Ipod: permission denied</source>
666 <translation type="unfinished"></translation>
667 </message>
668 <message>
669 <location filename="../base/bootloaderinstallipod.cpp" line="253"/>
670 <source>Could not open Ipod</source>
671 <translation type="unfinished"></translation>
672 </message>
673 <message>
674 <location filename="../base/bootloaderinstallipod.cpp" line="264"/>
675 <source>No firmware partition on disk</source>
676 <translation type="unfinished"></translation>
677 </message>
678 <message>
679 <location filename="../base/bootloaderinstallipod.cpp" line="90"/>
680 <source>Installing Rockbox bootloader</source>
681 <translation type="unfinished"></translation>
682 </message>
683 <message>
684 <location filename="../base/bootloaderinstallipod.cpp" line="142"/>
685 <source>Uninstalling bootloader</source>
686 <translation type="unfinished"></translation>
687 </message>
688 <message>
689 <location filename="../base/bootloaderinstallipod.cpp" line="258"/>
690 <source>Error reading partition table - possibly not an Ipod</source>
691 <translation type="unfinished"></translation>
692 </message>
693</context>
694<context>
695 <name>BootloaderInstallMi4</name>
696 <message>
697 <location filename="../base/bootloaderinstallmi4.cpp" line="34"/>
698 <source>Downloading bootloader</source>
699 <translation type="unfinished"></translation>
700 </message>
701 <message>
702 <location filename="../base/bootloaderinstallmi4.cpp" line="43"/>
703 <source>Installing Rockbox bootloader</source>
704 <translation type="unfinished"></translation>
705 </message>
706 <message>
707 <location filename="../base/bootloaderinstallmi4.cpp" line="66"/>
708 <source>A firmware file is already present on player</source>
709 <translation type="unfinished"></translation>
710 </message>
711 <message>
712 <location filename="../base/bootloaderinstallmi4.cpp" line="71"/>
713 <location filename="../base/bootloaderinstallmi4.cpp" line="79"/>
714 <source>Bootloader successful installed</source>
715 <translation type="unfinished"></translation>
716 </message>
717 <message>
718 <location filename="../base/bootloaderinstallmi4.cpp" line="74"/>
719 <source>Copying modified firmware file failed</source>
720 <translation type="unfinished"></translation>
721 </message>
722 <message>
723 <location filename="../base/bootloaderinstallmi4.cpp" line="91"/>
724 <source>Checking for Rockbox bootloader</source>
725 <translation type="unfinished"></translation>
726 </message>
727 <message>
728 <location filename="../base/bootloaderinstallmi4.cpp" line="93"/>
729 <source>No Rockbox bootloader found</source>
730 <translation type="unfinished"></translation>
731 </message>
732 <message>
733 <location filename="../base/bootloaderinstallmi4.cpp" line="98"/>
734 <source>Checking for original firmware file</source>
735 <translation type="unfinished"></translation>
736 </message>
737 <message>
738 <location filename="../base/bootloaderinstallmi4.cpp" line="103"/>
739 <source>Error finding original firmware file</source>
740 <translation type="unfinished"></translation>
741 </message>
742 <message>
743 <location filename="../base/bootloaderinstallmi4.cpp" line="113"/>
744 <source>Rockbox bootloader successful removed</source>
745 <translation type="unfinished"></translation>
746 </message>
747</context>
748<context>
749 <name>BootloaderInstallMpio</name>
750 <message>
751 <location filename="../base/bootloaderinstallmpio.cpp" line="34"/>
752 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
753 <translation type="unfinished"></translation>
754 </message>
755 <message>
756 <location filename="../base/bootloaderinstallmpio.cpp" line="53"/>
757 <source>Downloading bootloader file</source>
758 <translation type="unfinished"></translation>
759 </message>
760 <message>
761 <location filename="../base/bootloaderinstallmpio.cpp" line="80"/>
762 <source>Could not open the original firmware.</source>
763 <translation type="unfinished"></translation>
764 </message>
765 <message>
766 <location filename="../base/bootloaderinstallmpio.cpp" line="83"/>
767 <source>Could not read the original firmware.</source>
768 <translation type="unfinished"></translation>
769 </message>
770 <message>
771 <location filename="../base/bootloaderinstallmpio.cpp" line="86"/>
772 <source>Loaded firmware file does not look like MPIO original firmware file.</source>
773 <translation type="unfinished"></translation>
774 </message>
775 <message>
776 <location filename="../base/bootloaderinstallmpio.cpp" line="101"/>
777 <source>Could not open output file.</source>
778 <translation type="unfinished"></translation>
779 </message>
780 <message>
781 <location filename="../base/bootloaderinstallmpio.cpp" line="104"/>
782 <source>Could not write output file.</source>
783 <translation type="unfinished"></translation>
784 </message>
785 <message>
786 <location filename="../base/bootloaderinstallmpio.cpp" line="107"/>
787 <source>Unknown error number: %1</source>
788 <translation type="unfinished"></translation>
789 </message>
790 <message>
791 <location filename="../base/bootloaderinstallmpio.cpp" line="89"/>
792 <source>Could not open downloaded bootloader.</source>
793 <translation type="unfinished"></translation>
794 </message>
795 <message>
796 <location filename="../base/bootloaderinstallmpio.cpp" line="92"/>
797 <source>Place for bootloader in OF file not empty.</source>
798 <translation type="unfinished"></translation>
799 </message>
800 <message>
801 <location filename="../base/bootloaderinstallmpio.cpp" line="95"/>
802 <source>Could not read the downloaded bootloader.</source>
803 <translation type="unfinished"></translation>
804 </message>
805 <message>
806 <location filename="../base/bootloaderinstallmpio.cpp" line="98"/>
807 <source>Bootloader checksum error.</source>
808 <translation type="unfinished"></translation>
809 </message>
810 <message>
811 <location filename="../base/bootloaderinstallmpio.cpp" line="112"/>
812 <source>Patching original firmware failed: %1</source>
813 <translation type="unfinished"></translation>
814 </message>
815 <message>
816 <location filename="../base/bootloaderinstallmpio.cpp" line="119"/>
817 <source>Success: modified firmware file created</source>
818 <translation type="unfinished"></translation>
819 </message>
820 <message>
821 <location filename="../base/bootloaderinstallmpio.cpp" line="127"/>
822 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
823 <translation type="unfinished"></translation>
824 </message>
825</context>
826<context>
827 <name>BootloaderInstallSansa</name>
828 <message>
829 <location filename="../base/bootloaderinstallsansa.cpp" line="50"/>
830 <source>Error: can&apos;t allocate buffer memory!</source>
831 <translation type="unfinished"></translation>
832 </message>
833 <message>
834 <location filename="../base/bootloaderinstallsansa.cpp" line="55"/>
835 <source>Searching for Sansa</source>
836 <translation type="unfinished"></translation>
837 </message>
838 <message>
839 <location filename="../base/bootloaderinstallsansa.cpp" line="59"/>
840 <source>Permission for disc access denied!
841This is required to install the bootloader</source>
842 <translation type="unfinished"></translation>
843 </message>
844 <message>
845 <location filename="../base/bootloaderinstallsansa.cpp" line="66"/>
846 <source>No Sansa detected!</source>
847 <translation type="unfinished"></translation>
848 </message>
849 <message>
850 <location filename="../base/bootloaderinstallsansa.cpp" line="79"/>
851 <source>Downloading bootloader file</source>
852 <translation type="unfinished"></translation>
853 </message>
854 <message>
855 <location filename="../base/bootloaderinstallsansa.cpp" line="71"/>
856 <location filename="../base/bootloaderinstallsansa.cpp" line="179"/>
857 <source>OLD ROCKBOX INSTALLATION DETECTED, ABORTING.
858You must reinstall the original Sansa firmware before running
859sansapatcher for the first time.
860See http://www.rockbox.org/wiki/SansaE200Install
861</source>
862 <translation type="unfinished"></translation>
863 </message>
864 <message>
865 <location filename="../base/bootloaderinstallsansa.cpp" line="102"/>
866 <location filename="../base/bootloaderinstallsansa.cpp" line="189"/>
867 <source>Could not open Sansa in R/W mode</source>
868 <translation type="unfinished"></translation>
869 </message>
870 <message>
871 <location filename="../base/bootloaderinstallsansa.cpp" line="129"/>
872 <source>Successfully installed bootloader</source>
873 <translation type="unfinished"></translation>
874 </message>
875 <message>
876 <location filename="../base/bootloaderinstallsansa.cpp" line="140"/>
877 <source>Failed to install bootloader</source>
878 <translation type="unfinished"></translation>
879 </message>
880 <message>
881 <location filename="../base/bootloaderinstallsansa.cpp" line="153"/>
882 <source>Bootloader Installation complete.</source>
883 <translation type="unfinished"></translation>
884 </message>
885 <message>
886 <location filename="../base/bootloaderinstallsansa.cpp" line="158"/>
887 <source>Writing log aborted</source>
888 <translation type="unfinished"></translation>
889 </message>
890 <message>
891 <location filename="../base/bootloaderinstallsansa.cpp" line="238"/>
892 <source>Error: could not retrieve device name</source>
893 <translation type="unfinished"></translation>
894 </message>
895 <message>
896 <location filename="../base/bootloaderinstallsansa.cpp" line="254"/>
897 <source>Can&apos;t find Sansa</source>
898 <translation type="unfinished"></translation>
899 </message>
900 <message>
901 <location filename="../base/bootloaderinstallsansa.cpp" line="259"/>
902 <source>Could not open Sansa</source>
903 <translation type="unfinished"></translation>
904 </message>
905 <message>
906 <location filename="../base/bootloaderinstallsansa.cpp" line="264"/>
907 <source>Could not read partition table</source>
908 <translation type="unfinished"></translation>
909 </message>
910 <message>
911 <location filename="../base/bootloaderinstallsansa.cpp" line="271"/>
912 <source>Disk is not a Sansa (Error %1), aborting.</source>
913 <translation type="unfinished"></translation>
914 </message>
915 <message>
916 <location filename="../base/bootloaderinstallsansa.cpp" line="195"/>
917 <source>Successfully removed bootloader</source>
918 <translation type="unfinished"></translation>
919 </message>
920 <message>
921 <location filename="../base/bootloaderinstallsansa.cpp" line="202"/>
922 <source>Removing bootloader failed.</source>
923 <translation type="unfinished"></translation>
924 </message>
925 <message>
926 <location filename="../base/bootloaderinstallsansa.cpp" line="94"/>
927 <source>Installing Rockbox bootloader</source>
928 <translation type="unfinished"></translation>
929 </message>
930 <message>
931 <location filename="../base/bootloaderinstallsansa.cpp" line="111"/>
932 <source>Checking downloaded bootloader</source>
933 <translation type="unfinished"></translation>
934 </message>
935 <message>
936 <location filename="../base/bootloaderinstallsansa.cpp" line="119"/>
937 <source>Bootloader mismatch! Aborting.</source>
938 <translation type="unfinished"></translation>
939 </message>
940 <message>
941 <location filename="../base/bootloaderinstallsansa.cpp" line="170"/>
942 <source>Uninstalling bootloader</source>
943 <translation type="unfinished"></translation>
944 </message>
945</context>
946<context>
947 <name>BootloaderInstallTcc</name>
948 <message>
949 <location filename="../base/bootloaderinstalltcc.cpp" line="33"/>
950 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wiki page on how to obtain the file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
951 <translation type="unfinished"></translation>
952 </message>
953 <message>
954 <location filename="../base/bootloaderinstalltcc.cpp" line="50"/>
955 <source>Downloading bootloader file</source>
956 <translation type="unfinished"></translation>
957 </message>
958 <message>
959 <location filename="../base/bootloaderinstalltcc.cpp" line="82"/>
960 <location filename="../base/bootloaderinstalltcc.cpp" line="99"/>
961 <source>Could not load %1</source>
962 <translation type="unfinished"></translation>
963 </message>
964 <message>
965 <location filename="../base/bootloaderinstalltcc.cpp" line="90"/>
966 <source>Unknown OF file used: %1</source>
967 <translation type="unfinished"></translation>
968 </message>
969 <message>
970 <location filename="../base/bootloaderinstalltcc.cpp" line="104"/>
971 <source>Patching Firmware...</source>
972 <translation type="unfinished"></translation>
973 </message>
974 <message>
975 <location filename="../base/bootloaderinstalltcc.cpp" line="111"/>
976 <source>Could not patch firmware</source>
977 <translation type="unfinished"></translation>
978 </message>
979 <message>
980 <location filename="../base/bootloaderinstalltcc.cpp" line="117"/>
981 <source>Could not open %1 for writing</source>
982 <translation type="unfinished"></translation>
983 </message>
984 <message>
985 <location filename="../base/bootloaderinstalltcc.cpp" line="126"/>
986 <source>Could not write firmware file</source>
987 <translation type="unfinished"></translation>
988 </message>
989 <message>
990 <location filename="../base/bootloaderinstalltcc.cpp" line="131"/>
991 <source>Success: modified firmware file created</source>
992 <translation type="unfinished"></translation>
993 </message>
994 <message>
995 <location filename="../base/bootloaderinstalltcc.cpp" line="151"/>
996 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
997 <translation type="unfinished"></translation>
998 </message>
999</context>
1000<context>
1001 <name>Changelog</name>
1002 <message>
1003 <location filename="../gui/changelogfrm.ui" line="17"/>
1004 <source>Changelog</source>
1005 <translation type="unfinished"></translation>
1006 </message>
1007 <message>
1008 <location filename="../gui/changelogfrm.ui" line="39"/>
1009 <source>Show on startup</source>
1010 <translation type="unfinished"></translation>
1011 </message>
1012 <message>
1013 <location filename="../gui/changelogfrm.ui" line="46"/>
1014 <source>&amp;Ok</source>
1015 <translation type="unfinished">&amp;OK</translation>
1016 </message>
1017</context>
1018<context>
1019 <name>Config</name>
1020 <message>
1021 <location filename="../configure.cpp" line="340"/>
1022 <source>Showing disabled targets</source>
1023 <translation type="unfinished"></translation>
1024 </message>
1025 <message>
1026 <location filename="../configure.cpp" line="341"/>
1027 <source>You just enabled showing targets that are marked disabled. Disabled targets are not recommended to end users. Please use this option only if you know what you are doing.</source>
1028 <translation type="unfinished"></translation>
1029 </message>
1030 <message>
1031 <location filename="../configure.cpp" line="529"/>
1032 <source>Proxy Detection</source>
1033 <translation type="unfinished"></translation>
1034 </message>
1035 <message>
1036 <location filename="../configure.cpp" line="530"/>
1037 <source>The System Proxy settings are invalid!
1038Rockbox Utility can&apos;t work with this proxy settings. Make sure the system proxy is set correctly. Note that &quot;proxy auto-config (PAC)&quot; scripts are not supported by Rockbox Utility. If your system uses this you need to use manual proxy settings.</source>
1039 <translation type="unfinished"></translation>
1040 </message>
1041 <message>
1042 <location filename="../configure.cpp" line="643"/>
1043 <source>Set Cache Path</source>
1044 <translation type="unfinished"></translation>
1045 </message>
1046 <message>
1047 <location filename="../configure.cpp" line="788"/>
1048 <source>%1 &quot;MacPod&quot; found!
1049Rockbox needs a FAT formatted Ipod (so-called &quot;WinPod&quot;) to run. </source>
1050 <translation type="unfinished"></translation>
1051 </message>
1052 <message>
1053 <location filename="../configure.cpp" line="780"/>
1054 <source>%1 in MTP mode found!
1055You need to change your player to MSC mode for installation. </source>
1056 <translation type="unfinished"></translation>
1057 </message>
1058 <message>
1059 <location filename="../configure.cpp" line="774"/>
1060 <source>Detected an unsupported player:
1061%1
1062Sorry, Rockbox doesn&apos;t run on your player.</source>
1063 <translation type="unfinished"></translation>
1064 </message>
1065 <message>
1066 <location filename="../configure.cpp" line="858"/>
1067 <source>Autodetection</source>
1068 <translation>自动识别</translation>
1069 </message>
1070 <message>
1071 <location filename="../configure.cpp" line="859"/>
1072 <source>Could not detect a Mountpoint.
1073Select your Mountpoint manually.</source>
1074 <translation>找不到 mountpoint
1075请手动选择你的 mountpoing.</translation>
1076 </message>
1077 <message>
1078 <location filename="../configure.cpp" line="764"/>
1079 <source>Could not detect a device.
1080Select your device and Mountpoint manually.</source>
1081 <translation>不能识别你的播放器
1082请手动选择.</translation>
1083 </message>
1084 <message>
1085 <location filename="../configure.cpp" line="448"/>
1086 <location filename="../configure.cpp" line="914"/>
1087 <source>TTS error</source>
1088 <translation type="unfinished"></translation>
1089 </message>
1090 <message>
1091 <location filename="../configure.cpp" line="449"/>
1092 <location filename="../configure.cpp" line="915"/>
1093 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1094 <translation type="unfinished"></translation>
1095 </message>
1096 <message>
1097 <location filename="../configure.cpp" line="665"/>
1098 <source>%1 (%2 GiB of %3 GiB free)</source>
1099 <translation type="unfinished"></translation>
1100 </message>
1101 <message>
1102 <location filename="../configure.cpp" line="739"/>
1103 <source>Multiple devices have been detected. Please disconnect all players but one and try again.</source>
1104 <translation type="unfinished"></translation>
1105 </message>
1106 <message>
1107 <location filename="../configure.cpp" line="742"/>
1108 <source>Detected devices:</source>
1109 <translation type="unfinished"></translation>
1110 </message>
1111 <message>
1112 <location filename="../configure.cpp" line="747"/>
1113 <source>(unknown)</source>
1114 <translation type="unfinished"></translation>
1115 </message>
1116 <message>
1117 <location filename="../configure.cpp" line="749"/>
1118 <source>%1 at %2</source>
1119 <translation type="unfinished"></translation>
1120 </message>
1121 <message>
1122 <location filename="../configure.cpp" line="755"/>
1123 <source>Note: detecting connected devices might be ambiguous. You might have less devices connected than listed. In this case it might not be possible to detect your player unambiguously.</source>
1124 <translation type="unfinished"></translation>
1125 </message>
1126 <message>
1127 <location filename="../configure.cpp" line="759"/>
1128 <location filename="../configure.cpp" line="763"/>
1129 <location filename="../configure.cpp" line="805"/>
1130 <source>Device Detection</source>
1131 <translation type="unfinished"></translation>
1132 </message>
1133 <message>
1134 <location filename="../configure.cpp" line="794"/>
1135 <source>The player contains an incompatible filesystem.
1136Make sure you selected the correct mountpoint and the player is set up to use a filesystem compatible with Rockbox.</source>
1137 <translation type="unfinished"></translation>
1138 </message>
1139 <message>
1140 <location filename="../configure.cpp" line="802"/>
1141 <source>An unknown error occured during player detection.</source>
1142 <translation type="unfinished"></translation>
1143 </message>
1144 <message>
1145 <location filename="../configure.cpp" line="869"/>
1146 <source>Really delete cache?</source>
1147 <translation>你肯定要删除缓冲吗?</translation>
1148 </message>
1149 <message>
1150 <location filename="../configure.cpp" line="870"/>
1151 <source>Do you really want to delete the cache? Make absolutely sure this setting is correct as it will remove &lt;b&gt;all&lt;/b&gt; files in this folder!</source>
1152 <translation>你真的肯定要删除缓冲吗? 请确认你的设定是正确的因为这会删除 &lt;b&gt;全部&lt;/b&gt; 的文件在此文件夹 !</translation>
1153 </message>
1154 <message>
1155 <location filename="../configure.cpp" line="878"/>
1156 <source>Path wrong!</source>
1157 <translation>路径错误!</translation>
1158 </message>
1159 <message>
1160 <location filename="../configure.cpp" line="879"/>
1161 <source>The cache path is invalid. Aborting.</source>
1162 <translation>缓冲路径错误. 正在取消.</translation>
1163 </message>
1164 <message>
1165 <location filename="../configure.cpp" line="921"/>
1166 <source>TTS configuration invalid</source>
1167 <translation type="unfinished"></translation>
1168 </message>
1169 <message>
1170 <location filename="../configure.cpp" line="922"/>
1171 <source>TTS configuration invalid.
1172 Please configure TTS engine.</source>
1173 <translation type="unfinished"></translation>
1174 </message>
1175 <message>
1176 <location filename="../configure.cpp" line="927"/>
1177 <source>Could not start TTS engine.</source>
1178 <translation type="unfinished"></translation>
1179 </message>
1180 <message>
1181 <location filename="../configure.cpp" line="928"/>
1182 <source>Could not start TTS engine.
1183</source>
1184 <translation type="unfinished"></translation>
1185 </message>
1186 <message>
1187 <location filename="../configure.cpp" line="929"/>
1188 <location filename="../configure.cpp" line="948"/>
1189 <source>
1190Please configure TTS engine.</source>
1191 <translation type="unfinished"></translation>
1192 </message>
1193 <message>
1194 <location filename="../configure.cpp" line="943"/>
1195 <source>Rockbox Utility Voice Test</source>
1196 <translation type="unfinished"></translation>
1197 </message>
1198 <message>
1199 <location filename="../configure.cpp" line="946"/>
1200 <source>Could not voice test string.</source>
1201 <translation type="unfinished"></translation>
1202 </message>
1203 <message>
1204 <location filename="../configure.cpp" line="947"/>
1205 <source>Could not voice test string.
1206</source>
1207 <translation type="unfinished"></translation>
1208 </message>
1209 <message>
1210 <location filename="../configure.cpp" line="322"/>
1211 <source>Current cache size is %L1 kiB.</source>
1212 <translation type="unfinished"></translation>
1213 </message>
1214 <message>
1215 <location filename="../configure.cpp" line="455"/>
1216 <location filename="../configure.cpp" line="485"/>
1217 <source>Configuration OK</source>
1218 <translation type="unfinished"></translation>
1219 </message>
1220 <message>
1221 <location filename="../configure.cpp" line="461"/>
1222 <location filename="../configure.cpp" line="490"/>
1223 <source>Configuration INVALID</source>
1224 <translation type="unfinished"></translation>
1225 </message>
1226 <message>
1227 <location filename="../configure.cpp" line="130"/>
1228 <source>The following errors occurred:</source>
1229 <translation type="unfinished"></translation>
1230 </message>
1231 <message>
1232 <location filename="../configure.cpp" line="175"/>
1233 <source>No mountpoint given</source>
1234 <translation type="unfinished"></translation>
1235 </message>
1236 <message>
1237 <location filename="../configure.cpp" line="179"/>
1238 <source>Mountpoint does not exist</source>
1239 <translation type="unfinished"></translation>
1240 </message>
1241 <message>
1242 <location filename="../configure.cpp" line="183"/>
1243 <source>Mountpoint is not a directory.</source>
1244 <translation type="unfinished"></translation>
1245 </message>
1246 <message>
1247 <location filename="../configure.cpp" line="187"/>
1248 <source>Mountpoint is not writeable</source>
1249 <translation type="unfinished"></translation>
1250 </message>
1251 <message>
1252 <location filename="../configure.cpp" line="202"/>
1253 <source>No player selected</source>
1254 <translation type="unfinished"></translation>
1255 </message>
1256 <message>
1257 <location filename="../configure.cpp" line="209"/>
1258 <source>Cache path not writeable. Leave path empty to default to systems temporary path.</source>
1259 <translation type="unfinished"></translation>
1260 </message>
1261 <message>
1262 <location filename="../configure.cpp" line="228"/>
1263 <source>You need to fix the above errors before you can continue.</source>
1264 <translation type="unfinished"></translation>
1265 </message>
1266 <message>
1267 <location filename="../configure.cpp" line="231"/>
1268 <source>Configuration error</source>
1269 <translation type="unfinished"></translation>
1270 </message>
1271</context>
1272<context>
1273 <name>ConfigForm</name>
1274 <message>
1275 <location filename="../configurefrm.ui" line="14"/>
1276 <source>Configuration</source>
1277 <translation>设置</translation>
1278 </message>
1279 <message>
1280 <location filename="../configurefrm.ui" line="20"/>
1281 <source>Configure Rockbox Utility</source>
1282 <translation>设置 Rockbox 安装程序</translation>
1283 </message>
1284 <message>
1285 <location filename="../configurefrm.ui" line="35"/>
1286 <source>&amp;Device</source>
1287 <translation>&amp;播放器</translation>
1288 </message>
1289 <message>
1290 <location filename="../configurefrm.ui" line="41"/>
1291 <source>Select your device in the &amp;filesystem</source>
1292 <translation>请选择你的播放器在你的 &amp;文件系统</translation>
1293 </message>
1294 <message>
1295 <location filename="../configurefrm.ui" line="319"/>
1296 <source>&amp;Browse</source>
1297 <translation>&amp;浏览</translation>
1298 </message>
1299 <message>
1300 <location filename="../configurefrm.ui" line="72"/>
1301 <source>&amp;Select your audio player</source>
1302 <translation>&amp;选择你的音乐播放器</translation>
1303 </message>
1304 <message>
1305 <location filename="../configurefrm.ui" line="58"/>
1306 <source>&amp;Refresh</source>
1307 <translation type="unfinished"></translation>
1308 </message>
1309 <message>
1310 <location filename="../configurefrm.ui" line="114"/>
1311 <source>&amp;Autodetect</source>
1312 <translation>自动识别(&amp;A)</translation>
1313 </message>
1314 <message>
1315 <location filename="../configurefrm.ui" line="136"/>
1316 <source>&amp;Proxy</source>
1317 <translation>网络代理服务(&amp;P)</translation>
1318 </message>
1319 <message>
1320 <location filename="../configurefrm.ui" line="142"/>
1321 <source>&amp;No Proxy</source>
1322 <translation>没有网络代理服务(&amp;N)</translation>
1323 </message>
1324 <message>
1325 <location filename="../configurefrm.ui" line="152"/>
1326 <source>Use S&amp;ystem values</source>
1327 <translation>使用系统值(&amp;S)</translation>
1328 </message>
1329 <message>
1330 <location filename="../configurefrm.ui" line="159"/>
1331 <source>&amp;Manual Proxy settings</source>
1332 <translation>手动设置代理服务(&amp;M)</translation>
1333 </message>
1334 <message>
1335 <location filename="../configurefrm.ui" line="166"/>
1336 <source>Proxy Values</source>
1337 <translation>代理服务值</translation>
1338 </message>
1339 <message>
1340 <location filename="../configurefrm.ui" line="172"/>
1341 <source>&amp;Host:</source>
1342 <translation>&amp;主机:</translation>
1343 </message>
1344 <message>
1345 <location filename="../configurefrm.ui" line="182"/>
1346 <source>&amp;Port:</source>
1347 <translation>&amp;接口:</translation>
1348 </message>
1349 <message>
1350 <location filename="../configurefrm.ui" line="199"/>
1351 <source>&amp;Username</source>
1352 <translation>&amp;用户名</translation>
1353 </message>
1354 <message>
1355 <location filename="../configurefrm.ui" line="209"/>
1356 <source>Pass&amp;word</source>
1357 <translation>&amp;密码</translation>
1358 </message>
1359 <message>
1360 <location filename="../configurefrm.ui" line="219"/>
1361 <source>Show</source>
1362 <translation type="unfinished"></translation>
1363 </message>
1364 <message>
1365 <location filename="../configurefrm.ui" line="260"/>
1366 <source>&amp;Language</source>
1367 <translation>&amp;语言</translation>
1368 </message>
1369 <message>
1370 <location filename="../configurefrm.ui" line="274"/>
1371 <source>Cac&amp;he</source>
1372 <translation>&amp;缓冲</translation>
1373 </message>
1374 <message>
1375 <location filename="../configurefrm.ui" line="277"/>
1376 <source>Download cache settings</source>
1377 <translation>下载缓冲设置</translation>
1378 </message>
1379 <message>
1380 <location filename="../configurefrm.ui" line="283"/>
1381 <source>Rockbox Utility uses a local download cache to save network traffic. You can change the path to the cache and use it as local repository by enabling Offline mode.</source>
1382 <translation>Rockbox 安装程序使用本机缓冲来保存网络资料. 你可以改变这个缓冲的路径. 启动下线模式后, 你还可以用路径来保存文件.</translation>
1383 </message>
1384 <message>
1385 <location filename="../configurefrm.ui" line="293"/>
1386 <source>Current cache size is %1</source>
1387 <translation>现在缓冲大小是 %1</translation>
1388 </message>
1389 <message>
1390 <location filename="../configurefrm.ui" line="302"/>
1391 <source>P&amp;ath</source>
1392 <translation>&amp;路径</translation>
1393 </message>
1394 <message>
1395 <location filename="../configurefrm.ui" line="312"/>
1396 <source>Entering an invalid folder will reset the path to the systems temporary path.</source>
1397 <translation>输入无效地址会重设到系统临时文件夹.</translation>
1398 </message>
1399 <message>
1400 <location filename="../configurefrm.ui" line="334"/>
1401 <source>Disable local &amp;download cache</source>
1402 <translation>&amp;不使用本机缓冲</translation>
1403 </message>
1404 <message>
1405 <source>&lt;p&gt;This will try to use all information from the cache, even information about updates. Only use this option if you want to install without network connection. Note: you need to do the same install you want to perform later with network access first to download all required files to the cache.&lt;/p&gt;</source>
1406 <translation type="obsolete">&lt;p&gt;所有资料, 包括更新资料, 将会从本机缓冲里拿取. 不要选择此模式如果你不需要下线安装. 注意: 你需要先用网络做至少一次安装才可以下载到需要的文件.&lt;/p&gt;</translation>
1407 </message>
1408 <message>
1409 <source>O&amp;ffline mode</source>
1410 <translation type="obsolete">&amp;下线安装</translation>
1411 </message>
1412 <message>
1413 <location filename="../configurefrm.ui" line="369"/>
1414 <source>Clean cache &amp;now</source>
1415 <translation>&amp;现在清除缓冲文件夹</translation>
1416 </message>
1417 <message>
1418 <location filename="../configurefrm.ui" line="385"/>
1419 <source>&amp;TTS &amp;&amp; Encoder</source>
1420 <translation>&amp;TTS &amp;&amp; 信号转换器</translation>
1421 </message>
1422 <message>
1423 <location filename="../configurefrm.ui" line="391"/>
1424 <source>TTS Engine</source>
1425 <translation>TTS 引擎</translation>
1426 </message>
1427 <message>
1428 <location filename="../configurefrm.ui" line="445"/>
1429 <source>Test TTS</source>
1430 <translation type="unfinished"></translation>
1431 </message>
1432 <message>
1433 <location filename="../configurefrm.ui" line="452"/>
1434 <source>&amp;Use string corrections for TTS</source>
1435 <translation type="unfinished"></translation>
1436 </message>
1437 <message>
1438 <location filename="../configurefrm.ui" line="462"/>
1439 <source>Encoder Engine</source>
1440 <translation>信号转换器引擎</translation>
1441 </message>
1442 <message>
1443 <location filename="../configurefrm.ui" line="536"/>
1444 <source>&amp;Ok</source>
1445 <translation>&amp;OK</translation>
1446 </message>
1447 <message>
1448 <location filename="../configurefrm.ui" line="547"/>
1449 <source>&amp;Cancel</source>
1450 <translation>&amp;取消</translation>
1451 </message>
1452 <message>
1453 <location filename="../configurefrm.ui" line="397"/>
1454 <source>&amp;Select TTS Engine</source>
1455 <translation type="unfinished"></translation>
1456 </message>
1457 <message>
1458 <location filename="../configurefrm.ui" line="95"/>
1459 <source>Show disabled targets</source>
1460 <translation type="unfinished"></translation>
1461 </message>
1462 <message>
1463 <location filename="../configurefrm.ui" line="410"/>
1464 <source>Configure TTS Engine</source>
1465 <translation type="unfinished"></translation>
1466 </message>
1467 <message>
1468 <location filename="../configurefrm.ui" line="417"/>
1469 <location filename="../configurefrm.ui" line="468"/>
1470 <source>Configuration invalid!</source>
1471 <translation type="unfinished"></translation>
1472 </message>
1473 <message>
1474 <location filename="../configurefrm.ui" line="434"/>
1475 <source>Configure &amp;TTS</source>
1476 <translation type="unfinished"></translation>
1477 </message>
1478 <message>
1479 <location filename="../configurefrm.ui" line="485"/>
1480 <source>Configure &amp;Enc</source>
1481 <translation type="unfinished"></translation>
1482 </message>
1483 <message>
1484 <location filename="../configurefrm.ui" line="496"/>
1485 <source>encoder name</source>
1486 <translation type="unfinished"></translation>
1487 </message>
1488</context>
1489<context>
1490 <name>Configure</name>
1491 <message>
1492 <location filename="../configure.cpp" line="589"/>
1493 <source>English</source>
1494 <comment>This is the localized language name, i.e. your language.</comment>
1495 <translation type="unfinished">中文 (Chinese Simplified)</translation>
1496 </message>
1497</context>
1498<context>
1499 <name>CreateVoiceFrm</name>
1500 <message>
1501 <location filename="../createvoicefrm.ui" line="17"/>
1502 <source>Create Voice File</source>
1503 <translation type="unfinished"></translation>
1504 </message>
1505 <message>
1506 <location filename="../createvoicefrm.ui" line="42"/>
1507 <source>Select the Language you want to generate a voicefile for:</source>
1508 <translation type="unfinished"></translation>
1509 </message>
1510 <message>
1511 <location filename="../createvoicefrm.ui" line="55"/>
1512 <source>TTS:</source>
1513 <translation type="unfinished"></translation>
1514 </message>
1515 <message>
1516 <location filename="../createvoicefrm.ui" line="101"/>
1517 <source>Silence threshold</source>
1518 <translation type="unfinished"></translation>
1519 </message>
1520 <message>
1521 <location filename="../createvoicefrm.ui" line="163"/>
1522 <source>Language</source>
1523 <translation type="unfinished"></translation>
1524 </message>
1525 <message>
1526 <location filename="../createvoicefrm.ui" line="49"/>
1527 <source>Generation settings</source>
1528 <translation type="unfinished">语音合成设置</translation>
1529 </message>
1530 <message>
1531 <location filename="../createvoicefrm.ui" line="68"/>
1532 <source>Change</source>
1533 <translation type="unfinished"></translation>
1534 </message>
1535 <message>
1536 <location filename="../createvoicefrm.ui" line="139"/>
1537 <source>&amp;Install</source>
1538 <translation type="unfinished"></translation>
1539 </message>
1540 <message>
1541 <location filename="../createvoicefrm.ui" line="150"/>
1542 <source>&amp;Cancel</source>
1543 <translation type="unfinished">&amp;取消</translation>
1544 </message>
1545 <message>
1546 <location filename="../createvoicefrm.ui" line="88"/>
1547 <source>Wavtrim Threshold</source>
1548 <translation type="unfinished"></translation>
1549 </message>
1550</context>
1551<context>
1552 <name>CreateVoiceWindow</name>
1553 <message>
1554 <location filename="../createvoicewindow.cpp" line="100"/>
1555 <source>TTS error</source>
1556 <translation type="unfinished"></translation>
1557 </message>
1558 <message>
1559 <location filename="../createvoicewindow.cpp" line="101"/>
1560 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1561 <translation type="unfinished"></translation>
1562 </message>
1563 <message>
1564 <location filename="../createvoicewindow.cpp" line="105"/>
1565 <location filename="../createvoicewindow.cpp" line="108"/>
1566 <source>Engine: &lt;b&gt;%1&lt;/b&gt;</source>
1567 <translation type="unfinished"></translation>
1568 </message>
1569</context>
1570<context>
1571 <name>EncTtsCfgGui</name>
1572 <message>
1573 <location filename="../encttscfggui.cpp" line="45"/>
1574 <source>Waiting for engine...</source>
1575 <translation type="unfinished"></translation>
1576 </message>
1577 <message>
1578 <location filename="../encttscfggui.cpp" line="95"/>
1579 <source>Ok</source>
1580 <translation type="unfinished"></translation>
1581 </message>
1582 <message>
1583 <location filename="../encttscfggui.cpp" line="98"/>
1584 <source>Cancel</source>
1585 <translation type="unfinished"></translation>
1586 </message>
1587 <message>
1588 <location filename="../encttscfggui.cpp" line="197"/>
1589 <source>Browse</source>
1590 <translation type="unfinished"></translation>
1591 </message>
1592 <message>
1593 <location filename="../encttscfggui.cpp" line="205"/>
1594 <source>Refresh</source>
1595 <translation type="unfinished"></translation>
1596 </message>
1597 <message>
1598 <location filename="../encttscfggui.cpp" line="377"/>
1599 <source>Select executable</source>
1600 <translation type="unfinished"></translation>
1601 </message>
1602</context>
1603<context>
1604 <name>EncoderExe</name>
1605 <message>
1606 <location filename="../base/encoderexe.cpp" line="41"/>
1607 <source>Path to Encoder:</source>
1608 <translation type="unfinished"></translation>
1609 </message>
1610 <message>
1611 <location filename="../base/encoderexe.cpp" line="43"/>
1612 <source>Encoder options:</source>
1613 <translation type="unfinished"></translation>
1614 </message>
1615</context>
1616<context>
1617 <name>EncoderLame</name>
1618 <message>
1619 <location filename="../base/encoderlame.cpp" line="73"/>
1620 <location filename="../base/encoderlame.cpp" line="83"/>
1621 <source>LAME</source>
1622 <translation type="unfinished"></translation>
1623 </message>
1624 <message>
1625 <location filename="../base/encoderlame.cpp" line="75"/>
1626 <source>Volume</source>
1627 <translation type="unfinished"></translation>
1628 </message>
1629 <message>
1630 <location filename="../base/encoderlame.cpp" line="79"/>
1631 <source>Quality</source>
1632 <translation type="unfinished"></translation>
1633 </message>
1634 <message>
1635 <location filename="../base/encoderlame.cpp" line="83"/>
1636 <source>Could not find libmp3lame!</source>
1637 <translation type="unfinished"></translation>
1638 </message>
1639</context>
1640<context>
1641 <name>EncoderRbSpeex</name>
1642 <message>
1643 <location filename="../base/encoderrbspeex.cpp" line="34"/>
1644 <source>Volume:</source>
1645 <translation type="unfinished"></translation>
1646 </message>
1647 <message>
1648 <location filename="../base/encoderrbspeex.cpp" line="36"/>
1649 <source>Quality:</source>
1650 <translation type="unfinished"></translation>
1651 </message>
1652 <message>
1653 <location filename="../base/encoderrbspeex.cpp" line="38"/>
1654 <source>Complexity:</source>
1655 <translation type="unfinished"></translation>
1656 </message>
1657 <message>
1658 <location filename="../base/encoderrbspeex.cpp" line="40"/>
1659 <source>Use Narrowband:</source>
1660 <translation type="unfinished"></translation>
1661 </message>
1662</context>
1663<context>
1664 <name>InfoWidget</name>
1665 <message>
1666 <location filename="../gui/infowidget.cpp" line="30"/>
1667 <location filename="../gui/infowidget.cpp" line="107"/>
1668 <source>File</source>
1669 <translation type="unfinished">文件</translation>
1670 </message>
1671 <message>
1672 <location filename="../gui/infowidget.cpp" line="30"/>
1673 <location filename="../gui/infowidget.cpp" line="107"/>
1674 <source>Version</source>
1675 <translation type="unfinished">版本</translation>
1676 </message>
1677</context>
1678<context>
1679 <name>InfoWidgetFrm</name>
1680 <message>
1681 <location filename="../gui/infowidgetfrm.ui" line="14"/>
1682 <source>Info</source>
1683 <translation type="unfinished"></translation>
1684 </message>
1685 <message>
1686 <location filename="../gui/infowidgetfrm.ui" line="20"/>
1687 <source>Currently installed packages.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; if you manually installed packages this might not be correct!</source>
1688 <translation type="unfinished"></translation>
1689 </message>
1690 <message>
1691 <location filename="../gui/infowidgetfrm.ui" line="34"/>
1692 <source>Package</source>
1693 <translation type="unfinished"></translation>
1694 </message>
1695</context>
1696<context>
1697 <name>InstallTalkFrm</name>
1698 <message>
1699 <location filename="../installtalkfrm.ui" line="17"/>
1700 <source>Install Talk Files</source>
1701 <translation>安装说话文件</translation>
1702 </message>
1703 <message>
1704 <location filename="../installtalkfrm.ui" line="52"/>
1705 <source>Generate for files</source>
1706 <translation type="unfinished"></translation>
1707 </message>
1708 <message>
1709 <location filename="../installtalkfrm.ui" line="85"/>
1710 <source>Generate for folders</source>
1711 <translation type="unfinished"></translation>
1712 </message>
1713 <message>
1714 <location filename="../installtalkfrm.ui" line="95"/>
1715 <source>Recurse into folders</source>
1716 <translation type="unfinished"></translation>
1717 </message>
1718 <message>
1719 <location filename="../installtalkfrm.ui" line="118"/>
1720 <source>Ignore files</source>
1721 <translation type="unfinished"></translation>
1722 </message>
1723 <message>
1724 <location filename="../installtalkfrm.ui" line="128"/>
1725 <source>Skip existing</source>
1726 <translation type="unfinished"></translation>
1727 </message>
1728 <message>
1729 <location filename="../installtalkfrm.ui" line="170"/>
1730 <source>Select folders for Talkfile generation (Ctrl for multiselect)</source>
1731 <translation type="unfinished"></translation>
1732 </message>
1733 <message>
1734 <location filename="../installtalkfrm.ui" line="78"/>
1735 <source>TTS profile:</source>
1736 <translation>TTS 设置:</translation>
1737 </message>
1738 <message>
1739 <location filename="../installtalkfrm.ui" line="36"/>
1740 <source>Generation options</source>
1741 <translation>语音合成设置</translation>
1742 </message>
1743 <message>
1744 <location filename="../installtalkfrm.ui" line="42"/>
1745 <source>Strip Extensions</source>
1746 <translation>除去后缀</translation>
1747 </message>
1748 <message>
1749 <location filename="../installtalkfrm.ui" line="154"/>
1750 <source>&amp;Cancel</source>
1751 <translation>&amp;取消</translation>
1752 </message>
1753 <message>
1754 <location filename="../installtalkfrm.ui" line="111"/>
1755 <source>Change</source>
1756 <translation type="unfinished"></translation>
1757 </message>
1758 <message>
1759 <location filename="../installtalkfrm.ui" line="143"/>
1760 <source>&amp;Install</source>
1761 <translation type="unfinished"></translation>
1762 </message>
1763</context>
1764<context>
1765 <name>InstallTalkWindow</name>
1766 <message>
1767 <location filename="../installtalkwindow.cpp" line="96"/>
1768 <source>Empty selection</source>
1769 <translation type="unfinished"></translation>
1770 </message>
1771 <message>
1772 <location filename="../installtalkwindow.cpp" line="97"/>
1773 <source>No files or folders selected. Please select files or folders first.</source>
1774 <translation type="unfinished"></translation>
1775 </message>
1776 <message>
1777 <location filename="../installtalkwindow.cpp" line="137"/>
1778 <source>TTS error</source>
1779 <translation type="unfinished"></translation>
1780 </message>
1781 <message>
1782 <location filename="../installtalkwindow.cpp" line="138"/>
1783 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1784 <translation type="unfinished"></translation>
1785 </message>
1786</context>
1787<context>
1788 <name>ManualWidget</name>
1789 <message>
1790 <location filename="../gui/manualwidget.cpp" line="44"/>
1791 <source>&lt;a href=&apos;%1&apos;&gt;PDF Manual&lt;/a&gt;</source>
1792 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;PDF 用户手册(英文)&lt;/a&gt;</translation>
1793 </message>
1794 <message>
1795 <location filename="../gui/manualwidget.cpp" line="46"/>
1796 <source>&lt;a href=&apos;%1&apos;&gt;HTML Manual (opens in browser)&lt;/a&gt;</source>
1797 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;HTML 用户手册(英文,在浏览器打开)&lt;/a&gt;</translation>
1798 </message>
1799 <message>
1800 <location filename="../gui/manualwidget.cpp" line="50"/>
1801 <source>Select a device for a link to the correct manual</source>
1802 <translation type="unfinished">请选择你的播放器</translation>
1803 </message>
1804 <message>
1805 <location filename="../gui/manualwidget.cpp" line="51"/>
1806 <source>&lt;a href=&apos;%1&apos;&gt;Manual Overview&lt;/a&gt;</source>
1807 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;用户手册总观&lt;/a&gt;</translation>
1808 </message>
1809 <message>
1810 <location filename="../gui/manualwidget.cpp" line="62"/>
1811 <source>Confirm download</source>
1812 <translation type="unfinished">确认下载</translation>
1813 </message>
1814 <message>
1815 <location filename="../gui/manualwidget.cpp" line="63"/>
1816 <source>Do you really want to download the manual? The manual will be saved to the root folder of your player.</source>
1817 <translation type="unfinished">你确认要下载用户手册吗? 用户手册将会被放在你播放器的主目录里.</translation>
1818 </message>
1819</context>
1820<context>
1821 <name>ManualWidgetFrm</name>
1822 <message>
1823 <location filename="../gui/manualwidgetfrm.ui" line="14"/>
1824 <source>Manual</source>
1825 <translation type="unfinished"></translation>
1826 </message>
1827 <message>
1828 <location filename="../gui/manualwidgetfrm.ui" line="20"/>
1829 <source>Read the manual</source>
1830 <translation type="unfinished">查看用户手册</translation>
1831 </message>
1832 <message>
1833 <location filename="../gui/manualwidgetfrm.ui" line="26"/>
1834 <source>PDF manual</source>
1835 <translation type="unfinished">PDF 用户手册</translation>
1836 </message>
1837 <message>
1838 <location filename="../gui/manualwidgetfrm.ui" line="39"/>
1839 <source>HTML manual</source>
1840 <translation type="unfinished">HTML 用户手册</translation>
1841 </message>
1842 <message>
1843 <location filename="../gui/manualwidgetfrm.ui" line="55"/>
1844 <source>Download the manual</source>
1845 <translation type="unfinished">下载用户手册</translation>
1846 </message>
1847 <message>
1848 <location filename="../gui/manualwidgetfrm.ui" line="63"/>
1849 <source>&amp;PDF version</source>
1850 <translation type="unfinished">PDF 版本</translation>
1851 </message>
1852 <message>
1853 <location filename="../gui/manualwidgetfrm.ui" line="70"/>
1854 <source>&amp;HTML version (zip file)</source>
1855 <translation type="unfinished">HTML 版本 (zip)</translation>
1856 </message>
1857 <message>
1858 <location filename="../gui/manualwidgetfrm.ui" line="92"/>
1859 <source>Down&amp;load</source>
1860 <translation type="unfinished">下载</translation>
1861 </message>
1862</context>
1863<context>
1864 <name>MsPackUtil</name>
1865 <message>
1866 <location filename="../base/mspackutil.cpp" line="101"/>
1867 <source>Creating output path failed</source>
1868 <translation type="unfinished"></translation>
1869 </message>
1870 <message>
1871 <location filename="../base/mspackutil.cpp" line="109"/>
1872 <source>Error during CAB operation</source>
1873 <translation type="unfinished"></translation>
1874 </message>
1875</context>
1876<context>
1877 <name>PreviewFrm</name>
1878 <message>
1879 <location filename="../previewfrm.ui" line="16"/>
1880 <source>Preview</source>
1881 <translation>预览</translation>
1882 </message>
1883</context>
1884<context>
1885 <name>ProgressLoggerFrm</name>
1886 <message>
1887 <location filename="../progressloggerfrm.ui" line="13"/>
1888 <location filename="../progressloggerfrm.ui" line="19"/>
1889 <source>Progress</source>
1890 <translation type="unfinished">进程</translation>
1891 </message>
1892 <message>
1893 <location filename="../progressloggerfrm.ui" line="58"/>
1894 <source>Save Log</source>
1895 <translation type="unfinished"></translation>
1896 </message>
1897 <message>
1898 <location filename="../progressloggerfrm.ui" line="82"/>
1899 <source>&amp;Abort</source>
1900 <translation type="unfinished">&amp;取消</translation>
1901 </message>
1902 <message>
1903 <location filename="../progressloggerfrm.ui" line="32"/>
1904 <source>progresswindow</source>
1905 <translation type="unfinished"></translation>
1906 </message>
1907</context>
1908<context>
1909 <name>ProgressLoggerGui</name>
1910 <message>
1911 <location filename="../progressloggergui.cpp" line="122"/>
1912 <source>&amp;Ok</source>
1913 <translation>&amp;OK</translation>
1914 </message>
1915 <message>
1916 <location filename="../progressloggergui.cpp" line="146"/>
1917 <source>Save system trace log</source>
1918 <translation type="unfinished"></translation>
1919 </message>
1920 <message>
1921 <location filename="../progressloggergui.cpp" line="104"/>
1922 <source>&amp;Abort</source>
1923 <translation>&amp;取消</translation>
1924 </message>
1925</context>
1926<context>
1927 <name>QObject</name>
1928 <message>
1929 <location filename="../configure.cpp" line="625"/>
1930 <location filename="../main.cpp" line="83"/>
1931 <source>LTR</source>
1932 <extracomment>This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.
1933----------
1934This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.</extracomment>
1935 <translation type="unfinished"></translation>
1936 </message>
1937 <message>
1938 <location filename="../base/system.cpp" line="385"/>
1939 <source>(unknown vendor name) </source>
1940 <translation type="unfinished"></translation>
1941 </message>
1942 <message>
1943 <location filename="../base/system.cpp" line="403"/>
1944 <source>(unknown product name)</source>
1945 <translation type="unfinished"></translation>
1946 </message>
1947 <message>
1948 <location filename="../base/bootloaderinstallhelper.cpp" line="80"/>
1949 <source>Bootloader installation is almost complete. Installation &lt;b&gt;requires&lt;/b&gt; you to perform the following steps manually:</source>
1950 <translation type="unfinished"></translation>
1951 </message>
1952 <message>
1953 <location filename="../base/bootloaderinstallhelper.cpp" line="86"/>
1954 <source>&lt;li&gt;Safely remove your player.&lt;/li&gt;</source>
1955 <translation type="unfinished"></translation>
1956 </message>
1957 <message>
1958 <location filename="../base/bootloaderinstallhelper.cpp" line="91"/>
1959 <source>&lt;li&gt;Reboot your player into the original firmware.&lt;/li&gt;&lt;li&gt;Perform a firmware upgrade using the update functionality of the original firmware. Please refer to your player&apos;s manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before starting the firmware update process.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1960 <translation type="unfinished"></translation>
1961 </message>
1962 <message>
1963 <location filename="../base/bootloaderinstallhelper.cpp" line="102"/>
1964 <source>&lt;li&gt;Remove any previously inserted microSD card&lt;/li&gt;</source>
1965 <translation type="unfinished"></translation>
1966 </message>
1967 <message>
1968 <location filename="../base/bootloaderinstallhelper.cpp" line="103"/>
1969 <source>&lt;li&gt;Disconnect your player. The player will reboot and perform an update of the original firmware. Please refer to your players manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before disconnecting the player.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1970 <translation type="unfinished"></translation>
1971 </message>
1972 <message>
1973 <location filename="../base/bootloaderinstallhelper.cpp" line="114"/>
1974 <source>&lt;li&gt;Turn the player off&lt;/li&gt;&lt;li&gt;Insert the charger&lt;/li&gt;</source>
1975 <translation type="unfinished"></translation>
1976 </message>
1977 <message>
1978 <location filename="../base/bootloaderinstallhelper.cpp" line="119"/>
1979 <source>&lt;li&gt;Unplug USB and power adaptors&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to turn the player off&lt;/li&gt;&lt;li&gt;Toggle the battery switch on the player&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to boot into Rockbox&lt;/li&gt;</source>
1980 <translation type="unfinished"></translation>
1981 </message>
1982 <message>
1983 <location filename="../base/bootloaderinstallhelper.cpp" line="125"/>
1984 <source>&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You can safely install other parts first, but the above steps are &lt;b&gt;required&lt;/b&gt; to finish the installation!&lt;/p&gt;</source>
1985 <translation type="unfinished"></translation>
1986 </message>
1987</context>
1988<context>
1989 <name>QuaZipFile</name>
1990 <message>
1991 <location filename="../quazip/quazipfile.cpp" line="141"/>
1992 <source>ZIP/UNZIP API error %1</source>
1993 <translation type="unfinished"></translation>
1994 </message>
1995</context>
1996<context>
1997 <name>RbUtilQt</name>
1998 <message>
1999 <location filename="../rbutilqt.cpp" line="224"/>
2000 <source>Downloading build information, please wait ...</source>
2001 <translation type="unfinished"></translation>
2002 </message>
2003 <message>
2004 <location filename="../rbutilqt.cpp" line="235"/>
2005 <source>Can&apos;t get version information!</source>
2006 <translation type="unfinished"></translation>
2007 </message>
2008 <message>
2009 <location filename="../rbutilqt.cpp" line="249"/>
2010 <source>Download build information finished.</source>
2011 <translation type="unfinished"></translation>
2012 </message>
2013 <message>
2014 <location filename="../rbutilqt.cpp" line="450"/>
2015 <source>Confirm Installation</source>
2016 <translation>确认安装</translation>
2017 </message>
2018 <message>
2019 <location filename="../rbutilqt.cpp" line="582"/>
2020 <source>Mount point is wrong!</source>
2021 <translation>Mountpoint 错误!</translation>
2022 </message>
2023 <message>
2024 <location filename="../rbutilqt.cpp" line="430"/>
2025 <source>No Rockbox installation found</source>
2026 <translation type="unfinished"></translation>
2027 </message>
2028 <message>
2029 <location filename="../rbutilqt.cpp" line="431"/>
2030 <source>Could not determine the installed Rockbox version. Please install a Rockbox build before installing voice files.</source>
2031 <translation type="unfinished"></translation>
2032 </message>
2033 <message>
2034 <location filename="../rbutilqt.cpp" line="451"/>
2035 <source>Do you really want to install the voice file?</source>
2036 <translation>你确认要安装语音文件吗?</translation>
2037 </message>
2038 <message>
2039 <location filename="../rbutilqt.cpp" line="439"/>
2040 <source>No voice file available</source>
2041 <translation type="unfinished"></translation>
2042 </message>
2043 <message>
2044 <location filename="../rbutilqt.cpp" line="440"/>
2045 <source>The installed version of Rockbox is a development version. Pre-built voices are only available for release versions of Rockbox. Please generate a voice yourself using the &quot;Create voice file&quot; functionality.</source>
2046 <translation type="unfinished"></translation>
2047 </message>
2048 <message>
2049 <location filename="../rbutilqt.cpp" line="512"/>
2050 <source>Confirm Uninstallation</source>
2051 <translation>确认安装</translation>
2052 </message>
2053 <message>
2054 <location filename="../rbutilqt.cpp" line="513"/>
2055 <source>Do you really want to uninstall the Bootloader?</source>
2056 <translation>你确认要卸载启动程序吗?</translation>
2057 </message>
2058 <message>
2059 <location filename="../rbutilqt.cpp" line="528"/>
2060 <source>No uninstall method for this target known.</source>
2061 <translation type="unfinished"></translation>
2062 </message>
2063 <message>
2064 <location filename="../rbutilqt.cpp" line="542"/>
2065 <source>Rockbox Utility can not uninstall the bootloader on this target. Try a normal firmware update to remove the booloader.</source>
2066 <translation type="unfinished"></translation>
2067 </message>
2068 <message>
2069 <location filename="../rbutilqt.cpp" line="550"/>
2070 <source>No Rockbox bootloader found.</source>
2071 <translation type="unfinished"></translation>
2072 </message>
2073 <message>
2074 <location filename="../rbutilqt.cpp" line="568"/>
2075 <source>Confirm installation</source>
2076 <translation>确认安装</translation>
2077 </message>
2078 <message>
2079 <location filename="../rbutilqt.cpp" line="569"/>
2080 <source>Do you really want to install Rockbox Utility to your player? After installation you can run it from the players hard drive.</source>
2081 <translation>你确认要安装Rockbox安装程序到你的播放器上吗? 安装后你可以从你播放器上运行此程序.</translation>
2082 </message>
2083 <message>
2084 <location filename="../rbutilqt.cpp" line="578"/>
2085 <source>Installing Rockbox Utility</source>
2086 <translation>安装 Rockbox安装程序</translation>
2087 </message>
2088 <message>
2089 <location filename="../rbutilqt.cpp" line="596"/>
2090 <source>Error installing Rockbox Utility</source>
2091 <translation>安装 Rockbox安装程序错误!</translation>
2092 </message>
2093 <message>
2094 <location filename="../rbutilqt.cpp" line="600"/>
2095 <source>Installing user configuration</source>
2096 <translation>安装用户设置</translation>
2097 </message>
2098 <message>
2099 <location filename="../rbutilqt.cpp" line="604"/>
2100 <source>Error installing user configuration</source>
2101 <translation>安装用户设置错误</translation>
2102 </message>
2103 <message>
2104 <location filename="../rbutilqt.cpp" line="608"/>
2105 <source>Successfully installed Rockbox Utility.</source>
2106 <translation>成功安装 Rockbox安装程序.</translation>
2107 </message>
2108 <message>
2109 <location filename="../rbutilqt.cpp" line="664"/>
2110 <source>Checking for update ...</source>
2111 <translation type="unfinished"></translation>
2112 </message>
2113 <message>
2114 <location filename="../rbutilqt.cpp" line="729"/>
2115 <source>RockboxUtility Update available</source>
2116 <translation type="unfinished"></translation>
2117 </message>
2118 <message>
2119 <location filename="../rbutilqt.cpp" line="730"/>
2120 <source>&lt;b&gt;New RockboxUtility Version available.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Download it from here: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</source>
2121 <translation type="unfinished"></translation>
2122 </message>
2123 <message>
2124 <location filename="../rbutilqt.cpp" line="733"/>
2125 <source>New version of Rockbox Utility available.</source>
2126 <translation type="unfinished"></translation>
2127 </message>
2128 <message>
2129 <location filename="../rbutilqt.cpp" line="736"/>
2130 <source>Rockbox Utility is up to date.</source>
2131 <translation type="unfinished"></translation>
2132 </message>
2133 <message>
2134 <location filename="../rbutilqt.cpp" line="759"/>
2135 <source>Device ejected</source>
2136 <translation type="unfinished"></translation>
2137 </message>
2138 <message>
2139 <location filename="../rbutilqt.cpp" line="760"/>
2140 <source>Device successfully ejected. You may now disconnect the player from the PC.</source>
2141 <translation type="unfinished"></translation>
2142 </message>
2143 <message>
2144 <location filename="../rbutilqt.cpp" line="764"/>
2145 <source>Ejecting failed</source>
2146 <translation type="unfinished"></translation>
2147 </message>
2148 <message>
2149 <location filename="../rbutilqt.cpp" line="765"/>
2150 <source>Ejecting the device failed. Please make sure no programs are accessing files on the device. If ejecting still fails please use your computers eject funtionality.</source>
2151 <translation type="unfinished"></translation>
2152 </message>
2153 <message>
2154 <location filename="../rbutilqt.cpp" line="337"/>
2155 <location filename="../rbutilqt.cpp" line="642"/>
2156 <source>Configuration error</source>
2157 <translation type="unfinished"></translation>
2158 </message>
2159 <message>
2160 <location filename="../rbutilqt.cpp" line="643"/>
2161 <source>Your configuration is invalid. Please go to the configuration dialog and make sure the selected values are correct.</source>
2162 <translation type="unfinished"></translation>
2163 </message>
2164 <message>
2165 <location filename="../rbutilqt.cpp" line="330"/>
2166 <source>This is a new installation of Rockbox Utility, or a new version. The configuration dialog will now open to allow you to setup the program, or review your settings.</source>
2167 <translation type="unfinished"></translation>
2168 </message>
2169 <message>
2170 <location filename="../rbutilqt.cpp" line="110"/>
2171 <source>Wine detected!</source>
2172 <translation type="unfinished"></translation>
2173 </message>
2174 <message>
2175 <location filename="../rbutilqt.cpp" line="111"/>
2176 <source>It seems you are trying to run this program under Wine. Please don&apos;t do this, running under Wine will fail. Use the native Linux binary instead.</source>
2177 <translation type="unfinished"></translation>
2178 </message>
2179 <message>
2180 <location filename="../rbutilqt.cpp" line="237"/>
2181 <source>Can&apos;t get version information.
2182Network error: %1. Please check your network and proxy settings.</source>
2183 <translation type="unfinished"></translation>
2184 </message>
2185 <message>
2186 <location filename="../rbutilqt.cpp" line="416"/>
2187 <source>Warning</source>
2188 <translation type="unfinished"></translation>
2189 </message>
2190 <message>
2191 <location filename="../rbutilqt.cpp" line="417"/>
2192 <source>The Application is still downloading Information about new Builds. Please try again shortly.</source>
2193 <translation type="unfinished"></translation>
2194 </message>
2195 <message>
2196 <location filename="../rbutilqt.cpp" line="329"/>
2197 <source>New installation</source>
2198 <translation type="unfinished"></translation>
2199 </message>
2200 <message>
2201 <location filename="../rbutilqt.cpp" line="338"/>
2202 <source>Your configuration is invalid. This is most likely due to a changed device path. The configuration dialog will now open to allow you to correct the problem.</source>
2203 <translation type="unfinished"></translation>
2204 </message>
2205 <message>
2206 <location filename="../rbutilqt.cpp" line="236"/>
2207 <source>Network error</source>
2208 <translation type="unfinished"></translation>
2209 </message>
2210</context>
2211<context>
2212 <name>RbUtilQtFrm</name>
2213 <message>
2214 <location filename="../rbutilqtfrm.ui" line="14"/>
2215 <source>Rockbox Utility</source>
2216 <translation>Rockbox 安装程序</translation>
2217 </message>
2218 <message>
2219 <location filename="../rbutilqtfrm.ui" line="31"/>
2220 <source>Device</source>
2221 <translation>播放器</translation>
2222 </message>
2223 <message>
2224 <location filename="../rbutilqtfrm.ui" line="92"/>
2225 <source>&amp;Change</source>
2226 <translation>&amp;更改</translation>
2227 </message>
2228 <message>
2229 <location filename="../rbutilqtfrm.ui" line="163"/>
2230 <source>Welcome</source>
2231 <translation>欢迎</translation>
2232 </message>
2233 <message>
2234 <location filename="../rbutilqtfrm.ui" line="160"/>
2235 <location filename="../rbutilqtfrm.ui" line="658"/>
2236 <source>&amp;Installation</source>
2237 <translation>&amp;安装</translation>
2238 </message>
2239 <message>
2240 <location filename="../rbutilqtfrm.ui" line="168"/>
2241 <location filename="../rbutilqtfrm.ui" line="450"/>
2242 <source>&amp;Accessibility</source>
2243 <translation>&amp;辅助</translation>
2244 </message>
2245 <message>
2246 <location filename="../rbutilqtfrm.ui" line="171"/>
2247 <source>Install accessibility add-ons</source>
2248 <translation>安装辅助功能</translation>
2249 </message>
2250 <message>
2251 <location filename="../rbutilqtfrm.ui" line="177"/>
2252 <source>Install Voice files</source>
2253 <translation>安装语音文件</translation>
2254 </message>
2255 <message>
2256 <location filename="../rbutilqtfrm.ui" line="204"/>
2257 <source>Install Talk files</source>
2258 <translation>安装说话文件</translation>
2259 </message>
2260 <message>
2261 <location filename="../rbutilqtfrm.ui" line="458"/>
2262 <source>&amp;Uninstallation</source>
2263 <translation>&amp;卸载</translation>
2264 </message>
2265 <message>
2266 <location filename="../rbutilqtfrm.ui" line="286"/>
2267 <location filename="../rbutilqtfrm.ui" line="319"/>
2268 <source>Uninstall Rockbox</source>
2269 <translation>卸载 Rockbox</translation>
2270 </message>
2271 <message>
2272 <location filename="../rbutilqtfrm.ui" line="121"/>
2273 <source>mountpoint unknown or invalid</source>
2274 <translation type="unfinished"></translation>
2275 </message>
2276 <message>
2277 <location filename="../rbutilqtfrm.ui" line="114"/>
2278 <source>Mountpoint:</source>
2279 <translation type="unfinished"></translation>
2280 </message>
2281 <message>
2282 <location filename="../rbutilqtfrm.ui" line="72"/>
2283 <source>device unknown or invalid</source>
2284 <translation type="unfinished"></translation>
2285 </message>
2286 <message>
2287 <location filename="../rbutilqtfrm.ui" line="65"/>
2288 <source>Device:</source>
2289 <translation type="unfinished"></translation>
2290 </message>
2291 <message>
2292 <location filename="../rbutilqtfrm.ui" line="292"/>
2293 <source>Uninstall Bootloader</source>
2294 <translation>卸载启动程序</translation>
2295 </message>
2296 <message>
2297 <location filename="../rbutilqtfrm.ui" line="393"/>
2298 <source>&amp;Manual</source>
2299 <translation>&amp;用户手册</translation>
2300 </message>
2301 <message>
2302 <location filename="../rbutilqtfrm.ui" line="396"/>
2303 <source>View and download the manual</source>
2304 <translation>查看和下载用户手册</translation>
2305 </message>
2306 <message>
2307 <location filename="../rbutilqtfrm.ui" line="401"/>
2308 <source>Inf&amp;o</source>
2309 <translation>&amp;信息</translation>
2310 </message>
2311 <message>
2312 <location filename="../rbutilqtfrm.ui" line="419"/>
2313 <source>&amp;File</source>
2314 <translation>&amp;文件</translation>
2315 </message>
2316 <message>
2317 <location filename="../rbutilqtfrm.ui" line="432"/>
2318 <source>&amp;Troubleshoot</source>
2319 <translation type="unfinished"></translation>
2320 </message>
2321 <message>
2322 <location filename="../rbutilqtfrm.ui" line="497"/>
2323 <source>&amp;About</source>
2324 <translation>&amp;关于</translation>
2325 </message>
2326 <message>
2327 <location filename="../rbutilqtfrm.ui" line="653"/>
2328 <source>System &amp;Trace</source>
2329 <translation type="unfinished"></translation>
2330 </message>
2331 <message>
2332 <location filename="../rbutilqtfrm.ui" line="474"/>
2333 <source>Empty local download cache</source>
2334 <translation>清除本机下载缓冲</translation>
2335 </message>
2336 <message>
2337 <location filename="../rbutilqtfrm.ui" line="479"/>
2338 <source>Install Rockbox Utility on player</source>
2339 <translation>安装Rockbox安装程序到你的播放器</translation>
2340 </message>
2341 <message>
2342 <location filename="../rbutilqtfrm.ui" line="484"/>
2343 <source>&amp;Configure</source>
2344 <translation>&amp;设置</translation>
2345 </message>
2346 <message>
2347 <location filename="../rbutilqtfrm.ui" line="489"/>
2348 <source>E&amp;xit</source>
2349 <translation>&amp;退出</translation>
2350 </message>
2351 <message>
2352 <location filename="../rbutilqtfrm.ui" line="492"/>
2353 <source>Ctrl+Q</source>
2354 <translation>Ctrl+Q</translation>
2355 </message>
2356 <message>
2357 <location filename="../rbutilqtfrm.ui" line="502"/>
2358 <source>About &amp;Qt</source>
2359 <translation>关于&amp;Qt</translation>
2360 </message>
2361 <message>
2362 <location filename="../rbutilqtfrm.ui" line="428"/>
2363 <location filename="../rbutilqtfrm.ui" line="507"/>
2364 <source>&amp;Help</source>
2365 <translation>&amp;帮助</translation>
2366 </message>
2367 <message>
2368 <location filename="../rbutilqtfrm.ui" line="446"/>
2369 <source>Action&amp;s</source>
2370 <translation type="unfinished"></translation>
2371 </message>
2372 <message>
2373 <location filename="../rbutilqtfrm.ui" line="512"/>
2374 <source>Info</source>
2375 <translation type="unfinished"></translation>
2376 </message>
2377 <message>
2378 <location filename="../rbutilqtfrm.ui" line="616"/>
2379 <source>Read PDF manual</source>
2380 <translation type="unfinished"></translation>
2381 </message>
2382 <message>
2383 <location filename="../rbutilqtfrm.ui" line="621"/>
2384 <source>Read HTML manual</source>
2385 <translation type="unfinished"></translation>
2386 </message>
2387 <message>
2388 <location filename="../rbutilqtfrm.ui" line="626"/>
2389 <source>Download PDF manual</source>
2390 <translation type="unfinished"></translation>
2391 </message>
2392 <message>
2393 <location filename="../rbutilqtfrm.ui" line="631"/>
2394 <source>Download HTML manual (zip)</source>
2395 <translation type="unfinished"></translation>
2396 </message>
2397 <message>
2398 <location filename="../rbutilqtfrm.ui" line="254"/>
2399 <source>Create Voice files</source>
2400 <translation type="unfinished"></translation>
2401 </message>
2402 <message>
2403 <location filename="../rbutilqtfrm.ui" line="643"/>
2404 <source>Create Voice File</source>
2405 <translation type="unfinished"></translation>
2406 </message>
2407 <message>
2408 <location filename="../rbutilqtfrm.ui" line="194"/>
2409 <source>&lt;b&gt;Install Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so if you installed the voice file Rockbox will speak.</source>
2410 <translation type="unfinished"></translation>
2411 </message>
2412 <message>
2413 <location filename="../rbutilqtfrm.ui" line="103"/>
2414 <source>&amp;Eject</source>
2415 <translation type="unfinished"></translation>
2416 </message>
2417 <message>
2418 <location filename="../rbutilqtfrm.ui" line="221"/>
2419 <source>&lt;b&gt;Create Talk Files&lt;/b&gt;&lt;br/&gt;Talkfiles are needed to let Rockbox speak File and Foldernames</source>
2420 <translation type="unfinished"></translation>
2421 </message>
2422 <message>
2423 <location filename="../rbutilqtfrm.ui" line="271"/>
2424 <source>&lt;b&gt;Create Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so
2425 if you installed the voice file Rockbox will speak.</source>
2426 <translation type="unfinished"></translation>
2427 </message>
2428 <message>
2429 <location filename="../rbutilqtfrm.ui" line="283"/>
2430 <source>Backup &amp;&amp; &amp;Uninstallation</source>
2431 <translation type="unfinished"></translation>
2432 </message>
2433 <message>
2434 <location filename="../rbutilqtfrm.ui" line="309"/>
2435 <source>&lt;b&gt;Remove the bootloader&lt;/b&gt;&lt;br/&gt;After removing the bootloader you won&apos;t be able to start Rockbox.</source>
2436 <translation type="unfinished"></translation>
2437 </message>
2438 <message>
2439 <location filename="../rbutilqtfrm.ui" line="336"/>
2440 <source>&lt;b&gt;Uninstall Rockbox from your audio player.&lt;/b&gt;&lt;br/&gt;This will leave the bootloader in place (you need to remove it manually).</source>
2441 <translation type="unfinished"></translation>
2442 </message>
2443 <message>
2444 <location filename="../rbutilqtfrm.ui" line="349"/>
2445 <source>Backup</source>
2446 <translation type="unfinished"></translation>
2447 </message>
2448 <message>
2449 <location filename="../rbutilqtfrm.ui" line="366"/>
2450 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup current installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Create a backup by archiving the contents of the Rockbox installation folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2451 <translation type="unfinished"></translation>
2452 </message>
2453 <message>
2454 <location filename="../rbutilqtfrm.ui" line="539"/>
2455 <source>Install &amp;Bootloader</source>
2456 <translation type="unfinished"></translation>
2457 </message>
2458 <message>
2459 <location filename="../rbutilqtfrm.ui" line="548"/>
2460 <source>Install &amp;Rockbox</source>
2461 <translation type="unfinished"></translation>
2462 </message>
2463 <message>
2464 <location filename="../rbutilqtfrm.ui" line="557"/>
2465 <source>Install &amp;Fonts Package</source>
2466 <translation type="unfinished"></translation>
2467 </message>
2468 <message>
2469 <location filename="../rbutilqtfrm.ui" line="566"/>
2470 <source>Install &amp;Themes</source>
2471 <translation type="unfinished"></translation>
2472 </message>
2473 <message>
2474 <location filename="../rbutilqtfrm.ui" line="575"/>
2475 <source>Install &amp;Game Files</source>
2476 <translation type="unfinished"></translation>
2477 </message>
2478 <message>
2479 <location filename="../rbutilqtfrm.ui" line="584"/>
2480 <source>&amp;Install Voice File</source>
2481 <translation type="unfinished"></translation>
2482 </message>
2483 <message>
2484 <location filename="../rbutilqtfrm.ui" line="593"/>
2485 <source>Create &amp;Talk Files</source>
2486 <translation type="unfinished"></translation>
2487 </message>
2488 <message>
2489 <location filename="../rbutilqtfrm.ui" line="602"/>
2490 <source>Remove &amp;bootloader</source>
2491 <translation type="unfinished"></translation>
2492 </message>
2493 <message>
2494 <location filename="../rbutilqtfrm.ui" line="611"/>
2495 <source>Uninstall &amp;Rockbox</source>
2496 <translation type="unfinished"></translation>
2497 </message>
2498 <message>
2499 <location filename="../rbutilqtfrm.ui" line="640"/>
2500 <source>Create &amp;Voice File</source>
2501 <translation type="unfinished"></translation>
2502 </message>
2503 <message>
2504 <location filename="../rbutilqtfrm.ui" line="648"/>
2505 <source>&amp;System Info</source>
2506 <translation type="unfinished"></translation>
2507 </message>
2508 <message>
2509 <location filename="../rbutilqtfrm.ui" line="663"/>
2510 <source>Show &amp;Changelog</source>
2511 <translation type="unfinished"></translation>
2512 </message>
2513 <message>
2514 <location filename="../rbutilqtfrm.ui" line="521"/>
2515 <source>&amp;Complete Installation</source>
2516 <translation type="unfinished"></translation>
2517 </message>
2518 <message>
2519 <location filename="../rbutilqtfrm.ui" line="530"/>
2520 <source>&amp;Minimal Installation</source>
2521 <translation type="unfinished"></translation>
2522 </message>
2523</context>
2524<context>
2525 <name>SelectiveInstallWidget</name>
2526 <message>
2527 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="20"/>
2528 <source>Selective Installation</source>
2529 <translation type="unfinished"></translation>
2530 </message>
2531 <message>
2532 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="26"/>
2533 <source>Rockbox version to install</source>
2534 <translation type="unfinished"></translation>
2535 </message>
2536 <message>
2537 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="35"/>
2538 <source>Version information not available yet.</source>
2539 <translation type="unfinished"></translation>
2540 </message>
2541 <message>
2542 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="54"/>
2543 <source>Rockbox components to install</source>
2544 <translation type="unfinished"></translation>
2545 </message>
2546 <message>
2547 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="60"/>
2548 <source>&amp;Bootloader</source>
2549 <translation type="unfinished"></translation>
2550 </message>
2551 <message>
2552 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="80"/>
2553 <source>The main Rockbox firmware.</source>
2554 <translation type="unfinished"></translation>
2555 </message>
2556 <message>
2557 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="90"/>
2558 <source>Fonts</source>
2559 <translation type="unfinished"></translation>
2560 </message>
2561 <message>
2562 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="104"/>
2563 <source>&amp;Rockbox</source>
2564 <translation type="unfinished"></translation>
2565 </message>
2566 <message>
2567 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="124"/>
2568 <source>Some game plugins require additional files.</source>
2569 <translation type="unfinished"></translation>
2570 </message>
2571 <message>
2572 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="140"/>
2573 <source>Additional fonts for the User Interface.</source>
2574 <translation type="unfinished"></translation>
2575 </message>
2576 <message>
2577 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="156"/>
2578 <source>The bootloader is required for starting Rockbox. Only necessary for first time install.</source>
2579 <translation type="unfinished"></translation>
2580 </message>
2581 <message>
2582 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="166"/>
2583 <source>Game Files</source>
2584 <translation type="unfinished"></translation>
2585 </message>
2586 <message>
2587 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="177"/>
2588 <source>Customize</source>
2589 <translation type="unfinished"></translation>
2590 </message>
2591 <message>
2592 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="188"/>
2593 <source>Themes</source>
2594 <translation type="unfinished"></translation>
2595 </message>
2596 <message>
2597 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="205"/>
2598 <source>Themes allow adjusting the user interface of Rockbox. Use &quot;Customize&quot; to select themes.</source>
2599 <translation type="unfinished"></translation>
2600 </message>
2601 <message>
2602 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="250"/>
2603 <source>&amp;Install</source>
2604 <translation type="unfinished"></translation>
2605 </message>
2606 <message>
2607 <location filename="../gui/selectiveinstallwidget.cpp" line="67"/>
2608 <source>This is the latest stable release available.</source>
2609 <translation type="unfinished"></translation>
2610 </message>
2611 <message>
2612 <location filename="../gui/selectiveinstallwidget.cpp" line="70"/>
2613 <source>The development version is updated on every code change. Last update was on %1</source>
2614 <translation type="unfinished"></translation>
2615 </message>
2616 <message>
2617 <location filename="../gui/selectiveinstallwidget.cpp" line="74"/>
2618 <source>This will eventually become the next Rockbox version. Install it to help testing.</source>
2619 <translation type="unfinished"></translation>
2620 </message>
2621 <message>
2622 <location filename="../gui/selectiveinstallwidget.cpp" line="100"/>
2623 <source>Stable Release (Version %1)</source>
2624 <translation type="unfinished"></translation>
2625 </message>
2626 <message>
2627 <location filename="../gui/selectiveinstallwidget.cpp" line="104"/>
2628 <source>Development Version (Revison %1)</source>
2629 <translation type="unfinished"></translation>
2630 </message>
2631 <message>
2632 <location filename="../gui/selectiveinstallwidget.cpp" line="108"/>
2633 <source>Release Candidate (Revison %1)</source>
2634 <translation type="unfinished"></translation>
2635 </message>
2636 <message>
2637 <location filename="../gui/selectiveinstallwidget.cpp" line="131"/>
2638 <source>The selected player doesn&apos;t need a bootloader.</source>
2639 <translation type="unfinished"></translation>
2640 </message>
2641 <message>
2642 <location filename="../gui/selectiveinstallwidget.cpp" line="136"/>
2643 <source>The bootloader is required for starting Rockbox. Installation of the bootloader is only necessary on first time installation.</source>
2644 <translation type="unfinished"></translation>
2645 </message>
2646 <message>
2647 <location filename="../gui/selectiveinstallwidget.cpp" line="183"/>
2648 <source>Mountpoint is wrong</source>
2649 <translation type="unfinished"></translation>
2650 </message>
2651 <message>
2652 <location filename="../gui/selectiveinstallwidget.cpp" line="239"/>
2653 <source>No install method known.</source>
2654 <translation type="unfinished"></translation>
2655 </message>
2656 <message>
2657 <location filename="../gui/selectiveinstallwidget.cpp" line="266"/>
2658 <source>Bootloader detected</source>
2659 <translation type="unfinished"></translation>
2660 </message>
2661 <message>
2662 <location filename="../gui/selectiveinstallwidget.cpp" line="267"/>
2663 <source>Bootloader already installed. Do you want to reinstall the bootloader?</source>
2664 <translation type="unfinished"></translation>
2665 </message>
2666 <message>
2667 <location filename="../gui/selectiveinstallwidget.cpp" line="271"/>
2668 <source>Bootloader installation skipped</source>
2669 <translation type="unfinished"></translation>
2670 </message>
2671 <message>
2672 <location filename="../gui/selectiveinstallwidget.cpp" line="284"/>
2673 <source>Create Bootloader backup</source>
2674 <translation type="unfinished"></translation>
2675 </message>
2676 <message>
2677 <location filename="../gui/selectiveinstallwidget.cpp" line="285"/>
2678 <source>You can create a backup of the original bootloader file. Press &quot;Yes&quot; to select an output folder on your computer to save the file to. The file will get placed in a new folder &quot;%1&quot; created below the selected folder.
2679Press &quot;No&quot; to skip this step.</source>
2680 <translation type="unfinished"></translation>
2681 </message>
2682 <message>
2683 <location filename="../gui/selectiveinstallwidget.cpp" line="292"/>
2684 <source>Browse backup folder</source>
2685 <translation type="unfinished"></translation>
2686 </message>
2687 <message>
2688 <location filename="../gui/selectiveinstallwidget.cpp" line="304"/>
2689 <source>Prerequisites</source>
2690 <translation type="unfinished"></translation>
2691 </message>
2692 <message>
2693 <location filename="../gui/selectiveinstallwidget.cpp" line="309"/>
2694 <source>Bootloader installation aborted</source>
2695 <translation type="unfinished"></translation>
2696 </message>
2697 <message>
2698 <location filename="../gui/selectiveinstallwidget.cpp" line="319"/>
2699 <source>Bootloader files (%1)</source>
2700 <translation type="unfinished"></translation>
2701 </message>
2702 <message>
2703 <location filename="../gui/selectiveinstallwidget.cpp" line="321"/>
2704 <source>All files (*)</source>
2705 <translation type="unfinished"></translation>
2706 </message>
2707 <message>
2708 <location filename="../gui/selectiveinstallwidget.cpp" line="323"/>
2709 <source>Select firmware file</source>
2710 <translation type="unfinished"></translation>
2711 </message>
2712 <message>
2713 <location filename="../gui/selectiveinstallwidget.cpp" line="325"/>
2714 <source>Error opening firmware file</source>
2715 <translation type="unfinished"></translation>
2716 </message>
2717 <message>
2718 <location filename="../gui/selectiveinstallwidget.cpp" line="331"/>
2719 <source>Error reading firmware file</source>
2720 <translation type="unfinished"></translation>
2721 </message>
2722 <message>
2723 <location filename="../gui/selectiveinstallwidget.cpp" line="341"/>
2724 <source>Backup error</source>
2725 <translation type="unfinished"></translation>
2726 </message>
2727 <message>
2728 <location filename="../gui/selectiveinstallwidget.cpp" line="342"/>
2729 <source>Could not create backup file. Continue?</source>
2730 <translation type="unfinished"></translation>
2731 </message>
2732 <message>
2733 <location filename="../gui/selectiveinstallwidget.cpp" line="366"/>
2734 <source>Manual steps required</source>
2735 <translation type="unfinished"></translation>
2736 </message>
2737 <message>
2738 <location filename="../gui/selectiveinstallwidget.cpp" line="171"/>
2739 <source>Continue with installation?</source>
2740 <translation type="unfinished"></translation>
2741 </message>
2742 <message>
2743 <location filename="../gui/selectiveinstallwidget.cpp" line="172"/>
2744 <source>Really continue?</source>
2745 <translation type="unfinished"></translation>
2746 </message>
2747 <message>
2748 <location filename="../gui/selectiveinstallwidget.cpp" line="490"/>
2749 <source>Your installation doesn&apos;t require game files, skipping.</source>
2750 <translation type="unfinished"></translation>
2751 </message>
2752</context>
2753<context>
2754 <name>ServerInfo</name>
2755 <message>
2756 <location filename="../base/serverinfo.cpp" line="117"/>
2757 <source>Unknown</source>
2758 <translation type="unfinished"></translation>
2759 </message>
2760 <message>
2761 <location filename="../base/serverinfo.cpp" line="121"/>
2762 <source>Unusable</source>
2763 <translation type="unfinished"></translation>
2764 </message>
2765 <message>
2766 <location filename="../base/serverinfo.cpp" line="124"/>
2767 <source>Unstable</source>
2768 <translation type="unfinished"></translation>
2769 </message>
2770 <message>
2771 <location filename="../base/serverinfo.cpp" line="127"/>
2772 <source>Stable</source>
2773 <translation type="unfinished"></translation>
2774 </message>
2775</context>
2776<context>
2777 <name>SysTrace</name>
2778 <message>
2779 <location filename="../systrace.cpp" line="98"/>
2780 <location filename="../systrace.cpp" line="107"/>
2781 <source>Save system trace log</source>
2782 <translation type="unfinished"></translation>
2783 </message>
2784</context>
2785<context>
2786 <name>SysTraceFrm</name>
2787 <message>
2788 <location filename="../systracefrm.ui" line="14"/>
2789 <source>System Trace</source>
2790 <translation type="unfinished"></translation>
2791 </message>
2792 <message>
2793 <location filename="../systracefrm.ui" line="20"/>
2794 <source>System State trace</source>
2795 <translation type="unfinished"></translation>
2796 </message>
2797 <message>
2798 <location filename="../systracefrm.ui" line="46"/>
2799 <source>&amp;Close</source>
2800 <translation type="unfinished"></translation>
2801 </message>
2802 <message>
2803 <location filename="../systracefrm.ui" line="57"/>
2804 <source>&amp;Save</source>
2805 <translation type="unfinished"></translation>
2806 </message>
2807 <message>
2808 <location filename="../systracefrm.ui" line="68"/>
2809 <source>&amp;Refresh</source>
2810 <translation type="unfinished"></translation>
2811 </message>
2812 <message>
2813 <location filename="../systracefrm.ui" line="79"/>
2814 <source>Save &amp;previous</source>
2815 <translation type="unfinished"></translation>
2816 </message>
2817</context>
2818<context>
2819 <name>Sysinfo</name>
2820 <message>
2821 <location filename="../sysinfo.cpp" line="45"/>
2822 <source>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</source>
2823 <translation type="unfinished"></translation>
2824 </message>
2825 <message>
2826 <location filename="../sysinfo.cpp" line="46"/>
2827 <source>&lt;b&gt;Username&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2828 <translation type="unfinished"></translation>
2829 </message>
2830 <message>
2831 <location filename="../sysinfo.cpp" line="48"/>
2832 <source>&lt;b&gt;Permissions&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2833 <translation type="unfinished"></translation>
2834 </message>
2835 <message>
2836 <location filename="../sysinfo.cpp" line="50"/>
2837 <source>&lt;b&gt;Attached USB devices&lt;/b&gt;&lt;br/&gt;</source>
2838 <translation type="unfinished"></translation>
2839 </message>
2840 <message>
2841 <location filename="../sysinfo.cpp" line="54"/>
2842 <source>VID: %1 PID: %2, %3</source>
2843 <translation type="unfinished"></translation>
2844 </message>
2845 <message>
2846 <location filename="../sysinfo.cpp" line="63"/>
2847 <source>Filesystem</source>
2848 <translation type="unfinished"></translation>
2849 </message>
2850 <message>
2851 <location filename="../sysinfo.cpp" line="66"/>
2852 <source>Mountpoint</source>
2853 <translation type="unfinished"></translation>
2854 </message>
2855 <message>
2856 <location filename="../sysinfo.cpp" line="66"/>
2857 <source>Label</source>
2858 <translation type="unfinished"></translation>
2859 </message>
2860 <message>
2861 <location filename="../sysinfo.cpp" line="67"/>
2862 <source>Free</source>
2863 <translation type="unfinished"></translation>
2864 </message>
2865 <message>
2866 <location filename="../sysinfo.cpp" line="67"/>
2867 <source>Total</source>
2868 <translation type="unfinished"></translation>
2869 </message>
2870 <message>
2871 <location filename="../sysinfo.cpp" line="68"/>
2872 <source>Cluster Size</source>
2873 <translation type="unfinished"></translation>
2874 </message>
2875 <message>
2876 <location filename="../sysinfo.cpp" line="70"/>
2877 <source>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</source>
2878 <translation type="unfinished"></translation>
2879 </message>
2880</context>
2881<context>
2882 <name>SysinfoFrm</name>
2883 <message>
2884 <location filename="../sysinfofrm.ui" line="13"/>
2885 <source>System Info</source>
2886 <translation type="unfinished"></translation>
2887 </message>
2888 <message>
2889 <location filename="../sysinfofrm.ui" line="22"/>
2890 <source>&amp;Refresh</source>
2891 <translation type="unfinished"></translation>
2892 </message>
2893 <message>
2894 <location filename="../sysinfofrm.ui" line="45"/>
2895 <source>&amp;OK</source>
2896 <translation type="unfinished"></translation>
2897 </message>
2898</context>
2899<context>
2900 <name>System</name>
2901 <message>
2902 <location filename="../base/system.cpp" line="121"/>
2903 <source>Guest</source>
2904 <translation type="unfinished"></translation>
2905 </message>
2906 <message>
2907 <location filename="../base/system.cpp" line="124"/>
2908 <source>Admin</source>
2909 <translation type="unfinished"></translation>
2910 </message>
2911 <message>
2912 <location filename="../base/system.cpp" line="127"/>
2913 <source>User</source>
2914 <translation type="unfinished"></translation>
2915 </message>
2916 <message>
2917 <location filename="../base/system.cpp" line="130"/>
2918 <source>Error</source>
2919 <translation type="unfinished"></translation>
2920 </message>
2921 <message>
2922 <location filename="../base/system.cpp" line="278"/>
2923 <location filename="../base/system.cpp" line="323"/>
2924 <source>(no description available)</source>
2925 <translation type="unfinished"></translation>
2926 </message>
2927</context>
2928<context>
2929 <name>TTSBase</name>
2930 <message>
2931 <location filename="../base/ttsbase.cpp" line="45"/>
2932 <source>Espeak TTS Engine</source>
2933 <translation type="unfinished"></translation>
2934 </message>
2935 <message>
2936 <location filename="../base/ttsbase.cpp" line="47"/>
2937 <source>Flite TTS Engine</source>
2938 <translation type="unfinished"></translation>
2939 </message>
2940 <message>
2941 <location filename="../base/ttsbase.cpp" line="48"/>
2942 <source>Swift TTS Engine</source>
2943 <translation type="unfinished"></translation>
2944 </message>
2945 <message>
2946 <location filename="../base/ttsbase.cpp" line="51"/>
2947 <source>SAPI4 TTS Engine</source>
2948 <translation type="unfinished"></translation>
2949 </message>
2950 <message>
2951 <location filename="../base/ttsbase.cpp" line="53"/>
2952 <source>SAPI5 TTS Engine</source>
2953 <translation type="unfinished"></translation>
2954 </message>
2955 <message>
2956 <location filename="../base/ttsbase.cpp" line="54"/>
2957 <source>MS Speech Platform</source>
2958 <translation type="unfinished"></translation>
2959 </message>
2960 <message>
2961 <location filename="../base/ttsbase.cpp" line="57"/>
2962 <source>Festival TTS Engine</source>
2963 <translation type="unfinished"></translation>
2964 </message>
2965 <message>
2966 <location filename="../base/ttsbase.cpp" line="60"/>
2967 <source>OS X System Engine</source>
2968 <translation type="unfinished"></translation>
2969 </message>
2970</context>
2971<context>
2972 <name>TTSCarbon</name>
2973 <message>
2974 <location filename="../base/ttscarbon.cpp" line="139"/>
2975 <source>Voice:</source>
2976 <translation type="unfinished"></translation>
2977 </message>
2978 <message>
2979 <location filename="../base/ttscarbon.cpp" line="145"/>
2980 <source>Speed (words/min):</source>
2981 <translation type="unfinished"></translation>
2982 </message>
2983 <message>
2984 <location filename="../base/ttscarbon.cpp" line="152"/>
2985 <source>Pitch (0 for default):</source>
2986 <translation type="unfinished"></translation>
2987 </message>
2988 <message>
2989 <location filename="../base/ttscarbon.cpp" line="222"/>
2990 <source>Could not voice string</source>
2991 <translation type="unfinished"></translation>
2992 </message>
2993 <message>
2994 <location filename="../base/ttscarbon.cpp" line="232"/>
2995 <source>Could not convert intermediate file</source>
2996 <translation type="unfinished"></translation>
2997 </message>
2998</context>
2999<context>
3000 <name>TTSExes</name>
3001 <message>
3002 <location filename="../base/ttsexes.cpp" line="78"/>
3003 <source>TTS executable not found</source>
3004 <translation type="unfinished"></translation>
3005 </message>
3006 <message>
3007 <location filename="../base/ttsexes.cpp" line="44"/>
3008 <source>Path to TTS engine:</source>
3009 <translation type="unfinished"></translation>
3010 </message>
3011 <message>
3012 <location filename="../base/ttsexes.cpp" line="46"/>
3013 <source>TTS engine options:</source>
3014 <translation type="unfinished"></translation>
3015 </message>
3016</context>
3017<context>
3018 <name>TTSFestival</name>
3019 <message>
3020 <location filename="../base/ttsfestival.cpp" line="207"/>
3021 <source>engine could not voice string</source>
3022 <translation type="unfinished"></translation>
3023 </message>
3024 <message>
3025 <location filename="../base/ttsfestival.cpp" line="290"/>
3026 <source>No description available</source>
3027 <translation type="unfinished"></translation>
3028 </message>
3029 <message>
3030 <location filename="../base/ttsfestival.cpp" line="53"/>
3031 <source>Path to Festival client:</source>
3032 <translation type="unfinished"></translation>
3033 </message>
3034 <message>
3035 <location filename="../base/ttsfestival.cpp" line="58"/>
3036 <source>Voice:</source>
3037 <translation type="unfinished"></translation>
3038 </message>
3039 <message>
3040 <location filename="../base/ttsfestival.cpp" line="67"/>
3041 <source>Voice description:</source>
3042 <translation type="unfinished"></translation>
3043 </message>
3044</context>
3045<context>
3046 <name>TTSSapi</name>
3047 <message>
3048 <location filename="../base/ttssapi.cpp" line="49"/>
3049 <source>Language:</source>
3050 <translation type="unfinished"></translation>
3051 </message>
3052 <message>
3053 <location filename="../base/ttssapi.cpp" line="56"/>
3054 <source>Voice:</source>
3055 <translation type="unfinished"></translation>
3056 </message>
3057 <message>
3058 <location filename="../base/ttssapi.cpp" line="68"/>
3059 <source>Speed:</source>
3060 <translation type="unfinished"></translation>
3061 </message>
3062 <message>
3063 <location filename="../base/ttssapi.cpp" line="71"/>
3064 <source>Options:</source>
3065 <translation type="unfinished"></translation>
3066 </message>
3067 <message>
3068 <location filename="../base/ttssapi.cpp" line="115"/>
3069 <source>Could not copy the SAPI script</source>
3070 <translation type="unfinished"></translation>
3071 </message>
3072 <message>
3073 <location filename="../base/ttssapi.cpp" line="133"/>
3074 <source>Could not start SAPI process</source>
3075 <translation type="unfinished"></translation>
3076 </message>
3077</context>
3078<context>
3079 <name>TalkFileCreator</name>
3080 <message>
3081 <location filename="../base/talkfile.cpp" line="68"/>
3082 <source>Copying Talkfiles...</source>
3083 <translation type="unfinished"></translation>
3084 </message>
3085 <message>
3086 <location filename="../base/talkfile.cpp" line="240"/>
3087 <source>File copy aborted</source>
3088 <translation type="unfinished"></translation>
3089 </message>
3090 <message>
3091 <location filename="../base/talkfile.cpp" line="280"/>
3092 <source>Cleaning up...</source>
3093 <translation type="unfinished"></translation>
3094 </message>
3095 <message>
3096 <location filename="../base/talkfile.cpp" line="291"/>
3097 <source>Finished</source>
3098 <translation type="unfinished"></translation>
3099 </message>
3100 <message>
3101 <location filename="../base/talkfile.cpp" line="45"/>
3102 <source>Talk file creation aborted</source>
3103 <translation type="unfinished"></translation>
3104 </message>
3105 <message>
3106 <location filename="../base/talkfile.cpp" line="36"/>
3107 <source>Starting Talk file generation for folder %1</source>
3108 <translation type="unfinished"></translation>
3109 </message>
3110 <message>
3111 <location filename="../base/talkfile.cpp" line="80"/>
3112 <source>Finished creating Talk files</source>
3113 <translation type="unfinished"></translation>
3114 </message>
3115 <message>
3116 <location filename="../base/talkfile.cpp" line="42"/>
3117 <source>Reading Filelist...</source>
3118 <translation type="unfinished"></translation>
3119 </message>
3120 <message>
3121 <location filename="../base/talkfile.cpp" line="259"/>
3122 <source>Copying of %1 to %2 failed</source>
3123 <translation type="unfinished"></translation>
3124 </message>
3125</context>
3126<context>
3127 <name>TalkGenerator</name>
3128 <message>
3129 <location filename="../base/talkgenerator.cpp" line="39"/>
3130 <source>Starting TTS Engine</source>
3131 <translation type="unfinished"></translation>
3132 </message>
3133 <message>
3134 <location filename="../base/talkgenerator.cpp" line="44"/>
3135 <location filename="../base/talkgenerator.cpp" line="51"/>
3136 <source>Init of TTS engine failed</source>
3137 <translation type="unfinished"></translation>
3138 </message>
3139 <message>
3140 <location filename="../base/talkgenerator.cpp" line="58"/>
3141 <source>Starting Encoder Engine</source>
3142 <translation type="unfinished"></translation>
3143 </message>
3144 <message>
3145 <location filename="../base/talkgenerator.cpp" line="62"/>
3146 <source>Init of Encoder engine failed</source>
3147 <translation type="unfinished"></translation>
3148 </message>
3149 <message>
3150 <location filename="../base/talkgenerator.cpp" line="72"/>
3151 <source>Voicing entries...</source>
3152 <translation type="unfinished"></translation>
3153 </message>
3154 <message>
3155 <location filename="../base/talkgenerator.cpp" line="87"/>
3156 <source>Encoding files...</source>
3157 <translation type="unfinished"></translation>
3158 </message>
3159 <message>
3160 <location filename="../base/talkgenerator.cpp" line="126"/>
3161 <source>Voicing aborted</source>
3162 <translation type="unfinished"></translation>
3163 </message>
3164 <message>
3165 <location filename="../base/talkgenerator.cpp" line="162"/>
3166 <location filename="../base/talkgenerator.cpp" line="167"/>
3167 <source>Voicing of %1 failed: %2</source>
3168 <translation type="unfinished"></translation>
3169 </message>
3170 <message>
3171 <location filename="../base/talkgenerator.cpp" line="211"/>
3172 <source>Encoding aborted</source>
3173 <translation type="unfinished"></translation>
3174 </message>
3175 <message>
3176 <location filename="../base/talkgenerator.cpp" line="239"/>
3177 <source>Encoding of %1 failed</source>
3178 <translation type="unfinished"></translation>
3179 </message>
3180</context>
3181<context>
3182 <name>ThemeInstallFrm</name>
3183 <message>
3184 <location filename="../themesinstallfrm.ui" line="13"/>
3185 <source>Theme Installation</source>
3186 <translation>安装主题</translation>
3187 </message>
3188 <message>
3189 <location filename="../themesinstallfrm.ui" line="48"/>
3190 <source>Selected Theme</source>
3191 <translation>被选择的主题</translation>
3192 </message>
3193 <message>
3194 <location filename="../themesinstallfrm.ui" line="73"/>
3195 <source>Description</source>
3196 <translation>描述</translation>
3197 </message>
3198 <message>
3199 <location filename="../themesinstallfrm.ui" line="83"/>
3200 <source>Download size:</source>
3201 <translation>下载大小:</translation>
3202 </message>
3203 <message>
3204 <location filename="../themesinstallfrm.ui" line="125"/>
3205 <source>&amp;Cancel</source>
3206 <translation>&amp;取消</translation>
3207 </message>
3208 <message>
3209 <location filename="../themesinstallfrm.ui" line="115"/>
3210 <source>&amp;Install</source>
3211 <translation type="unfinished"></translation>
3212 </message>
3213 <message>
3214 <location filename="../themesinstallfrm.ui" line="93"/>
3215 <source>Hold Ctrl to select multiple item, Shift for a range</source>
3216 <translation type="unfinished"></translation>
3217 </message>
3218</context>
3219<context>
3220 <name>ThemesInstallWindow</name>
3221 <message>
3222 <location filename="../themesinstallwindow.cpp" line="40"/>
3223 <source>no theme selected</source>
3224 <translation>没有选择主题</translation>
3225 </message>
3226 <message>
3227 <location filename="../themesinstallwindow.cpp" line="125"/>
3228 <source>Network error: %1.
3229Please check your network and proxy settings.</source>
3230 <translation>网络错误: %1.
3231请检查你的网络和代理服务的设置.</translation>
3232 </message>
3233 <message>
3234 <location filename="../themesinstallwindow.cpp" line="144"/>
3235 <source>done.</source>
3236 <translation>完成.</translation>
3237 </message>
3238 <message>
3239 <location filename="../themesinstallwindow.cpp" line="211"/>
3240 <source>fetching details for %1</source>
3241 <translation>正在拿取 %1 的细节</translation>
3242 </message>
3243 <message>
3244 <location filename="../themesinstallwindow.cpp" line="214"/>
3245 <source>fetching preview ...</source>
3246 <translation>正在拿取预览...</translation>
3247 </message>
3248 <message>
3249 <location filename="../themesinstallwindow.cpp" line="227"/>
3250 <source>&lt;b&gt;Author:&lt;/b&gt; %1&lt;hr/&gt;</source>
3251 <translation>&lt;b&gt;作者:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3252 </message>
3253 <message>
3254 <location filename="../themesinstallwindow.cpp" line="228"/>
3255 <location filename="../themesinstallwindow.cpp" line="230"/>
3256 <source>unknown</source>
3257 <translation>不明</translation>
3258 </message>
3259 <message>
3260 <location filename="../themesinstallwindow.cpp" line="229"/>
3261 <source>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</source>
3262 <translation>&lt;b&gt;版本:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3263 </message>
3264 <message>
3265 <location filename="../themesinstallwindow.cpp" line="231"/>
3266 <source>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</source>
3267 <translation>&lt;b&gt;描述:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3268 </message>
3269 <message>
3270 <location filename="../themesinstallwindow.cpp" line="232"/>
3271 <source>no description</source>
3272 <translation>无描述</translation>
3273 </message>
3274 <message>
3275 <location filename="../themesinstallwindow.cpp" line="260"/>
3276 <source>no theme preview</source>
3277 <translation>无主题预览</translation>
3278 </message>
3279 <message>
3280 <location filename="../themesinstallwindow.cpp" line="289"/>
3281 <source>Select</source>
3282 <translation type="unfinished"></translation>
3283 </message>
3284 <message>
3285 <location filename="../themesinstallwindow.cpp" line="296"/>
3286 <source>getting themes information ...</source>
3287 <translation>正在拿取主题信息...</translation>
3288 </message>
3289 <message>
3290 <location filename="../themesinstallwindow.cpp" line="326"/>
3291 <source>No themes selected, skipping</source>
3292 <translation type="unfinished"></translation>
3293 </message>
3294 <message>
3295 <location filename="../themesinstallwindow.cpp" line="356"/>
3296 <source>Mount point is wrong!</source>
3297 <translation>Mountpoint 错误!</translation>
3298 </message>
3299 <message>
3300 <location filename="../themesinstallwindow.cpp" line="138"/>
3301 <source>the following error occured:
3302%1</source>
3303 <translation type="unfinished"></translation>
3304 </message>
3305 <message>
3306 <location filename="../themesinstallwindow.cpp" line="41"/>
3307 <source>no selection</source>
3308 <translation type="unfinished"></translation>
3309 </message>
3310 <message>
3311 <location filename="../themesinstallwindow.cpp" line="181"/>
3312 <source>Information</source>
3313 <translation type="unfinished"></translation>
3314 </message>
3315 <message numerus="yes">
3316 <location filename="../themesinstallwindow.cpp" line="198"/>
3317 <source>Download size %L1 kiB (%n item(s))</source>
3318 <translation type="unfinished">
3319 <numerusform></numerusform>
3320 </translation>
3321 </message>
3322 <message>
3323 <location filename="../themesinstallwindow.cpp" line="248"/>
3324 <source>Retrieving theme preview failed.
3325HTTP response code: %1</source>
3326 <translation type="unfinished"></translation>
3327 </message>
3328</context>
3329<context>
3330 <name>UninstallFrm</name>
3331 <message>
3332 <location filename="../uninstallfrm.ui" line="16"/>
3333 <source>Uninstall Rockbox</source>
3334 <translation>卸载 Rockbox</translation>
3335 </message>
3336 <message>
3337 <location filename="../uninstallfrm.ui" line="35"/>
3338 <source>Please select the Uninstallation Method</source>
3339 <translation>请选择卸载模式</translation>
3340 </message>
3341 <message>
3342 <location filename="../uninstallfrm.ui" line="45"/>
3343 <source>Uninstallation Method</source>
3344 <translation>卸载模式</translation>
3345 </message>
3346 <message>
3347 <location filename="../uninstallfrm.ui" line="51"/>
3348 <source>Complete Uninstallation</source>
3349 <translation>完全卸载</translation>
3350 </message>
3351 <message>
3352 <location filename="../uninstallfrm.ui" line="58"/>
3353 <source>Smart Uninstallation</source>
3354 <translation>智能卸载</translation>
3355 </message>
3356 <message>
3357 <location filename="../uninstallfrm.ui" line="68"/>
3358 <source>Please select what you want to uninstall</source>
3359 <translation>请选择卸载部分</translation>
3360 </message>
3361 <message>
3362 <location filename="../uninstallfrm.ui" line="78"/>
3363 <source>Installed Parts</source>
3364 <translation>已安装的部分</translation>
3365 </message>
3366 <message>
3367 <location filename="../uninstallfrm.ui" line="138"/>
3368 <source>&amp;Cancel</source>
3369 <translation>&amp;取消</translation>
3370 </message>
3371 <message>
3372 <location filename="../uninstallfrm.ui" line="128"/>
3373 <source>&amp;Uninstall</source>
3374 <translation type="unfinished"></translation>
3375 </message>
3376</context>
3377<context>
3378 <name>Uninstaller</name>
3379 <message>
3380 <location filename="../base/uninstall.cpp" line="32"/>
3381 <location filename="../base/uninstall.cpp" line="43"/>
3382 <source>Starting Uninstallation</source>
3383 <translation>开始卸载</translation>
3384 </message>
3385 <message>
3386 <location filename="../base/uninstall.cpp" line="36"/>
3387 <source>Finished Uninstallation</source>
3388 <translation>完成卸载</translation>
3389 </message>
3390 <message>
3391 <location filename="../base/uninstall.cpp" line="49"/>
3392 <source>Uninstalling %1...</source>
3393 <translation type="unfinished"></translation>
3394 </message>
3395 <message>
3396 <location filename="../base/uninstall.cpp" line="80"/>
3397 <source>Could not delete %1</source>
3398 <translation type="unfinished"></translation>
3399 </message>
3400 <message>
3401 <location filename="../base/uninstall.cpp" line="109"/>
3402 <source>Uninstallation finished</source>
3403 <translation>完成卸载</translation>
3404 </message>
3405</context>
3406<context>
3407 <name>Utils</name>
3408 <message>
3409 <location filename="../base/utils.cpp" line="312"/>
3410 <source>&lt;li&gt;Permissions insufficient for bootloader installation.
3411Administrator priviledges are necessary.&lt;/li&gt;</source>
3412 <translation type="unfinished"></translation>
3413 </message>
3414 <message>
3415 <location filename="../base/utils.cpp" line="324"/>
3416 <source>&lt;li&gt;Target mismatch detected.&lt;br/&gt;Installed target: %1&lt;br/&gt;Selected target: %2.&lt;/li&gt;</source>
3417 <translation type="unfinished"></translation>
3418 </message>
3419 <message>
3420 <location filename="../base/utils.cpp" line="331"/>
3421 <source>Problem detected:</source>
3422 <translation type="unfinished"></translation>
3423 </message>
3424</context>
3425<context>
3426 <name>VoiceFileCreator</name>
3427 <message>
3428 <location filename="../base/voicefile.cpp" line="43"/>
3429 <source>Starting Voicefile generation</source>
3430 <translation type="unfinished"></translation>
3431 </message>
3432 <message>
3433 <location filename="../base/voicefile.cpp" line="90"/>
3434 <source>Extracted voice strings from installation</source>
3435 <translation type="unfinished"></translation>
3436 </message>
3437 <message>
3438 <location filename="../base/voicefile.cpp" line="100"/>
3439 <source>Extracted voice strings incompatible</source>
3440 <translation type="unfinished"></translation>
3441 </message>
3442 <message>
3443 <location filename="../base/voicefile.cpp" line="145"/>
3444 <source>Could not retrieve strings from installation, downloading</source>
3445 <translation type="unfinished"></translation>
3446 </message>
3447 <message>
3448 <location filename="../base/voicefile.cpp" line="171"/>
3449 <source>Downloading voice info...</source>
3450 <translation type="unfinished"></translation>
3451 </message>
3452 <message>
3453 <location filename="../base/voicefile.cpp" line="184"/>
3454 <source>Download error: received HTTP error %1.</source>
3455 <translation type="unfinished">下载错误: 接到 HTTP 错误 %1. </translation>
3456 </message>
3457 <message>
3458 <location filename="../base/voicefile.cpp" line="191"/>
3459 <source>Cached file used.</source>
3460 <translation type="unfinished">使用缓冲文件.</translation>
3461 </message>
3462 <message>
3463 <location filename="../base/voicefile.cpp" line="194"/>
3464 <source>Download error: %1</source>
3465 <translation type="unfinished">下载错误: %1</translation>
3466 </message>
3467 <message>
3468 <location filename="../base/voicefile.cpp" line="199"/>
3469 <source>Download finished.</source>
3470 <translation type="unfinished">完成下载.</translation>
3471 </message>
3472 <message>
3473 <location filename="../base/voicefile.cpp" line="212"/>
3474 <source>failed to open downloaded file</source>
3475 <translation type="unfinished"></translation>
3476 </message>
3477 <message>
3478 <location filename="../base/voicefile.cpp" line="218"/>
3479 <source>Reading strings...</source>
3480 <translation type="unfinished"></translation>
3481 </message>
3482 <message>
3483 <location filename="../base/voicefile.cpp" line="297"/>
3484 <source>Creating voicefiles...</source>
3485 <translation type="unfinished"></translation>
3486 </message>
3487 <message>
3488 <location filename="../base/voicefile.cpp" line="342"/>
3489 <source>Cleaning up...</source>
3490 <translation type="unfinished"></translation>
3491 </message>
3492 <message>
3493 <location filename="../base/voicefile.cpp" line="353"/>
3494 <source>Finished</source>
3495 <translation type="unfinished"></translation>
3496 </message>
3497 <message>
3498 <location filename="../base/voicefile.cpp" line="271"/>
3499 <source>The downloaded file was empty!</source>
3500 <translation type="unfinished"></translation>
3501 </message>
3502 <message>
3503 <location filename="../base/voicefile.cpp" line="302"/>
3504 <source>Error opening downloaded file</source>
3505 <translation type="unfinished"></translation>
3506 </message>
3507 <message>
3508 <location filename="../base/voicefile.cpp" line="313"/>
3509 <source>Error opening output file</source>
3510 <translation type="unfinished"></translation>
3511 </message>
3512 <message>
3513 <location filename="../base/voicefile.cpp" line="333"/>
3514 <source>successfully created.</source>
3515 <translation type="unfinished"></translation>
3516 </message>
3517 <message>
3518 <location filename="../base/voicefile.cpp" line="56"/>
3519 <source>could not find rockbox-info.txt</source>
3520 <translation type="unfinished"></translation>
3521 </message>
3522</context>
3523<context>
3524 <name>ZipInstaller</name>
3525 <message>
3526 <location filename="../base/zipinstaller.cpp" line="60"/>
3527 <source>done.</source>
3528 <translation>完成.</translation>
3529 </message>
3530 <message>
3531 <location filename="../base/zipinstaller.cpp" line="68"/>
3532 <source>Package installation finished successfully.</source>
3533 <translation type="unfinished"></translation>
3534 </message>
3535 <message>
3536 <location filename="../base/zipinstaller.cpp" line="80"/>
3537 <source>Downloading file %1.%2</source>
3538 <translation>正在下载文件 %1.%2</translation>
3539 </message>
3540 <message>
3541 <location filename="../base/zipinstaller.cpp" line="115"/>
3542 <source>Download error: received HTTP error %1.</source>
3543 <translation>下载错误: 接到 HTTP 错误 %1. </translation>
3544 </message>
3545 <message>
3546 <location filename="../base/zipinstaller.cpp" line="121"/>
3547 <source>Cached file used.</source>
3548 <translation>使用缓冲文件.</translation>
3549 </message>
3550 <message>
3551 <location filename="../base/zipinstaller.cpp" line="123"/>
3552 <source>Download error: %1</source>
3553 <translation>下载错误: %1</translation>
3554 </message>
3555 <message>
3556 <location filename="../base/zipinstaller.cpp" line="127"/>
3557 <source>Download finished.</source>
3558 <translation>完成下载.</translation>
3559 </message>
3560 <message>
3561 <location filename="../base/zipinstaller.cpp" line="133"/>
3562 <source>Extracting file.</source>
3563 <translation>正在解压文件.</translation>
3564 </message>
3565 <message>
3566 <location filename="../base/zipinstaller.cpp" line="153"/>
3567 <source>Extraction failed!</source>
3568 <translation type="unfinished"></translation>
3569 </message>
3570 <message>
3571 <location filename="../base/zipinstaller.cpp" line="162"/>
3572 <source>Installing file.</source>
3573 <translation>正在安装文件.</translation>
3574 </message>
3575 <message>
3576 <location filename="../base/zipinstaller.cpp" line="173"/>
3577 <source>Installing file failed.</source>
3578 <translation>安装文件失败.</translation>
3579 </message>
3580 <message>
3581 <location filename="../base/zipinstaller.cpp" line="186"/>
3582 <source>Creating installation log</source>
3583 <translation>正在建立安装日志</translation>
3584 </message>
3585 <message>
3586 <location filename="../base/zipinstaller.cpp" line="146"/>
3587 <source>Not enough disk space! Aborting.</source>
3588 <translation type="unfinished"></translation>
3589 </message>
3590</context>
3591<context>
3592 <name>ZipUtil</name>
3593 <message>
3594 <location filename="../base/ziputil.cpp" line="125"/>
3595 <source>Creating output path failed</source>
3596 <translation type="unfinished"></translation>
3597 </message>
3598 <message>
3599 <location filename="../base/ziputil.cpp" line="132"/>
3600 <source>Creating output file failed</source>
3601 <translation type="unfinished"></translation>
3602 </message>
3603 <message>
3604 <location filename="../base/ziputil.cpp" line="141"/>
3605 <source>Error during Zip operation</source>
3606 <translation type="unfinished"></translation>
3607 </message>
3608</context>
3609<context>
3610 <name>aboutBox</name>
3611 <message>
3612 <location filename="../aboutbox.ui" line="14"/>
3613 <source>About Rockbox Utility</source>
3614 <translation>关于Rockbox安装程序</translation>
3615 </message>
3616 <message>
3617 <location filename="../aboutbox.ui" line="32"/>
3618 <source>The Rockbox Utility</source>
3619 <translation>Rockbox安装程序</translation>
3620 </message>
3621 <message utf8="true">
3622 <location filename="../aboutbox.ui" line="54"/>
3623 <source>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</source>
3624 <translation type="unfinished"></translation>
3625 </message>
3626 <message>
3627 <location filename="../aboutbox.ui" line="74"/>
3628 <source>&amp;Credits</source>
3629 <translation>&amp;特别鸣谢</translation>
3630 </message>
3631 <message>
3632 <location filename="../aboutbox.ui" line="106"/>
3633 <source>&amp;License</source>
3634 <translation>&amp;授权</translation>
3635 </message>
3636 <message>
3637 <location filename="../aboutbox.ui" line="132"/>
3638 <source>&amp;Speex License</source>
3639 <translation type="unfinished"></translation>
3640 </message>
3641 <message>
3642 <location filename="../aboutbox.ui" line="158"/>
3643 <source>&amp;Ok</source>
3644 <translation>&amp;OK</translation>
3645 </message>
3646</context>
3647</TS>
diff --git a/utils/rbutilqt/lang/rbutil_zh_TW.ts b/utils/rbutilqt/lang/rbutil_zh_TW.ts
new file mode 100644
index 0000000000..96aaf40395
--- /dev/null
+++ b/utils/rbutilqt/lang/rbutil_zh_TW.ts
@@ -0,0 +1,3647 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE TS>
3<TS version="2.0" language="zh">
4<context>
5 <name>BackupDialog</name>
6 <message>
7 <location filename="../gui/backupdialogfrm.ui" line="17"/>
8 <location filename="../gui/backupdialogfrm.ui" line="43"/>
9 <source>Backup</source>
10 <translation type="unfinished"></translation>
11 </message>
12 <message>
13 <location filename="../gui/backupdialogfrm.ui" line="33"/>
14 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This dialog will create a backup by archiving the contents of the Rockbox installation on the player into a zip file. This will include installed themes and settings stored below the .rockbox folder on the player.&lt;/p&gt;&lt;p&gt;The backup filename will be created based on the installed version. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
15 <translation type="unfinished"></translation>
16 </message>
17 <message>
18 <location filename="../gui/backupdialogfrm.ui" line="49"/>
19 <source>Size: unknown</source>
20 <translation type="unfinished"></translation>
21 </message>
22 <message>
23 <location filename="../gui/backupdialogfrm.ui" line="56"/>
24 <source>Backup to: unknown</source>
25 <translation type="unfinished"></translation>
26 </message>
27 <message>
28 <location filename="../gui/backupdialogfrm.ui" line="76"/>
29 <source>&amp;Change</source>
30 <translation type="unfinished">&amp;更改</translation>
31 </message>
32 <message>
33 <location filename="../gui/backupdialogfrm.ui" line="116"/>
34 <source>&amp;Backup</source>
35 <translation type="unfinished"></translation>
36 </message>
37 <message>
38 <location filename="../gui/backupdialogfrm.ui" line="127"/>
39 <source>&amp;Cancel</source>
40 <translation type="unfinished">&amp;取消</translation>
41 </message>
42 <message>
43 <location filename="../gui/backupdialog.cpp" line="70"/>
44 <source>Installation size: calculating ...</source>
45 <translation type="unfinished"></translation>
46 </message>
47 <message>
48 <location filename="../gui/backupdialog.cpp" line="89"/>
49 <source>Select Backup Filename</source>
50 <translation type="unfinished"></translation>
51 </message>
52 <message>
53 <location filename="../gui/backupdialog.cpp" line="109"/>
54 <source>Installation size: %L1 %2</source>
55 <translation type="unfinished"></translation>
56 </message>
57 <message>
58 <location filename="../gui/backupdialog.cpp" line="116"/>
59 <source>File exists</source>
60 <translation type="unfinished"></translation>
61 </message>
62 <message>
63 <location filename="../gui/backupdialog.cpp" line="117"/>
64 <source>The selected backup file already exists. Overwrite?</source>
65 <translation type="unfinished"></translation>
66 </message>
67 <message>
68 <location filename="../gui/backupdialog.cpp" line="125"/>
69 <source>Starting backup ...</source>
70 <translation type="unfinished"></translation>
71 </message>
72 <message>
73 <location filename="../gui/backupdialog.cpp" line="144"/>
74 <source>Backup successful.</source>
75 <translation type="unfinished"></translation>
76 </message>
77 <message>
78 <location filename="../gui/backupdialog.cpp" line="147"/>
79 <source>Backup failed!</source>
80 <translation type="unfinished"></translation>
81 </message>
82</context>
83<context>
84 <name>BootloaderInstallAms</name>
85 <message>
86 <location filename="../base/bootloaderinstallams.cpp" line="33"/>
87 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (bin file). This firmware file will be patched and then installed to your player along with the rockbox bootloader. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/SansaAMS&apos;&gt;SansaAMS&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; This file is not present on your player and will disappear automatically after installing it.&lt;br/&gt;&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
88 <translation type="unfinished"></translation>
89 </message>
90 <message>
91 <location filename="../base/bootloaderinstallams.cpp" line="58"/>
92 <source>Downloading bootloader file</source>
93 <translation type="unfinished"></translation>
94 </message>
95 <message>
96 <location filename="../base/bootloaderinstallams.cpp" line="100"/>
97 <location filename="../base/bootloaderinstallams.cpp" line="113"/>
98 <source>Could not load %1</source>
99 <translation type="unfinished"></translation>
100 </message>
101 <message>
102 <location filename="../base/bootloaderinstallams.cpp" line="127"/>
103 <source>No room to insert bootloader, try another firmware version</source>
104 <translation type="unfinished"></translation>
105 </message>
106 <message>
107 <location filename="../base/bootloaderinstallams.cpp" line="137"/>
108 <source>Patching Firmware...</source>
109 <translation type="unfinished"></translation>
110 </message>
111 <message>
112 <location filename="../base/bootloaderinstallams.cpp" line="148"/>
113 <source>Could not open %1 for writing</source>
114 <translation type="unfinished"></translation>
115 </message>
116 <message>
117 <location filename="../base/bootloaderinstallams.cpp" line="161"/>
118 <source>Could not write firmware file</source>
119 <translation type="unfinished"></translation>
120 </message>
121 <message>
122 <location filename="../base/bootloaderinstallams.cpp" line="177"/>
123 <source>Success: modified firmware file created</source>
124 <translation type="unfinished"></translation>
125 </message>
126 <message>
127 <location filename="../base/bootloaderinstallams.cpp" line="185"/>
128 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
129 <translation type="unfinished"></translation>
130 </message>
131</context>
132<context>
133 <name>BootloaderInstallBase</name>
134 <message>
135 <location filename="../base/bootloaderinstallbase.cpp" line="78"/>
136 <source>Download error: received HTTP error %1.</source>
137 <translation type="unfinished">下載錯誤: 接到 HTTP 錯誤 %1. </translation>
138 </message>
139 <message>
140 <location filename="../base/bootloaderinstallbase.cpp" line="84"/>
141 <source>Download error: %1</source>
142 <translation type="unfinished">下載錯誤: %1</translation>
143 </message>
144 <message>
145 <location filename="../base/bootloaderinstallbase.cpp" line="90"/>
146 <source>Download finished (cache used).</source>
147 <translation type="unfinished"></translation>
148 </message>
149 <message>
150 <location filename="../base/bootloaderinstallbase.cpp" line="92"/>
151 <source>Download finished.</source>
152 <translation type="unfinished">完成下載.</translation>
153 </message>
154 <message>
155 <location filename="../base/bootloaderinstallbase.cpp" line="113"/>
156 <source>Creating backup of original firmware file.</source>
157 <translation type="unfinished"></translation>
158 </message>
159 <message>
160 <location filename="../base/bootloaderinstallbase.cpp" line="115"/>
161 <source>Creating backup folder failed</source>
162 <translation type="unfinished"></translation>
163 </message>
164 <message>
165 <location filename="../base/bootloaderinstallbase.cpp" line="121"/>
166 <source>Creating backup copy failed.</source>
167 <translation type="unfinished"></translation>
168 </message>
169 <message>
170 <location filename="../base/bootloaderinstallbase.cpp" line="124"/>
171 <source>Backup created.</source>
172 <translation type="unfinished"></translation>
173 </message>
174 <message>
175 <location filename="../base/bootloaderinstallbase.cpp" line="137"/>
176 <source>Creating installation log</source>
177 <translation type="unfinished">正在建立安裝日志</translation>
178 </message>
179 <message>
180 <location filename="../base/bootloaderinstallbase.cpp" line="226"/>
181 <source>Zip file format detected</source>
182 <translation type="unfinished"></translation>
183 </message>
184 <message>
185 <location filename="../base/bootloaderinstallbase.cpp" line="238"/>
186 <source>CAB file format detected</source>
187 <translation type="unfinished"></translation>
188 </message>
189 <message>
190 <location filename="../base/bootloaderinstallbase.cpp" line="259"/>
191 <source>Extracting firmware %1 from archive</source>
192 <translation type="unfinished"></translation>
193 </message>
194 <message>
195 <location filename="../base/bootloaderinstallbase.cpp" line="266"/>
196 <source>Error extracting firmware from archive</source>
197 <translation type="unfinished"></translation>
198 </message>
199 <message>
200 <location filename="../base/bootloaderinstallbase.cpp" line="275"/>
201 <source>Could not find firmware in archive</source>
202 <translation type="unfinished"></translation>
203 </message>
204 <message>
205 <location filename="../base/bootloaderinstallbase.cpp" line="159"/>
206 <source>Waiting for system to remount player</source>
207 <translation type="unfinished"></translation>
208 </message>
209 <message>
210 <location filename="../base/bootloaderinstallbase.cpp" line="189"/>
211 <source>Player remounted</source>
212 <translation type="unfinished"></translation>
213 </message>
214 <message>
215 <location filename="../base/bootloaderinstallbase.cpp" line="194"/>
216 <source>Timeout on remount</source>
217 <translation type="unfinished"></translation>
218 </message>
219 <message>
220 <location filename="../base/bootloaderinstallbase.cpp" line="149"/>
221 <source>Installation log created</source>
222 <translation type="unfinished"></translation>
223 </message>
224</context>
225<context>
226 <name>BootloaderInstallChinaChip</name>
227 <message>
228 <location filename="../base/bootloaderinstallchinachip.cpp" line="33"/>
229 <source>Bootloader installation requires you to provide a firmware file of the original firmware (HXF file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/OndaVX747#Download_and_extract_a_recent_ve&apos;&gt;OndaVX747&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
230 <translation type="unfinished"></translation>
231 </message>
232 <message>
233 <location filename="../base/bootloaderinstallchinachip.cpp" line="50"/>
234 <source>Downloading bootloader file</source>
235 <translation type="unfinished"></translation>
236 </message>
237 <message>
238 <location filename="../base/bootloaderinstallchinachip.cpp" line="75"/>
239 <source>Could not open firmware file</source>
240 <translation type="unfinished"></translation>
241 </message>
242 <message>
243 <location filename="../base/bootloaderinstallchinachip.cpp" line="78"/>
244 <source>Could not open bootloader file</source>
245 <translation type="unfinished"></translation>
246 </message>
247 <message>
248 <location filename="../base/bootloaderinstallchinachip.cpp" line="81"/>
249 <source>Could not allocate memory</source>
250 <translation type="unfinished"></translation>
251 </message>
252 <message>
253 <location filename="../base/bootloaderinstallchinachip.cpp" line="84"/>
254 <source>Could not load firmware file</source>
255 <translation type="unfinished"></translation>
256 </message>
257 <message>
258 <location filename="../base/bootloaderinstallchinachip.cpp" line="87"/>
259 <source>File is not a valid ChinaChip firmware</source>
260 <translation type="unfinished"></translation>
261 </message>
262 <message>
263 <location filename="../base/bootloaderinstallchinachip.cpp" line="90"/>
264 <source>Could not find ccpmp.bin in input file</source>
265 <translation type="unfinished"></translation>
266 </message>
267 <message>
268 <location filename="../base/bootloaderinstallchinachip.cpp" line="93"/>
269 <source>Could not open backup file for ccpmp.bin</source>
270 <translation type="unfinished"></translation>
271 </message>
272 <message>
273 <location filename="../base/bootloaderinstallchinachip.cpp" line="96"/>
274 <source>Could not write backup file for ccpmp.bin</source>
275 <translation type="unfinished"></translation>
276 </message>
277 <message>
278 <location filename="../base/bootloaderinstallchinachip.cpp" line="99"/>
279 <source>Could not load bootloader file</source>
280 <translation type="unfinished"></translation>
281 </message>
282 <message>
283 <location filename="../base/bootloaderinstallchinachip.cpp" line="102"/>
284 <source>Could not get current time</source>
285 <translation type="unfinished"></translation>
286 </message>
287 <message>
288 <location filename="../base/bootloaderinstallchinachip.cpp" line="105"/>
289 <source>Could not open output file</source>
290 <translation type="unfinished"></translation>
291 </message>
292 <message>
293 <location filename="../base/bootloaderinstallchinachip.cpp" line="108"/>
294 <source>Could not write output file</source>
295 <translation type="unfinished"></translation>
296 </message>
297 <message>
298 <location filename="../base/bootloaderinstallchinachip.cpp" line="111"/>
299 <source>Unexpected error from chinachippatcher</source>
300 <translation type="unfinished"></translation>
301 </message>
302</context>
303<context>
304 <name>BootloaderInstallFile</name>
305 <message>
306 <location filename="../base/bootloaderinstallfile.cpp" line="34"/>
307 <source>Downloading bootloader</source>
308 <translation type="unfinished"></translation>
309 </message>
310 <message>
311 <location filename="../base/bootloaderinstallfile.cpp" line="43"/>
312 <source>Installing Rockbox bootloader</source>
313 <translation type="unfinished"></translation>
314 </message>
315 <message>
316 <location filename="../base/bootloaderinstallfile.cpp" line="75"/>
317 <source>Error accessing output folder</source>
318 <translation type="unfinished"></translation>
319 </message>
320 <message>
321 <location filename="../base/bootloaderinstallfile.cpp" line="89"/>
322 <source>A firmware file is already present on player</source>
323 <translation type="unfinished"></translation>
324 </message>
325 <message>
326 <location filename="../base/bootloaderinstallfile.cpp" line="94"/>
327 <source>Bootloader successful installed</source>
328 <translation type="unfinished"></translation>
329 </message>
330 <message>
331 <location filename="../base/bootloaderinstallfile.cpp" line="97"/>
332 <source>Copying modified firmware file failed</source>
333 <translation type="unfinished"></translation>
334 </message>
335 <message>
336 <location filename="../base/bootloaderinstallfile.cpp" line="111"/>
337 <source>Removing Rockbox bootloader</source>
338 <translation type="unfinished"></translation>
339 </message>
340 <message>
341 <location filename="../base/bootloaderinstallfile.cpp" line="115"/>
342 <source>No original firmware file found.</source>
343 <translation type="unfinished"></translation>
344 </message>
345 <message>
346 <location filename="../base/bootloaderinstallfile.cpp" line="121"/>
347 <source>Can&apos;t remove Rockbox bootloader file.</source>
348 <translation type="unfinished"></translation>
349 </message>
350 <message>
351 <location filename="../base/bootloaderinstallfile.cpp" line="126"/>
352 <source>Can&apos;t restore bootloader file.</source>
353 <translation type="unfinished"></translation>
354 </message>
355 <message>
356 <location filename="../base/bootloaderinstallfile.cpp" line="130"/>
357 <source>Original bootloader restored successfully.</source>
358 <translation type="unfinished"></translation>
359 </message>
360</context>
361<context>
362 <name>BootloaderInstallHex</name>
363 <message>
364 <location filename="../base/bootloaderinstallhex.cpp" line="69"/>
365 <source>checking MD5 hash of input file ...</source>
366 <translation type="unfinished"></translation>
367 </message>
368 <message>
369 <location filename="../base/bootloaderinstallhex.cpp" line="80"/>
370 <source>Could not verify original firmware file</source>
371 <translation type="unfinished"></translation>
372 </message>
373 <message>
374 <location filename="../base/bootloaderinstallhex.cpp" line="95"/>
375 <source>Firmware file not recognized.</source>
376 <translation type="unfinished"></translation>
377 </message>
378 <message>
379 <location filename="../base/bootloaderinstallhex.cpp" line="99"/>
380 <source>MD5 hash ok</source>
381 <translation type="unfinished"></translation>
382 </message>
383 <message>
384 <location filename="../base/bootloaderinstallhex.cpp" line="106"/>
385 <source>Firmware file doesn&apos;t match selected player.</source>
386 <translation type="unfinished"></translation>
387 </message>
388 <message>
389 <location filename="../base/bootloaderinstallhex.cpp" line="111"/>
390 <source>Descrambling file</source>
391 <translation type="unfinished"></translation>
392 </message>
393 <message>
394 <location filename="../base/bootloaderinstallhex.cpp" line="119"/>
395 <source>Error in descramble: %1</source>
396 <translation type="unfinished"></translation>
397 </message>
398 <message>
399 <location filename="../base/bootloaderinstallhex.cpp" line="124"/>
400 <source>Downloading bootloader file</source>
401 <translation type="unfinished"></translation>
402 </message>
403 <message>
404 <location filename="../base/bootloaderinstallhex.cpp" line="134"/>
405 <source>Adding bootloader to firmware file</source>
406 <translation type="unfinished"></translation>
407 </message>
408 <message>
409 <location filename="../base/bootloaderinstallhex.cpp" line="172"/>
410 <source>could not open input file</source>
411 <translation type="unfinished"></translation>
412 </message>
413 <message>
414 <location filename="../base/bootloaderinstallhex.cpp" line="173"/>
415 <source>reading header failed</source>
416 <translation type="unfinished"></translation>
417 </message>
418 <message>
419 <location filename="../base/bootloaderinstallhex.cpp" line="174"/>
420 <source>reading firmware failed</source>
421 <translation type="unfinished"></translation>
422 </message>
423 <message>
424 <location filename="../base/bootloaderinstallhex.cpp" line="175"/>
425 <source>can&apos;t open bootloader file</source>
426 <translation type="unfinished"></translation>
427 </message>
428 <message>
429 <location filename="../base/bootloaderinstallhex.cpp" line="176"/>
430 <source>reading bootloader file failed</source>
431 <translation type="unfinished"></translation>
432 </message>
433 <message>
434 <location filename="../base/bootloaderinstallhex.cpp" line="177"/>
435 <source>can&apos;t open output file</source>
436 <translation type="unfinished"></translation>
437 </message>
438 <message>
439 <location filename="../base/bootloaderinstallhex.cpp" line="178"/>
440 <source>writing output file failed</source>
441 <translation type="unfinished"></translation>
442 </message>
443 <message>
444 <location filename="../base/bootloaderinstallhex.cpp" line="180"/>
445 <source>Error in patching: %1</source>
446 <translation type="unfinished"></translation>
447 </message>
448 <message>
449 <location filename="../base/bootloaderinstallhex.cpp" line="191"/>
450 <source>Error in scramble: %1</source>
451 <translation type="unfinished"></translation>
452 </message>
453 <message>
454 <location filename="../base/bootloaderinstallhex.cpp" line="206"/>
455 <source>Checking modified firmware file</source>
456 <translation type="unfinished"></translation>
457 </message>
458 <message>
459 <location filename="../base/bootloaderinstallhex.cpp" line="208"/>
460 <source>Error: modified file checksum wrong</source>
461 <translation type="unfinished"></translation>
462 </message>
463 <message>
464 <location filename="../base/bootloaderinstallhex.cpp" line="215"/>
465 <source>A firmware file is already present on player</source>
466 <translation type="unfinished"></translation>
467 </message>
468 <message>
469 <location filename="../base/bootloaderinstallhex.cpp" line="220"/>
470 <source>Success: modified firmware file created</source>
471 <translation type="unfinished"></translation>
472 </message>
473 <message>
474 <location filename="../base/bootloaderinstallhex.cpp" line="223"/>
475 <source>Copying modified firmware file failed</source>
476 <translation type="unfinished"></translation>
477 </message>
478 <message>
479 <location filename="../base/bootloaderinstallhex.cpp" line="237"/>
480 <source>Uninstallation not possible, only installation info removed</source>
481 <translation type="unfinished"></translation>
482 </message>
483 <message>
484 <location filename="../base/bootloaderinstallhex.cpp" line="258"/>
485 <source>Can&apos;t open input file</source>
486 <translation type="unfinished"></translation>
487 </message>
488 <message>
489 <location filename="../base/bootloaderinstallhex.cpp" line="259"/>
490 <source>Can&apos;t open output file</source>
491 <translation type="unfinished"></translation>
492 </message>
493 <message>
494 <location filename="../base/bootloaderinstallhex.cpp" line="260"/>
495 <source>invalid file: header length wrong</source>
496 <translation type="unfinished"></translation>
497 </message>
498 <message>
499 <location filename="../base/bootloaderinstallhex.cpp" line="261"/>
500 <source>invalid file: unrecognized header</source>
501 <translation type="unfinished"></translation>
502 </message>
503 <message>
504 <location filename="../base/bootloaderinstallhex.cpp" line="262"/>
505 <source>invalid file: &quot;length&quot; field wrong</source>
506 <translation type="unfinished"></translation>
507 </message>
508 <message>
509 <location filename="../base/bootloaderinstallhex.cpp" line="263"/>
510 <source>invalid file: &quot;length2&quot; field wrong</source>
511 <translation type="unfinished"></translation>
512 </message>
513 <message>
514 <location filename="../base/bootloaderinstallhex.cpp" line="264"/>
515 <source>invalid file: internal checksum error</source>
516 <translation type="unfinished"></translation>
517 </message>
518 <message>
519 <location filename="../base/bootloaderinstallhex.cpp" line="265"/>
520 <source>invalid file: &quot;length3&quot; field wrong</source>
521 <translation type="unfinished"></translation>
522 </message>
523 <message>
524 <location filename="../base/bootloaderinstallhex.cpp" line="266"/>
525 <source>unknown</source>
526 <translation type="unfinished">不明</translation>
527 </message>
528 <message>
529 <location filename="../base/bootloaderinstallhex.cpp" line="50"/>
530 <source>Bootloader installation requires you to provide a firmware file of the original firmware (hex file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/IriverBoot#Download_and_extract_a_recent_ve&apos;&gt;IriverBoot&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
531 <translation type="unfinished"></translation>
532 </message>
533</context>
534<context>
535 <name>BootloaderInstallImx</name>
536 <message>
537 <location filename="../base/bootloaderinstallimx.cpp" line="72"/>
538 <source>Bootloader installation requires you to provide a copy of the original Sandisk firmware (firmware.sb file). This file will be patched with the Rockbox bootloader and installed to your player. You need to download this file yourself due to legal reasons. Please browse the &lt;a href=&apos;http://forums.sandisk.com/sansa/&apos;&gt;Sansa Forums&lt;/a&gt; or refer to the &lt;a href= &apos;http://www.rockbox.org/wiki/SansaFuzePlus&apos;&gt;SansaFuzePlus&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
539 <translation type="unfinished"></translation>
540 </message>
541 <message>
542 <location filename="../base/bootloaderinstallimx.cpp" line="94"/>
543 <source>Could not read original firmware file</source>
544 <translation type="unfinished"></translation>
545 </message>
546 <message>
547 <location filename="../base/bootloaderinstallimx.cpp" line="100"/>
548 <source>Downloading bootloader file</source>
549 <translation type="unfinished"></translation>
550 </message>
551 <message>
552 <location filename="../base/bootloaderinstallimx.cpp" line="110"/>
553 <source>Patching file...</source>
554 <translation type="unfinished"></translation>
555 </message>
556 <message>
557 <location filename="../base/bootloaderinstallimx.cpp" line="137"/>
558 <source>Patching the original firmware failed</source>
559 <translation type="unfinished"></translation>
560 </message>
561 <message>
562 <location filename="../base/bootloaderinstallimx.cpp" line="143"/>
563 <source>Succesfully patched firmware file</source>
564 <translation type="unfinished"></translation>
565 </message>
566 <message>
567 <location filename="../base/bootloaderinstallimx.cpp" line="158"/>
568 <source>Bootloader successful installed</source>
569 <translation type="unfinished"></translation>
570 </message>
571 <message>
572 <location filename="../base/bootloaderinstallimx.cpp" line="164"/>
573 <source>Patched bootloader could not be installed</source>
574 <translation type="unfinished"></translation>
575 </message>
576 <message>
577 <location filename="../base/bootloaderinstallimx.cpp" line="175"/>
578 <source>To uninstall, perform a normal upgrade with an unmodified original firmware.</source>
579 <translation type="unfinished"></translation>
580 </message>
581</context>
582<context>
583 <name>BootloaderInstallIpod</name>
584 <message>
585 <location filename="../base/bootloaderinstallipod.cpp" line="49"/>
586 <source>Error: can&apos;t allocate buffer memory!</source>
587 <translation type="unfinished"></translation>
588 </message>
589 <message>
590 <location filename="../base/bootloaderinstallipod.cpp" line="80"/>
591 <source>Downloading bootloader file</source>
592 <translation type="unfinished"></translation>
593 </message>
594 <message>
595 <location filename="../base/bootloaderinstallipod.cpp" line="64"/>
596 <location filename="../base/bootloaderinstallipod.cpp" line="151"/>
597 <source>Failed to read firmware directory</source>
598 <translation type="unfinished">讀不了固件文件夾</translation>
599 </message>
600 <message>
601 <location filename="../base/bootloaderinstallipod.cpp" line="69"/>
602 <location filename="../base/bootloaderinstallipod.cpp" line="156"/>
603 <source>Unknown version number in firmware (%1)</source>
604 <translation type="unfinished">固件版本不明 (%1)</translation>
605 </message>
606 <message>
607 <location filename="../base/bootloaderinstallipod.cpp" line="75"/>
608 <source>Warning: This is a MacPod, Rockbox only runs on WinPods.
609See http://www.rockbox.org/wiki/IpodConversionToFAT32</source>
610 <translation type="unfinished"></translation>
611 </message>
612 <message>
613 <location filename="../base/bootloaderinstallipod.cpp" line="94"/>
614 <location filename="../base/bootloaderinstallipod.cpp" line="163"/>
615 <source>Could not open Ipod in R/W mode</source>
616 <translation type="unfinished"></translation>
617 </message>
618 <message>
619 <location filename="../base/bootloaderinstallipod.cpp" line="104"/>
620 <source>Successfull added bootloader</source>
621 <translation type="unfinished"></translation>
622 </message>
623 <message>
624 <location filename="../base/bootloaderinstallipod.cpp" line="115"/>
625 <source>Failed to add bootloader</source>
626 <translation type="unfinished"></translation>
627 </message>
628 <message>
629 <location filename="../base/bootloaderinstallipod.cpp" line="127"/>
630 <source>Bootloader Installation complete.</source>
631 <translation type="unfinished"></translation>
632 </message>
633 <message>
634 <location filename="../base/bootloaderinstallipod.cpp" line="132"/>
635 <source>Writing log aborted</source>
636 <translation type="unfinished"></translation>
637 </message>
638 <message>
639 <location filename="../base/bootloaderinstallipod.cpp" line="169"/>
640 <source>No bootloader detected.</source>
641 <translation type="unfinished">找不到啟動程序.</translation>
642 </message>
643 <message>
644 <location filename="../base/bootloaderinstallipod.cpp" line="175"/>
645 <source>Successfully removed bootloader</source>
646 <translation type="unfinished"></translation>
647 </message>
648 <message>
649 <location filename="../base/bootloaderinstallipod.cpp" line="182"/>
650 <source>Removing bootloader failed.</source>
651 <translation type="unfinished"></translation>
652 </message>
653 <message>
654 <location filename="../base/bootloaderinstallipod.cpp" line="228"/>
655 <source>Error: could not retrieve device name</source>
656 <translation type="unfinished"></translation>
657 </message>
658 <message>
659 <location filename="../base/bootloaderinstallipod.cpp" line="244"/>
660 <source>Error: no mountpoint specified!</source>
661 <translation type="unfinished"></translation>
662 </message>
663 <message>
664 <location filename="../base/bootloaderinstallipod.cpp" line="249"/>
665 <source>Could not open Ipod: permission denied</source>
666 <translation type="unfinished"></translation>
667 </message>
668 <message>
669 <location filename="../base/bootloaderinstallipod.cpp" line="253"/>
670 <source>Could not open Ipod</source>
671 <translation type="unfinished"></translation>
672 </message>
673 <message>
674 <location filename="../base/bootloaderinstallipod.cpp" line="264"/>
675 <source>No firmware partition on disk</source>
676 <translation type="unfinished"></translation>
677 </message>
678 <message>
679 <location filename="../base/bootloaderinstallipod.cpp" line="90"/>
680 <source>Installing Rockbox bootloader</source>
681 <translation type="unfinished"></translation>
682 </message>
683 <message>
684 <location filename="../base/bootloaderinstallipod.cpp" line="142"/>
685 <source>Uninstalling bootloader</source>
686 <translation type="unfinished"></translation>
687 </message>
688 <message>
689 <location filename="../base/bootloaderinstallipod.cpp" line="258"/>
690 <source>Error reading partition table - possibly not an Ipod</source>
691 <translation type="unfinished"></translation>
692 </message>
693</context>
694<context>
695 <name>BootloaderInstallMi4</name>
696 <message>
697 <location filename="../base/bootloaderinstallmi4.cpp" line="34"/>
698 <source>Downloading bootloader</source>
699 <translation type="unfinished"></translation>
700 </message>
701 <message>
702 <location filename="../base/bootloaderinstallmi4.cpp" line="43"/>
703 <source>Installing Rockbox bootloader</source>
704 <translation type="unfinished"></translation>
705 </message>
706 <message>
707 <location filename="../base/bootloaderinstallmi4.cpp" line="66"/>
708 <source>A firmware file is already present on player</source>
709 <translation type="unfinished"></translation>
710 </message>
711 <message>
712 <location filename="../base/bootloaderinstallmi4.cpp" line="71"/>
713 <location filename="../base/bootloaderinstallmi4.cpp" line="79"/>
714 <source>Bootloader successful installed</source>
715 <translation type="unfinished"></translation>
716 </message>
717 <message>
718 <location filename="../base/bootloaderinstallmi4.cpp" line="74"/>
719 <source>Copying modified firmware file failed</source>
720 <translation type="unfinished"></translation>
721 </message>
722 <message>
723 <location filename="../base/bootloaderinstallmi4.cpp" line="91"/>
724 <source>Checking for Rockbox bootloader</source>
725 <translation type="unfinished"></translation>
726 </message>
727 <message>
728 <location filename="../base/bootloaderinstallmi4.cpp" line="93"/>
729 <source>No Rockbox bootloader found</source>
730 <translation type="unfinished"></translation>
731 </message>
732 <message>
733 <location filename="../base/bootloaderinstallmi4.cpp" line="98"/>
734 <source>Checking for original firmware file</source>
735 <translation type="unfinished"></translation>
736 </message>
737 <message>
738 <location filename="../base/bootloaderinstallmi4.cpp" line="103"/>
739 <source>Error finding original firmware file</source>
740 <translation type="unfinished"></translation>
741 </message>
742 <message>
743 <location filename="../base/bootloaderinstallmi4.cpp" line="113"/>
744 <source>Rockbox bootloader successful removed</source>
745 <translation type="unfinished"></translation>
746 </message>
747</context>
748<context>
749 <name>BootloaderInstallMpio</name>
750 <message>
751 <location filename="../base/bootloaderinstallmpio.cpp" line="34"/>
752 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/MPIOHD200Port&apos;&gt;MPIOHD200Port&lt;/a&gt; wiki page on how to obtain this file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
753 <translation type="unfinished"></translation>
754 </message>
755 <message>
756 <location filename="../base/bootloaderinstallmpio.cpp" line="53"/>
757 <source>Downloading bootloader file</source>
758 <translation type="unfinished"></translation>
759 </message>
760 <message>
761 <location filename="../base/bootloaderinstallmpio.cpp" line="80"/>
762 <source>Could not open the original firmware.</source>
763 <translation type="unfinished"></translation>
764 </message>
765 <message>
766 <location filename="../base/bootloaderinstallmpio.cpp" line="83"/>
767 <source>Could not read the original firmware.</source>
768 <translation type="unfinished"></translation>
769 </message>
770 <message>
771 <location filename="../base/bootloaderinstallmpio.cpp" line="86"/>
772 <source>Loaded firmware file does not look like MPIO original firmware file.</source>
773 <translation type="unfinished"></translation>
774 </message>
775 <message>
776 <location filename="../base/bootloaderinstallmpio.cpp" line="101"/>
777 <source>Could not open output file.</source>
778 <translation type="unfinished"></translation>
779 </message>
780 <message>
781 <location filename="../base/bootloaderinstallmpio.cpp" line="104"/>
782 <source>Could not write output file.</source>
783 <translation type="unfinished"></translation>
784 </message>
785 <message>
786 <location filename="../base/bootloaderinstallmpio.cpp" line="107"/>
787 <source>Unknown error number: %1</source>
788 <translation type="unfinished"></translation>
789 </message>
790 <message>
791 <location filename="../base/bootloaderinstallmpio.cpp" line="89"/>
792 <source>Could not open downloaded bootloader.</source>
793 <translation type="unfinished"></translation>
794 </message>
795 <message>
796 <location filename="../base/bootloaderinstallmpio.cpp" line="92"/>
797 <source>Place for bootloader in OF file not empty.</source>
798 <translation type="unfinished"></translation>
799 </message>
800 <message>
801 <location filename="../base/bootloaderinstallmpio.cpp" line="95"/>
802 <source>Could not read the downloaded bootloader.</source>
803 <translation type="unfinished"></translation>
804 </message>
805 <message>
806 <location filename="../base/bootloaderinstallmpio.cpp" line="98"/>
807 <source>Bootloader checksum error.</source>
808 <translation type="unfinished"></translation>
809 </message>
810 <message>
811 <location filename="../base/bootloaderinstallmpio.cpp" line="112"/>
812 <source>Patching original firmware failed: %1</source>
813 <translation type="unfinished"></translation>
814 </message>
815 <message>
816 <location filename="../base/bootloaderinstallmpio.cpp" line="119"/>
817 <source>Success: modified firmware file created</source>
818 <translation type="unfinished"></translation>
819 </message>
820 <message>
821 <location filename="../base/bootloaderinstallmpio.cpp" line="127"/>
822 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
823 <translation type="unfinished"></translation>
824 </message>
825</context>
826<context>
827 <name>BootloaderInstallSansa</name>
828 <message>
829 <location filename="../base/bootloaderinstallsansa.cpp" line="50"/>
830 <source>Error: can&apos;t allocate buffer memory!</source>
831 <translation type="unfinished"></translation>
832 </message>
833 <message>
834 <location filename="../base/bootloaderinstallsansa.cpp" line="55"/>
835 <source>Searching for Sansa</source>
836 <translation type="unfinished"></translation>
837 </message>
838 <message>
839 <location filename="../base/bootloaderinstallsansa.cpp" line="59"/>
840 <source>Permission for disc access denied!
841This is required to install the bootloader</source>
842 <translation type="unfinished"></translation>
843 </message>
844 <message>
845 <location filename="../base/bootloaderinstallsansa.cpp" line="66"/>
846 <source>No Sansa detected!</source>
847 <translation type="unfinished"></translation>
848 </message>
849 <message>
850 <location filename="../base/bootloaderinstallsansa.cpp" line="79"/>
851 <source>Downloading bootloader file</source>
852 <translation type="unfinished"></translation>
853 </message>
854 <message>
855 <location filename="../base/bootloaderinstallsansa.cpp" line="71"/>
856 <location filename="../base/bootloaderinstallsansa.cpp" line="179"/>
857 <source>OLD ROCKBOX INSTALLATION DETECTED, ABORTING.
858You must reinstall the original Sansa firmware before running
859sansapatcher for the first time.
860See http://www.rockbox.org/wiki/SansaE200Install
861</source>
862 <translation type="unfinished"></translation>
863 </message>
864 <message>
865 <location filename="../base/bootloaderinstallsansa.cpp" line="102"/>
866 <location filename="../base/bootloaderinstallsansa.cpp" line="189"/>
867 <source>Could not open Sansa in R/W mode</source>
868 <translation type="unfinished"></translation>
869 </message>
870 <message>
871 <location filename="../base/bootloaderinstallsansa.cpp" line="129"/>
872 <source>Successfully installed bootloader</source>
873 <translation type="unfinished"></translation>
874 </message>
875 <message>
876 <location filename="../base/bootloaderinstallsansa.cpp" line="140"/>
877 <source>Failed to install bootloader</source>
878 <translation type="unfinished"></translation>
879 </message>
880 <message>
881 <location filename="../base/bootloaderinstallsansa.cpp" line="153"/>
882 <source>Bootloader Installation complete.</source>
883 <translation type="unfinished"></translation>
884 </message>
885 <message>
886 <location filename="../base/bootloaderinstallsansa.cpp" line="158"/>
887 <source>Writing log aborted</source>
888 <translation type="unfinished"></translation>
889 </message>
890 <message>
891 <location filename="../base/bootloaderinstallsansa.cpp" line="238"/>
892 <source>Error: could not retrieve device name</source>
893 <translation type="unfinished"></translation>
894 </message>
895 <message>
896 <location filename="../base/bootloaderinstallsansa.cpp" line="254"/>
897 <source>Can&apos;t find Sansa</source>
898 <translation type="unfinished"></translation>
899 </message>
900 <message>
901 <location filename="../base/bootloaderinstallsansa.cpp" line="259"/>
902 <source>Could not open Sansa</source>
903 <translation type="unfinished"></translation>
904 </message>
905 <message>
906 <location filename="../base/bootloaderinstallsansa.cpp" line="264"/>
907 <source>Could not read partition table</source>
908 <translation type="unfinished"></translation>
909 </message>
910 <message>
911 <location filename="../base/bootloaderinstallsansa.cpp" line="271"/>
912 <source>Disk is not a Sansa (Error %1), aborting.</source>
913 <translation type="unfinished"></translation>
914 </message>
915 <message>
916 <location filename="../base/bootloaderinstallsansa.cpp" line="195"/>
917 <source>Successfully removed bootloader</source>
918 <translation type="unfinished"></translation>
919 </message>
920 <message>
921 <location filename="../base/bootloaderinstallsansa.cpp" line="202"/>
922 <source>Removing bootloader failed.</source>
923 <translation type="unfinished"></translation>
924 </message>
925 <message>
926 <location filename="../base/bootloaderinstallsansa.cpp" line="94"/>
927 <source>Installing Rockbox bootloader</source>
928 <translation type="unfinished"></translation>
929 </message>
930 <message>
931 <location filename="../base/bootloaderinstallsansa.cpp" line="111"/>
932 <source>Checking downloaded bootloader</source>
933 <translation type="unfinished"></translation>
934 </message>
935 <message>
936 <location filename="../base/bootloaderinstallsansa.cpp" line="119"/>
937 <source>Bootloader mismatch! Aborting.</source>
938 <translation type="unfinished"></translation>
939 </message>
940 <message>
941 <location filename="../base/bootloaderinstallsansa.cpp" line="170"/>
942 <source>Uninstalling bootloader</source>
943 <translation type="unfinished"></translation>
944 </message>
945</context>
946<context>
947 <name>BootloaderInstallTcc</name>
948 <message>
949 <location filename="../base/bootloaderinstalltcc.cpp" line="33"/>
950 <source>Bootloader installation requires you to provide a firmware file of the original firmware (bin file). You need to download this file yourself due to legal reasons. Please refer to the &lt;a href=&apos;http://www.rockbox.org/manual.shtml&apos;&gt;manual&lt;/a&gt; and the &lt;a href=&apos;http://www.rockbox.org/wiki/CowonD2Info&apos;&gt;CowonD2Info&lt;/a&gt; wiki page on how to obtain the file.&lt;br/&gt;Press Ok to continue and browse your computer for the firmware file.</source>
951 <translation type="unfinished"></translation>
952 </message>
953 <message>
954 <location filename="../base/bootloaderinstalltcc.cpp" line="50"/>
955 <source>Downloading bootloader file</source>
956 <translation type="unfinished"></translation>
957 </message>
958 <message>
959 <location filename="../base/bootloaderinstalltcc.cpp" line="82"/>
960 <location filename="../base/bootloaderinstalltcc.cpp" line="99"/>
961 <source>Could not load %1</source>
962 <translation type="unfinished"></translation>
963 </message>
964 <message>
965 <location filename="../base/bootloaderinstalltcc.cpp" line="90"/>
966 <source>Unknown OF file used: %1</source>
967 <translation type="unfinished"></translation>
968 </message>
969 <message>
970 <location filename="../base/bootloaderinstalltcc.cpp" line="104"/>
971 <source>Patching Firmware...</source>
972 <translation type="unfinished"></translation>
973 </message>
974 <message>
975 <location filename="../base/bootloaderinstalltcc.cpp" line="111"/>
976 <source>Could not patch firmware</source>
977 <translation type="unfinished"></translation>
978 </message>
979 <message>
980 <location filename="../base/bootloaderinstalltcc.cpp" line="117"/>
981 <source>Could not open %1 for writing</source>
982 <translation type="unfinished"></translation>
983 </message>
984 <message>
985 <location filename="../base/bootloaderinstalltcc.cpp" line="126"/>
986 <source>Could not write firmware file</source>
987 <translation type="unfinished"></translation>
988 </message>
989 <message>
990 <location filename="../base/bootloaderinstalltcc.cpp" line="131"/>
991 <source>Success: modified firmware file created</source>
992 <translation type="unfinished"></translation>
993 </message>
994 <message>
995 <location filename="../base/bootloaderinstalltcc.cpp" line="151"/>
996 <source>To uninstall, perform a normal upgrade with an unmodified original firmware</source>
997 <translation type="unfinished"></translation>
998 </message>
999</context>
1000<context>
1001 <name>Changelog</name>
1002 <message>
1003 <location filename="../gui/changelogfrm.ui" line="17"/>
1004 <source>Changelog</source>
1005 <translation type="unfinished"></translation>
1006 </message>
1007 <message>
1008 <location filename="../gui/changelogfrm.ui" line="39"/>
1009 <source>Show on startup</source>
1010 <translation type="unfinished"></translation>
1011 </message>
1012 <message>
1013 <location filename="../gui/changelogfrm.ui" line="46"/>
1014 <source>&amp;Ok</source>
1015 <translation type="unfinished">&amp;OK</translation>
1016 </message>
1017</context>
1018<context>
1019 <name>Config</name>
1020 <message>
1021 <location filename="../configure.cpp" line="340"/>
1022 <source>Showing disabled targets</source>
1023 <translation type="unfinished"></translation>
1024 </message>
1025 <message>
1026 <location filename="../configure.cpp" line="341"/>
1027 <source>You just enabled showing targets that are marked disabled. Disabled targets are not recommended to end users. Please use this option only if you know what you are doing.</source>
1028 <translation type="unfinished"></translation>
1029 </message>
1030 <message>
1031 <location filename="../configure.cpp" line="529"/>
1032 <source>Proxy Detection</source>
1033 <translation type="unfinished"></translation>
1034 </message>
1035 <message>
1036 <location filename="../configure.cpp" line="530"/>
1037 <source>The System Proxy settings are invalid!
1038Rockbox Utility can&apos;t work with this proxy settings. Make sure the system proxy is set correctly. Note that &quot;proxy auto-config (PAC)&quot; scripts are not supported by Rockbox Utility. If your system uses this you need to use manual proxy settings.</source>
1039 <translation type="unfinished"></translation>
1040 </message>
1041 <message>
1042 <location filename="../configure.cpp" line="643"/>
1043 <source>Set Cache Path</source>
1044 <translation type="unfinished"></translation>
1045 </message>
1046 <message>
1047 <location filename="../configure.cpp" line="788"/>
1048 <source>%1 &quot;MacPod&quot; found!
1049Rockbox needs a FAT formatted Ipod (so-called &quot;WinPod&quot;) to run. </source>
1050 <translation type="unfinished"></translation>
1051 </message>
1052 <message>
1053 <location filename="../configure.cpp" line="780"/>
1054 <source>%1 in MTP mode found!
1055You need to change your player to MSC mode for installation. </source>
1056 <translation type="unfinished"></translation>
1057 </message>
1058 <message>
1059 <location filename="../configure.cpp" line="774"/>
1060 <source>Detected an unsupported player:
1061%1
1062Sorry, Rockbox doesn&apos;t run on your player.</source>
1063 <translation type="unfinished"></translation>
1064 </message>
1065 <message>
1066 <location filename="../configure.cpp" line="858"/>
1067 <source>Autodetection</source>
1068 <translation>自動識別</translation>
1069 </message>
1070 <message>
1071 <location filename="../configure.cpp" line="859"/>
1072 <source>Could not detect a Mountpoint.
1073Select your Mountpoint manually.</source>
1074 <translation>找不到 mountpoint
1075請手動選擇你的 mountpoing.</translation>
1076 </message>
1077 <message>
1078 <location filename="../configure.cpp" line="764"/>
1079 <source>Could not detect a device.
1080Select your device and Mountpoint manually.</source>
1081 <translation>不能識別你的播放器
1082請手動選擇.</translation>
1083 </message>
1084 <message>
1085 <location filename="../configure.cpp" line="448"/>
1086 <location filename="../configure.cpp" line="914"/>
1087 <source>TTS error</source>
1088 <translation type="unfinished"></translation>
1089 </message>
1090 <message>
1091 <location filename="../configure.cpp" line="449"/>
1092 <location filename="../configure.cpp" line="915"/>
1093 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1094 <translation type="unfinished"></translation>
1095 </message>
1096 <message>
1097 <location filename="../configure.cpp" line="665"/>
1098 <source>%1 (%2 GiB of %3 GiB free)</source>
1099 <translation type="unfinished"></translation>
1100 </message>
1101 <message>
1102 <location filename="../configure.cpp" line="739"/>
1103 <source>Multiple devices have been detected. Please disconnect all players but one and try again.</source>
1104 <translation type="unfinished"></translation>
1105 </message>
1106 <message>
1107 <location filename="../configure.cpp" line="742"/>
1108 <source>Detected devices:</source>
1109 <translation type="unfinished"></translation>
1110 </message>
1111 <message>
1112 <location filename="../configure.cpp" line="747"/>
1113 <source>(unknown)</source>
1114 <translation type="unfinished"></translation>
1115 </message>
1116 <message>
1117 <location filename="../configure.cpp" line="749"/>
1118 <source>%1 at %2</source>
1119 <translation type="unfinished"></translation>
1120 </message>
1121 <message>
1122 <location filename="../configure.cpp" line="755"/>
1123 <source>Note: detecting connected devices might be ambiguous. You might have less devices connected than listed. In this case it might not be possible to detect your player unambiguously.</source>
1124 <translation type="unfinished"></translation>
1125 </message>
1126 <message>
1127 <location filename="../configure.cpp" line="759"/>
1128 <location filename="../configure.cpp" line="763"/>
1129 <location filename="../configure.cpp" line="805"/>
1130 <source>Device Detection</source>
1131 <translation type="unfinished"></translation>
1132 </message>
1133 <message>
1134 <location filename="../configure.cpp" line="794"/>
1135 <source>The player contains an incompatible filesystem.
1136Make sure you selected the correct mountpoint and the player is set up to use a filesystem compatible with Rockbox.</source>
1137 <translation type="unfinished"></translation>
1138 </message>
1139 <message>
1140 <location filename="../configure.cpp" line="802"/>
1141 <source>An unknown error occured during player detection.</source>
1142 <translation type="unfinished"></translation>
1143 </message>
1144 <message>
1145 <location filename="../configure.cpp" line="869"/>
1146 <source>Really delete cache?</source>
1147 <translation>你肯定要刪除緩沖嗎?</translation>
1148 </message>
1149 <message>
1150 <location filename="../configure.cpp" line="870"/>
1151 <source>Do you really want to delete the cache? Make absolutely sure this setting is correct as it will remove &lt;b&gt;all&lt;/b&gt; files in this folder!</source>
1152 <translation>你真的肯定要刪除緩沖嗎? 請确認你的設定是正确的因為這會刪除 &lt;b&gt;全部&lt;/b&gt; 的文件在此文件夾 !</translation>
1153 </message>
1154 <message>
1155 <location filename="../configure.cpp" line="878"/>
1156 <source>Path wrong!</source>
1157 <translation>路徑錯誤!</translation>
1158 </message>
1159 <message>
1160 <location filename="../configure.cpp" line="879"/>
1161 <source>The cache path is invalid. Aborting.</source>
1162 <translation>緩沖路徑錯誤. 正在取消.</translation>
1163 </message>
1164 <message>
1165 <location filename="../configure.cpp" line="921"/>
1166 <source>TTS configuration invalid</source>
1167 <translation type="unfinished"></translation>
1168 </message>
1169 <message>
1170 <location filename="../configure.cpp" line="922"/>
1171 <source>TTS configuration invalid.
1172 Please configure TTS engine.</source>
1173 <translation type="unfinished"></translation>
1174 </message>
1175 <message>
1176 <location filename="../configure.cpp" line="927"/>
1177 <source>Could not start TTS engine.</source>
1178 <translation type="unfinished"></translation>
1179 </message>
1180 <message>
1181 <location filename="../configure.cpp" line="928"/>
1182 <source>Could not start TTS engine.
1183</source>
1184 <translation type="unfinished"></translation>
1185 </message>
1186 <message>
1187 <location filename="../configure.cpp" line="929"/>
1188 <location filename="../configure.cpp" line="948"/>
1189 <source>
1190Please configure TTS engine.</source>
1191 <translation type="unfinished"></translation>
1192 </message>
1193 <message>
1194 <location filename="../configure.cpp" line="943"/>
1195 <source>Rockbox Utility Voice Test</source>
1196 <translation type="unfinished"></translation>
1197 </message>
1198 <message>
1199 <location filename="../configure.cpp" line="946"/>
1200 <source>Could not voice test string.</source>
1201 <translation type="unfinished"></translation>
1202 </message>
1203 <message>
1204 <location filename="../configure.cpp" line="947"/>
1205 <source>Could not voice test string.
1206</source>
1207 <translation type="unfinished"></translation>
1208 </message>
1209 <message>
1210 <location filename="../configure.cpp" line="322"/>
1211 <source>Current cache size is %L1 kiB.</source>
1212 <translation type="unfinished"></translation>
1213 </message>
1214 <message>
1215 <location filename="../configure.cpp" line="455"/>
1216 <location filename="../configure.cpp" line="485"/>
1217 <source>Configuration OK</source>
1218 <translation type="unfinished"></translation>
1219 </message>
1220 <message>
1221 <location filename="../configure.cpp" line="461"/>
1222 <location filename="../configure.cpp" line="490"/>
1223 <source>Configuration INVALID</source>
1224 <translation type="unfinished"></translation>
1225 </message>
1226 <message>
1227 <location filename="../configure.cpp" line="130"/>
1228 <source>The following errors occurred:</source>
1229 <translation type="unfinished"></translation>
1230 </message>
1231 <message>
1232 <location filename="../configure.cpp" line="175"/>
1233 <source>No mountpoint given</source>
1234 <translation type="unfinished"></translation>
1235 </message>
1236 <message>
1237 <location filename="../configure.cpp" line="179"/>
1238 <source>Mountpoint does not exist</source>
1239 <translation type="unfinished"></translation>
1240 </message>
1241 <message>
1242 <location filename="../configure.cpp" line="183"/>
1243 <source>Mountpoint is not a directory.</source>
1244 <translation type="unfinished"></translation>
1245 </message>
1246 <message>
1247 <location filename="../configure.cpp" line="187"/>
1248 <source>Mountpoint is not writeable</source>
1249 <translation type="unfinished"></translation>
1250 </message>
1251 <message>
1252 <location filename="../configure.cpp" line="202"/>
1253 <source>No player selected</source>
1254 <translation type="unfinished"></translation>
1255 </message>
1256 <message>
1257 <location filename="../configure.cpp" line="209"/>
1258 <source>Cache path not writeable. Leave path empty to default to systems temporary path.</source>
1259 <translation type="unfinished"></translation>
1260 </message>
1261 <message>
1262 <location filename="../configure.cpp" line="228"/>
1263 <source>You need to fix the above errors before you can continue.</source>
1264 <translation type="unfinished"></translation>
1265 </message>
1266 <message>
1267 <location filename="../configure.cpp" line="231"/>
1268 <source>Configuration error</source>
1269 <translation type="unfinished"></translation>
1270 </message>
1271</context>
1272<context>
1273 <name>ConfigForm</name>
1274 <message>
1275 <location filename="../configurefrm.ui" line="14"/>
1276 <source>Configuration</source>
1277 <translation>設置</translation>
1278 </message>
1279 <message>
1280 <location filename="../configurefrm.ui" line="20"/>
1281 <source>Configure Rockbox Utility</source>
1282 <translation>設置 Rockbox 安裝程序</translation>
1283 </message>
1284 <message>
1285 <location filename="../configurefrm.ui" line="35"/>
1286 <source>&amp;Device</source>
1287 <translation>&amp;播放器</translation>
1288 </message>
1289 <message>
1290 <location filename="../configurefrm.ui" line="41"/>
1291 <source>Select your device in the &amp;filesystem</source>
1292 <translation>請選擇你的播放器在你的 &amp;文件系統</translation>
1293 </message>
1294 <message>
1295 <location filename="../configurefrm.ui" line="319"/>
1296 <source>&amp;Browse</source>
1297 <translation>&amp;瀏覽</translation>
1298 </message>
1299 <message>
1300 <location filename="../configurefrm.ui" line="72"/>
1301 <source>&amp;Select your audio player</source>
1302 <translation>&amp;選擇你的音樂播放器</translation>
1303 </message>
1304 <message>
1305 <location filename="../configurefrm.ui" line="58"/>
1306 <source>&amp;Refresh</source>
1307 <translation type="unfinished"></translation>
1308 </message>
1309 <message>
1310 <location filename="../configurefrm.ui" line="114"/>
1311 <source>&amp;Autodetect</source>
1312 <translation>自動識別(&amp;A)</translation>
1313 </message>
1314 <message>
1315 <location filename="../configurefrm.ui" line="136"/>
1316 <source>&amp;Proxy</source>
1317 <translation>网絡代理服務(&amp;P)</translation>
1318 </message>
1319 <message>
1320 <location filename="../configurefrm.ui" line="142"/>
1321 <source>&amp;No Proxy</source>
1322 <translation>沒有网絡代理服務(&amp;N)</translation>
1323 </message>
1324 <message>
1325 <location filename="../configurefrm.ui" line="152"/>
1326 <source>Use S&amp;ystem values</source>
1327 <translation>使用系統值(&amp;S)</translation>
1328 </message>
1329 <message>
1330 <location filename="../configurefrm.ui" line="159"/>
1331 <source>&amp;Manual Proxy settings</source>
1332 <translation>手動設置代理服務(&amp;M)</translation>
1333 </message>
1334 <message>
1335 <location filename="../configurefrm.ui" line="166"/>
1336 <source>Proxy Values</source>
1337 <translation>代理服務值</translation>
1338 </message>
1339 <message>
1340 <location filename="../configurefrm.ui" line="172"/>
1341 <source>&amp;Host:</source>
1342 <translation>&amp;主机:</translation>
1343 </message>
1344 <message>
1345 <location filename="../configurefrm.ui" line="182"/>
1346 <source>&amp;Port:</source>
1347 <translation>&amp;接口:</translation>
1348 </message>
1349 <message>
1350 <location filename="../configurefrm.ui" line="199"/>
1351 <source>&amp;Username</source>
1352 <translation>&amp;用戶名</translation>
1353 </message>
1354 <message>
1355 <location filename="../configurefrm.ui" line="209"/>
1356 <source>Pass&amp;word</source>
1357 <translation>&amp;密碼</translation>
1358 </message>
1359 <message>
1360 <location filename="../configurefrm.ui" line="219"/>
1361 <source>Show</source>
1362 <translation type="unfinished"></translation>
1363 </message>
1364 <message>
1365 <location filename="../configurefrm.ui" line="260"/>
1366 <source>&amp;Language</source>
1367 <translation>&amp;語言</translation>
1368 </message>
1369 <message>
1370 <location filename="../configurefrm.ui" line="274"/>
1371 <source>Cac&amp;he</source>
1372 <translation>&amp;緩沖</translation>
1373 </message>
1374 <message>
1375 <location filename="../configurefrm.ui" line="277"/>
1376 <source>Download cache settings</source>
1377 <translation>下載緩沖設置</translation>
1378 </message>
1379 <message>
1380 <location filename="../configurefrm.ui" line="283"/>
1381 <source>Rockbox Utility uses a local download cache to save network traffic. You can change the path to the cache and use it as local repository by enabling Offline mode.</source>
1382 <translation>Rockbox 安裝程序使用本机緩沖來保存网絡資料. 你可以改變這個緩沖的路徑. 啟動下線模式后, 你還可以用路徑來保存文件.</translation>
1383 </message>
1384 <message>
1385 <location filename="../configurefrm.ui" line="293"/>
1386 <source>Current cache size is %1</source>
1387 <translation>現在緩沖大小是 %1</translation>
1388 </message>
1389 <message>
1390 <location filename="../configurefrm.ui" line="302"/>
1391 <source>P&amp;ath</source>
1392 <translation>&amp;路徑</translation>
1393 </message>
1394 <message>
1395 <location filename="../configurefrm.ui" line="312"/>
1396 <source>Entering an invalid folder will reset the path to the systems temporary path.</source>
1397 <translation>輸入無效地址會重設到系統臨時文件夾.</translation>
1398 </message>
1399 <message>
1400 <location filename="../configurefrm.ui" line="334"/>
1401 <source>Disable local &amp;download cache</source>
1402 <translation>&amp;不使用本机緩沖</translation>
1403 </message>
1404 <message>
1405 <source>&lt;p&gt;This will try to use all information from the cache, even information about updates. Only use this option if you want to install without network connection. Note: you need to do the same install you want to perform later with network access first to download all required files to the cache.&lt;/p&gt;</source>
1406 <translation type="obsolete">&lt;p&gt;所有資料, 包括更新資料, 將會從本机緩沖里拿取. 不要選擇此模式如果你不需要下線安裝. 注意: 你需要先用网絡做至少一次安裝才可以下載到需要的文件.&lt;/p&gt;</translation>
1407 </message>
1408 <message>
1409 <source>O&amp;ffline mode</source>
1410 <translation type="obsolete">&amp;下線安裝</translation>
1411 </message>
1412 <message>
1413 <location filename="../configurefrm.ui" line="369"/>
1414 <source>Clean cache &amp;now</source>
1415 <translation>&amp;現在清除緩沖文件夾</translation>
1416 </message>
1417 <message>
1418 <location filename="../configurefrm.ui" line="385"/>
1419 <source>&amp;TTS &amp;&amp; Encoder</source>
1420 <translation>&amp;TTS &amp;&amp; 信號轉換器</translation>
1421 </message>
1422 <message>
1423 <location filename="../configurefrm.ui" line="391"/>
1424 <source>TTS Engine</source>
1425 <translation>TTS 引擎</translation>
1426 </message>
1427 <message>
1428 <location filename="../configurefrm.ui" line="445"/>
1429 <source>Test TTS</source>
1430 <translation type="unfinished"></translation>
1431 </message>
1432 <message>
1433 <location filename="../configurefrm.ui" line="452"/>
1434 <source>&amp;Use string corrections for TTS</source>
1435 <translation type="unfinished"></translation>
1436 </message>
1437 <message>
1438 <location filename="../configurefrm.ui" line="462"/>
1439 <source>Encoder Engine</source>
1440 <translation>信號轉換器引擎</translation>
1441 </message>
1442 <message>
1443 <location filename="../configurefrm.ui" line="536"/>
1444 <source>&amp;Ok</source>
1445 <translation>&amp;OK</translation>
1446 </message>
1447 <message>
1448 <location filename="../configurefrm.ui" line="547"/>
1449 <source>&amp;Cancel</source>
1450 <translation>&amp;取消</translation>
1451 </message>
1452 <message>
1453 <location filename="../configurefrm.ui" line="397"/>
1454 <source>&amp;Select TTS Engine</source>
1455 <translation type="unfinished"></translation>
1456 </message>
1457 <message>
1458 <location filename="../configurefrm.ui" line="95"/>
1459 <source>Show disabled targets</source>
1460 <translation type="unfinished"></translation>
1461 </message>
1462 <message>
1463 <location filename="../configurefrm.ui" line="410"/>
1464 <source>Configure TTS Engine</source>
1465 <translation type="unfinished"></translation>
1466 </message>
1467 <message>
1468 <location filename="../configurefrm.ui" line="417"/>
1469 <location filename="../configurefrm.ui" line="468"/>
1470 <source>Configuration invalid!</source>
1471 <translation type="unfinished"></translation>
1472 </message>
1473 <message>
1474 <location filename="../configurefrm.ui" line="434"/>
1475 <source>Configure &amp;TTS</source>
1476 <translation type="unfinished"></translation>
1477 </message>
1478 <message>
1479 <location filename="../configurefrm.ui" line="485"/>
1480 <source>Configure &amp;Enc</source>
1481 <translation type="unfinished"></translation>
1482 </message>
1483 <message>
1484 <location filename="../configurefrm.ui" line="496"/>
1485 <source>encoder name</source>
1486 <translation type="unfinished"></translation>
1487 </message>
1488</context>
1489<context>
1490 <name>Configure</name>
1491 <message>
1492 <location filename="../configure.cpp" line="589"/>
1493 <source>English</source>
1494 <comment>This is the localized language name, i.e. your language.</comment>
1495 <translation type="unfinished">中文 (Chinese Traditional)</translation>
1496 </message>
1497</context>
1498<context>
1499 <name>CreateVoiceFrm</name>
1500 <message>
1501 <location filename="../createvoicefrm.ui" line="17"/>
1502 <source>Create Voice File</source>
1503 <translation type="unfinished"></translation>
1504 </message>
1505 <message>
1506 <location filename="../createvoicefrm.ui" line="42"/>
1507 <source>Select the Language you want to generate a voicefile for:</source>
1508 <translation type="unfinished"></translation>
1509 </message>
1510 <message>
1511 <location filename="../createvoicefrm.ui" line="55"/>
1512 <source>TTS:</source>
1513 <translation type="unfinished"></translation>
1514 </message>
1515 <message>
1516 <location filename="../createvoicefrm.ui" line="101"/>
1517 <source>Silence threshold</source>
1518 <translation type="unfinished"></translation>
1519 </message>
1520 <message>
1521 <location filename="../createvoicefrm.ui" line="163"/>
1522 <source>Language</source>
1523 <translation type="unfinished"></translation>
1524 </message>
1525 <message>
1526 <location filename="../createvoicefrm.ui" line="49"/>
1527 <source>Generation settings</source>
1528 <translation type="unfinished">語音合成設置</translation>
1529 </message>
1530 <message>
1531 <location filename="../createvoicefrm.ui" line="68"/>
1532 <source>Change</source>
1533 <translation type="unfinished"></translation>
1534 </message>
1535 <message>
1536 <location filename="../createvoicefrm.ui" line="139"/>
1537 <source>&amp;Install</source>
1538 <translation type="unfinished"></translation>
1539 </message>
1540 <message>
1541 <location filename="../createvoicefrm.ui" line="150"/>
1542 <source>&amp;Cancel</source>
1543 <translation type="unfinished">&amp;取消</translation>
1544 </message>
1545 <message>
1546 <location filename="../createvoicefrm.ui" line="88"/>
1547 <source>Wavtrim Threshold</source>
1548 <translation type="unfinished"></translation>
1549 </message>
1550</context>
1551<context>
1552 <name>CreateVoiceWindow</name>
1553 <message>
1554 <location filename="../createvoicewindow.cpp" line="100"/>
1555 <source>TTS error</source>
1556 <translation type="unfinished"></translation>
1557 </message>
1558 <message>
1559 <location filename="../createvoicewindow.cpp" line="101"/>
1560 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1561 <translation type="unfinished"></translation>
1562 </message>
1563 <message>
1564 <location filename="../createvoicewindow.cpp" line="105"/>
1565 <location filename="../createvoicewindow.cpp" line="108"/>
1566 <source>Engine: &lt;b&gt;%1&lt;/b&gt;</source>
1567 <translation type="unfinished"></translation>
1568 </message>
1569</context>
1570<context>
1571 <name>EncTtsCfgGui</name>
1572 <message>
1573 <location filename="../encttscfggui.cpp" line="45"/>
1574 <source>Waiting for engine...</source>
1575 <translation type="unfinished"></translation>
1576 </message>
1577 <message>
1578 <location filename="../encttscfggui.cpp" line="95"/>
1579 <source>Ok</source>
1580 <translation type="unfinished"></translation>
1581 </message>
1582 <message>
1583 <location filename="../encttscfggui.cpp" line="98"/>
1584 <source>Cancel</source>
1585 <translation type="unfinished"></translation>
1586 </message>
1587 <message>
1588 <location filename="../encttscfggui.cpp" line="197"/>
1589 <source>Browse</source>
1590 <translation type="unfinished"></translation>
1591 </message>
1592 <message>
1593 <location filename="../encttscfggui.cpp" line="205"/>
1594 <source>Refresh</source>
1595 <translation type="unfinished"></translation>
1596 </message>
1597 <message>
1598 <location filename="../encttscfggui.cpp" line="377"/>
1599 <source>Select executable</source>
1600 <translation type="unfinished"></translation>
1601 </message>
1602</context>
1603<context>
1604 <name>EncoderExe</name>
1605 <message>
1606 <location filename="../base/encoderexe.cpp" line="41"/>
1607 <source>Path to Encoder:</source>
1608 <translation type="unfinished"></translation>
1609 </message>
1610 <message>
1611 <location filename="../base/encoderexe.cpp" line="43"/>
1612 <source>Encoder options:</source>
1613 <translation type="unfinished"></translation>
1614 </message>
1615</context>
1616<context>
1617 <name>EncoderLame</name>
1618 <message>
1619 <location filename="../base/encoderlame.cpp" line="73"/>
1620 <location filename="../base/encoderlame.cpp" line="83"/>
1621 <source>LAME</source>
1622 <translation type="unfinished"></translation>
1623 </message>
1624 <message>
1625 <location filename="../base/encoderlame.cpp" line="75"/>
1626 <source>Volume</source>
1627 <translation type="unfinished"></translation>
1628 </message>
1629 <message>
1630 <location filename="../base/encoderlame.cpp" line="79"/>
1631 <source>Quality</source>
1632 <translation type="unfinished"></translation>
1633 </message>
1634 <message>
1635 <location filename="../base/encoderlame.cpp" line="83"/>
1636 <source>Could not find libmp3lame!</source>
1637 <translation type="unfinished"></translation>
1638 </message>
1639</context>
1640<context>
1641 <name>EncoderRbSpeex</name>
1642 <message>
1643 <location filename="../base/encoderrbspeex.cpp" line="34"/>
1644 <source>Volume:</source>
1645 <translation type="unfinished"></translation>
1646 </message>
1647 <message>
1648 <location filename="../base/encoderrbspeex.cpp" line="36"/>
1649 <source>Quality:</source>
1650 <translation type="unfinished"></translation>
1651 </message>
1652 <message>
1653 <location filename="../base/encoderrbspeex.cpp" line="38"/>
1654 <source>Complexity:</source>
1655 <translation type="unfinished"></translation>
1656 </message>
1657 <message>
1658 <location filename="../base/encoderrbspeex.cpp" line="40"/>
1659 <source>Use Narrowband:</source>
1660 <translation type="unfinished"></translation>
1661 </message>
1662</context>
1663<context>
1664 <name>InfoWidget</name>
1665 <message>
1666 <location filename="../gui/infowidget.cpp" line="30"/>
1667 <location filename="../gui/infowidget.cpp" line="107"/>
1668 <source>File</source>
1669 <translation type="unfinished">文件</translation>
1670 </message>
1671 <message>
1672 <location filename="../gui/infowidget.cpp" line="30"/>
1673 <location filename="../gui/infowidget.cpp" line="107"/>
1674 <source>Version</source>
1675 <translation type="unfinished">版本</translation>
1676 </message>
1677</context>
1678<context>
1679 <name>InfoWidgetFrm</name>
1680 <message>
1681 <location filename="../gui/infowidgetfrm.ui" line="14"/>
1682 <source>Info</source>
1683 <translation type="unfinished"></translation>
1684 </message>
1685 <message>
1686 <location filename="../gui/infowidgetfrm.ui" line="20"/>
1687 <source>Currently installed packages.&lt;br/&gt;&lt;b&gt;Note:&lt;/b&gt; if you manually installed packages this might not be correct!</source>
1688 <translation type="unfinished"></translation>
1689 </message>
1690 <message>
1691 <location filename="../gui/infowidgetfrm.ui" line="34"/>
1692 <source>Package</source>
1693 <translation type="unfinished"></translation>
1694 </message>
1695</context>
1696<context>
1697 <name>InstallTalkFrm</name>
1698 <message>
1699 <location filename="../installtalkfrm.ui" line="17"/>
1700 <source>Install Talk Files</source>
1701 <translation>安裝說話文件</translation>
1702 </message>
1703 <message>
1704 <location filename="../installtalkfrm.ui" line="52"/>
1705 <source>Generate for files</source>
1706 <translation type="unfinished"></translation>
1707 </message>
1708 <message>
1709 <location filename="../installtalkfrm.ui" line="85"/>
1710 <source>Generate for folders</source>
1711 <translation type="unfinished"></translation>
1712 </message>
1713 <message>
1714 <location filename="../installtalkfrm.ui" line="95"/>
1715 <source>Recurse into folders</source>
1716 <translation type="unfinished"></translation>
1717 </message>
1718 <message>
1719 <location filename="../installtalkfrm.ui" line="118"/>
1720 <source>Ignore files</source>
1721 <translation type="unfinished"></translation>
1722 </message>
1723 <message>
1724 <location filename="../installtalkfrm.ui" line="128"/>
1725 <source>Skip existing</source>
1726 <translation type="unfinished"></translation>
1727 </message>
1728 <message>
1729 <location filename="../installtalkfrm.ui" line="170"/>
1730 <source>Select folders for Talkfile generation (Ctrl for multiselect)</source>
1731 <translation type="unfinished"></translation>
1732 </message>
1733 <message>
1734 <location filename="../installtalkfrm.ui" line="78"/>
1735 <source>TTS profile:</source>
1736 <translation>TTS 設置:</translation>
1737 </message>
1738 <message>
1739 <location filename="../installtalkfrm.ui" line="36"/>
1740 <source>Generation options</source>
1741 <translation>語音合成設置</translation>
1742 </message>
1743 <message>
1744 <location filename="../installtalkfrm.ui" line="42"/>
1745 <source>Strip Extensions</source>
1746 <translation>除去后綴</translation>
1747 </message>
1748 <message>
1749 <location filename="../installtalkfrm.ui" line="154"/>
1750 <source>&amp;Cancel</source>
1751 <translation>&amp;取消</translation>
1752 </message>
1753 <message>
1754 <location filename="../installtalkfrm.ui" line="111"/>
1755 <source>Change</source>
1756 <translation type="unfinished"></translation>
1757 </message>
1758 <message>
1759 <location filename="../installtalkfrm.ui" line="143"/>
1760 <source>&amp;Install</source>
1761 <translation type="unfinished"></translation>
1762 </message>
1763</context>
1764<context>
1765 <name>InstallTalkWindow</name>
1766 <message>
1767 <location filename="../installtalkwindow.cpp" line="96"/>
1768 <source>Empty selection</source>
1769 <translation type="unfinished"></translation>
1770 </message>
1771 <message>
1772 <location filename="../installtalkwindow.cpp" line="97"/>
1773 <source>No files or folders selected. Please select files or folders first.</source>
1774 <translation type="unfinished"></translation>
1775 </message>
1776 <message>
1777 <location filename="../installtalkwindow.cpp" line="137"/>
1778 <source>TTS error</source>
1779 <translation type="unfinished"></translation>
1780 </message>
1781 <message>
1782 <location filename="../installtalkwindow.cpp" line="138"/>
1783 <source>The selected TTS failed to initialize. You can&apos;t use this TTS.</source>
1784 <translation type="unfinished"></translation>
1785 </message>
1786</context>
1787<context>
1788 <name>ManualWidget</name>
1789 <message>
1790 <location filename="../gui/manualwidget.cpp" line="44"/>
1791 <source>&lt;a href=&apos;%1&apos;&gt;PDF Manual&lt;/a&gt;</source>
1792 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;PDF 用戶手冊(英文)&lt;/a&gt;</translation>
1793 </message>
1794 <message>
1795 <location filename="../gui/manualwidget.cpp" line="46"/>
1796 <source>&lt;a href=&apos;%1&apos;&gt;HTML Manual (opens in browser)&lt;/a&gt;</source>
1797 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;HTML 用戶手冊(英文,在瀏覽器打開)&lt;/a&gt;</translation>
1798 </message>
1799 <message>
1800 <location filename="../gui/manualwidget.cpp" line="50"/>
1801 <source>Select a device for a link to the correct manual</source>
1802 <translation type="unfinished">請選擇你的播放器</translation>
1803 </message>
1804 <message>
1805 <location filename="../gui/manualwidget.cpp" line="51"/>
1806 <source>&lt;a href=&apos;%1&apos;&gt;Manual Overview&lt;/a&gt;</source>
1807 <translation type="unfinished">&lt;a href=&apos;%1&apos;&gt;用戶手冊總觀&lt;/a&gt;</translation>
1808 </message>
1809 <message>
1810 <location filename="../gui/manualwidget.cpp" line="62"/>
1811 <source>Confirm download</source>
1812 <translation type="unfinished">确認下載</translation>
1813 </message>
1814 <message>
1815 <location filename="../gui/manualwidget.cpp" line="63"/>
1816 <source>Do you really want to download the manual? The manual will be saved to the root folder of your player.</source>
1817 <translation type="unfinished">你确認要下載用戶手冊嗎? 用戶手冊將會被放在你播放器的主目錄里.</translation>
1818 </message>
1819</context>
1820<context>
1821 <name>ManualWidgetFrm</name>
1822 <message>
1823 <location filename="../gui/manualwidgetfrm.ui" line="14"/>
1824 <source>Manual</source>
1825 <translation type="unfinished"></translation>
1826 </message>
1827 <message>
1828 <location filename="../gui/manualwidgetfrm.ui" line="20"/>
1829 <source>Read the manual</source>
1830 <translation type="unfinished">查看用戶手冊</translation>
1831 </message>
1832 <message>
1833 <location filename="../gui/manualwidgetfrm.ui" line="26"/>
1834 <source>PDF manual</source>
1835 <translation type="unfinished">PDF 用戶手冊</translation>
1836 </message>
1837 <message>
1838 <location filename="../gui/manualwidgetfrm.ui" line="39"/>
1839 <source>HTML manual</source>
1840 <translation type="unfinished">HTML 用戶手冊</translation>
1841 </message>
1842 <message>
1843 <location filename="../gui/manualwidgetfrm.ui" line="55"/>
1844 <source>Download the manual</source>
1845 <translation type="unfinished">下載用戶手冊</translation>
1846 </message>
1847 <message>
1848 <location filename="../gui/manualwidgetfrm.ui" line="63"/>
1849 <source>&amp;PDF version</source>
1850 <translation type="unfinished">PDF 版本</translation>
1851 </message>
1852 <message>
1853 <location filename="../gui/manualwidgetfrm.ui" line="70"/>
1854 <source>&amp;HTML version (zip file)</source>
1855 <translation type="unfinished">HTML 版本 (zip)</translation>
1856 </message>
1857 <message>
1858 <location filename="../gui/manualwidgetfrm.ui" line="92"/>
1859 <source>Down&amp;load</source>
1860 <translation type="unfinished">下載</translation>
1861 </message>
1862</context>
1863<context>
1864 <name>MsPackUtil</name>
1865 <message>
1866 <location filename="../base/mspackutil.cpp" line="101"/>
1867 <source>Creating output path failed</source>
1868 <translation type="unfinished"></translation>
1869 </message>
1870 <message>
1871 <location filename="../base/mspackutil.cpp" line="109"/>
1872 <source>Error during CAB operation</source>
1873 <translation type="unfinished"></translation>
1874 </message>
1875</context>
1876<context>
1877 <name>PreviewFrm</name>
1878 <message>
1879 <location filename="../previewfrm.ui" line="16"/>
1880 <source>Preview</source>
1881 <translation>預覽</translation>
1882 </message>
1883</context>
1884<context>
1885 <name>ProgressLoggerFrm</name>
1886 <message>
1887 <location filename="../progressloggerfrm.ui" line="13"/>
1888 <location filename="../progressloggerfrm.ui" line="19"/>
1889 <source>Progress</source>
1890 <translation type="unfinished">進程</translation>
1891 </message>
1892 <message>
1893 <location filename="../progressloggerfrm.ui" line="58"/>
1894 <source>Save Log</source>
1895 <translation type="unfinished"></translation>
1896 </message>
1897 <message>
1898 <location filename="../progressloggerfrm.ui" line="82"/>
1899 <source>&amp;Abort</source>
1900 <translation type="unfinished">&amp;取消</translation>
1901 </message>
1902 <message>
1903 <location filename="../progressloggerfrm.ui" line="32"/>
1904 <source>progresswindow</source>
1905 <translation type="unfinished"></translation>
1906 </message>
1907</context>
1908<context>
1909 <name>ProgressLoggerGui</name>
1910 <message>
1911 <location filename="../progressloggergui.cpp" line="122"/>
1912 <source>&amp;Ok</source>
1913 <translation>&amp;OK</translation>
1914 </message>
1915 <message>
1916 <location filename="../progressloggergui.cpp" line="146"/>
1917 <source>Save system trace log</source>
1918 <translation type="unfinished"></translation>
1919 </message>
1920 <message>
1921 <location filename="../progressloggergui.cpp" line="104"/>
1922 <source>&amp;Abort</source>
1923 <translation>&amp;取消</translation>
1924 </message>
1925</context>
1926<context>
1927 <name>QObject</name>
1928 <message>
1929 <location filename="../configure.cpp" line="625"/>
1930 <location filename="../main.cpp" line="83"/>
1931 <source>LTR</source>
1932 <extracomment>This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.
1933----------
1934This string is used to indicate the writing direction. Translate it to &quot;RTL&quot; (without quotes) for RTL languages. Anything else will get treated as LTR language.</extracomment>
1935 <translation type="unfinished"></translation>
1936 </message>
1937 <message>
1938 <location filename="../base/system.cpp" line="385"/>
1939 <source>(unknown vendor name) </source>
1940 <translation type="unfinished"></translation>
1941 </message>
1942 <message>
1943 <location filename="../base/system.cpp" line="403"/>
1944 <source>(unknown product name)</source>
1945 <translation type="unfinished"></translation>
1946 </message>
1947 <message>
1948 <location filename="../base/bootloaderinstallhelper.cpp" line="80"/>
1949 <source>Bootloader installation is almost complete. Installation &lt;b&gt;requires&lt;/b&gt; you to perform the following steps manually:</source>
1950 <translation type="unfinished"></translation>
1951 </message>
1952 <message>
1953 <location filename="../base/bootloaderinstallhelper.cpp" line="86"/>
1954 <source>&lt;li&gt;Safely remove your player.&lt;/li&gt;</source>
1955 <translation type="unfinished"></translation>
1956 </message>
1957 <message>
1958 <location filename="../base/bootloaderinstallhelper.cpp" line="91"/>
1959 <source>&lt;li&gt;Reboot your player into the original firmware.&lt;/li&gt;&lt;li&gt;Perform a firmware upgrade using the update functionality of the original firmware. Please refer to your player&apos;s manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before starting the firmware update process.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1960 <translation type="unfinished"></translation>
1961 </message>
1962 <message>
1963 <location filename="../base/bootloaderinstallhelper.cpp" line="102"/>
1964 <source>&lt;li&gt;Remove any previously inserted microSD card&lt;/li&gt;</source>
1965 <translation type="unfinished"></translation>
1966 </message>
1967 <message>
1968 <location filename="../base/bootloaderinstallhelper.cpp" line="103"/>
1969 <source>&lt;li&gt;Disconnect your player. The player will reboot and perform an update of the original firmware. Please refer to your players manual on details.&lt;br/&gt;&lt;b&gt;Important:&lt;/b&gt; updating the firmware is a critical process that must not be interrupted. &lt;b&gt;Make sure the player is charged before disconnecting the player.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;After the firmware has been updated reboot your player.&lt;/li&gt;</source>
1970 <translation type="unfinished"></translation>
1971 </message>
1972 <message>
1973 <location filename="../base/bootloaderinstallhelper.cpp" line="114"/>
1974 <source>&lt;li&gt;Turn the player off&lt;/li&gt;&lt;li&gt;Insert the charger&lt;/li&gt;</source>
1975 <translation type="unfinished"></translation>
1976 </message>
1977 <message>
1978 <location filename="../base/bootloaderinstallhelper.cpp" line="119"/>
1979 <source>&lt;li&gt;Unplug USB and power adaptors&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to turn the player off&lt;/li&gt;&lt;li&gt;Toggle the battery switch on the player&lt;/li&gt;&lt;li&gt;Hold &lt;i&gt;Power&lt;/i&gt; to boot into Rockbox&lt;/li&gt;</source>
1980 <translation type="unfinished"></translation>
1981 </message>
1982 <message>
1983 <location filename="../base/bootloaderinstallhelper.cpp" line="125"/>
1984 <source>&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You can safely install other parts first, but the above steps are &lt;b&gt;required&lt;/b&gt; to finish the installation!&lt;/p&gt;</source>
1985 <translation type="unfinished"></translation>
1986 </message>
1987</context>
1988<context>
1989 <name>QuaZipFile</name>
1990 <message>
1991 <location filename="../quazip/quazipfile.cpp" line="141"/>
1992 <source>ZIP/UNZIP API error %1</source>
1993 <translation type="unfinished"></translation>
1994 </message>
1995</context>
1996<context>
1997 <name>RbUtilQt</name>
1998 <message>
1999 <location filename="../rbutilqt.cpp" line="224"/>
2000 <source>Downloading build information, please wait ...</source>
2001 <translation type="unfinished"></translation>
2002 </message>
2003 <message>
2004 <location filename="../rbutilqt.cpp" line="235"/>
2005 <source>Can&apos;t get version information!</source>
2006 <translation type="unfinished"></translation>
2007 </message>
2008 <message>
2009 <location filename="../rbutilqt.cpp" line="249"/>
2010 <source>Download build information finished.</source>
2011 <translation type="unfinished"></translation>
2012 </message>
2013 <message>
2014 <location filename="../rbutilqt.cpp" line="450"/>
2015 <source>Confirm Installation</source>
2016 <translation>确認安裝</translation>
2017 </message>
2018 <message>
2019 <location filename="../rbutilqt.cpp" line="582"/>
2020 <source>Mount point is wrong!</source>
2021 <translation>Mountpoint 錯誤!</translation>
2022 </message>
2023 <message>
2024 <location filename="../rbutilqt.cpp" line="430"/>
2025 <source>No Rockbox installation found</source>
2026 <translation type="unfinished"></translation>
2027 </message>
2028 <message>
2029 <location filename="../rbutilqt.cpp" line="431"/>
2030 <source>Could not determine the installed Rockbox version. Please install a Rockbox build before installing voice files.</source>
2031 <translation type="unfinished"></translation>
2032 </message>
2033 <message>
2034 <location filename="../rbutilqt.cpp" line="451"/>
2035 <source>Do you really want to install the voice file?</source>
2036 <translation>你确認要安裝語音文件嗎?</translation>
2037 </message>
2038 <message>
2039 <location filename="../rbutilqt.cpp" line="439"/>
2040 <source>No voice file available</source>
2041 <translation type="unfinished"></translation>
2042 </message>
2043 <message>
2044 <location filename="../rbutilqt.cpp" line="440"/>
2045 <source>The installed version of Rockbox is a development version. Pre-built voices are only available for release versions of Rockbox. Please generate a voice yourself using the &quot;Create voice file&quot; functionality.</source>
2046 <translation type="unfinished"></translation>
2047 </message>
2048 <message>
2049 <location filename="../rbutilqt.cpp" line="512"/>
2050 <source>Confirm Uninstallation</source>
2051 <translation>确認安裝</translation>
2052 </message>
2053 <message>
2054 <location filename="../rbutilqt.cpp" line="513"/>
2055 <source>Do you really want to uninstall the Bootloader?</source>
2056 <translation>你确認要卸載啟動程序嗎?</translation>
2057 </message>
2058 <message>
2059 <location filename="../rbutilqt.cpp" line="528"/>
2060 <source>No uninstall method for this target known.</source>
2061 <translation type="unfinished"></translation>
2062 </message>
2063 <message>
2064 <location filename="../rbutilqt.cpp" line="542"/>
2065 <source>Rockbox Utility can not uninstall the bootloader on this target. Try a normal firmware update to remove the booloader.</source>
2066 <translation type="unfinished"></translation>
2067 </message>
2068 <message>
2069 <location filename="../rbutilqt.cpp" line="550"/>
2070 <source>No Rockbox bootloader found.</source>
2071 <translation type="unfinished"></translation>
2072 </message>
2073 <message>
2074 <location filename="../rbutilqt.cpp" line="568"/>
2075 <source>Confirm installation</source>
2076 <translation>确認安裝</translation>
2077 </message>
2078 <message>
2079 <location filename="../rbutilqt.cpp" line="569"/>
2080 <source>Do you really want to install Rockbox Utility to your player? After installation you can run it from the players hard drive.</source>
2081 <translation>你确認要安裝Rockbox安裝程序到你的播放器上嗎? 安裝后你可以從你播放器上運行此程序.</translation>
2082 </message>
2083 <message>
2084 <location filename="../rbutilqt.cpp" line="578"/>
2085 <source>Installing Rockbox Utility</source>
2086 <translation>安裝 Rockbox安裝程序</translation>
2087 </message>
2088 <message>
2089 <location filename="../rbutilqt.cpp" line="596"/>
2090 <source>Error installing Rockbox Utility</source>
2091 <translation>安裝 Rockbox安裝程序錯誤!</translation>
2092 </message>
2093 <message>
2094 <location filename="../rbutilqt.cpp" line="600"/>
2095 <source>Installing user configuration</source>
2096 <translation>安裝用戶設置</translation>
2097 </message>
2098 <message>
2099 <location filename="../rbutilqt.cpp" line="604"/>
2100 <source>Error installing user configuration</source>
2101 <translation>安裝用戶設置錯誤</translation>
2102 </message>
2103 <message>
2104 <location filename="../rbutilqt.cpp" line="608"/>
2105 <source>Successfully installed Rockbox Utility.</source>
2106 <translation>成功安裝 Rockbox安裝程序.</translation>
2107 </message>
2108 <message>
2109 <location filename="../rbutilqt.cpp" line="664"/>
2110 <source>Checking for update ...</source>
2111 <translation type="unfinished"></translation>
2112 </message>
2113 <message>
2114 <location filename="../rbutilqt.cpp" line="729"/>
2115 <source>RockboxUtility Update available</source>
2116 <translation type="unfinished"></translation>
2117 </message>
2118 <message>
2119 <location filename="../rbutilqt.cpp" line="730"/>
2120 <source>&lt;b&gt;New RockboxUtility Version available.&lt;/b&gt; &lt;br&gt;&lt;br&gt;Download it from here: &lt;a href=&apos;%1&apos;&gt;%2&lt;/a&gt;</source>
2121 <translation type="unfinished"></translation>
2122 </message>
2123 <message>
2124 <location filename="../rbutilqt.cpp" line="733"/>
2125 <source>New version of Rockbox Utility available.</source>
2126 <translation type="unfinished"></translation>
2127 </message>
2128 <message>
2129 <location filename="../rbutilqt.cpp" line="736"/>
2130 <source>Rockbox Utility is up to date.</source>
2131 <translation type="unfinished"></translation>
2132 </message>
2133 <message>
2134 <location filename="../rbutilqt.cpp" line="759"/>
2135 <source>Device ejected</source>
2136 <translation type="unfinished"></translation>
2137 </message>
2138 <message>
2139 <location filename="../rbutilqt.cpp" line="760"/>
2140 <source>Device successfully ejected. You may now disconnect the player from the PC.</source>
2141 <translation type="unfinished"></translation>
2142 </message>
2143 <message>
2144 <location filename="../rbutilqt.cpp" line="764"/>
2145 <source>Ejecting failed</source>
2146 <translation type="unfinished"></translation>
2147 </message>
2148 <message>
2149 <location filename="../rbutilqt.cpp" line="765"/>
2150 <source>Ejecting the device failed. Please make sure no programs are accessing files on the device. If ejecting still fails please use your computers eject funtionality.</source>
2151 <translation type="unfinished"></translation>
2152 </message>
2153 <message>
2154 <location filename="../rbutilqt.cpp" line="337"/>
2155 <location filename="../rbutilqt.cpp" line="642"/>
2156 <source>Configuration error</source>
2157 <translation type="unfinished"></translation>
2158 </message>
2159 <message>
2160 <location filename="../rbutilqt.cpp" line="643"/>
2161 <source>Your configuration is invalid. Please go to the configuration dialog and make sure the selected values are correct.</source>
2162 <translation type="unfinished"></translation>
2163 </message>
2164 <message>
2165 <location filename="../rbutilqt.cpp" line="330"/>
2166 <source>This is a new installation of Rockbox Utility, or a new version. The configuration dialog will now open to allow you to setup the program, or review your settings.</source>
2167 <translation type="unfinished"></translation>
2168 </message>
2169 <message>
2170 <location filename="../rbutilqt.cpp" line="110"/>
2171 <source>Wine detected!</source>
2172 <translation type="unfinished"></translation>
2173 </message>
2174 <message>
2175 <location filename="../rbutilqt.cpp" line="111"/>
2176 <source>It seems you are trying to run this program under Wine. Please don&apos;t do this, running under Wine will fail. Use the native Linux binary instead.</source>
2177 <translation type="unfinished"></translation>
2178 </message>
2179 <message>
2180 <location filename="../rbutilqt.cpp" line="237"/>
2181 <source>Can&apos;t get version information.
2182Network error: %1. Please check your network and proxy settings.</source>
2183 <translation type="unfinished"></translation>
2184 </message>
2185 <message>
2186 <location filename="../rbutilqt.cpp" line="416"/>
2187 <source>Warning</source>
2188 <translation type="unfinished"></translation>
2189 </message>
2190 <message>
2191 <location filename="../rbutilqt.cpp" line="417"/>
2192 <source>The Application is still downloading Information about new Builds. Please try again shortly.</source>
2193 <translation type="unfinished"></translation>
2194 </message>
2195 <message>
2196 <location filename="../rbutilqt.cpp" line="329"/>
2197 <source>New installation</source>
2198 <translation type="unfinished"></translation>
2199 </message>
2200 <message>
2201 <location filename="../rbutilqt.cpp" line="338"/>
2202 <source>Your configuration is invalid. This is most likely due to a changed device path. The configuration dialog will now open to allow you to correct the problem.</source>
2203 <translation type="unfinished"></translation>
2204 </message>
2205 <message>
2206 <location filename="../rbutilqt.cpp" line="236"/>
2207 <source>Network error</source>
2208 <translation type="unfinished"></translation>
2209 </message>
2210</context>
2211<context>
2212 <name>RbUtilQtFrm</name>
2213 <message>
2214 <location filename="../rbutilqtfrm.ui" line="14"/>
2215 <source>Rockbox Utility</source>
2216 <translation>Rockbox 安裝程序</translation>
2217 </message>
2218 <message>
2219 <location filename="../rbutilqtfrm.ui" line="31"/>
2220 <source>Device</source>
2221 <translation>播放器</translation>
2222 </message>
2223 <message>
2224 <location filename="../rbutilqtfrm.ui" line="92"/>
2225 <source>&amp;Change</source>
2226 <translation>&amp;更改</translation>
2227 </message>
2228 <message>
2229 <location filename="../rbutilqtfrm.ui" line="163"/>
2230 <source>Welcome</source>
2231 <translation>歡迎</translation>
2232 </message>
2233 <message>
2234 <location filename="../rbutilqtfrm.ui" line="160"/>
2235 <location filename="../rbutilqtfrm.ui" line="658"/>
2236 <source>&amp;Installation</source>
2237 <translation>&amp;安裝</translation>
2238 </message>
2239 <message>
2240 <location filename="../rbutilqtfrm.ui" line="168"/>
2241 <location filename="../rbutilqtfrm.ui" line="450"/>
2242 <source>&amp;Accessibility</source>
2243 <translation>&amp;輔助</translation>
2244 </message>
2245 <message>
2246 <location filename="../rbutilqtfrm.ui" line="171"/>
2247 <source>Install accessibility add-ons</source>
2248 <translation>安裝輔助功能</translation>
2249 </message>
2250 <message>
2251 <location filename="../rbutilqtfrm.ui" line="177"/>
2252 <source>Install Voice files</source>
2253 <translation>安裝語音文件</translation>
2254 </message>
2255 <message>
2256 <location filename="../rbutilqtfrm.ui" line="204"/>
2257 <source>Install Talk files</source>
2258 <translation>安裝說話文件</translation>
2259 </message>
2260 <message>
2261 <location filename="../rbutilqtfrm.ui" line="458"/>
2262 <source>&amp;Uninstallation</source>
2263 <translation>&amp;卸載</translation>
2264 </message>
2265 <message>
2266 <location filename="../rbutilqtfrm.ui" line="286"/>
2267 <location filename="../rbutilqtfrm.ui" line="319"/>
2268 <source>Uninstall Rockbox</source>
2269 <translation>卸載 Rockbox</translation>
2270 </message>
2271 <message>
2272 <location filename="../rbutilqtfrm.ui" line="121"/>
2273 <source>mountpoint unknown or invalid</source>
2274 <translation type="unfinished"></translation>
2275 </message>
2276 <message>
2277 <location filename="../rbutilqtfrm.ui" line="114"/>
2278 <source>Mountpoint:</source>
2279 <translation type="unfinished"></translation>
2280 </message>
2281 <message>
2282 <location filename="../rbutilqtfrm.ui" line="72"/>
2283 <source>device unknown or invalid</source>
2284 <translation type="unfinished"></translation>
2285 </message>
2286 <message>
2287 <location filename="../rbutilqtfrm.ui" line="65"/>
2288 <source>Device:</source>
2289 <translation type="unfinished"></translation>
2290 </message>
2291 <message>
2292 <location filename="../rbutilqtfrm.ui" line="292"/>
2293 <source>Uninstall Bootloader</source>
2294 <translation>卸載啟動程序</translation>
2295 </message>
2296 <message>
2297 <location filename="../rbutilqtfrm.ui" line="393"/>
2298 <source>&amp;Manual</source>
2299 <translation>&amp;用戶手冊</translation>
2300 </message>
2301 <message>
2302 <location filename="../rbutilqtfrm.ui" line="396"/>
2303 <source>View and download the manual</source>
2304 <translation>查看和下載用戶手冊</translation>
2305 </message>
2306 <message>
2307 <location filename="../rbutilqtfrm.ui" line="401"/>
2308 <source>Inf&amp;o</source>
2309 <translation>&amp;信息</translation>
2310 </message>
2311 <message>
2312 <location filename="../rbutilqtfrm.ui" line="419"/>
2313 <source>&amp;File</source>
2314 <translation>&amp;文件</translation>
2315 </message>
2316 <message>
2317 <location filename="../rbutilqtfrm.ui" line="432"/>
2318 <source>&amp;Troubleshoot</source>
2319 <translation type="unfinished"></translation>
2320 </message>
2321 <message>
2322 <location filename="../rbutilqtfrm.ui" line="497"/>
2323 <source>&amp;About</source>
2324 <translation>&amp;關于</translation>
2325 </message>
2326 <message>
2327 <location filename="../rbutilqtfrm.ui" line="653"/>
2328 <source>System &amp;Trace</source>
2329 <translation type="unfinished"></translation>
2330 </message>
2331 <message>
2332 <location filename="../rbutilqtfrm.ui" line="474"/>
2333 <source>Empty local download cache</source>
2334 <translation>清除本机下載緩沖</translation>
2335 </message>
2336 <message>
2337 <location filename="../rbutilqtfrm.ui" line="479"/>
2338 <source>Install Rockbox Utility on player</source>
2339 <translation>安裝Rockbox安裝程序到你的播放器</translation>
2340 </message>
2341 <message>
2342 <location filename="../rbutilqtfrm.ui" line="484"/>
2343 <source>&amp;Configure</source>
2344 <translation>&amp;設置</translation>
2345 </message>
2346 <message>
2347 <location filename="../rbutilqtfrm.ui" line="489"/>
2348 <source>E&amp;xit</source>
2349 <translation>&amp;退出</translation>
2350 </message>
2351 <message>
2352 <location filename="../rbutilqtfrm.ui" line="492"/>
2353 <source>Ctrl+Q</source>
2354 <translation>Ctrl+Q</translation>
2355 </message>
2356 <message>
2357 <location filename="../rbutilqtfrm.ui" line="502"/>
2358 <source>About &amp;Qt</source>
2359 <translation>關于&amp;Qt</translation>
2360 </message>
2361 <message>
2362 <location filename="../rbutilqtfrm.ui" line="428"/>
2363 <location filename="../rbutilqtfrm.ui" line="507"/>
2364 <source>&amp;Help</source>
2365 <translation>&amp;幫助</translation>
2366 </message>
2367 <message>
2368 <location filename="../rbutilqtfrm.ui" line="446"/>
2369 <source>Action&amp;s</source>
2370 <translation type="unfinished"></translation>
2371 </message>
2372 <message>
2373 <location filename="../rbutilqtfrm.ui" line="512"/>
2374 <source>Info</source>
2375 <translation type="unfinished"></translation>
2376 </message>
2377 <message>
2378 <location filename="../rbutilqtfrm.ui" line="616"/>
2379 <source>Read PDF manual</source>
2380 <translation type="unfinished"></translation>
2381 </message>
2382 <message>
2383 <location filename="../rbutilqtfrm.ui" line="621"/>
2384 <source>Read HTML manual</source>
2385 <translation type="unfinished"></translation>
2386 </message>
2387 <message>
2388 <location filename="../rbutilqtfrm.ui" line="626"/>
2389 <source>Download PDF manual</source>
2390 <translation type="unfinished"></translation>
2391 </message>
2392 <message>
2393 <location filename="../rbutilqtfrm.ui" line="631"/>
2394 <source>Download HTML manual (zip)</source>
2395 <translation type="unfinished"></translation>
2396 </message>
2397 <message>
2398 <location filename="../rbutilqtfrm.ui" line="254"/>
2399 <source>Create Voice files</source>
2400 <translation type="unfinished"></translation>
2401 </message>
2402 <message>
2403 <location filename="../rbutilqtfrm.ui" line="643"/>
2404 <source>Create Voice File</source>
2405 <translation type="unfinished"></translation>
2406 </message>
2407 <message>
2408 <location filename="../rbutilqtfrm.ui" line="194"/>
2409 <source>&lt;b&gt;Install Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so if you installed the voice file Rockbox will speak.</source>
2410 <translation type="unfinished"></translation>
2411 </message>
2412 <message>
2413 <location filename="../rbutilqtfrm.ui" line="103"/>
2414 <source>&amp;Eject</source>
2415 <translation type="unfinished"></translation>
2416 </message>
2417 <message>
2418 <location filename="../rbutilqtfrm.ui" line="221"/>
2419 <source>&lt;b&gt;Create Talk Files&lt;/b&gt;&lt;br/&gt;Talkfiles are needed to let Rockbox speak File and Foldernames</source>
2420 <translation type="unfinished"></translation>
2421 </message>
2422 <message>
2423 <location filename="../rbutilqtfrm.ui" line="271"/>
2424 <source>&lt;b&gt;Create Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so
2425 if you installed the voice file Rockbox will speak.</source>
2426 <translation type="unfinished"></translation>
2427 </message>
2428 <message>
2429 <location filename="../rbutilqtfrm.ui" line="283"/>
2430 <source>Backup &amp;&amp; &amp;Uninstallation</source>
2431 <translation type="unfinished"></translation>
2432 </message>
2433 <message>
2434 <location filename="../rbutilqtfrm.ui" line="309"/>
2435 <source>&lt;b&gt;Remove the bootloader&lt;/b&gt;&lt;br/&gt;After removing the bootloader you won&apos;t be able to start Rockbox.</source>
2436 <translation type="unfinished"></translation>
2437 </message>
2438 <message>
2439 <location filename="../rbutilqtfrm.ui" line="336"/>
2440 <source>&lt;b&gt;Uninstall Rockbox from your audio player.&lt;/b&gt;&lt;br/&gt;This will leave the bootloader in place (you need to remove it manually).</source>
2441 <translation type="unfinished"></translation>
2442 </message>
2443 <message>
2444 <location filename="../rbutilqtfrm.ui" line="349"/>
2445 <source>Backup</source>
2446 <translation type="unfinished"></translation>
2447 </message>
2448 <message>
2449 <location filename="../rbutilqtfrm.ui" line="366"/>
2450 <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup current installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Create a backup by archiving the contents of the Rockbox installation folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
2451 <translation type="unfinished"></translation>
2452 </message>
2453 <message>
2454 <location filename="../rbutilqtfrm.ui" line="539"/>
2455 <source>Install &amp;Bootloader</source>
2456 <translation type="unfinished"></translation>
2457 </message>
2458 <message>
2459 <location filename="../rbutilqtfrm.ui" line="548"/>
2460 <source>Install &amp;Rockbox</source>
2461 <translation type="unfinished"></translation>
2462 </message>
2463 <message>
2464 <location filename="../rbutilqtfrm.ui" line="557"/>
2465 <source>Install &amp;Fonts Package</source>
2466 <translation type="unfinished"></translation>
2467 </message>
2468 <message>
2469 <location filename="../rbutilqtfrm.ui" line="566"/>
2470 <source>Install &amp;Themes</source>
2471 <translation type="unfinished"></translation>
2472 </message>
2473 <message>
2474 <location filename="../rbutilqtfrm.ui" line="575"/>
2475 <source>Install &amp;Game Files</source>
2476 <translation type="unfinished"></translation>
2477 </message>
2478 <message>
2479 <location filename="../rbutilqtfrm.ui" line="584"/>
2480 <source>&amp;Install Voice File</source>
2481 <translation type="unfinished"></translation>
2482 </message>
2483 <message>
2484 <location filename="../rbutilqtfrm.ui" line="593"/>
2485 <source>Create &amp;Talk Files</source>
2486 <translation type="unfinished"></translation>
2487 </message>
2488 <message>
2489 <location filename="../rbutilqtfrm.ui" line="602"/>
2490 <source>Remove &amp;bootloader</source>
2491 <translation type="unfinished"></translation>
2492 </message>
2493 <message>
2494 <location filename="../rbutilqtfrm.ui" line="611"/>
2495 <source>Uninstall &amp;Rockbox</source>
2496 <translation type="unfinished"></translation>
2497 </message>
2498 <message>
2499 <location filename="../rbutilqtfrm.ui" line="640"/>
2500 <source>Create &amp;Voice File</source>
2501 <translation type="unfinished"></translation>
2502 </message>
2503 <message>
2504 <location filename="../rbutilqtfrm.ui" line="648"/>
2505 <source>&amp;System Info</source>
2506 <translation type="unfinished"></translation>
2507 </message>
2508 <message>
2509 <location filename="../rbutilqtfrm.ui" line="663"/>
2510 <source>Show &amp;Changelog</source>
2511 <translation type="unfinished"></translation>
2512 </message>
2513 <message>
2514 <location filename="../rbutilqtfrm.ui" line="521"/>
2515 <source>&amp;Complete Installation</source>
2516 <translation type="unfinished"></translation>
2517 </message>
2518 <message>
2519 <location filename="../rbutilqtfrm.ui" line="530"/>
2520 <source>&amp;Minimal Installation</source>
2521 <translation type="unfinished"></translation>
2522 </message>
2523</context>
2524<context>
2525 <name>SelectiveInstallWidget</name>
2526 <message>
2527 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="20"/>
2528 <source>Selective Installation</source>
2529 <translation type="unfinished"></translation>
2530 </message>
2531 <message>
2532 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="26"/>
2533 <source>Rockbox version to install</source>
2534 <translation type="unfinished"></translation>
2535 </message>
2536 <message>
2537 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="35"/>
2538 <source>Version information not available yet.</source>
2539 <translation type="unfinished"></translation>
2540 </message>
2541 <message>
2542 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="54"/>
2543 <source>Rockbox components to install</source>
2544 <translation type="unfinished"></translation>
2545 </message>
2546 <message>
2547 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="60"/>
2548 <source>&amp;Bootloader</source>
2549 <translation type="unfinished"></translation>
2550 </message>
2551 <message>
2552 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="80"/>
2553 <source>The main Rockbox firmware.</source>
2554 <translation type="unfinished"></translation>
2555 </message>
2556 <message>
2557 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="90"/>
2558 <source>Fonts</source>
2559 <translation type="unfinished"></translation>
2560 </message>
2561 <message>
2562 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="104"/>
2563 <source>&amp;Rockbox</source>
2564 <translation type="unfinished"></translation>
2565 </message>
2566 <message>
2567 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="124"/>
2568 <source>Some game plugins require additional files.</source>
2569 <translation type="unfinished"></translation>
2570 </message>
2571 <message>
2572 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="140"/>
2573 <source>Additional fonts for the User Interface.</source>
2574 <translation type="unfinished"></translation>
2575 </message>
2576 <message>
2577 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="156"/>
2578 <source>The bootloader is required for starting Rockbox. Only necessary for first time install.</source>
2579 <translation type="unfinished"></translation>
2580 </message>
2581 <message>
2582 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="166"/>
2583 <source>Game Files</source>
2584 <translation type="unfinished"></translation>
2585 </message>
2586 <message>
2587 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="177"/>
2588 <source>Customize</source>
2589 <translation type="unfinished"></translation>
2590 </message>
2591 <message>
2592 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="188"/>
2593 <source>Themes</source>
2594 <translation type="unfinished"></translation>
2595 </message>
2596 <message>
2597 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="205"/>
2598 <source>Themes allow adjusting the user interface of Rockbox. Use &quot;Customize&quot; to select themes.</source>
2599 <translation type="unfinished"></translation>
2600 </message>
2601 <message>
2602 <location filename="../gui/selectiveinstallwidgetfrm.ui" line="250"/>
2603 <source>&amp;Install</source>
2604 <translation type="unfinished"></translation>
2605 </message>
2606 <message>
2607 <location filename="../gui/selectiveinstallwidget.cpp" line="67"/>
2608 <source>This is the latest stable release available.</source>
2609 <translation type="unfinished"></translation>
2610 </message>
2611 <message>
2612 <location filename="../gui/selectiveinstallwidget.cpp" line="70"/>
2613 <source>The development version is updated on every code change. Last update was on %1</source>
2614 <translation type="unfinished"></translation>
2615 </message>
2616 <message>
2617 <location filename="../gui/selectiveinstallwidget.cpp" line="74"/>
2618 <source>This will eventually become the next Rockbox version. Install it to help testing.</source>
2619 <translation type="unfinished"></translation>
2620 </message>
2621 <message>
2622 <location filename="../gui/selectiveinstallwidget.cpp" line="100"/>
2623 <source>Stable Release (Version %1)</source>
2624 <translation type="unfinished"></translation>
2625 </message>
2626 <message>
2627 <location filename="../gui/selectiveinstallwidget.cpp" line="104"/>
2628 <source>Development Version (Revison %1)</source>
2629 <translation type="unfinished"></translation>
2630 </message>
2631 <message>
2632 <location filename="../gui/selectiveinstallwidget.cpp" line="108"/>
2633 <source>Release Candidate (Revison %1)</source>
2634 <translation type="unfinished"></translation>
2635 </message>
2636 <message>
2637 <location filename="../gui/selectiveinstallwidget.cpp" line="131"/>
2638 <source>The selected player doesn&apos;t need a bootloader.</source>
2639 <translation type="unfinished"></translation>
2640 </message>
2641 <message>
2642 <location filename="../gui/selectiveinstallwidget.cpp" line="136"/>
2643 <source>The bootloader is required for starting Rockbox. Installation of the bootloader is only necessary on first time installation.</source>
2644 <translation type="unfinished"></translation>
2645 </message>
2646 <message>
2647 <location filename="../gui/selectiveinstallwidget.cpp" line="183"/>
2648 <source>Mountpoint is wrong</source>
2649 <translation type="unfinished"></translation>
2650 </message>
2651 <message>
2652 <location filename="../gui/selectiveinstallwidget.cpp" line="239"/>
2653 <source>No install method known.</source>
2654 <translation type="unfinished"></translation>
2655 </message>
2656 <message>
2657 <location filename="../gui/selectiveinstallwidget.cpp" line="266"/>
2658 <source>Bootloader detected</source>
2659 <translation type="unfinished"></translation>
2660 </message>
2661 <message>
2662 <location filename="../gui/selectiveinstallwidget.cpp" line="267"/>
2663 <source>Bootloader already installed. Do you want to reinstall the bootloader?</source>
2664 <translation type="unfinished"></translation>
2665 </message>
2666 <message>
2667 <location filename="../gui/selectiveinstallwidget.cpp" line="271"/>
2668 <source>Bootloader installation skipped</source>
2669 <translation type="unfinished"></translation>
2670 </message>
2671 <message>
2672 <location filename="../gui/selectiveinstallwidget.cpp" line="284"/>
2673 <source>Create Bootloader backup</source>
2674 <translation type="unfinished"></translation>
2675 </message>
2676 <message>
2677 <location filename="../gui/selectiveinstallwidget.cpp" line="285"/>
2678 <source>You can create a backup of the original bootloader file. Press &quot;Yes&quot; to select an output folder on your computer to save the file to. The file will get placed in a new folder &quot;%1&quot; created below the selected folder.
2679Press &quot;No&quot; to skip this step.</source>
2680 <translation type="unfinished"></translation>
2681 </message>
2682 <message>
2683 <location filename="../gui/selectiveinstallwidget.cpp" line="292"/>
2684 <source>Browse backup folder</source>
2685 <translation type="unfinished"></translation>
2686 </message>
2687 <message>
2688 <location filename="../gui/selectiveinstallwidget.cpp" line="304"/>
2689 <source>Prerequisites</source>
2690 <translation type="unfinished"></translation>
2691 </message>
2692 <message>
2693 <location filename="../gui/selectiveinstallwidget.cpp" line="309"/>
2694 <source>Bootloader installation aborted</source>
2695 <translation type="unfinished"></translation>
2696 </message>
2697 <message>
2698 <location filename="../gui/selectiveinstallwidget.cpp" line="319"/>
2699 <source>Bootloader files (%1)</source>
2700 <translation type="unfinished"></translation>
2701 </message>
2702 <message>
2703 <location filename="../gui/selectiveinstallwidget.cpp" line="321"/>
2704 <source>All files (*)</source>
2705 <translation type="unfinished"></translation>
2706 </message>
2707 <message>
2708 <location filename="../gui/selectiveinstallwidget.cpp" line="323"/>
2709 <source>Select firmware file</source>
2710 <translation type="unfinished"></translation>
2711 </message>
2712 <message>
2713 <location filename="../gui/selectiveinstallwidget.cpp" line="325"/>
2714 <source>Error opening firmware file</source>
2715 <translation type="unfinished"></translation>
2716 </message>
2717 <message>
2718 <location filename="../gui/selectiveinstallwidget.cpp" line="331"/>
2719 <source>Error reading firmware file</source>
2720 <translation type="unfinished"></translation>
2721 </message>
2722 <message>
2723 <location filename="../gui/selectiveinstallwidget.cpp" line="341"/>
2724 <source>Backup error</source>
2725 <translation type="unfinished"></translation>
2726 </message>
2727 <message>
2728 <location filename="../gui/selectiveinstallwidget.cpp" line="342"/>
2729 <source>Could not create backup file. Continue?</source>
2730 <translation type="unfinished"></translation>
2731 </message>
2732 <message>
2733 <location filename="../gui/selectiveinstallwidget.cpp" line="366"/>
2734 <source>Manual steps required</source>
2735 <translation type="unfinished"></translation>
2736 </message>
2737 <message>
2738 <location filename="../gui/selectiveinstallwidget.cpp" line="171"/>
2739 <source>Continue with installation?</source>
2740 <translation type="unfinished"></translation>
2741 </message>
2742 <message>
2743 <location filename="../gui/selectiveinstallwidget.cpp" line="172"/>
2744 <source>Really continue?</source>
2745 <translation type="unfinished"></translation>
2746 </message>
2747 <message>
2748 <location filename="../gui/selectiveinstallwidget.cpp" line="490"/>
2749 <source>Your installation doesn&apos;t require game files, skipping.</source>
2750 <translation type="unfinished"></translation>
2751 </message>
2752</context>
2753<context>
2754 <name>ServerInfo</name>
2755 <message>
2756 <location filename="../base/serverinfo.cpp" line="117"/>
2757 <source>Unknown</source>
2758 <translation type="unfinished"></translation>
2759 </message>
2760 <message>
2761 <location filename="../base/serverinfo.cpp" line="121"/>
2762 <source>Unusable</source>
2763 <translation type="unfinished"></translation>
2764 </message>
2765 <message>
2766 <location filename="../base/serverinfo.cpp" line="124"/>
2767 <source>Unstable</source>
2768 <translation type="unfinished"></translation>
2769 </message>
2770 <message>
2771 <location filename="../base/serverinfo.cpp" line="127"/>
2772 <source>Stable</source>
2773 <translation type="unfinished"></translation>
2774 </message>
2775</context>
2776<context>
2777 <name>SysTrace</name>
2778 <message>
2779 <location filename="../systrace.cpp" line="98"/>
2780 <location filename="../systrace.cpp" line="107"/>
2781 <source>Save system trace log</source>
2782 <translation type="unfinished"></translation>
2783 </message>
2784</context>
2785<context>
2786 <name>SysTraceFrm</name>
2787 <message>
2788 <location filename="../systracefrm.ui" line="14"/>
2789 <source>System Trace</source>
2790 <translation type="unfinished"></translation>
2791 </message>
2792 <message>
2793 <location filename="../systracefrm.ui" line="20"/>
2794 <source>System State trace</source>
2795 <translation type="unfinished"></translation>
2796 </message>
2797 <message>
2798 <location filename="../systracefrm.ui" line="46"/>
2799 <source>&amp;Close</source>
2800 <translation type="unfinished"></translation>
2801 </message>
2802 <message>
2803 <location filename="../systracefrm.ui" line="57"/>
2804 <source>&amp;Save</source>
2805 <translation type="unfinished"></translation>
2806 </message>
2807 <message>
2808 <location filename="../systracefrm.ui" line="68"/>
2809 <source>&amp;Refresh</source>
2810 <translation type="unfinished"></translation>
2811 </message>
2812 <message>
2813 <location filename="../systracefrm.ui" line="79"/>
2814 <source>Save &amp;previous</source>
2815 <translation type="unfinished"></translation>
2816 </message>
2817</context>
2818<context>
2819 <name>Sysinfo</name>
2820 <message>
2821 <location filename="../sysinfo.cpp" line="45"/>
2822 <source>&lt;b&gt;OS&lt;/b&gt;&lt;br/&gt;</source>
2823 <translation type="unfinished"></translation>
2824 </message>
2825 <message>
2826 <location filename="../sysinfo.cpp" line="46"/>
2827 <source>&lt;b&gt;Username&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2828 <translation type="unfinished"></translation>
2829 </message>
2830 <message>
2831 <location filename="../sysinfo.cpp" line="48"/>
2832 <source>&lt;b&gt;Permissions&lt;/b&gt;&lt;br/&gt;%1&lt;hr/&gt;</source>
2833 <translation type="unfinished"></translation>
2834 </message>
2835 <message>
2836 <location filename="../sysinfo.cpp" line="50"/>
2837 <source>&lt;b&gt;Attached USB devices&lt;/b&gt;&lt;br/&gt;</source>
2838 <translation type="unfinished"></translation>
2839 </message>
2840 <message>
2841 <location filename="../sysinfo.cpp" line="54"/>
2842 <source>VID: %1 PID: %2, %3</source>
2843 <translation type="unfinished"></translation>
2844 </message>
2845 <message>
2846 <location filename="../sysinfo.cpp" line="63"/>
2847 <source>Filesystem</source>
2848 <translation type="unfinished"></translation>
2849 </message>
2850 <message>
2851 <location filename="../sysinfo.cpp" line="66"/>
2852 <source>Mountpoint</source>
2853 <translation type="unfinished"></translation>
2854 </message>
2855 <message>
2856 <location filename="../sysinfo.cpp" line="66"/>
2857 <source>Label</source>
2858 <translation type="unfinished"></translation>
2859 </message>
2860 <message>
2861 <location filename="../sysinfo.cpp" line="67"/>
2862 <source>Free</source>
2863 <translation type="unfinished"></translation>
2864 </message>
2865 <message>
2866 <location filename="../sysinfo.cpp" line="67"/>
2867 <source>Total</source>
2868 <translation type="unfinished"></translation>
2869 </message>
2870 <message>
2871 <location filename="../sysinfo.cpp" line="68"/>
2872 <source>Cluster Size</source>
2873 <translation type="unfinished"></translation>
2874 </message>
2875 <message>
2876 <location filename="../sysinfo.cpp" line="70"/>
2877 <source>&lt;tr&gt;&lt;td&gt;%1&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;td&gt;%2 GiB&lt;/td&gt;&lt;td&gt;%3 GiB&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;</source>
2878 <translation type="unfinished"></translation>
2879 </message>
2880</context>
2881<context>
2882 <name>SysinfoFrm</name>
2883 <message>
2884 <location filename="../sysinfofrm.ui" line="13"/>
2885 <source>System Info</source>
2886 <translation type="unfinished"></translation>
2887 </message>
2888 <message>
2889 <location filename="../sysinfofrm.ui" line="22"/>
2890 <source>&amp;Refresh</source>
2891 <translation type="unfinished"></translation>
2892 </message>
2893 <message>
2894 <location filename="../sysinfofrm.ui" line="45"/>
2895 <source>&amp;OK</source>
2896 <translation type="unfinished"></translation>
2897 </message>
2898</context>
2899<context>
2900 <name>System</name>
2901 <message>
2902 <location filename="../base/system.cpp" line="121"/>
2903 <source>Guest</source>
2904 <translation type="unfinished"></translation>
2905 </message>
2906 <message>
2907 <location filename="../base/system.cpp" line="124"/>
2908 <source>Admin</source>
2909 <translation type="unfinished"></translation>
2910 </message>
2911 <message>
2912 <location filename="../base/system.cpp" line="127"/>
2913 <source>User</source>
2914 <translation type="unfinished"></translation>
2915 </message>
2916 <message>
2917 <location filename="../base/system.cpp" line="130"/>
2918 <source>Error</source>
2919 <translation type="unfinished"></translation>
2920 </message>
2921 <message>
2922 <location filename="../base/system.cpp" line="278"/>
2923 <location filename="../base/system.cpp" line="323"/>
2924 <source>(no description available)</source>
2925 <translation type="unfinished"></translation>
2926 </message>
2927</context>
2928<context>
2929 <name>TTSBase</name>
2930 <message>
2931 <location filename="../base/ttsbase.cpp" line="45"/>
2932 <source>Espeak TTS Engine</source>
2933 <translation type="unfinished"></translation>
2934 </message>
2935 <message>
2936 <location filename="../base/ttsbase.cpp" line="47"/>
2937 <source>Flite TTS Engine</source>
2938 <translation type="unfinished"></translation>
2939 </message>
2940 <message>
2941 <location filename="../base/ttsbase.cpp" line="48"/>
2942 <source>Swift TTS Engine</source>
2943 <translation type="unfinished"></translation>
2944 </message>
2945 <message>
2946 <location filename="../base/ttsbase.cpp" line="51"/>
2947 <source>SAPI4 TTS Engine</source>
2948 <translation type="unfinished"></translation>
2949 </message>
2950 <message>
2951 <location filename="../base/ttsbase.cpp" line="53"/>
2952 <source>SAPI5 TTS Engine</source>
2953 <translation type="unfinished"></translation>
2954 </message>
2955 <message>
2956 <location filename="../base/ttsbase.cpp" line="54"/>
2957 <source>MS Speech Platform</source>
2958 <translation type="unfinished"></translation>
2959 </message>
2960 <message>
2961 <location filename="../base/ttsbase.cpp" line="57"/>
2962 <source>Festival TTS Engine</source>
2963 <translation type="unfinished"></translation>
2964 </message>
2965 <message>
2966 <location filename="../base/ttsbase.cpp" line="60"/>
2967 <source>OS X System Engine</source>
2968 <translation type="unfinished"></translation>
2969 </message>
2970</context>
2971<context>
2972 <name>TTSCarbon</name>
2973 <message>
2974 <location filename="../base/ttscarbon.cpp" line="139"/>
2975 <source>Voice:</source>
2976 <translation type="unfinished"></translation>
2977 </message>
2978 <message>
2979 <location filename="../base/ttscarbon.cpp" line="145"/>
2980 <source>Speed (words/min):</source>
2981 <translation type="unfinished"></translation>
2982 </message>
2983 <message>
2984 <location filename="../base/ttscarbon.cpp" line="152"/>
2985 <source>Pitch (0 for default):</source>
2986 <translation type="unfinished"></translation>
2987 </message>
2988 <message>
2989 <location filename="../base/ttscarbon.cpp" line="222"/>
2990 <source>Could not voice string</source>
2991 <translation type="unfinished"></translation>
2992 </message>
2993 <message>
2994 <location filename="../base/ttscarbon.cpp" line="232"/>
2995 <source>Could not convert intermediate file</source>
2996 <translation type="unfinished"></translation>
2997 </message>
2998</context>
2999<context>
3000 <name>TTSExes</name>
3001 <message>
3002 <location filename="../base/ttsexes.cpp" line="78"/>
3003 <source>TTS executable not found</source>
3004 <translation type="unfinished"></translation>
3005 </message>
3006 <message>
3007 <location filename="../base/ttsexes.cpp" line="44"/>
3008 <source>Path to TTS engine:</source>
3009 <translation type="unfinished"></translation>
3010 </message>
3011 <message>
3012 <location filename="../base/ttsexes.cpp" line="46"/>
3013 <source>TTS engine options:</source>
3014 <translation type="unfinished"></translation>
3015 </message>
3016</context>
3017<context>
3018 <name>TTSFestival</name>
3019 <message>
3020 <location filename="../base/ttsfestival.cpp" line="207"/>
3021 <source>engine could not voice string</source>
3022 <translation type="unfinished"></translation>
3023 </message>
3024 <message>
3025 <location filename="../base/ttsfestival.cpp" line="290"/>
3026 <source>No description available</source>
3027 <translation type="unfinished"></translation>
3028 </message>
3029 <message>
3030 <location filename="../base/ttsfestival.cpp" line="53"/>
3031 <source>Path to Festival client:</source>
3032 <translation type="unfinished"></translation>
3033 </message>
3034 <message>
3035 <location filename="../base/ttsfestival.cpp" line="58"/>
3036 <source>Voice:</source>
3037 <translation type="unfinished"></translation>
3038 </message>
3039 <message>
3040 <location filename="../base/ttsfestival.cpp" line="67"/>
3041 <source>Voice description:</source>
3042 <translation type="unfinished"></translation>
3043 </message>
3044</context>
3045<context>
3046 <name>TTSSapi</name>
3047 <message>
3048 <location filename="../base/ttssapi.cpp" line="49"/>
3049 <source>Language:</source>
3050 <translation type="unfinished"></translation>
3051 </message>
3052 <message>
3053 <location filename="../base/ttssapi.cpp" line="56"/>
3054 <source>Voice:</source>
3055 <translation type="unfinished"></translation>
3056 </message>
3057 <message>
3058 <location filename="../base/ttssapi.cpp" line="68"/>
3059 <source>Speed:</source>
3060 <translation type="unfinished"></translation>
3061 </message>
3062 <message>
3063 <location filename="../base/ttssapi.cpp" line="71"/>
3064 <source>Options:</source>
3065 <translation type="unfinished"></translation>
3066 </message>
3067 <message>
3068 <location filename="../base/ttssapi.cpp" line="115"/>
3069 <source>Could not copy the SAPI script</source>
3070 <translation type="unfinished"></translation>
3071 </message>
3072 <message>
3073 <location filename="../base/ttssapi.cpp" line="133"/>
3074 <source>Could not start SAPI process</source>
3075 <translation type="unfinished"></translation>
3076 </message>
3077</context>
3078<context>
3079 <name>TalkFileCreator</name>
3080 <message>
3081 <location filename="../base/talkfile.cpp" line="68"/>
3082 <source>Copying Talkfiles...</source>
3083 <translation type="unfinished"></translation>
3084 </message>
3085 <message>
3086 <location filename="../base/talkfile.cpp" line="240"/>
3087 <source>File copy aborted</source>
3088 <translation type="unfinished"></translation>
3089 </message>
3090 <message>
3091 <location filename="../base/talkfile.cpp" line="280"/>
3092 <source>Cleaning up...</source>
3093 <translation type="unfinished"></translation>
3094 </message>
3095 <message>
3096 <location filename="../base/talkfile.cpp" line="291"/>
3097 <source>Finished</source>
3098 <translation type="unfinished"></translation>
3099 </message>
3100 <message>
3101 <location filename="../base/talkfile.cpp" line="45"/>
3102 <source>Talk file creation aborted</source>
3103 <translation type="unfinished"></translation>
3104 </message>
3105 <message>
3106 <location filename="../base/talkfile.cpp" line="36"/>
3107 <source>Starting Talk file generation for folder %1</source>
3108 <translation type="unfinished"></translation>
3109 </message>
3110 <message>
3111 <location filename="../base/talkfile.cpp" line="80"/>
3112 <source>Finished creating Talk files</source>
3113 <translation type="unfinished"></translation>
3114 </message>
3115 <message>
3116 <location filename="../base/talkfile.cpp" line="42"/>
3117 <source>Reading Filelist...</source>
3118 <translation type="unfinished"></translation>
3119 </message>
3120 <message>
3121 <location filename="../base/talkfile.cpp" line="259"/>
3122 <source>Copying of %1 to %2 failed</source>
3123 <translation type="unfinished"></translation>
3124 </message>
3125</context>
3126<context>
3127 <name>TalkGenerator</name>
3128 <message>
3129 <location filename="../base/talkgenerator.cpp" line="39"/>
3130 <source>Starting TTS Engine</source>
3131 <translation type="unfinished"></translation>
3132 </message>
3133 <message>
3134 <location filename="../base/talkgenerator.cpp" line="44"/>
3135 <location filename="../base/talkgenerator.cpp" line="51"/>
3136 <source>Init of TTS engine failed</source>
3137 <translation type="unfinished"></translation>
3138 </message>
3139 <message>
3140 <location filename="../base/talkgenerator.cpp" line="58"/>
3141 <source>Starting Encoder Engine</source>
3142 <translation type="unfinished"></translation>
3143 </message>
3144 <message>
3145 <location filename="../base/talkgenerator.cpp" line="62"/>
3146 <source>Init of Encoder engine failed</source>
3147 <translation type="unfinished"></translation>
3148 </message>
3149 <message>
3150 <location filename="../base/talkgenerator.cpp" line="72"/>
3151 <source>Voicing entries...</source>
3152 <translation type="unfinished"></translation>
3153 </message>
3154 <message>
3155 <location filename="../base/talkgenerator.cpp" line="87"/>
3156 <source>Encoding files...</source>
3157 <translation type="unfinished"></translation>
3158 </message>
3159 <message>
3160 <location filename="../base/talkgenerator.cpp" line="126"/>
3161 <source>Voicing aborted</source>
3162 <translation type="unfinished"></translation>
3163 </message>
3164 <message>
3165 <location filename="../base/talkgenerator.cpp" line="162"/>
3166 <location filename="../base/talkgenerator.cpp" line="167"/>
3167 <source>Voicing of %1 failed: %2</source>
3168 <translation type="unfinished"></translation>
3169 </message>
3170 <message>
3171 <location filename="../base/talkgenerator.cpp" line="211"/>
3172 <source>Encoding aborted</source>
3173 <translation type="unfinished"></translation>
3174 </message>
3175 <message>
3176 <location filename="../base/talkgenerator.cpp" line="239"/>
3177 <source>Encoding of %1 failed</source>
3178 <translation type="unfinished"></translation>
3179 </message>
3180</context>
3181<context>
3182 <name>ThemeInstallFrm</name>
3183 <message>
3184 <location filename="../themesinstallfrm.ui" line="13"/>
3185 <source>Theme Installation</source>
3186 <translation>安裝主題</translation>
3187 </message>
3188 <message>
3189 <location filename="../themesinstallfrm.ui" line="48"/>
3190 <source>Selected Theme</source>
3191 <translation>被選擇的主題</translation>
3192 </message>
3193 <message>
3194 <location filename="../themesinstallfrm.ui" line="73"/>
3195 <source>Description</source>
3196 <translation>描述</translation>
3197 </message>
3198 <message>
3199 <location filename="../themesinstallfrm.ui" line="83"/>
3200 <source>Download size:</source>
3201 <translation>下載大小:</translation>
3202 </message>
3203 <message>
3204 <location filename="../themesinstallfrm.ui" line="125"/>
3205 <source>&amp;Cancel</source>
3206 <translation>&amp;取消</translation>
3207 </message>
3208 <message>
3209 <location filename="../themesinstallfrm.ui" line="115"/>
3210 <source>&amp;Install</source>
3211 <translation type="unfinished"></translation>
3212 </message>
3213 <message>
3214 <location filename="../themesinstallfrm.ui" line="93"/>
3215 <source>Hold Ctrl to select multiple item, Shift for a range</source>
3216 <translation type="unfinished"></translation>
3217 </message>
3218</context>
3219<context>
3220 <name>ThemesInstallWindow</name>
3221 <message>
3222 <location filename="../themesinstallwindow.cpp" line="40"/>
3223 <source>no theme selected</source>
3224 <translation>沒有選擇主題</translation>
3225 </message>
3226 <message>
3227 <location filename="../themesinstallwindow.cpp" line="125"/>
3228 <source>Network error: %1.
3229Please check your network and proxy settings.</source>
3230 <translation>网絡錯誤: %1.
3231請檢查你的网絡和代理服務的設置.</translation>
3232 </message>
3233 <message>
3234 <location filename="../themesinstallwindow.cpp" line="144"/>
3235 <source>done.</source>
3236 <translation>完成.</translation>
3237 </message>
3238 <message>
3239 <location filename="../themesinstallwindow.cpp" line="211"/>
3240 <source>fetching details for %1</source>
3241 <translation>正在拿取 %1 的細節</translation>
3242 </message>
3243 <message>
3244 <location filename="../themesinstallwindow.cpp" line="214"/>
3245 <source>fetching preview ...</source>
3246 <translation>正在拿取預覽...</translation>
3247 </message>
3248 <message>
3249 <location filename="../themesinstallwindow.cpp" line="227"/>
3250 <source>&lt;b&gt;Author:&lt;/b&gt; %1&lt;hr/&gt;</source>
3251 <translation>&lt;b&gt;作者:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3252 </message>
3253 <message>
3254 <location filename="../themesinstallwindow.cpp" line="228"/>
3255 <location filename="../themesinstallwindow.cpp" line="230"/>
3256 <source>unknown</source>
3257 <translation>不明</translation>
3258 </message>
3259 <message>
3260 <location filename="../themesinstallwindow.cpp" line="229"/>
3261 <source>&lt;b&gt;Version:&lt;/b&gt; %1&lt;hr/&gt;</source>
3262 <translation>&lt;b&gt;版本:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3263 </message>
3264 <message>
3265 <location filename="../themesinstallwindow.cpp" line="231"/>
3266 <source>&lt;b&gt;Description:&lt;/b&gt; %1&lt;hr/&gt;</source>
3267 <translation>&lt;b&gt;描述:&lt;/b&gt; %1&lt;hr/&gt;</translation>
3268 </message>
3269 <message>
3270 <location filename="../themesinstallwindow.cpp" line="232"/>
3271 <source>no description</source>
3272 <translation>無描述</translation>
3273 </message>
3274 <message>
3275 <location filename="../themesinstallwindow.cpp" line="260"/>
3276 <source>no theme preview</source>
3277 <translation>無主題預覽</translation>
3278 </message>
3279 <message>
3280 <location filename="../themesinstallwindow.cpp" line="289"/>
3281 <source>Select</source>
3282 <translation type="unfinished"></translation>
3283 </message>
3284 <message>
3285 <location filename="../themesinstallwindow.cpp" line="296"/>
3286 <source>getting themes information ...</source>
3287 <translation>正在拿取主題信息...</translation>
3288 </message>
3289 <message>
3290 <location filename="../themesinstallwindow.cpp" line="326"/>
3291 <source>No themes selected, skipping</source>
3292 <translation type="unfinished"></translation>
3293 </message>
3294 <message>
3295 <location filename="../themesinstallwindow.cpp" line="356"/>
3296 <source>Mount point is wrong!</source>
3297 <translation>Mountpoint 錯誤!</translation>
3298 </message>
3299 <message>
3300 <location filename="../themesinstallwindow.cpp" line="138"/>
3301 <source>the following error occured:
3302%1</source>
3303 <translation type="unfinished"></translation>
3304 </message>
3305 <message>
3306 <location filename="../themesinstallwindow.cpp" line="41"/>
3307 <source>no selection</source>
3308 <translation type="unfinished"></translation>
3309 </message>
3310 <message>
3311 <location filename="../themesinstallwindow.cpp" line="181"/>
3312 <source>Information</source>
3313 <translation type="unfinished"></translation>
3314 </message>
3315 <message numerus="yes">
3316 <location filename="../themesinstallwindow.cpp" line="198"/>
3317 <source>Download size %L1 kiB (%n item(s))</source>
3318 <translation type="unfinished">
3319 <numerusform></numerusform>
3320 </translation>
3321 </message>
3322 <message>
3323 <location filename="../themesinstallwindow.cpp" line="248"/>
3324 <source>Retrieving theme preview failed.
3325HTTP response code: %1</source>
3326 <translation type="unfinished"></translation>
3327 </message>
3328</context>
3329<context>
3330 <name>UninstallFrm</name>
3331 <message>
3332 <location filename="../uninstallfrm.ui" line="16"/>
3333 <source>Uninstall Rockbox</source>
3334 <translation>卸載 Rockbox</translation>
3335 </message>
3336 <message>
3337 <location filename="../uninstallfrm.ui" line="35"/>
3338 <source>Please select the Uninstallation Method</source>
3339 <translation>請選擇卸載模式</translation>
3340 </message>
3341 <message>
3342 <location filename="../uninstallfrm.ui" line="45"/>
3343 <source>Uninstallation Method</source>
3344 <translation>卸載模式</translation>
3345 </message>
3346 <message>
3347 <location filename="../uninstallfrm.ui" line="51"/>
3348 <source>Complete Uninstallation</source>
3349 <translation>完全卸載</translation>
3350 </message>
3351 <message>
3352 <location filename="../uninstallfrm.ui" line="58"/>
3353 <source>Smart Uninstallation</source>
3354 <translation>智能卸載</translation>
3355 </message>
3356 <message>
3357 <location filename="../uninstallfrm.ui" line="68"/>
3358 <source>Please select what you want to uninstall</source>
3359 <translation>請選擇卸載部分</translation>
3360 </message>
3361 <message>
3362 <location filename="../uninstallfrm.ui" line="78"/>
3363 <source>Installed Parts</source>
3364 <translation>已安裝的部分</translation>
3365 </message>
3366 <message>
3367 <location filename="../uninstallfrm.ui" line="138"/>
3368 <source>&amp;Cancel</source>
3369 <translation>&amp;取消</translation>
3370 </message>
3371 <message>
3372 <location filename="../uninstallfrm.ui" line="128"/>
3373 <source>&amp;Uninstall</source>
3374 <translation type="unfinished"></translation>
3375 </message>
3376</context>
3377<context>
3378 <name>Uninstaller</name>
3379 <message>
3380 <location filename="../base/uninstall.cpp" line="32"/>
3381 <location filename="../base/uninstall.cpp" line="43"/>
3382 <source>Starting Uninstallation</source>
3383 <translation>開始卸載</translation>
3384 </message>
3385 <message>
3386 <location filename="../base/uninstall.cpp" line="36"/>
3387 <source>Finished Uninstallation</source>
3388 <translation>完成卸載</translation>
3389 </message>
3390 <message>
3391 <location filename="../base/uninstall.cpp" line="49"/>
3392 <source>Uninstalling %1...</source>
3393 <translation type="unfinished"></translation>
3394 </message>
3395 <message>
3396 <location filename="../base/uninstall.cpp" line="80"/>
3397 <source>Could not delete %1</source>
3398 <translation type="unfinished"></translation>
3399 </message>
3400 <message>
3401 <location filename="../base/uninstall.cpp" line="109"/>
3402 <source>Uninstallation finished</source>
3403 <translation>完成卸載</translation>
3404 </message>
3405</context>
3406<context>
3407 <name>Utils</name>
3408 <message>
3409 <location filename="../base/utils.cpp" line="312"/>
3410 <source>&lt;li&gt;Permissions insufficient for bootloader installation.
3411Administrator priviledges are necessary.&lt;/li&gt;</source>
3412 <translation type="unfinished"></translation>
3413 </message>
3414 <message>
3415 <location filename="../base/utils.cpp" line="324"/>
3416 <source>&lt;li&gt;Target mismatch detected.&lt;br/&gt;Installed target: %1&lt;br/&gt;Selected target: %2.&lt;/li&gt;</source>
3417 <translation type="unfinished"></translation>
3418 </message>
3419 <message>
3420 <location filename="../base/utils.cpp" line="331"/>
3421 <source>Problem detected:</source>
3422 <translation type="unfinished"></translation>
3423 </message>
3424</context>
3425<context>
3426 <name>VoiceFileCreator</name>
3427 <message>
3428 <location filename="../base/voicefile.cpp" line="43"/>
3429 <source>Starting Voicefile generation</source>
3430 <translation type="unfinished"></translation>
3431 </message>
3432 <message>
3433 <location filename="../base/voicefile.cpp" line="90"/>
3434 <source>Extracted voice strings from installation</source>
3435 <translation type="unfinished"></translation>
3436 </message>
3437 <message>
3438 <location filename="../base/voicefile.cpp" line="100"/>
3439 <source>Extracted voice strings incompatible</source>
3440 <translation type="unfinished"></translation>
3441 </message>
3442 <message>
3443 <location filename="../base/voicefile.cpp" line="145"/>
3444 <source>Could not retrieve strings from installation, downloading</source>
3445 <translation type="unfinished"></translation>
3446 </message>
3447 <message>
3448 <location filename="../base/voicefile.cpp" line="171"/>
3449 <source>Downloading voice info...</source>
3450 <translation type="unfinished"></translation>
3451 </message>
3452 <message>
3453 <location filename="../base/voicefile.cpp" line="184"/>
3454 <source>Download error: received HTTP error %1.</source>
3455 <translation type="unfinished">下載錯誤: 接到 HTTP 錯誤 %1. </translation>
3456 </message>
3457 <message>
3458 <location filename="../base/voicefile.cpp" line="191"/>
3459 <source>Cached file used.</source>
3460 <translation type="unfinished">使用緩沖文件.</translation>
3461 </message>
3462 <message>
3463 <location filename="../base/voicefile.cpp" line="194"/>
3464 <source>Download error: %1</source>
3465 <translation type="unfinished">下載錯誤: %1</translation>
3466 </message>
3467 <message>
3468 <location filename="../base/voicefile.cpp" line="199"/>
3469 <source>Download finished.</source>
3470 <translation type="unfinished">完成下載.</translation>
3471 </message>
3472 <message>
3473 <location filename="../base/voicefile.cpp" line="212"/>
3474 <source>failed to open downloaded file</source>
3475 <translation type="unfinished"></translation>
3476 </message>
3477 <message>
3478 <location filename="../base/voicefile.cpp" line="218"/>
3479 <source>Reading strings...</source>
3480 <translation type="unfinished"></translation>
3481 </message>
3482 <message>
3483 <location filename="../base/voicefile.cpp" line="297"/>
3484 <source>Creating voicefiles...</source>
3485 <translation type="unfinished"></translation>
3486 </message>
3487 <message>
3488 <location filename="../base/voicefile.cpp" line="342"/>
3489 <source>Cleaning up...</source>
3490 <translation type="unfinished"></translation>
3491 </message>
3492 <message>
3493 <location filename="../base/voicefile.cpp" line="353"/>
3494 <source>Finished</source>
3495 <translation type="unfinished"></translation>
3496 </message>
3497 <message>
3498 <location filename="../base/voicefile.cpp" line="271"/>
3499 <source>The downloaded file was empty!</source>
3500 <translation type="unfinished"></translation>
3501 </message>
3502 <message>
3503 <location filename="../base/voicefile.cpp" line="302"/>
3504 <source>Error opening downloaded file</source>
3505 <translation type="unfinished"></translation>
3506 </message>
3507 <message>
3508 <location filename="../base/voicefile.cpp" line="313"/>
3509 <source>Error opening output file</source>
3510 <translation type="unfinished"></translation>
3511 </message>
3512 <message>
3513 <location filename="../base/voicefile.cpp" line="333"/>
3514 <source>successfully created.</source>
3515 <translation type="unfinished"></translation>
3516 </message>
3517 <message>
3518 <location filename="../base/voicefile.cpp" line="56"/>
3519 <source>could not find rockbox-info.txt</source>
3520 <translation type="unfinished"></translation>
3521 </message>
3522</context>
3523<context>
3524 <name>ZipInstaller</name>
3525 <message>
3526 <location filename="../base/zipinstaller.cpp" line="60"/>
3527 <source>done.</source>
3528 <translation>完成.</translation>
3529 </message>
3530 <message>
3531 <location filename="../base/zipinstaller.cpp" line="68"/>
3532 <source>Package installation finished successfully.</source>
3533 <translation type="unfinished"></translation>
3534 </message>
3535 <message>
3536 <location filename="../base/zipinstaller.cpp" line="80"/>
3537 <source>Downloading file %1.%2</source>
3538 <translation>正在下載文件 %1.%2</translation>
3539 </message>
3540 <message>
3541 <location filename="../base/zipinstaller.cpp" line="115"/>
3542 <source>Download error: received HTTP error %1.</source>
3543 <translation>下載錯誤: 接到 HTTP 錯誤 %1. </translation>
3544 </message>
3545 <message>
3546 <location filename="../base/zipinstaller.cpp" line="121"/>
3547 <source>Cached file used.</source>
3548 <translation>使用緩沖文件.</translation>
3549 </message>
3550 <message>
3551 <location filename="../base/zipinstaller.cpp" line="123"/>
3552 <source>Download error: %1</source>
3553 <translation>下載錯誤: %1</translation>
3554 </message>
3555 <message>
3556 <location filename="../base/zipinstaller.cpp" line="127"/>
3557 <source>Download finished.</source>
3558 <translation>完成下載.</translation>
3559 </message>
3560 <message>
3561 <location filename="../base/zipinstaller.cpp" line="133"/>
3562 <source>Extracting file.</source>
3563 <translation>正在解壓文件.</translation>
3564 </message>
3565 <message>
3566 <location filename="../base/zipinstaller.cpp" line="153"/>
3567 <source>Extraction failed!</source>
3568 <translation type="unfinished"></translation>
3569 </message>
3570 <message>
3571 <location filename="../base/zipinstaller.cpp" line="162"/>
3572 <source>Installing file.</source>
3573 <translation>正在安裝文件.</translation>
3574 </message>
3575 <message>
3576 <location filename="../base/zipinstaller.cpp" line="173"/>
3577 <source>Installing file failed.</source>
3578 <translation>安裝文件失敗.</translation>
3579 </message>
3580 <message>
3581 <location filename="../base/zipinstaller.cpp" line="186"/>
3582 <source>Creating installation log</source>
3583 <translation>正在建立安裝日志</translation>
3584 </message>
3585 <message>
3586 <location filename="../base/zipinstaller.cpp" line="146"/>
3587 <source>Not enough disk space! Aborting.</source>
3588 <translation type="unfinished"></translation>
3589 </message>
3590</context>
3591<context>
3592 <name>ZipUtil</name>
3593 <message>
3594 <location filename="../base/ziputil.cpp" line="125"/>
3595 <source>Creating output path failed</source>
3596 <translation type="unfinished"></translation>
3597 </message>
3598 <message>
3599 <location filename="../base/ziputil.cpp" line="132"/>
3600 <source>Creating output file failed</source>
3601 <translation type="unfinished"></translation>
3602 </message>
3603 <message>
3604 <location filename="../base/ziputil.cpp" line="141"/>
3605 <source>Error during Zip operation</source>
3606 <translation type="unfinished"></translation>
3607 </message>
3608</context>
3609<context>
3610 <name>aboutBox</name>
3611 <message>
3612 <location filename="../aboutbox.ui" line="14"/>
3613 <source>About Rockbox Utility</source>
3614 <translation>關于Rockbox安裝程序</translation>
3615 </message>
3616 <message>
3617 <location filename="../aboutbox.ui" line="32"/>
3618 <source>The Rockbox Utility</source>
3619 <translation>Rockbox安裝程序</translation>
3620 </message>
3621 <message utf8="true">
3622 <location filename="../aboutbox.ui" line="54"/>
3623 <source>Installer and housekeeping utility for the Rockbox open source digital audio player firmware.&lt;br/&gt;© The Rockbox Team.&lt;br/&gt;Released under the GNU General Public License v2.&lt;br/&gt;Uses icons by the &lt;a href=&quot;http://tango.freedesktop.org/&quot;&gt;Tango Project&lt;/a&gt;.&lt;br/&gt;&lt;center&gt;&lt;a href=&quot;http://www.rockbox.org&quot;&gt;http://www.rockbox.org&lt;/a&gt;&lt;/center&gt;</source>
3624 <translation type="unfinished"></translation>
3625 </message>
3626 <message>
3627 <location filename="../aboutbox.ui" line="74"/>
3628 <source>&amp;Credits</source>
3629 <translation>&amp;特別鳴謝</translation>
3630 </message>
3631 <message>
3632 <location filename="../aboutbox.ui" line="106"/>
3633 <source>&amp;License</source>
3634 <translation>&amp;授權</translation>
3635 </message>
3636 <message>
3637 <location filename="../aboutbox.ui" line="132"/>
3638 <source>&amp;Speex License</source>
3639 <translation type="unfinished"></translation>
3640 </message>
3641 <message>
3642 <location filename="../aboutbox.ui" line="158"/>
3643 <source>&amp;Ok</source>
3644 <translation>&amp;OK</translation>
3645 </message>
3646</context>
3647</TS>
diff --git a/utils/rbutilqt/langstats.py b/utils/rbutilqt/langstats.py
new file mode 100755
index 0000000000..cbf49dce08
--- /dev/null
+++ b/utils/rbutilqt/langstats.py
@@ -0,0 +1,195 @@
1#!/usr/bin/python3
2# __________ __ ___.
3# Open \______ \ ____ ____ | | _\_ |__ _______ ___
4# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7# \/ \/ \/ \/ \/
8#
9# Copyright (c) 2010 Dominik Riebeling
10#
11# All files in this archive are subject to the GNU General Public License.
12# See the file COPYING in the source tree root for full license agreement.
13#
14# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15# KIND, either express or implied.
16#
17#
18# lrelease all rbutil translations and create a nice table from the output
19# suited to paste in the wiki.
20#
21
22import subprocess
23import re
24import sys
25import tempfile
26import os
27import shutil
28import argparse
29
30# extend search path for gitscraper
31sys.path.append(os.path.abspath(os.path.join(
32 os.path.dirname(os.path.realpath(__file__)), "../../utils/common")))
33import gitscraper
34
35
36LANGS = {
37 'cs': 'Czech',
38 'de': 'German',
39 'fi': 'Finnish',
40 'fr': 'French',
41 'gr': 'Greek',
42 'he': 'Hebrew',
43 'it': 'Italian',
44 'ja': 'Japanese',
45 'nl': 'Dutch',
46 'pl': 'Polish',
47 'pt': 'Portuguese',
48 'pt_BR': 'Portuguese (Brasileiro)',
49 'ru': 'Russian',
50 'tr': 'Turkish',
51 'zh_CN': 'Chinese',
52 'zh_TW': 'Chinese (trad)'
53}
54
55
56LANGBASE = "rbutil/rbutilqt/"
57# Paths and files to retrieve from svn.
58# This is a mixed list, holding both paths and filenames.
59# Get cpp sources as well for lupdate to work.
60GITPATHS = [LANGBASE]
61
62
63def main():
64 parser = argparse.ArgumentParser(
65 description='Print translation statistics for pasting in the wiki.')
66 parser.add_argument('-p', '--pretty', action='store_true',
67 help='Display pretty output instead of wiki-style')
68 parser.add_argument('-c', '--commit', nargs='?', help='Git commit hash')
69
70 args = parser.parse_args()
71
72 langstat(args.pretty, args.commit)
73
74
75def langstat(pretty=True, tree=None):
76 '''Get translation stats and print to stdout.'''
77 # get gitpaths to temporary folder
78 workfolder = tempfile.mkdtemp() + "/"
79 repo = os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))
80 if tree is None:
81 tree = gitscraper.get_refs(repo)['HEAD']
82 filesprops = gitscraper.scrape_files(
83 repo, tree, GITPATHS, dest=workfolder,
84 timestamp_files=["rbutil/rbutilqt/lang"])
85
86 projectfolder = workfolder + LANGBASE
87 # lupdate translations and drop all obsolete translations
88 subprocess.Popen(["lupdate", "-no-obsolete", "rbutilqt.pro"],
89 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
90 cwd=projectfolder).communicate()
91 # lrelease translations to get status
92 output = subprocess.Popen(["lrelease", "rbutilqt.pro"],
93 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
94 cwd=projectfolder).communicate()
95 lines = re.split(r"\n", output[0].decode())
96
97 re_updating = re.compile(r"^Updating.*")
98 re_generated = re.compile(r"Generated.*")
99 re_ignored = re.compile(r"Ignored.*")
100 re_qmlang = re.compile(r"'.*/rbutil_(.*)\.qm'")
101 re_qmbase = re.compile(r"'.*/(rbutil_.*)\.qm'")
102 re_genout = re.compile(
103 r"[^0-9]([0-9]+) .*[^0-9]([0-9]+) .*[^0-9]([0-9]+) ")
104 re_ignout = re.compile(r"([0-9]+) ")
105
106 # print header
107 titlemax = 0
108 for lang in LANGS:
109 cur = len(LANGS[lang])
110 if titlemax < cur:
111 titlemax = cur
112
113 if pretty:
114 delim = "+--" + titlemax * "-"
115 for spc in [7, 5, 5, 5, 5, 27, 17]:
116 delim += "+" + "-" * spc
117 delim += "+"
118 head = ("| {:%s} | {:6}|{:5}|{:5}|{:5}|{:5}| {:26}| {:16}|"
119 % titlemax).format("Language", "Code", "Trans", "Fin", "Unfin",
120 "Untr", "Updated", "Done")
121 print(delim)
122 print(("| {:^%s} |" % (len(head) - 4)).format(tree))
123 print(delim)
124 print(head)
125 print(delim)
126 else:
127 rev = "%s (%s)" % (
128 tree, gitscraper.get_file_timestamp(repo, tree, "."))
129 print("| *Translation status as of revision %s* ||||||||" % rev)
130 print("| *Language* | *Language Code* | *Translations* "
131 "| *Finished* | *Unfinished* | *Untranslated* | *Updated* "
132 "| *Done* |")
133
134 # scan output
135 for i, line in enumerate(lines):
136 if re_updating.search(line):
137 lang = re_qmlang.findall(line)
138 tsfile = "rbutil/rbutilqt/lang/%s.ts" % re_qmbase.findall(line)[0]
139 tsdate = filesprops[1][tsfile]
140
141 line = lines[i + 1]
142 if re_generated.search(line):
143 values = re_genout.findall(line)
144 translations = int(values[0][0])
145 finished = int(values[0][1])
146 unfinished = int(values[0][2])
147 line = lines[i + 2]
148 if not line.strip():
149 line = lines[i + 3]
150 if re_ignored.search(line):
151 ignored = int(re_ignout.findall(line)[0])
152 else:
153 ignored = 0
154 if lang[0] in LANGS:
155 name = LANGS[lang[0]].strip()
156 else:
157 name = '(unknown)'
158
159 percent = (finished + unfinished) * 100. / (translations + ignored)
160 progress = "#" * int(percent / 10)
161 if (percent % 10) > 5:
162 progress += "+"
163 progress += " " * (10 - len(progress))
164 if pretty:
165 fancylang = lang[0] + " " * (5 - len(lang[0]))
166 else:
167 fancylang = lang[0]
168 if pretty:
169 print(("| {:%i} | {:5} | {:3} | {:3} | {:3} | {:3} | {:25} | "
170 "{:3}%% {} |"
171 % titlemax).format(
172 name, fancylang, translations, finished, unfinished,
173 ignored, tsdate, int(percent), progress))
174 else:
175 if percent > 90:
176 color = r'%GREEN%'
177 else:
178 if percent > 50:
179 color = r'%ORANGE%'
180 else:
181 color = r'%RED%'
182
183 print("| %s | %s | %s | %s | %s | %s | %s | %s %i%% "
184 "%%ENDCOLOR%% %s |" %
185 (name, fancylang, translations, finished, unfinished,
186 ignored, tsdate, color, percent, progress))
187
188 if pretty:
189 print(delim)
190
191 shutil.rmtree(workfolder)
192
193
194if __name__ == "__main__":
195 main()
diff --git a/utils/rbutilqt/logger/LICENSE.LGPL b/utils/rbutilqt/logger/LICENSE.LGPL
new file mode 100644
index 0000000000..5ab7695ab8
--- /dev/null
+++ b/utils/rbutilqt/logger/LICENSE.LGPL
@@ -0,0 +1,504 @@
1 GNU LESSER GENERAL PUBLIC LICENSE
2 Version 2.1, February 1999
3
4 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 Everyone is permitted to copy and distribute verbatim copies
7 of this license document, but changing it is not allowed.
8
9[This is the first released version of the Lesser GPL. It also counts
10 as the successor of the GNU Library Public License, version 2, hence
11 the version number 2.1.]
12
13 Preamble
14
15 The licenses for most software are designed to take away your
16freedom to share and change it. By contrast, the GNU General Public
17Licenses are intended to guarantee your freedom to share and change
18free software--to make sure the software is free for all its users.
19
20 This license, the Lesser General Public License, applies to some
21specially designated software packages--typically libraries--of the
22Free Software Foundation and other authors who decide to use it. You
23can use it too, but we suggest you first think carefully about whether
24this license or the ordinary General Public License is the better
25strategy to use in any particular case, based on the explanations below.
26
27 When we speak of free software, we are referring to freedom of use,
28not price. Our General Public Licenses are designed to make sure that
29you have the freedom to distribute copies of free software (and charge
30for this service if you wish); that you receive source code or can get
31it if you want it; that you can change the software and use pieces of
32it in new free programs; and that you are informed that you can do
33these things.
34
35 To protect your rights, we need to make restrictions that forbid
36distributors to deny you these rights or to ask you to surrender these
37rights. These restrictions translate to certain responsibilities for
38you if you distribute copies of the library or if you modify it.
39
40 For example, if you distribute copies of the library, whether gratis
41or for a fee, you must give the recipients all the rights that we gave
42you. You must make sure that they, too, receive or can get the source
43code. If you link other code with the library, you must provide
44complete object files to the recipients, so that they can relink them
45with the library after making changes to the library and recompiling
46it. And you must show them these terms so they know their rights.
47
48 We protect your rights with a two-step method: (1) we copyright the
49library, and (2) we offer you this license, which gives you legal
50permission to copy, distribute and/or modify the library.
51
52 To protect each distributor, we want to make it very clear that
53there is no warranty for the free library. Also, if the library is
54modified by someone else and passed on, the recipients should know
55that what they have is not the original version, so that the original
56author's reputation will not be affected by problems that might be
57introduced by others.
58
59 Finally, software patents pose a constant threat to the existence of
60any free program. We wish to make sure that a company cannot
61effectively restrict the users of a free program by obtaining a
62restrictive license from a patent holder. Therefore, we insist that
63any patent license obtained for a version of the library must be
64consistent with the full freedom of use specified in this license.
65
66 Most GNU software, including some libraries, is covered by the
67ordinary GNU General Public License. This license, the GNU Lesser
68General Public License, applies to certain designated libraries, and
69is quite different from the ordinary General Public License. We use
70this license for certain libraries in order to permit linking those
71libraries into non-free programs.
72
73 When a program is linked with a library, whether statically or using
74a shared library, the combination of the two is legally speaking a
75combined work, a derivative of the original library. The ordinary
76General Public License therefore permits such linking only if the
77entire combination fits its criteria of freedom. The Lesser General
78Public License permits more lax criteria for linking other code with
79the library.
80
81 We call this license the "Lesser" General Public License because it
82does Less to protect the user's freedom than the ordinary General
83Public License. It also provides other free software developers Less
84of an advantage over competing non-free programs. These disadvantages
85are the reason we use the ordinary General Public License for many
86libraries. However, the Lesser license provides advantages in certain
87special circumstances.
88
89 For example, on rare occasions, there may be a special need to
90encourage the widest possible use of a certain library, so that it becomes
91a de-facto standard. To achieve this, non-free programs must be
92allowed to use the library. A more frequent case is that a free
93library does the same job as widely used non-free libraries. In this
94case, there is little to gain by limiting the free library to free
95software only, so we use the Lesser General Public License.
96
97 In other cases, permission to use a particular library in non-free
98programs enables a greater number of people to use a large body of
99free software. For example, permission to use the GNU C Library in
100non-free programs enables many more people to use the whole GNU
101operating system, as well as its variant, the GNU/Linux operating
102system.
103
104 Although the Lesser General Public License is Less protective of the
105users' freedom, it does ensure that the user of a program that is
106linked with the Library has the freedom and the wherewithal to run
107that program using a modified version of the Library.
108
109 The precise terms and conditions for copying, distribution and
110modification follow. Pay close attention to the difference between a
111"work based on the library" and a "work that uses the library". The
112former contains code derived from the library, whereas the latter must
113be combined with the library in order to run.
114
115 GNU LESSER GENERAL PUBLIC LICENSE
116 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
117
118 0. This License Agreement applies to any software library or other
119program which contains a notice placed by the copyright holder or
120other authorized party saying it may be distributed under the terms of
121this Lesser General Public License (also called "this License").
122Each licensee is addressed as "you".
123
124 A "library" means a collection of software functions and/or data
125prepared so as to be conveniently linked with application programs
126(which use some of those functions and data) to form executables.
127
128 The "Library", below, refers to any such software library or work
129which has been distributed under these terms. A "work based on the
130Library" means either the Library or any derivative work under
131copyright law: that is to say, a work containing the Library or a
132portion of it, either verbatim or with modifications and/or translated
133straightforwardly into another language. (Hereinafter, translation is
134included without limitation in the term "modification".)
135
136 "Source code" for a work means the preferred form of the work for
137making modifications to it. For a library, complete source code means
138all the source code for all modules it contains, plus any associated
139interface definition files, plus the scripts used to control compilation
140and installation of the library.
141
142 Activities other than copying, distribution and modification are not
143covered by this License; they are outside its scope. The act of
144running a program using the Library is not restricted, and output from
145such a program is covered only if its contents constitute a work based
146on the Library (independent of the use of the Library in a tool for
147writing it). Whether that is true depends on what the Library does
148and what the program that uses the Library does.
149
150 1. You may copy and distribute verbatim copies of the Library's
151complete source code as you receive it, in any medium, provided that
152you conspicuously and appropriately publish on each copy an
153appropriate copyright notice and disclaimer of warranty; keep intact
154all the notices that refer to this License and to the absence of any
155warranty; and distribute a copy of this License along with the
156Library.
157
158 You may charge a fee for the physical act of transferring a copy,
159and you may at your option offer warranty protection in exchange for a
160fee.
161
162 2. You may modify your copy or copies of the Library or any portion
163of it, thus forming a work based on the Library, and copy and
164distribute such modifications or work under the terms of Section 1
165above, provided that you also meet all of these conditions:
166
167 a) The modified work must itself be a software library.
168
169 b) You must cause the files modified to carry prominent notices
170 stating that you changed the files and the date of any change.
171
172 c) You must cause the whole of the work to be licensed at no
173 charge to all third parties under the terms of this License.
174
175 d) If a facility in the modified Library refers to a function or a
176 table of data to be supplied by an application program that uses
177 the facility, other than as an argument passed when the facility
178 is invoked, then you must make a good faith effort to ensure that,
179 in the event an application does not supply such function or
180 table, the facility still operates, and performs whatever part of
181 its purpose remains meaningful.
182
183 (For example, a function in a library to compute square roots has
184 a purpose that is entirely well-defined independent of the
185 application. Therefore, Subsection 2d requires that any
186 application-supplied function or table used by this function must
187 be optional: if the application does not supply it, the square
188 root function must still compute square roots.)
189
190These requirements apply to the modified work as a whole. If
191identifiable sections of that work are not derived from the Library,
192and can be reasonably considered independent and separate works in
193themselves, then this License, and its terms, do not apply to those
194sections when you distribute them as separate works. But when you
195distribute the same sections as part of a whole which is a work based
196on the Library, the distribution of the whole must be on the terms of
197this License, whose permissions for other licensees extend to the
198entire whole, and thus to each and every part regardless of who wrote
199it.
200
201Thus, it is not the intent of this section to claim rights or contest
202your rights to work written entirely by you; rather, the intent is to
203exercise the right to control the distribution of derivative or
204collective works based on the Library.
205
206In addition, mere aggregation of another work not based on the Library
207with the Library (or with a work based on the Library) on a volume of
208a storage or distribution medium does not bring the other work under
209the scope of this License.
210
211 3. You may opt to apply the terms of the ordinary GNU General Public
212License instead of this License to a given copy of the Library. To do
213this, you must alter all the notices that refer to this License, so
214that they refer to the ordinary GNU General Public License, version 2,
215instead of to this License. (If a newer version than version 2 of the
216ordinary GNU General Public License has appeared, then you can specify
217that version instead if you wish.) Do not make any other change in
218these notices.
219
220 Once this change is made in a given copy, it is irreversible for
221that copy, so the ordinary GNU General Public License applies to all
222subsequent copies and derivative works made from that copy.
223
224 This option is useful when you wish to copy part of the code of
225the Library into a program that is not a library.
226
227 4. You may copy and distribute the Library (or a portion or
228derivative of it, under Section 2) in object code or executable form
229under the terms of Sections 1 and 2 above provided that you accompany
230it with the complete corresponding machine-readable source code, which
231must be distributed under the terms of Sections 1 and 2 above on a
232medium customarily used for software interchange.
233
234 If distribution of object code is made by offering access to copy
235from a designated place, then offering equivalent access to copy the
236source code from the same place satisfies the requirement to
237distribute the source code, even though third parties are not
238compelled to copy the source along with the object code.
239
240 5. A program that contains no derivative of any portion of the
241Library, but is designed to work with the Library by being compiled or
242linked with it, is called a "work that uses the Library". Such a
243work, in isolation, is not a derivative work of the Library, and
244therefore falls outside the scope of this License.
245
246 However, linking a "work that uses the Library" with the Library
247creates an executable that is a derivative of the Library (because it
248contains portions of the Library), rather than a "work that uses the
249library". The executable is therefore covered by this License.
250Section 6 states terms for distribution of such executables.
251
252 When a "work that uses the Library" uses material from a header file
253that is part of the Library, the object code for the work may be a
254derivative work of the Library even though the source code is not.
255Whether this is true is especially significant if the work can be
256linked without the Library, or if the work is itself a library. The
257threshold for this to be true is not precisely defined by law.
258
259 If such an object file uses only numerical parameters, data
260structure layouts and accessors, and small macros and small inline
261functions (ten lines or less in length), then the use of the object
262file is unrestricted, regardless of whether it is legally a derivative
263work. (Executables containing this object code plus portions of the
264Library will still fall under Section 6.)
265
266 Otherwise, if the work is a derivative of the Library, you may
267distribute the object code for the work under the terms of Section 6.
268Any executables containing that work also fall under Section 6,
269whether or not they are linked directly with the Library itself.
270
271 6. As an exception to the Sections above, you may also combine or
272link a "work that uses the Library" with the Library to produce a
273work containing portions of the Library, and distribute that work
274under terms of your choice, provided that the terms permit
275modification of the work for the customer's own use and reverse
276engineering for debugging such modifications.
277
278 You must give prominent notice with each copy of the work that the
279Library is used in it and that the Library and its use are covered by
280this License. You must supply a copy of this License. If the work
281during execution displays copyright notices, you must include the
282copyright notice for the Library among them, as well as a reference
283directing the user to the copy of this License. Also, you must do one
284of these things:
285
286 a) Accompany the work with the complete corresponding
287 machine-readable source code for the Library including whatever
288 changes were used in the work (which must be distributed under
289 Sections 1 and 2 above); and, if the work is an executable linked
290 with the Library, with the complete machine-readable "work that
291 uses the Library", as object code and/or source code, so that the
292 user can modify the Library and then relink to produce a modified
293 executable containing the modified Library. (It is understood
294 that the user who changes the contents of definitions files in the
295 Library will not necessarily be able to recompile the application
296 to use the modified definitions.)
297
298 b) Use a suitable shared library mechanism for linking with the
299 Library. A suitable mechanism is one that (1) uses at run time a
300 copy of the library already present on the user's computer system,
301 rather than copying library functions into the executable, and (2)
302 will operate properly with a modified version of the library, if
303 the user installs one, as long as the modified version is
304 interface-compatible with the version that the work was made with.
305
306 c) Accompany the work with a written offer, valid for at
307 least three years, to give the same user the materials
308 specified in Subsection 6a, above, for a charge no more
309 than the cost of performing this distribution.
310
311 d) If distribution of the work is made by offering access to copy
312 from a designated place, offer equivalent access to copy the above
313 specified materials from the same place.
314
315 e) Verify that the user has already received a copy of these
316 materials or that you have already sent this user a copy.
317
318 For an executable, the required form of the "work that uses the
319Library" must include any data and utility programs needed for
320reproducing the executable from it. However, as a special exception,
321the materials to be distributed need not include anything that is
322normally distributed (in either source or binary form) with the major
323components (compiler, kernel, and so on) of the operating system on
324which the executable runs, unless that component itself accompanies
325the executable.
326
327 It may happen that this requirement contradicts the license
328restrictions of other proprietary libraries that do not normally
329accompany the operating system. Such a contradiction means you cannot
330use both them and the Library together in an executable that you
331distribute.
332
333 7. You may place library facilities that are a work based on the
334Library side-by-side in a single library together with other library
335facilities not covered by this License, and distribute such a combined
336library, provided that the separate distribution of the work based on
337the Library and of the other library facilities is otherwise
338permitted, and provided that you do these two things:
339
340 a) Accompany the combined library with a copy of the same work
341 based on the Library, uncombined with any other library
342 facilities. This must be distributed under the terms of the
343 Sections above.
344
345 b) Give prominent notice with the combined library of the fact
346 that part of it is a work based on the Library, and explaining
347 where to find the accompanying uncombined form of the same work.
348
349 8. You may not copy, modify, sublicense, link with, or distribute
350the Library except as expressly provided under this License. Any
351attempt otherwise to copy, modify, sublicense, link with, or
352distribute the Library is void, and will automatically terminate your
353rights under this License. However, parties who have received copies,
354or rights, from you under this License will not have their licenses
355terminated so long as such parties remain in full compliance.
356
357 9. You are not required to accept this License, since you have not
358signed it. However, nothing else grants you permission to modify or
359distribute the Library or its derivative works. These actions are
360prohibited by law if you do not accept this License. Therefore, by
361modifying or distributing the Library (or any work based on the
362Library), you indicate your acceptance of this License to do so, and
363all its terms and conditions for copying, distributing or modifying
364the Library or works based on it.
365
366 10. Each time you redistribute the Library (or any work based on the
367Library), the recipient automatically receives a license from the
368original licensor to copy, distribute, link with or modify the Library
369subject to these terms and conditions. You may not impose any further
370restrictions on the recipients' exercise of the rights granted herein.
371You are not responsible for enforcing compliance by third parties with
372this License.
373
374 11. If, as a consequence of a court judgment or allegation of patent
375infringement or for any other reason (not limited to patent issues),
376conditions are imposed on you (whether by court order, agreement or
377otherwise) that contradict the conditions of this License, they do not
378excuse you from the conditions of this License. If you cannot
379distribute so as to satisfy simultaneously your obligations under this
380License and any other pertinent obligations, then as a consequence you
381may not distribute the Library at all. For example, if a patent
382license would not permit royalty-free redistribution of the Library by
383all those who receive copies directly or indirectly through you, then
384the only way you could satisfy both it and this License would be to
385refrain entirely from distribution of the Library.
386
387If any portion of this section is held invalid or unenforceable under any
388particular circumstance, the balance of the section is intended to apply,
389and the section as a whole is intended to apply in other circumstances.
390
391It is not the purpose of this section to induce you to infringe any
392patents or other property right claims or to contest validity of any
393such claims; this section has the sole purpose of protecting the
394integrity of the free software distribution system which is
395implemented by public license practices. Many people have made
396generous contributions to the wide range of software distributed
397through that system in reliance on consistent application of that
398system; it is up to the author/donor to decide if he or she is willing
399to distribute software through any other system and a licensee cannot
400impose that choice.
401
402This section is intended to make thoroughly clear what is believed to
403be a consequence of the rest of this License.
404
405 12. If the distribution and/or use of the Library is restricted in
406certain countries either by patents or by copyrighted interfaces, the
407original copyright holder who places the Library under this License may add
408an explicit geographical distribution limitation excluding those countries,
409so that distribution is permitted only in or among countries not thus
410excluded. In such case, this License incorporates the limitation as if
411written in the body of this License.
412
413 13. The Free Software Foundation may publish revised and/or new
414versions of the Lesser General Public License from time to time.
415Such new versions will be similar in spirit to the present version,
416but may differ in detail to address new problems or concerns.
417
418Each version is given a distinguishing version number. If the Library
419specifies a version number of this License which applies to it and
420"any later version", you have the option of following the terms and
421conditions either of that version or of any later version published by
422the Free Software Foundation. If the Library does not specify a
423license version number, you may choose any version ever published by
424the Free Software Foundation.
425
426 14. If you wish to incorporate parts of the Library into other free
427programs whose distribution conditions are incompatible with these,
428write to the author to ask for permission. For software which is
429copyrighted by the Free Software Foundation, write to the Free
430Software Foundation; we sometimes make exceptions for this. Our
431decision will be guided by the two goals of preserving the free status
432of all derivatives of our free software and of promoting the sharing
433and reuse of software generally.
434
435 NO WARRANTY
436
437 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
438WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
439EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
440OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
441KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
442IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
444LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
445THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
446
447 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
448WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
449AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
450FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
451CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
452LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
453RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
454FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
455SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
456DAMAGES.
457
458 END OF TERMS AND CONDITIONS
459
460 How to Apply These Terms to Your New Libraries
461
462 If you develop a new library, and you want it to be of the greatest
463possible use to the public, we recommend making it free software that
464everyone can redistribute and change. You can do so by permitting
465redistribution under these terms (or, alternatively, under the terms of the
466ordinary General Public License).
467
468 To apply these terms, attach the following notices to the library. It is
469safest to attach them to the start of each source file to most effectively
470convey the exclusion of warranty; and each file should have at least the
471"copyright" line and a pointer to where the full notice is found.
472
473 <one line to give the library's name and a brief idea of what it does.>
474 Copyright (C) <year> <name of author>
475
476 This library is free software; you can redistribute it and/or
477 modify it under the terms of the GNU Lesser General Public
478 License as published by the Free Software Foundation; either
479 version 2.1 of the License, or (at your option) any later version.
480
481 This library is distributed in the hope that it will be useful,
482 but WITHOUT ANY WARRANTY; without even the implied warranty of
483 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
484 Lesser General Public License for more details.
485
486 You should have received a copy of the GNU Lesser General Public
487 License along with this library; if not, write to the Free Software
488 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
489
490Also add information on how to contact you by electronic and paper mail.
491
492You should also get your employer (if you work as a programmer) or your
493school, if any, to sign a "copyright disclaimer" for the library, if
494necessary. Here is a sample; alter the names:
495
496 Yoyodyne, Inc., hereby disclaims all copyright interest in the
497 library `Frob' (a library for tweaking knobs) written by James Random Hacker.
498
499 <signature of Ty Coon>, 1 April 1990
500 Ty Coon, President of Vice
501
502That's all there is to it!
503
504
diff --git a/utils/rbutilqt/logger/README.ROCKBOX b/utils/rbutilqt/logger/README.ROCKBOX
new file mode 100644
index 0000000000..f501a410dd
--- /dev/null
+++ b/utils/rbutilqt/logger/README.ROCKBOX
@@ -0,0 +1,7 @@
1This folder contains the cutelogger project for logging functionality.
2These files are distributed under the LGPL v2 or later.
3The source files have been last synced with the projects at
4https://github.com/dept2/CuteLogger/ to commit
55ae6b9ac13e0cc2821d236e3542a83990b63c95c
6on Aug 7, 2020.
7
diff --git a/utils/rbutilqt/logger/include/AbstractAppender.h b/utils/rbutilqt/logger/include/AbstractAppender.h
new file mode 100644
index 0000000000..e029b045aa
--- /dev/null
+++ b/utils/rbutilqt/logger/include/AbstractAppender.h
@@ -0,0 +1,49 @@
1/*
2 Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com)
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License version 2.1
6 as published by the Free Software Foundation and appearing in the file
7 LICENSE.LGPL included in the packaging of this file.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13*/
14#ifndef ABSTRACTAPPENDER_H
15#define ABSTRACTAPPENDER_H
16
17// Local
18#include "CuteLogger_global.h"
19#include <Logger.h>
20
21// Qt
22#include <QMutex>
23
24
25class CUTELOGGERSHARED_EXPORT AbstractAppender
26{
27 public:
28 AbstractAppender();
29 virtual ~AbstractAppender();
30
31 Logger::LogLevel detailsLevel() const;
32 void setDetailsLevel(Logger::LogLevel level);
33 void setDetailsLevel(const QString& level);
34
35 void write(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line, const char* function,
36 const QString& category, const QString& message);
37
38 protected:
39 virtual void append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
40 const char* function, const QString& category, const QString& message) = 0;
41
42 private:
43 QMutex m_writeMutex;
44
45 Logger::LogLevel m_detailsLevel;
46 mutable QMutex m_detailsLevelMutex;
47};
48
49#endif // ABSTRACTAPPENDER_H
diff --git a/utils/rbutilqt/logger/include/AbstractStringAppender.h b/utils/rbutilqt/logger/include/AbstractStringAppender.h
new file mode 100644
index 0000000000..78df9e6176
--- /dev/null
+++ b/utils/rbutilqt/logger/include/AbstractStringAppender.h
@@ -0,0 +1,46 @@
1/*
2 Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com)
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License version 2.1
6 as published by the Free Software Foundation and appearing in the file
7 LICENSE.LGPL included in the packaging of this file.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13*/
14#ifndef ABSTRACTSTRINGAPPENDER_H
15#define ABSTRACTSTRINGAPPENDER_H
16
17// Local
18#include "CuteLogger_global.h"
19#include <AbstractAppender.h>
20
21// Qt
22#include <QReadWriteLock>
23
24
25class CUTELOGGERSHARED_EXPORT AbstractStringAppender : public AbstractAppender
26{
27 public:
28 AbstractStringAppender();
29
30 virtual QString format() const;
31 void setFormat(const QString&);
32
33 static QString stripFunctionName(const char*);
34
35 protected:
36 QString formattedString(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
37 const char* function, const QString& category, const QString& message) const;
38
39 private:
40 static QByteArray qCleanupFuncinfo(const char*);
41
42 QString m_format;
43 mutable QReadWriteLock m_formatLock;
44};
45
46#endif // ABSTRACTSTRINGAPPENDER_H
diff --git a/utils/rbutilqt/logger/include/ConsoleAppender.h b/utils/rbutilqt/logger/include/ConsoleAppender.h
new file mode 100644
index 0000000000..64ef2e7a19
--- /dev/null
+++ b/utils/rbutilqt/logger/include/ConsoleAppender.h
@@ -0,0 +1,36 @@
1/*
2 Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com)
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License version 2.1
6 as published by the Free Software Foundation and appearing in the file
7 LICENSE.LGPL included in the packaging of this file.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13*/
14#ifndef CONSOLEAPPENDER_H
15#define CONSOLEAPPENDER_H
16
17#include "CuteLogger_global.h"
18#include <AbstractStringAppender.h>
19
20
21class CUTELOGGERSHARED_EXPORT ConsoleAppender : public AbstractStringAppender
22{
23 public:
24 ConsoleAppender();
25 virtual QString format() const;
26 void ignoreEnvironmentPattern(bool ignore);
27
28 protected:
29 virtual void append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
30 const char* function, const QString& category, const QString& message);
31
32 private:
33 bool m_ignoreEnvPattern;
34};
35
36#endif // CONSOLEAPPENDER_H
diff --git a/utils/rbutilqt/logger/include/CuteLogger_global.h b/utils/rbutilqt/logger/include/CuteLogger_global.h
new file mode 100644
index 0000000000..c5e7680845
--- /dev/null
+++ b/utils/rbutilqt/logger/include/CuteLogger_global.h
@@ -0,0 +1,16 @@
1#ifndef CUTELOGGER_GLOBAL_H
2#define CUTELOGGER_GLOBAL_H
3
4#include <QtCore/qglobal.h>
5
6#if !defined(CUTELOGGER_STATIC)
7#if defined(CUTELOGGER_LIBRARY)
8# define CUTELOGGERSHARED_EXPORT Q_DECL_EXPORT
9#else
10# define CUTELOGGERSHARED_EXPORT Q_DECL_IMPORT
11#endif
12#else
13#define CUTELOGGERSHARED_EXPORT
14#endif
15
16#endif // CUTELOGGER_GLOBAL_H
diff --git a/utils/rbutilqt/logger/include/FileAppender.h b/utils/rbutilqt/logger/include/FileAppender.h
new file mode 100644
index 0000000000..ab9e12a91d
--- /dev/null
+++ b/utils/rbutilqt/logger/include/FileAppender.h
@@ -0,0 +1,49 @@
1/*
2 Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com)
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License version 2.1
6 as published by the Free Software Foundation and appearing in the file
7 LICENSE.LGPL included in the packaging of this file.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13*/
14#ifndef FILEAPPENDER_H
15#define FILEAPPENDER_H
16
17// Logger
18#include "CuteLogger_global.h"
19#include <AbstractStringAppender.h>
20
21// Qt
22#include <QFile>
23#include <QTextStream>
24
25
26class CUTELOGGERSHARED_EXPORT FileAppender : public AbstractStringAppender
27{
28 public:
29 FileAppender(const QString& fileName = QString());
30 ~FileAppender();
31
32 QString fileName() const;
33 void setFileName(const QString&);
34
35 bool reopenFile();
36
37 protected:
38 virtual void append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
39 const char* function, const QString& category, const QString& message);
40 bool openFile();
41 void closeFile();
42
43 private:
44 QFile m_logFile;
45 QTextStream m_logStream;
46 mutable QMutex m_logFileMutex;
47};
48
49#endif // FILEAPPENDER_H
diff --git a/utils/rbutilqt/logger/include/Logger.h b/utils/rbutilqt/logger/include/Logger.h
new file mode 100644
index 0000000000..941e556eb9
--- /dev/null
+++ b/utils/rbutilqt/logger/include/Logger.h
@@ -0,0 +1,238 @@
1/*
2 Copyright (c) 2012 Boris Moiseev (cyberbobs at gmail dot com)
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License version 2.1
6 as published by the Free Software Foundation and appearing in the file
7 LICENSE.LGPL included in the packaging of this file.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13*/
14#ifndef LOGGER_H
15#define LOGGER_H
16
17// Qt
18#include <QString>
19#include <QDebug>
20#include <QDateTime>
21#include <QElapsedTimer>
22
23// Local
24#include "CuteLogger_global.h"
25class AbstractAppender;
26
27
28class Logger;
29CUTELOGGERSHARED_EXPORT Logger* cuteLoggerInstance();
30#define cuteLogger cuteLoggerInstance()
31
32
33#define LOG_TRACE CuteMessageLogger(cuteLoggerInstance(), Logger::Trace, __FILE__, __LINE__, Q_FUNC_INFO).write
34#define LOG_DEBUG CuteMessageLogger(cuteLoggerInstance(), Logger::Debug, __FILE__, __LINE__, Q_FUNC_INFO).write
35#define LOG_INFO CuteMessageLogger(cuteLoggerInstance(), Logger::Info, __FILE__, __LINE__, Q_FUNC_INFO).write
36#define LOG_WARNING CuteMessageLogger(cuteLoggerInstance(), Logger::Warning, __FILE__, __LINE__, Q_FUNC_INFO).write
37#define LOG_ERROR CuteMessageLogger(cuteLoggerInstance(), Logger::Error, __FILE__, __LINE__, Q_FUNC_INFO).write
38#define LOG_FATAL CuteMessageLogger(cuteLoggerInstance(), Logger::Fatal, __FILE__, __LINE__, Q_FUNC_INFO).write
39
40#define LOG_CTRACE(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Trace, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
41#define LOG_CDEBUG(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Debug, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
42#define LOG_CINFO(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Info, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
43#define LOG_CWARNING(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Warning, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
44#define LOG_CERROR(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Error, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
45#define LOG_CFATAL(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Fatal, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
46
47#define LOG_TRACE_TIME LoggerTimingHelper loggerTimingHelper(cuteLoggerInstance(), Logger::Trace, __FILE__, __LINE__, Q_FUNC_INFO); loggerTimingHelper.start
48#define LOG_DEBUG_TIME LoggerTimingHelper loggerTimingHelper(cuteLoggerInstance(), Logger::Debug, __FILE__, __LINE__, Q_FUNC_INFO); loggerTimingHelper.start
49#define LOG_INFO_TIME LoggerTimingHelper loggerTimingHelper(cuteLoggerInstance(), Logger::Info, __FILE__, __LINE__, Q_FUNC_INFO); loggerTimingHelper.start
50
51#define LOG_ASSERT(cond) ((!(cond)) ? cuteLoggerInstance()->writeAssert(__FILE__, __LINE__, Q_FUNC_INFO, #cond) : qt_noop())
52#define LOG_ASSERT_X(cond, msg) ((!(cond)) ? cuteLoggerInstance()->writeAssert(__FILE__, __LINE__, Q_FUNC_INFO, msg) : qt_noop())
53
54#if (__cplusplus >= 201103L)
55#include <functional>
56
57#define LOG_CATEGORY(category) \
58 Logger customCuteLoggerInstance{category};\
59 std::function<Logger*()> cuteLoggerInstance = [&customCuteLoggerInstance]() {\
60 return &customCuteLoggerInstance;\
61 };\
62
63#define LOG_GLOBAL_CATEGORY(category) \
64 Logger customCuteLoggerInstance{category, true};\
65 std::function<Logger*()> cuteLoggerInstance = [&customCuteLoggerInstance]() {\
66 return &customCuteLoggerInstance;\
67 };\
68
69#else
70
71#define LOG_CATEGORY(category) \
72 Logger* cuteLoggerInstance()\
73 {\
74 static Logger customCuteLoggerInstance(category);\
75 return &customCuteLoggerInstance;\
76 }\
77
78#define LOG_GLOBAL_CATEGORY(category) \
79 Logger* cuteLoggerInstance()\
80 {\
81 static Logger customCuteLoggerInstance(category);\
82 customCuteLoggerInstance.logToGlobalInstance(category, true);\
83 return &customCuteLoggerInstance;\
84 }\
85
86#endif
87
88
89class LoggerPrivate;
90class CUTELOGGERSHARED_EXPORT Logger
91{
92 Q_DISABLE_COPY(Logger)
93
94 public:
95 Logger();
96 Logger(const QString& defaultCategory, bool writeToGlobalInstance = false);
97 ~Logger();
98
99 //! Describes the possible severity levels of the log records
100 enum LogLevel
101 {
102 Trace, //!< Trace level. Can be used for mostly unneeded records used for internal code tracing.
103 Debug, //!< Debug level. Useful for non-necessary records used for the debugging of the software.
104 Info, //!< Info level. Can be used for informational records, which may be interesting for not only developers.
105 Warning, //!< Warning. May be used to log some non-fatal warnings detected by your application.
106 Error, //!< Error. May be used for a big problems making your application work wrong but not crashing.
107 Fatal //!< Fatal. Used for unrecoverable errors, crashes the application right after the log record is written.
108 };
109
110 //! Sets the timing display mode for the LOG_TRACE_TIME, LOG_DEBUG_TIME and LOG_INFO_TIME macros
111 enum TimingMode
112 {
113 TimingAuto, //!< Show time in seconds, if it exceeds 10s (default)
114 TimingMs //!< Always use milliseconds to display
115 };
116
117 static QString levelToString(LogLevel logLevel);
118 static LogLevel levelFromString(const QString& s);
119
120 static Logger* globalInstance();
121
122 void registerAppender(AbstractAppender* appender);
123 void registerCategoryAppender(const QString& category, AbstractAppender* appender);
124
125 void removeAppender(AbstractAppender* appender);
126
127 void logToGlobalInstance(const QString& category, bool logToGlobal = false);
128
129 void setDefaultCategory(const QString& category);
130 QString defaultCategory() const;
131
132 void write(const QDateTime& timeStamp, LogLevel logLevel, const char* file, int line, const char* function, const char* category,
133 const QString& message);
134 void write(LogLevel logLevel, const char* file, int line, const char* function, const char* category, const QString& message);
135
136 void writeAssert(const char* file, int line, const char* function, const char* condition);
137
138 private:
139 void write(const QDateTime& timeStamp, LogLevel logLevel, const char* file, int line, const char* function, const char* category,
140 const QString& message, bool fromLocalInstance);
141 Q_DECLARE_PRIVATE(Logger)
142 LoggerPrivate* d_ptr;
143};
144
145
146class CUTELOGGERSHARED_EXPORT CuteMessageLogger
147{
148 Q_DISABLE_COPY(CuteMessageLogger)
149
150 public:
151 CuteMessageLogger(Logger* l, Logger::LogLevel level, const char* file, int line, const char* function)
152 : m_l(l),
153 m_level(level),
154 m_file(file),
155 m_line(line),
156 m_function(function),
157 m_category(nullptr)
158 {}
159
160 CuteMessageLogger(Logger* l, Logger::LogLevel level, const char* file, int line, const char* function, const char* category)
161 : m_l(l),
162 m_level(level),
163 m_file(file),
164 m_line(line),
165 m_function(function),
166 m_category(category)
167 {}
168
169 ~CuteMessageLogger();
170
171 void write(const char* msg, ...)
172#if defined(Q_CC_GNU) && !defined(__INSURE__)
173# if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG)
174 __attribute__ ((format (gnu_printf, 2, 3)))
175# else
176 __attribute__ ((format (printf, 2, 3)))
177# endif
178#endif
179 ;
180
181 void write(const QString& msg);
182
183 QDebug write();
184
185 private:
186 Logger* m_l;
187 Logger::LogLevel m_level;
188 const char* m_file;
189 int m_line;
190 const char* m_function;
191 const char* m_category;
192 QString m_message;
193};
194
195
196class CUTELOGGERSHARED_EXPORT LoggerTimingHelper
197{
198 Q_DISABLE_COPY(LoggerTimingHelper)
199
200 public:
201 inline explicit LoggerTimingHelper(Logger* l, Logger::LogLevel logLevel, const char* file, int line,
202 const char* function)
203 : m_logger(l),
204 m_logLevel(logLevel),
205 m_timingMode(Logger::TimingAuto),
206 m_file(file),
207 m_line(line),
208 m_function(function)
209 {}
210
211 void start(const char* msg, ...)
212#if defined(Q_CC_GNU) && !defined(__INSURE__)
213 # if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG)
214 __attribute__ ((format (gnu_printf, 2, 3)))
215 # else
216 __attribute__ ((format (printf, 2, 3)))
217 # endif
218#endif
219 ;
220
221 void start(const QString& msg = QString());
222 void start(Logger::TimingMode mode, const QString& msg);
223
224 ~LoggerTimingHelper();
225
226 private:
227 Logger* m_logger;
228 QElapsedTimer m_time;
229 Logger::LogLevel m_logLevel;
230 Logger::TimingMode m_timingMode;
231 const char* m_file;
232 int m_line;
233 const char* m_function;
234 QString m_block;
235};
236
237
238#endif // LOGGER_H
diff --git a/utils/rbutilqt/logger/include/OutputDebugAppender.h b/utils/rbutilqt/logger/include/OutputDebugAppender.h
new file mode 100644
index 0000000000..dd7ad4deb7
--- /dev/null
+++ b/utils/rbutilqt/logger/include/OutputDebugAppender.h
@@ -0,0 +1,29 @@
1/*
2 Copyright (c) 2010 Karl-Heinz Reichel (khreichel at googlemail dot com)
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License version 2.1
6 as published by the Free Software Foundation and appearing in the file
7 LICENSE.LGPL included in the packaging of this file.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13*/
14
15#ifndef OUTPUTDEBUGAPPENDER_H
16#define OUTPUTDEBUGAPPENDER_H
17
18#include "CuteLogger_global.h"
19#include <AbstractStringAppender.h>
20
21
22class CUTELOGGERSHARED_EXPORT OutputDebugAppender : public AbstractStringAppender
23{
24 protected:
25 virtual void append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
26 const char* function, const QString& category, const QString& message);
27};
28
29#endif // OUTPUTDEBUGAPPENDER_H
diff --git a/utils/rbutilqt/logger/logger.pri b/utils/rbutilqt/logger/logger.pri
new file mode 100644
index 0000000000..e34bccb3cf
--- /dev/null
+++ b/utils/rbutilqt/logger/logger.pri
@@ -0,0 +1,22 @@
1
2SOURCES += \
3 $$PWD/src/AbstractAppender.cpp \
4 $$PWD/src/AbstractStringAppender.cpp \
5 $$PWD/src/ConsoleAppender.cpp \
6 $$PWD/src/FileAppender.cpp \
7 $$PWD/src/Logger.cpp \
8
9HEADERS += \
10 $$PWD/include/AbstractAppender.h \
11 $$PWD/include/ConsoleAppender.h \
12 $$PWD/include/FileAppender.h \
13 $$PWD/include/OutputDebugAppender.h \
14 $$PWD/include/AbstractStringAppender.h \
15 $$PWD/include/CuteLogger_global.h \
16 $$PWD/include/Logger.h \
17
18INCLUDEPATH += $$PWD/include
19
20DEFINES += \
21 CUTELOGGER_STATIC
22
diff --git a/utils/rbutilqt/logger/src/AbstractAppender.cpp b/utils/rbutilqt/logger/src/AbstractAppender.cpp
new file mode 100644
index 0000000000..778bbddd11
--- /dev/null
+++ b/utils/rbutilqt/logger/src/AbstractAppender.cpp
@@ -0,0 +1,147 @@
1/*
2 Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com)
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License version 2.1
6 as published by the Free Software Foundation and appearing in the file
7 LICENSE.LGPL included in the packaging of this file.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13*/
14// Local
15#include "AbstractAppender.h"
16
17// Qt
18#include <QMutexLocker>
19
20
21/**
22 * \class AbstractAppender
23 *
24 * \brief The AbstractAppender class provides an abstract base class for writing a log entries.
25 *
26 * The AbstractAppender class is the base interface class for all log appenders that could be used with Logger.
27 *
28 * AbstractAppender provides a common implementation for the thread safe, mutex-protected logging of application
29 * messages, such as ConsoleAppender, FileAppender or something else. AbstractAppender is abstract and can not be
30 * instantiated, but you can use any of its subclasses or create a custom log appender at your choice.
31 *
32 * Appenders are the logical devices that is aimed to be attached to Logger object by calling
33 * Logger::registerAppender(). On each log record call from the application Logger object sequentially calls write()
34 * function on all the appenders registered in it.
35 *
36 * You can subclass AbstractAppender to implement a logging target of any kind you like. It may be the external logging
37 * subsystem (for example, syslog in *nix), XML file, SQL database entries, D-Bus messages or anything else you can
38 * imagine.
39 *
40 * For the simple non-structured plain text logging (for example, to a plain text file or to the console output) you may
41 * like to subclass the AbstractStringAppender instead of AbstractAppender, which will give you a more convinient way to
42 * control the format of the log output.
43 *
44 * \sa AbstractStringAppender
45 * \sa Logger::registerAppender()
46 */
47
48
49//! Constructs a AbstractAppender object.
50AbstractAppender::AbstractAppender()
51 : m_detailsLevel(Logger::Debug)
52{}
53
54
55//! Destructs the AbstractAppender object.
56AbstractAppender::~AbstractAppender()
57{}
58
59
60//! Returns the current details level of appender.
61/**
62 * Log records with a log level lower than a current detailsLevel() will be silently ignored by appender and would not
63 * be sent to its append() function.
64 *
65 * It provides additional logging flexibility, allowing you to set the different severity levels for different types
66 * of logs.
67 *
68 * \note This function is thread safe.
69 *
70 * \sa setDetailsLevel()
71 * \sa Logger::LogLevel
72 */
73Logger::LogLevel AbstractAppender::detailsLevel() const
74{
75 QMutexLocker locker(&m_detailsLevelMutex);
76 return m_detailsLevel;
77}
78
79
80//! Sets the current details level of appender.
81/**
82 * Default details level is Logger::Debug
83 *
84 * \note This function is thread safe.
85 *
86 * \sa detailsLevel()
87 * \sa Logger::LogLevel
88 */
89void AbstractAppender::setDetailsLevel(Logger::LogLevel level)
90{
91 QMutexLocker locker(&m_detailsLevelMutex);
92 m_detailsLevel = level;
93}
94
95
96
97//! Sets the current details level of appender
98/**
99 * This function is provided for convenience, it behaves like an above function.
100 *
101 * \sa detailsLevel()
102 * \sa Logger::LogLevel
103 */
104void AbstractAppender::setDetailsLevel(const QString& level)
105{
106 setDetailsLevel(Logger::levelFromString(level));
107}
108
109
110//! Tries to write the log record to this logger
111/**
112 * This is the function called by Logger object to write a log message to the appender.
113 *
114 * \note This function is thread safe.
115 *
116 * \sa Logger::write()
117 * \sa detailsLevel()
118 */
119void AbstractAppender::write(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
120 const char* function, const QString& category, const QString& message)
121{
122 if (logLevel >= detailsLevel())
123 {
124 QMutexLocker locker(&m_writeMutex);
125 append(timeStamp, logLevel, file, line, function, category, message);
126 }
127}
128
129
130/**
131 * \fn virtual void AbstractAppender::append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file,
132 * int line, const char* function, const QString& message)
133 *
134 * \brief Writes the log record to the logger instance
135 *
136 * This function is called every time when user tries to write a message to this AbstractAppender instance using
137 * the write() function. Write function works as proxy and transfers only the messages with log level more or equal
138 * to the current logLevel().
139 *
140 * Overload this function when you are implementing a custom appender.
141 *
142 * \note This function is not needed to be thread safe because it is never called directly by Logger object. The
143 * write() function works as a proxy and protects this function from concurrent access.
144 *
145 * \sa Logger::write()
146 */
147
diff --git a/utils/rbutilqt/logger/src/AbstractStringAppender.cpp b/utils/rbutilqt/logger/src/AbstractStringAppender.cpp
new file mode 100644
index 0000000000..ea5883f744
--- /dev/null
+++ b/utils/rbutilqt/logger/src/AbstractStringAppender.cpp
@@ -0,0 +1,460 @@
1/*
2 Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com) Nikolay Matyunin (matyunin.n at gmail dot com)
3
4 Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License version 2.1
8 as published by the Free Software Foundation and appearing in the file
9 LICENSE.LGPL included in the packaging of this file.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
15*/
16// Local
17#include "AbstractStringAppender.h"
18
19// Qt
20#include <QReadLocker>
21#include <QWriteLocker>
22#include <QDateTime>
23#include <QRegularExpression>
24#include <QCoreApplication>
25#include <QThread>
26
27
28/**
29 * \class AbstractStringAppender
30 *
31 * \brief The AbstractStringAppender class provides a convinient base for appenders working with plain text formatted
32 * logs.
33 *
34 * AbstractSringAppender is the simple extension of the AbstractAppender class providing the convinient way to create
35 * custom log appenders working with a plain text formatted log targets.
36 *
37 * It have the formattedString() protected function that formats the logging arguments according to a format set with
38 * setFormat().
39 *
40 * This class can not be directly instantiated because it contains pure virtual function inherited from AbstractAppender
41 * class.
42 *
43 * For more detailed description of customizing the log output format see the documentation on the setFormat() function.
44 */
45
46
47const char formattingMarker = '%';
48
49
50//! Constructs a new string appender object
51AbstractStringAppender::AbstractStringAppender()
52 : m_format(QLatin1String("%{time}{yyyy-MM-ddTHH:mm:ss.zzz} [%{type:-7}] <%{function}> %{message}\n"))
53{}
54
55
56//! Returns the current log format string.
57/**
58 * The default format is set to "%{time}{yyyy-MM-ddTHH:mm:ss.zzz} [%{type:-7}] <%{function}> %{message}\n". You can set a different log record
59 * format using the setFormat() function.
60 *
61 * \sa setFormat(const QString&)
62 */
63QString AbstractStringAppender::format() const
64{
65 QReadLocker locker(&m_formatLock);
66 return m_format;
67}
68
69
70//! Sets the logging format for writing strings to the log target with this appender.
71/**
72 * The string format seems to be very common to those developers who have used a standart sprintf function.
73 *
74 * Log output format is a simple QString with the special markers (starting with % sign) which will be replaced with
75 * it's internal meaning when writing a log record.
76 *
77 * Controlling marker begins with the percent sign (%) which is followed by the command inside {} brackets
78 * (the command describes, what will be put to log record instead of marker).
79 * Optional field width argument may be specified right after the command (through the colon symbol before the closing bracket)
80 * Some commands requires an additional formatting argument (in the second {} brackets).
81 *
82 * Field width argument works almost identically to the \c QString::arg() \c fieldWidth argument (and uses it
83 * internally). For example, \c "%{type:-7}" will be replaced with the left padded debug level of the message
84 * (\c "Debug ") or something. For the more detailed description of it you may consider to look to the Qt
85 * Reference Documentation.
86 *
87 * Supported marker commands are:
88 * \arg \c %{time} - timestamp. You may specify your custom timestamp format using the second {} brackets after the marker,
89 * timestamp format here will be similiar to those used in QDateTime::toString() function. For example,
90 * "%{time}{dd-MM-yyyy, HH:mm}" may be replaced with "17-12-2010, 20:17" depending on current date and time.
91 * The default format used here is "HH:mm:ss.zzz".
92 * \arg \c %{type} - Log level. Possible log levels are shown in the Logger::LogLevel enumerator.
93 * \arg \c %{Type} - Uppercased log level.
94 * \arg \c %{typeOne} - One letter log level.
95 * \arg \c %{TypeOne} - One uppercase letter log level.
96 * \arg \c %{File} - Full source file name (with path) of the file that requested log recording. Uses the \c __FILE__
97 * preprocessor macro.
98 * \arg \c %{file} - Short file name (with stripped path).
99 * \arg \c %{line} - Line number in the source file. Uses the \c __LINE__ preprocessor macro.
100 * \arg \c %{Function} - Name of function that called on of the LOG_* macros. Uses the \c Q_FUNC_INFO macro provided with
101 * Qt.
102 * \arg \c %{function} - Similiar to the %{Function}, but the function name is stripped using stripFunctionName
103 * \arg \c %{message} - The log message sent by the caller.
104 * \arg \c %{category} - The log category.
105 * \arg \c %{appname} - Application name (returned by QCoreApplication::applicationName() function).
106 * \arg \c %{pid} - Application pid (returned by QCoreApplication::applicationPid() function).
107 * \arg \c %{threadid} - ID of current thread.
108 * \arg \c %% - Convinient marker that is replaced with the single \c % mark.
109 *
110 * \note Format doesn't add \c '\\n' to the end of the format line. Please consider adding it manually.
111 *
112 * \sa format()
113 * \sa stripFunctionName()
114 * \sa Logger::LogLevel
115 */
116void AbstractStringAppender::setFormat(const QString& format)
117{
118 QWriteLocker locker(&m_formatLock);
119 m_format = format;
120}
121
122
123//! Strips the long function signature (as added by Q_FUNC_INFO macro)
124/**
125 * The string processing drops the returning type, arguments and template parameters of function. It is definitely
126 * useful for enchancing the log output readability.
127 * \return stripped function name
128 */
129QString AbstractStringAppender::stripFunctionName(const char* name)
130{
131 return QString::fromLatin1(qCleanupFuncinfo(name));
132}
133
134
135// The function was backported from Qt5 sources (qlogging.h)
136QByteArray AbstractStringAppender::qCleanupFuncinfo(const char* name)
137{
138 QByteArray info(name);
139
140 // Strip the function info down to the base function name
141 // note that this throws away the template definitions,
142 // the parameter types (overloads) and any const/volatile qualifiers.
143 if (info.isEmpty())
144 return info;
145
146 int pos;
147
148 // skip trailing [with XXX] for templates (gcc)
149 pos = info.size() - 1;
150 if (info.endsWith(']')) {
151 while (--pos) {
152 if (info.at(pos) == '[')
153 info.truncate(pos);
154 }
155 }
156
157 bool hasLambda = false;
158 QRegularExpression lambdaRegex("::<lambda\\(.*?\\)>");
159 QRegularExpressionMatch match = lambdaRegex.match(QString::fromLatin1(info));
160 int lambdaIndex = match.capturedStart();
161 if (lambdaIndex != -1)
162 {
163 hasLambda = true;
164 info.remove(lambdaIndex, match.capturedLength());
165 }
166
167 // operator names with '(', ')', '<', '>' in it
168 static const char operator_call[] = "operator()";
169 static const char operator_lessThan[] = "operator<";
170 static const char operator_greaterThan[] = "operator>";
171 static const char operator_lessThanEqual[] = "operator<=";
172 static const char operator_greaterThanEqual[] = "operator>=";
173
174 // canonize operator names
175 info.replace("operator ", "operator");
176
177 // remove argument list
178 forever {
179 int parencount = 0;
180 pos = info.lastIndexOf(')');
181 if (pos == -1) {
182 // Don't know how to parse this function name
183 return info;
184 }
185
186 // find the beginning of the argument list
187 --pos;
188 ++parencount;
189 while (pos && parencount) {
190 if (info.at(pos) == ')')
191 ++parencount;
192 else if (info.at(pos) == '(')
193 --parencount;
194 --pos;
195 }
196 if (parencount != 0)
197 return info;
198
199 info.truncate(++pos);
200
201 if (info.at(pos - 1) == ')') {
202 if (info.indexOf(operator_call) == pos - (int)strlen(operator_call))
203 break;
204
205 // this function returns a pointer to a function
206 // and we matched the arguments of the return type's parameter list
207 // try again
208 info.remove(0, info.indexOf('('));
209 info.chop(1);
210 continue;
211 } else {
212 break;
213 }
214 }
215
216 if (hasLambda)
217 info.append("::lambda");
218
219 // find the beginning of the function name
220 int parencount = 0;
221 int templatecount = 0;
222 --pos;
223
224 // make sure special characters in operator names are kept
225 if (pos > -1) {
226 switch (info.at(pos)) {
227 case ')':
228 if (info.indexOf(operator_call) == pos - (int)strlen(operator_call) + 1)
229 pos -= 2;
230 break;
231 case '<':
232 if (info.indexOf(operator_lessThan) == pos - (int)strlen(operator_lessThan) + 1)
233 --pos;
234 break;
235 case '>':
236 if (info.indexOf(operator_greaterThan) == pos - (int)strlen(operator_greaterThan) + 1)
237 --pos;
238 break;
239 case '=': {
240 int operatorLength = (int)strlen(operator_lessThanEqual);
241 if (info.indexOf(operator_lessThanEqual) == pos - operatorLength + 1)
242 pos -= 2;
243 else if (info.indexOf(operator_greaterThanEqual) == pos - operatorLength + 1)
244 pos -= 2;
245 break;
246 }
247 default:
248 break;
249 }
250 }
251
252 while (pos > -1) {
253 if (parencount < 0 || templatecount < 0)
254 return info;
255
256 char c = info.at(pos);
257 if (c == ')')
258 ++parencount;
259 else if (c == '(')
260 --parencount;
261 else if (c == '>')
262 ++templatecount;
263 else if (c == '<')
264 --templatecount;
265 else if (c == ' ' && templatecount == 0 && parencount == 0)
266 break;
267
268 --pos;
269 }
270 info = info.mid(pos + 1);
271
272 // remove trailing '*', '&' that are part of the return argument
273 while ((info.at(0) == '*')
274 || (info.at(0) == '&'))
275 info = info.mid(1);
276
277 // we have the full function name now.
278 // clean up the templates
279 while ((pos = info.lastIndexOf('>')) != -1) {
280 if (!info.contains('<'))
281 break;
282
283 // find the matching close
284 int end = pos;
285 templatecount = 1;
286 --pos;
287 while (pos && templatecount) {
288 char c = info.at(pos);
289 if (c == '>')
290 ++templatecount;
291 else if (c == '<')
292 --templatecount;
293 --pos;
294 }
295 ++pos;
296 info.remove(pos, end - pos + 1);
297 }
298
299 return info;
300}
301
302
303//! Returns the string to record to the logging target, formatted according to the format().
304/**
305 * \sa format()
306 * \sa setFormat(const QString&)
307 */
308QString AbstractStringAppender::formattedString(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file,
309 int line, const char* function, const QString& category, const QString& message) const
310{
311 QString f = format();
312 const int size = f.size();
313
314 QString result;
315
316 int i = 0;
317 while (i < f.size())
318 {
319 QChar c = f.at(i);
320
321 // We will silently ignore the broken % marker at the end of string
322 if (c != QLatin1Char(formattingMarker) || (i + 2) >= size)
323 {
324 result.append(c);
325 }
326 else
327 {
328 i += 2;
329 QChar currentChar = f.at(i);
330 QString command;
331 int fieldWidth = 0;
332
333 if (currentChar.isLetter())
334 {
335 command.append(currentChar);
336 int j = 1;
337 while ((i + j) < size && f.at(i + j).isLetter())
338 {
339 command.append(f.at(i+j));
340 j++;
341 }
342
343 i+=j;
344 currentChar = f.at(i);
345
346 // Check for the padding instruction
347 if (currentChar == QLatin1Char(':'))
348 {
349 currentChar = f.at(++i);
350 if (currentChar.isDigit() || currentChar.category() == QChar::Punctuation_Dash)
351 {
352 int j = 1;
353 while ((i + j) < size && f.at(i + j).isDigit())
354 j++;
355 fieldWidth = f.mid(i, j).toInt();
356
357 i += j;
358 }
359 }
360 }
361
362 // Log record chunk to insert instead of formatting instruction
363 QString chunk;
364
365 // Time stamp
366 if (command == QLatin1String("time"))
367 {
368 if (f.at(i + 1) == QLatin1Char('{'))
369 {
370 int j = 1;
371 while ((i + 2 + j) < size && f.at(i + 2 + j) != QLatin1Char('}'))
372 j++;
373
374 if ((i + 2 + j) < size)
375 {
376 chunk = timeStamp.toString(f.mid(i + 2, j));
377
378 i += j;
379 i += 2;
380 }
381 }
382
383 if (chunk.isNull())
384 chunk = timeStamp.toString(QLatin1String("HH:mm:ss.zzz"));
385 }
386
387 // Log level
388 else if (command == QLatin1String("type"))
389 chunk = Logger::levelToString(logLevel);
390
391 // Uppercased log level
392 else if (command == QLatin1String("Type"))
393 chunk = Logger::levelToString(logLevel).toUpper();
394
395 // One letter log level
396 else if (command == QLatin1String("typeOne"))
397 chunk = Logger::levelToString(logLevel).left(1).toLower();
398
399 // One uppercase letter log level
400 else if (command == QLatin1String("TypeOne"))
401 chunk = Logger::levelToString(logLevel).left(1).toUpper();
402
403 // Filename
404 else if (command == QLatin1String("File"))
405 chunk = QLatin1String(file);
406
407 // Filename without a path
408 else if (command == QLatin1String("file"))
409 chunk = QString(QLatin1String(file)).section(QRegularExpression("[/\\\\]"), -1);
410
411 // Source line number
412 else if (command == QLatin1String("line"))
413 chunk = QString::number(line);
414
415 // Function name, as returned by Q_FUNC_INFO
416 else if (command == QLatin1String("Function"))
417 chunk = QString::fromLatin1(function);
418
419 // Stripped function name
420 else if (command == QLatin1String("function"))
421 chunk = stripFunctionName(function);
422
423 // Log message
424 else if (command == QLatin1String("message"))
425 chunk = message;
426
427 else if (command == QLatin1String("category"))
428 chunk = category;
429
430 // Application pid
431 else if (command == QLatin1String("pid"))
432 chunk = QString::number(QCoreApplication::applicationPid());
433
434 // Appplication name
435 else if (command == QLatin1String("appname"))
436 chunk = QCoreApplication::applicationName();
437
438 // Thread ID (duplicates Qt5 threadid debbuging way)
439 else if (command == QLatin1String("threadid"))
440 chunk = QLatin1String("0x") + QString::number(qlonglong(QThread::currentThread()->currentThread()), 16);
441
442 // We simply replace the double formatting marker (%) with one
443 else if (command == QString(formattingMarker))
444 chunk = QLatin1Char(formattingMarker);
445
446 // Do not process any unknown commands
447 else
448 {
449 chunk = QString(formattingMarker);
450 chunk.append(command);
451 }
452
453 result.append(QString(QLatin1String("%1")).arg(chunk, fieldWidth));
454 }
455
456 ++i;
457 }
458
459 return result;
460}
diff --git a/utils/rbutilqt/logger/src/ConsoleAppender.cpp b/utils/rbutilqt/logger/src/ConsoleAppender.cpp
new file mode 100644
index 0000000000..932ffab787
--- /dev/null
+++ b/utils/rbutilqt/logger/src/ConsoleAppender.cpp
@@ -0,0 +1,64 @@
1/*
2 Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com)
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License version 2.1
6 as published by the Free Software Foundation and appearing in the file
7 LICENSE.LGPL included in the packaging of this file.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13*/
14// Local
15#include "ConsoleAppender.h"
16
17// STL
18#include <iostream>
19
20
21/**
22 * \class ConsoleAppender
23 *
24 * \brief ConsoleAppender is the simple appender that writes the log records to the std::cerr output stream.
25 *
26 * ConsoleAppender uses "[%{type:-7}] <%{function}> %{message}\n" as a default output format. It is similar to the
27 * AbstractStringAppender but doesn't show a timestamp.
28 *
29 * You can modify ConsoleAppender output format without modifying your code by using \c QT_MESSAGE_PATTERN environment
30 * variable. If you need your application to ignore this environment variable you can call
31 * ConsoleAppender::ignoreEnvironmentPattern(true)
32 */
33
34
35ConsoleAppender::ConsoleAppender()
36 : AbstractStringAppender()
37 , m_ignoreEnvPattern(false)
38{
39 setFormat("[%{type:-7}] <%{function}> %{message}\n");
40}
41
42
43QString ConsoleAppender::format() const
44{
45 const QString envPattern = QString::fromLocal8Bit(qgetenv("QT_MESSAGE_PATTERN"));
46 return (m_ignoreEnvPattern || envPattern.isEmpty()) ? AbstractStringAppender::format() : (envPattern + "\n");
47}
48
49
50void ConsoleAppender::ignoreEnvironmentPattern(bool ignore)
51{
52 m_ignoreEnvPattern = ignore;
53}
54
55
56//! Writes the log record to the std::cerr stream.
57/**
58 * \sa AbstractStringAppender::format()
59 */
60void ConsoleAppender::append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
61 const char* function, const QString& category, const QString& message)
62{
63 std::cerr << qPrintable(formattedString(timeStamp, logLevel, file, line, function, category, message));
64}
diff --git a/utils/rbutilqt/logger/src/FileAppender.cpp b/utils/rbutilqt/logger/src/FileAppender.cpp
new file mode 100644
index 0000000000..b9018b0324
--- /dev/null
+++ b/utils/rbutilqt/logger/src/FileAppender.cpp
@@ -0,0 +1,116 @@
1/*
2 Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com)
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License version 2.1
6 as published by the Free Software Foundation and appearing in the file
7 LICENSE.LGPL included in the packaging of this file.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13*/
14// Local
15#include "FileAppender.h"
16
17// STL
18#include <iostream>
19
20/**
21 * \class FileAppender
22 *
23 * \brief Simple appender that writes the log records to the plain text file.
24 */
25
26
27//! Constructs the new file appender assigned to file with the given name.
28FileAppender::FileAppender(const QString& fileName)
29{
30 setFileName(fileName);
31}
32
33
34FileAppender::~FileAppender()
35{
36 closeFile();
37}
38
39
40//! Returns the name set by setFileName() or to the FileAppender constructor.
41/**
42 * \sa setFileName()
43 */
44QString FileAppender::fileName() const
45{
46 QMutexLocker locker(&m_logFileMutex);
47 return m_logFile.fileName();
48}
49
50
51//! Sets the name of the file. The name can have no path, a relative path, or an absolute path.
52/**
53 * \sa fileName()
54 */
55void FileAppender::setFileName(const QString& s)
56{
57 if (s.isEmpty())
58 std::cerr << "<FileAppender::FileAppender> File name is empty. The appender will do nothing" << std::endl;
59
60 QMutexLocker locker(&m_logFileMutex);
61 if (m_logFile.isOpen())
62 m_logFile.close();
63
64 m_logFile.setFileName(s);
65}
66
67
68bool FileAppender::reopenFile()
69{
70 closeFile();
71 return openFile();
72}
73
74
75bool FileAppender::openFile()
76{
77 if (m_logFile.fileName().isEmpty())
78 return false;
79
80 bool isOpen = m_logFile.isOpen();
81 if (!isOpen)
82 {
83 isOpen = m_logFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);
84 if (isOpen)
85 m_logStream.setDevice(&m_logFile);
86 else
87 std::cerr << "<FileAppender::append> Cannot open the log file " << qPrintable(m_logFile.fileName()) << std::endl;
88 }
89 return isOpen;
90}
91
92
93//! Write the log record to the file.
94/**
95 * \sa fileName()
96 * \sa AbstractStringAppender::format()
97 */
98void FileAppender::append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
99 const char* function, const QString& category, const QString& message)
100{
101 QMutexLocker locker(&m_logFileMutex);
102
103 if (openFile())
104 {
105 m_logStream << formattedString(timeStamp, logLevel, file, line, function, category, message);
106 m_logStream.flush();
107 m_logFile.flush();
108 }
109}
110
111
112void FileAppender::closeFile()
113{
114 QMutexLocker locker(&m_logFileMutex);
115 m_logFile.close();
116}
diff --git a/utils/rbutilqt/logger/src/Logger.cpp b/utils/rbutilqt/logger/src/Logger.cpp
new file mode 100644
index 0000000000..689bc42e80
--- /dev/null
+++ b/utils/rbutilqt/logger/src/Logger.cpp
@@ -0,0 +1,1108 @@
1/*
2 Copyright (c) 2012 Boris Moiseev (cyberbobs at gmail dot com)
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License version 2.1
6 as published by the Free Software Foundation and appearing in the file
7 LICENSE.LGPL included in the packaging of this file.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13*/
14// Local
15#include "Logger.h"
16#include "AbstractAppender.h"
17#include "AbstractStringAppender.h"
18
19// Qt
20#include <QCoreApplication>
21#include <QReadWriteLock>
22#include <QSemaphore>
23#include <QDateTime>
24#include <QIODevice>
25#include <QTextCodec>
26
27#if defined(Q_OS_ANDROID)
28# include <android/log.h>
29# include <AndroidAppender.h>
30#endif
31
32// STL
33#include <iostream>
34
35
36/**
37 * \file Logger.h
38 * \brief A file containing the description of Logger class and and additional useful macros for logging
39 */
40
41
42/**
43 * \mainpage
44 *
45 * Logger is a simple way to write the history of your application lifecycle to any target logging device (which is
46 * called Appender and may write to any target you will implement with it: console, text file, XML or something - you
47 * choose) and to map logging message to a class, function, source file and line of code which it is called from.
48 *
49 * Some simple appenders (which may be considered an examples) are provided with the Logger itself: see ConsoleAppender
50 * and FileAppender documentation.
51 *
52 * It supports using it in a multithreaded applications, so all of its functions are thread safe.
53 *
54 * Simple usage example:
55 * \code
56 * #include <QCoreApplication>
57 *
58 * #include <Logger.h>
59 * #include <ConsoleAppender.h>
60 *
61 * int main(int argc, char* argv[])
62 * {
63 * QCoreApplication app(argc, argv);
64 * ...
65 * ConsoleAppender* consoleAppender = new ConsoleAppender;
66 * consoleAppender->setFormat("[%{type:-7}] <%{Function}> %{message}\n");
67 * cuteLogger->registerAppender(consoleAppender);
68 * ...
69 * LOG_INFO("Starting the application");
70 * int result = app.exec();
71 * ...
72 * if (result)
73 * LOG_WARNING() << "Something went wrong." << "Result code is" << result;
74 *
75 * return result;
76 * }
77 * \endcode
78 *
79 * Logger internally uses the lazy-initialized singleton object and needs no definite initialization, but you may
80 * consider registering a log appender before calling any log recording functions or macros.
81 *
82 * The library design of Logger allows you to simply mass-replace all occurrences of qDebug and similar calls with
83 * similar Logger macros (e.g. LOG_DEBUG())
84 *
85 * \note Logger uses a singleton global instance which lives through all the application life cycle and self-destroys
86 * destruction of the QCoreApplication (or QApplication) instance. It needs a QCoreApplication instance to be
87 * created before any of the Logger's functions are called.
88 *
89 * \sa cuteLogger
90 * \sa LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_FATAL
91 * \sa LOG_CTRACE, LOG_CDEBUG, LOG_CINFO, LOG_CWARNING, LOG_CERROR, LOG_CFATAL
92 * \sa LOG_ASSERT
93 * \sa LOG_TRACE_TIME, LOG_DEBUG_TIME, LOG_INFO_TIME
94 * \sa AbstractAppender
95 */
96
97
98/**
99 * \def cuteLogger
100 *
101 * \brief Macro returning the current instance of Logger object
102 *
103 * If you haven't created a local Logger object it returns the same value as the Logger::globalInstance() functions.
104 * This macro is a recommended way to get an access to the Logger instance used in current class.
105 *
106 * Example:
107 * \code
108 * ConsoleAppender* consoleAppender = new ConsoleAppender;
109 * cuteLogger->registerAppender(consoleAppender);
110 * \endcode
111 *
112 * \sa Logger::globalInstance()
113 */
114
115
116/**
117 * \def LOG_TRACE
118 *
119 * \brief Writes the trace log record
120 *
121 * This macro is the convinient way to call Logger::write(). It uses the common preprocessor macros \c __FILE__,
122 * \c __LINE__ and the standart Qt \c Q_FUNC_INFO macros to automatically determine the needed parameters to call
123 * Logger::write().
124 *
125 * \note This and other (LOG_INFO() etc...) macros uses the variadic macro arguments to give convinient usage form for
126 * the different versions of Logger::write() (using the QString or const char* argument or returning the QDebug class
127 * instance). Not all compilers will support this. Please, consider reviewing your compiler documentation to ensure
128 * it support __VA_ARGS__ macro.
129 *
130 * \sa Logger::LogLevel
131 * \sa Logger::write()
132 */
133
134
135/**
136 * \def LOG_DEBUG
137 *
138 * \brief Writes the debug log record
139 *
140 * This macro records the debug log record using the Logger::write() function. It works similar to the LOG_TRACE()
141 * macro.
142 *
143 * \sa LOG_TRACE()
144 * \sa Logger::LogLevel
145 * \sa Logger::write()
146 */
147
148
149/**
150 * \def LOG_INFO
151 *
152 * \brief Writes the info log record
153 *
154 * This macro records the info log record using the Logger::write() function. It works similar to the LOG_TRACE()
155 * macro.
156 *
157 * \sa LOG_TRACE()
158 * \sa Logger::LogLevel
159 * \sa Logger::write()
160 */
161
162
163/**
164 * \def LOG_WARNING
165 *
166 * \brief Write the warning log record
167 *
168 * This macro records the warning log record using the Logger::write() function. It works similar to the LOG_TRACE()
169 * macro.
170 *
171 * \sa LOG_TRACE()
172 * \sa Logger::LogLevel
173 * \sa Logger::write()
174 */
175
176
177/**
178 * \def LOG_ERROR
179 *
180 * \brief Write the error log record
181 * This macro records the error log record using the Logger::write() function. It works similar to the LOG_TRACE()
182 * macro.
183 *
184 * \sa LOG_TRACE()
185 * \sa Logger::LogLevel
186 * \sa Logger::write()
187 */
188
189
190/**
191 * \def LOG_FATAL
192 *
193 * \brief Write the fatal log record
194 *
195 * This macro records the fatal log record using the Logger::write() function. It works similar to the LOG_TRACE()
196 * macro.
197 *
198 * \note Recording of the log record using the Logger::Fatal log level will lead to calling the STL abort()
199 * function, which will interrupt the running of your software and begin the writing of the core dump.
200 *
201 * \sa LOG_TRACE()
202 * \sa Logger::LogLevel
203 * \sa Logger::write()
204 */
205
206
207/**
208 * \def LOG_CTRACE(category)
209 *
210 * \brief Writes the trace log record to the specific category
211 *
212 * This macro is the similar to the LOG_TRACE() macro, but has a category parameter
213 * to write only to the category appenders (registered using Logger::registerCategoryAppender() method).
214 *
215 * \param category category name string
216 *
217 * \sa LOG_TRACE()
218 * \sa Logger::LogLevel
219 * \sa Logger::registerCategoryAppender()
220 * \sa Logger::write()
221 * \sa LOG_CATEGORY(), LOG_GLOBAL_CATEGORY()
222 */
223
224
225/**
226 * \def LOG_CDEBUG
227 *
228 * \brief Writes the debug log record to the specific category
229 *
230 * This macro records the debug log record using the Logger::write() function. It works similar to the LOG_CTRACE()
231 * macro.
232 *
233 * \sa LOG_CTRACE()
234 */
235
236
237/**
238 * \def LOG_CINFO
239 *
240 * \brief Writes the info log record to the specific category
241 *
242 * This macro records the info log record using the Logger::write() function. It works similar to the LOG_CTRACE()
243 * macro.
244 *
245 * \sa LOG_CTRACE()
246 */
247
248
249/**
250 * \def LOG_CWARNING
251 *
252 * \brief Writes the warning log record to the specific category
253 *
254 * This macro records the warning log record using the Logger::write() function. It works similar to the LOG_CTRACE()
255 * macro.
256 *
257 * \sa LOG_CTRACE()
258 */
259
260
261/**
262 * \def LOG_CERROR
263 *
264 * \brief Writes the error log record to the specific category
265 *
266 * This macro records the error log record using the Logger::write() function. It works similar to the LOG_CTRACE()
267 * macro.
268 *
269 * \sa LOG_CTRACE()
270 */
271
272
273/**
274 * \def LOG_CFATAL
275 *
276 * \brief Write the fatal log record to the specific category
277 *
278 * This macro records the fatal log record using the Logger::write() function. It works similar to the LOG_CTRACE()
279 * macro.
280 *
281 * \note Recording of the log record using the Logger::Fatal log level will lead to calling the STL abort()
282 * function, which will interrupt the running of your software and begin the writing of the core dump.
283 *
284 * \sa LOG_CTRACE()
285 */
286
287
288/**
289 * \def LOG_CATEGORY(category)
290 *
291 * \brief Create logger instance inside your custom class to log all messages to the specified category
292 *
293 * This macro is used to pass all log messages inside your custom class to the specific category.
294 * You must include this macro inside your class declaration (similarly to the Q_OBJECT macro).
295 * Internally, this macro redefines cuteLoggerInstance() function, creates the local Logger object inside your class and
296 * sets the default category to the specified parameter.
297 *
298 * Thus, any call to cuteLoggerInstance() (for example, inside LOG_TRACE() macro) will return the local Logger object,
299 * so any logging message will be directed to the default category.
300 *
301 * \note This macro does not register any appender to the newly created logger instance. You should register
302 * logger appenders manually, inside your class.
303 *
304 * Usage example:
305 * \code
306 * class CustomClass : public QObject
307 * {
308 * Q_OBJECT
309 * LOG_CATEGORY("custom_category")
310 * ...
311 * };
312 *
313 * CustomClass::CustomClass(QObject* parent) : QObject(parent)
314 * {
315 * cuteLogger->registerAppender(new FileAppender("custom_category_log"));
316 * LOG_TRACE() << "Trace to the custom category log";
317 * }
318 * \endcode
319 *
320 * If used compiler supports C++11 standard, LOG_CATEGORY and LOG_GLOBAL_CATEGORY macros would also work when added
321 * inside of any scope. It could be useful, for example, to log every single run of a method to a different file.
322 *
323 * \code
324 * void foo()
325 * {
326 * QString categoryName = QDateTime::currentDateTime().toString("yyyy-MM-ddThh-mm-ss-zzz");
327 * LOG_CATEGORY(categoryName);
328 * cuteLogger->registerAppender(new FileAppender(categoryName + ".log"));
329 * ...
330 * }
331 * \endcode
332 *
333 * \sa Logger::write()
334 * \sa LOG_TRACE
335 * \sa Logger::registerCategoryAppender()
336 * \sa Logger::setDefaultCategory()
337 * \sa LOG_GLOBAL_CATEGORY
338 */
339
340
341/**
342 * \def LOG_GLOBAL_CATEGORY(category)
343 *
344 * \brief Create logger instance inside your custom class to log all messages both to the specified category and to
345 * the global logger instance.
346 *
347 * This macro is similar to LOG_CATEGORY(), but also passes all log messages to the global logger instance appenders.
348 * It is equal to defining the local category logger using LOG_CATEGORY macro and calling:
349 * \code cuteLogger->logToGlobalInstance(cuteLogger->defaultCategory(), true); \endcode
350 *
351 * \sa LOG_CATEGORY
352 * \sa Logger::logToGlobalInstance()
353 * \sa Logger::defaultCategory()
354 * \sa Logger::registerCategoryAppender()
355 * \sa Logger::write()
356 */
357
358
359
360/**
361 * \def LOG_ASSERT
362 *
363 * \brief Check the assertion
364 *
365 * This macro is a convinient and recommended to use way to call Logger::writeAssert() function. It uses the
366 * preprocessor macros (as the LOG_DEBUG() does) to fill the necessary arguments of the Logger::writeAssert() call. It
367 * also uses undocumented but rather mature and stable \c qt_noop() function (which does nothing) when the assertion
368 * is true.
369 *
370 * Example:
371 * \code
372 * bool b = checkSomething();
373 * ...
374 * LOG_ASSERT(b == true);
375 * \endcode
376 *
377 * \sa Logger::writeAssert()
378 */
379
380
381/**
382 * \def LOG_TRACE_TIME
383 *
384 * \brief Logs the processing time of current function / code block
385 *
386 * This macro automagically measures the function or code of block execution time and outputs it as a Logger::Trace
387 * level log record.
388 *
389 * Example:
390 * \code
391 * int foo()
392 * {
393 * LOG_TRACE_TIME();
394 * ... // Do some long operations
395 * return 0;
396 * } // Outputs: Function foo finished in <time> ms.
397 * \endcode
398 *
399 * If you are measuring a code of block execution time you may also add a name of block to the macro:
400 * \code
401 * int bar(bool doFoo)
402 * {
403 * LOG_TRACE_TIME();
404 *
405 * if (doFoo)
406 * {
407 * LOG_TRACE_TIME("Foo");
408 * ...
409 * }
410 *
411 * ...
412 * }
413 * // Outputs:
414 * // "Foo" finished in <time1> ms.
415 * // Function bar finished in <time2> ms.
416 * \endcode
417 *
418 * \note Macro switches to logging the seconds instead of milliseconds when the execution time reaches 10000 ms.
419 * \sa LOG_DEBUG_TIME, LOG_INFO_TIME
420 */
421
422
423/**
424 * \def LOG_DEBUG_TIME
425 *
426 * \brief Logs the processing time of current function / code block
427 *
428 * This macro automagically measures the function or code of block execution time and outputs it as a Logger::Debug
429 * level log record. It works similar to LOG_TRACE_TIME() macro.
430 *
431 * \sa LOG_TRACE_TIME
432 */
433
434
435/**
436 * \def LOG_INFO_TIME
437 *
438 * \brief Logs the processing time of current function / code block
439 *
440 * This macro automagically measures the function or code of block execution time and outputs it as a Logger::Info
441 * level log record. It works similar to LOG_TRACE_TIME() macro.
442 *
443 * \sa LOG_TRACE_TIME
444 */
445
446
447/**
448 * \class Logger
449 *
450 * \brief Very simple but rather powerful component which may be used for logging your application activities.
451 *
452 * Global logger instance created on a first access to it (e.g. registering appenders, calling a LOG_DEBUG() macro
453 * etc.) registers itself as a Qt default message handler and captures all the qDebug/qWarning/qCritical output.
454 *
455 * \note Qt 4 qDebug set of macro doesn't support capturing source function name, file name or line number so we
456 * recommend to use LOG_DEBUG() and other Logger macros instead.
457 *
458 * \sa cuteLogger
459 * \sa [CuteLogger Documentation](index.html)
460 */
461
462// Forward declarations
463static void cleanupLoggerGlobalInstance();
464
465#if QT_VERSION >= 0x050000
466static void qtLoggerMessageHandler(QtMsgType, const QMessageLogContext& context, const QString& msg);
467#else
468static void qtLoggerMessageHandler(QtMsgType type, const char* msg);
469#endif
470
471/**
472 * \internal
473 *
474 * LoggerPrivate class implements the Singleton pattern in a thread-safe way. It contains a static pointer to the
475 * global logger instance protected by QReadWriteLock
476 */
477class LoggerPrivate
478{
479 public:
480 static Logger* globalInstance;
481 static QReadWriteLock globalInstanceLock;
482
483 QList<AbstractAppender*> appenders;
484 QMutex loggerMutex;
485
486 QMap<QString, bool> categories;
487 QMultiMap<QString, AbstractAppender*> categoryAppenders;
488 QStringList noAppendersCategories; //<! Categories without appenders that was already warned about
489 QString defaultCategory;
490 bool writeDefaultCategoryToGlobalInstance;
491};
492
493
494// Static fields initialization
495Logger* LoggerPrivate::globalInstance = nullptr;
496QReadWriteLock LoggerPrivate::globalInstanceLock;
497
498
499static void cleanupLoggerGlobalInstance()
500{
501 QWriteLocker locker(&LoggerPrivate::globalInstanceLock);
502
503 delete LoggerPrivate::globalInstance;
504 LoggerPrivate::globalInstance = nullptr;
505}
506
507
508#if QT_VERSION >= 0x050000
509static void qtLoggerMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg)
510{
511 Logger::LogLevel level = Logger::Debug;
512 switch (type)
513 {
514 case QtDebugMsg:
515 level = Logger::Debug;
516 break;
517#if QT_VERSION >= 0x050500
518 case QtInfoMsg:
519 level = Logger::Info;
520 break;
521#endif
522 case QtWarningMsg:
523 level = Logger::Warning;
524 break;
525 case QtCriticalMsg:
526 level = Logger::Error;
527 break;
528 case QtFatalMsg:
529 level = Logger::Fatal;
530 break;
531 }
532
533 bool isDefaultCategory = QString::fromLatin1(context.category) == "default";
534 Logger::globalInstance()->write(level, context.file, context.line, context.function, isDefaultCategory ? nullptr : context.category, msg);
535}
536
537#else
538
539static void qtLoggerMessageHandler(QtMsgType type, const char* msg)
540{
541 switch (type)
542 {
543 case QtDebugMsg:
544 cuteLoggerInstance()->write(Logger::Debug, "", 0, "qDebug", 0, msg);
545 break;
546 case QtWarningMsg:
547 cuteLoggerInstance()->write(Logger::Warning, "", 0, "qDebug", 0, msg);
548 break;
549 case QtCriticalMsg:
550 cuteLoggerInstance()->write(Logger::Error, "", 0, "qDebug", 0, msg);
551 break;
552 case QtFatalMsg:
553 cuteLoggerInstance()->write(Logger::Fatal, "", 0, "qDebug", 0, msg);
554 break;
555 }
556}
557#endif
558
559
560//! Construct the instance of Logger
561/**
562 * If you're only using one global instance of logger you wouldn't probably need to use this constructor manually.
563 * Consider using [cuteLogger](@ref cuteLogger) macro instead to access the logger instance
564 */
565Logger::Logger()
566 : d_ptr(new LoggerPrivate)
567{
568 Q_D(Logger);
569 d->writeDefaultCategoryToGlobalInstance = false;
570}
571
572
573//! Construct the instance of Logger and set logger default category
574/**
575 * If you're only using one global instance of logger you wouldn't probably need to use this constructor manually.
576 * Consider using [cuteLogger](@ref cuteLogger) macro instead to access the logger instance and call
577 * [setDefaultCategory](@ref setDefaultCategory) method.
578 *
579 * \sa Logger()
580 * \sa setDefaultCategory()
581 */
582Logger::Logger(const QString& defaultCategory, bool writeToGlobalInstance)
583 : d_ptr(new LoggerPrivate)
584{
585 Q_D(Logger);
586 d->writeDefaultCategoryToGlobalInstance = writeToGlobalInstance;
587
588 setDefaultCategory(defaultCategory);
589}
590
591
592//! Destroy the instance of Logger
593/**
594 * You probably wouldn't need to use this function directly. Global instance of logger will be destroyed automatically
595 * at the end of your QCoreApplication execution
596 */
597Logger::~Logger()
598{
599 Q_D(Logger);
600
601 // Cleanup appenders
602 QMutexLocker appendersLocker(&d->loggerMutex);
603#if QT_VERSION >= 0x050e00
604 QSet<AbstractAppender*> deleteList(QSet<AbstractAppender*>(d->appenders.begin(), d->appenders.end()));
605 deleteList.unite(QSet<AbstractAppender*>(d->categoryAppenders.values().begin(), d->categoryAppenders.values().end()));
606#else
607 QSet<AbstractAppender*> deleteList(QSet<AbstractAppender*>::fromList(d->appenders));
608 deleteList.unite(QSet<AbstractAppender*>::fromList(d->categoryAppenders.values()));
609#endif
610 qDeleteAll(deleteList);
611
612 appendersLocker.unlock();
613
614 delete d_ptr;
615}
616
617
618//! Converts the LogLevel enum value to its string representation
619/**
620 * \param logLevel Log level to convert
621 *
622 * \sa LogLevel
623 * \sa levelFromString()
624 */
625QString Logger::levelToString(Logger::LogLevel logLevel)
626{
627 switch (logLevel)
628 {
629 case Trace:
630 return QLatin1String("Trace");
631 case Debug:
632 return QLatin1String("Debug");
633 case Info:
634 return QLatin1String("Info");
635 case Warning:
636 return QLatin1String("Warning");
637 case Error:
638 return QLatin1String("Error");
639 case Fatal:
640 return QLatin1String("Fatal");
641 }
642
643 return QString();
644}
645
646
647//! Converts the LogLevel string representation to enum value
648/**
649 * Comparation of the strings is case independent. If the log level string provided cannot be understood
650 * Logger::Debug is returned.
651 *
652 * \param s String to be decoded
653 *
654 * \sa LogLevel
655 * \sa levelToString()
656 */
657Logger::LogLevel Logger::levelFromString(const QString& s)
658{
659 QString str = s.trimmed().toLower();
660
661 LogLevel result = Debug;
662
663 if (str == QLatin1String("trace"))
664 result = Trace;
665 else if (str == QLatin1String("debug"))
666 result = Debug;
667 else if (str == QLatin1String("info"))
668 result = Info;
669 else if (str == QLatin1String("warning"))
670 result = Warning;
671 else if (str == QLatin1String("error"))
672 result = Error;
673 else if (str == QLatin1String("fatal"))
674 result = Fatal;
675
676 return result;
677}
678
679
680//! Returns the global instance of Logger
681/**
682 * In a most cases you shouldn't use this function directly. Consider using [cuteLogger](@ref cuteLogger) macro instead.
683 *
684 * \sa cuteLogger
685 */
686Logger* Logger::globalInstance()
687{
688 Logger* result = nullptr;
689 {
690 QReadLocker locker(&LoggerPrivate::globalInstanceLock);
691 result = LoggerPrivate::globalInstance;
692 }
693
694 if (!result)
695 {
696 QWriteLocker locker(&LoggerPrivate::globalInstanceLock);
697 LoggerPrivate::globalInstance = new Logger;
698
699#if QT_VERSION >= 0x050000
700 qInstallMessageHandler(qtLoggerMessageHandler);
701#else
702 qInstallMsgHandler(qtLoggerMessageHandler);
703#endif
704 qAddPostRoutine(cleanupLoggerGlobalInstance);
705 result = LoggerPrivate::globalInstance;
706 }
707
708 return result;
709}
710
711
712//! Registers the appender to write the log records to
713/**
714 * On the log writing call (using one of the macros or the write() function) Logger traverses through the list of
715 * the appenders and writes a log records to the each of them. Please, look through the AbstractAppender
716 * documentation to understand the concept of appenders.
717 *
718 * If no appenders was added to Logger, it falls back to logging into the \c std::cerr STL stream.
719 *
720 * \param appender Appender to register in the Logger
721 *
722 * \note Logger takes ownership on the appender and it will delete it on the application exit. According to this,
723 * appenders must be created on heap to prevent double destruction of the appender.
724 *
725 * \sa registerCategoryAppender
726 * \sa AbstractAppender
727 */
728void Logger::registerAppender(AbstractAppender* appender)
729{
730 Q_D(Logger);
731
732 QMutexLocker locker(&d->loggerMutex);
733
734 if (!d->appenders.contains(appender))
735 d->appenders.append(appender);
736 else
737 std::cerr << "Trying to register appender that was already registered" << std::endl;
738}
739
740//! Registers the appender to write the log records to the specific category
741/**
742 * Calling this method, you can link some appender with the named category.
743 * On the log writing call to the specific category (calling write() with category parameter directly,
744 * writing to the default category, or using special LOG_CDEBUG(), LOG_CWARNING() etc. macros),
745 * Logger writes the log message only to the list of registered category appenders.
746 *
747 * You can call logToGlobalInstance() to pass all category log messages to the global logger instance appenders
748 * (registered using registerAppender()).
749 * If no category appenders with specific name was registered to the Logger,
750 * it falls back to logging into the \c std::cerr STL stream, both with simple warning message.
751 *
752 * \param category Category name
753 * \param appender Appender to register in the Logger
754 *
755 * \note Logger takes ownership on the appender and it will delete it on the application exit. According to this,
756 * appenders must be created on heap to prevent double destruction of the appender.
757 *
758 * \sa registerAppender
759 * \sa LOG_CTRACE(), LOG_CDEBUG(), LOG_CINFO(), LOG_CWARNING(), LOG_CERROR(), LOG_CFATAL()
760 * \sa LOG_CATEGORY(), LOG_GLOBAL_CATEGORY()
761 * \sa logToGlobalInstance
762 * \sa setDefaultCategory
763 */
764void Logger::registerCategoryAppender(const QString& category, AbstractAppender* appender)
765{
766 Q_D(Logger);
767
768 QMutexLocker locker(&d->loggerMutex);
769
770 if (!d->categoryAppenders.values().contains(appender))
771 d->categoryAppenders.insert(category, appender);
772 else
773 std::cerr << "Trying to register appender that was already registered" << std::endl;
774}
775
776
777//! Removes the registered appender from logger
778/**
779 * After calling this function logger stops writing any of the records to the appender.
780 *
781 * \param appender Pointer to appender to remove from logger
782 * \note Removed appender will not be deleted on the application shutdown and you will need to destroy the object
783 * yourself.
784 * \sa registerAppender
785 */
786void Logger::removeAppender(AbstractAppender* appender)
787{
788 Q_D(Logger);
789
790 QMutexLocker locker(&d->loggerMutex);
791
792 d->appenders.removeAll(appender);
793 for (QMultiMap<QString,AbstractAppender*>::iterator it = d->categoryAppenders.begin(); it != d->categoryAppenders.end();)
794 {
795 if (it.value() == appender)
796 it = d->categoryAppenders.erase(it);
797 else
798 ++it;
799 }
800}
801
802
803//! Sets default logging category
804/**
805 * All log messages to this category appenders will also be written to general logger instance appenders (registered
806 * using [registerAppender](@ref registerAppender) method), and vice versa.
807 * In particular, any calls to the LOG_DEBUG() macro will be treated as category logging,
808 * so you needn't to specify category name using LOG_CDEBUG() macro.
809 *
810 * To unset the default category, pass a null string as a parameter.
811 *
812 * \param category Category name
813 *
814 * \note "category" format marker will be set to the category name for all of these messages
815 * (see [AbstractStringAppender::setFormat](@ref AbstractStringAppender::setFormat)).
816 *
817 * \sa defaultCategory()
818 * \sa registerCategoryAppender()
819 * \sa logToGlobalInstance()
820 */
821void Logger::setDefaultCategory(const QString& category)
822{
823 Q_D(Logger);
824
825 QMutexLocker locker(&d->loggerMutex);
826
827 d->defaultCategory = category;
828}
829
830//! Returns default logging category name
831/**
832 * \sa setDefaultCategory
833 */
834QString Logger::defaultCategory() const
835{
836 Q_D(const Logger);
837 return d->defaultCategory;
838}
839
840//! Links some logging category with the global logger instance appenders.
841/**
842 * If set to true, all log messages to the specified category appenders will also be written to the global logger instance appenders,
843 * registered using registerAppender().
844 *
845 * By default, all messages to the specific category are written only to the specific category appenders
846 * (registered using registerCategoryAppender()).
847 *
848 * \param category Category name
849 * \param logToGlobal Link or onlink the category from global logger instance appender
850 *
851 * \sa globalInstance
852 * \sa registerAppender
853 * \sa registerCategoryAppender
854 */
855void Logger::logToGlobalInstance(const QString& category, bool logToGlobal)
856{
857 Q_D(Logger);
858
859 if (this == globalInstance())
860 {
861 QMutexLocker locker(&d->loggerMutex);
862 d->categories.insert(category, logToGlobal);
863 }
864 else
865 {
866 globalInstance()->logToGlobalInstance(category, logToGlobal);
867 }
868}
869
870
871void Logger::write(const QDateTime& timeStamp, LogLevel logLevel, const char* file, int line, const char* function, const char* category,
872 const QString& message, bool fromLocalInstance)
873{
874 Q_D(Logger);
875
876 QMutexLocker locker(&d->loggerMutex);
877
878 QString logCategory = QString::fromLatin1(category);
879 if (logCategory.isNull() && !d->defaultCategory.isNull())
880 logCategory = d->defaultCategory;
881
882 bool wasWritten = false;
883 bool isGlobalInstance = this == globalInstance();
884 bool linkedToGlobal = isGlobalInstance && d->categories.value(logCategory, false);
885
886 if (!logCategory.isNull())
887 {
888 QList<AbstractAppender*> appenders = d->categoryAppenders.values(logCategory);
889 if (appenders.length() == 0)
890 {
891 if (logCategory != d->defaultCategory && !linkedToGlobal && !fromLocalInstance && !d->noAppendersCategories.contains(logCategory))
892 {
893 std::cerr << "No appenders associated with category " << qPrintable(logCategory) << std::endl;
894 d->noAppendersCategories.append(logCategory);
895 }
896 }
897 else
898 {
899 foreach (AbstractAppender* appender, appenders)
900 appender->write(timeStamp, logLevel, file, line, function, logCategory, message);
901 wasWritten = true;
902 }
903 }
904
905 // the default category is linked to the main logger appenders
906 // global logger instance also writes all linked categories to the main appenders
907 if (logCategory.isNull() || logCategory == d->defaultCategory || linkedToGlobal)
908 {
909 if (!d->appenders.isEmpty())
910 {
911 foreach (AbstractAppender* appender, d->appenders)
912 appender->write(timeStamp, logLevel, file, line, function, logCategory, message);
913 wasWritten = true;
914 }
915 else
916 {
917 static bool noAppendersWarningShown = false;
918 if (!noAppendersWarningShown)
919 {
920#if defined(Q_OS_ANDROID)
921 __android_log_write(ANDROID_LOG_WARN, "Logger", "No appenders registered with logger");
922#else
923 std::cerr << "No appenders registered with logger" << std::endl;
924#endif
925 noAppendersWarningShown = true;
926 }
927 }
928 }
929
930 // local logger instances send category messages to the global instance
931 if (!isGlobalInstance)
932 {
933 if (!logCategory.isNull())
934 {
935 globalInstance()->write(timeStamp, logLevel, file, line, function, logCategory.toLatin1(), message, true);
936 wasWritten = true;
937 }
938
939 if (d->writeDefaultCategoryToGlobalInstance && logCategory == d->defaultCategory)
940 {
941 globalInstance()->write(timeStamp, logLevel, file, line, function, nullptr, message, true);
942 wasWritten = true;
943 }
944 }
945
946 if (!wasWritten && !fromLocalInstance)
947 {
948 // Fallback
949#if defined(Q_OS_ANDROID)
950 QString result = QString(QLatin1String("<%2> %3")).arg(AbstractStringAppender::stripFunctionName(function)).arg(message);
951 __android_log_write(AndroidAppender::androidLogPriority(logLevel), "Logger", qPrintable(result));
952#else
953 QString result = QString(QLatin1String("[%1] <%2> %3")).arg(levelToString(logLevel), -7)
954 .arg(AbstractStringAppender::stripFunctionName(function)).arg(message);
955 std::cerr << qPrintable(result) << std::endl;
956#endif
957 }
958
959 if (logLevel == Logger::Fatal)
960 abort();
961}
962
963
964//! Writes the log record
965/**
966 * Writes the log records with the supplied arguments to all the registered appenders.
967 *
968 * \note It is not recommended to call this function directly. Instead of this you can just call one of the macros
969 * (LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_FATAL) that will supply all the needed
970 * information to this function.
971 *
972 * \param timeStamp - the time stamp of the record
973 * \param logLevel - the log level of the record
974 * \param file - the name of the source file that requested the log record
975 * \param line - the line of the code of source file that requested the log record
976 * \param function - name of the function that requested the log record
977 * \param category - logging category (0 for default category)
978 * \param message - log message
979 *
980 * \note Recording of the log record using the Logger::Fatal log level will lead to calling the STL abort()
981 * function, which will interrupt the running of your software and begin the writing of the core dump.
982 *
983 * \sa LogLevel
984 * \sa LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_FATAL
985 * \sa AbstractAppender
986 */
987void Logger::write(const QDateTime& timeStamp, LogLevel logLevel, const char* file, int line, const char* function, const char* category,
988 const QString& message)
989{
990 write(timeStamp, logLevel, file, line, function, category, message, /* fromLocalInstance = */ false);
991}
992
993/**
994 * This is the overloaded function provided for the convinience. It behaves similar to the above function.
995 *
996 * This function uses the current timestamp obtained with \c QDateTime::currentDateTime().
997 *
998 * \sa write()
999 */
1000void Logger::write(LogLevel logLevel, const char* file, int line, const char* function, const char* category,
1001 const QString& message)
1002{
1003 write(QDateTime::currentDateTime(), logLevel, file, line, function, category, message);
1004}
1005
1006
1007//! Writes the assertion
1008/**
1009 * This function writes the assertion record using the write() function.
1010 *
1011 * The assertion record is always written using the Logger::Fatal log level which leads to the abortation of the
1012 * program and generation of the core dump (if supported).
1013 *
1014 * The message written to the appenders will be identical to the \c condition argument prefixed with the
1015 * <tt>ASSERT:</tt> notification.
1016 *
1017 * \note It is not recommended to call this function directly. Instead of this you can just call the LOG_ASSERT
1018 * macro that will supply all the needed information to this function.
1019 *
1020 * \sa LOG_ASSERT
1021 * \sa write()
1022 */
1023void Logger::writeAssert(const char* file, int line, const char* function, const char* condition)
1024{
1025 write(Logger::Fatal, file, line, function, nullptr, QString("ASSERT: \"%1\"").arg(condition));
1026}
1027
1028
1029Logger* cuteLoggerInstance()
1030{
1031 return Logger::globalInstance();
1032}
1033
1034
1035
1036void LoggerTimingHelper::start(const char* msg, ...)
1037{
1038 va_list va;
1039 va_start(va, msg);
1040#if QT_VERSION >= 0x050500
1041 m_block = QString().vasprintf(msg, va);
1042#else
1043 m_block = QString().vsprintf(msg, va);
1044#endif
1045 va_end(va);
1046
1047 m_time.start();
1048}
1049
1050
1051void LoggerTimingHelper::start(const QString& block)
1052{
1053 m_block = block;
1054 m_time.start();
1055}
1056
1057
1058void LoggerTimingHelper::start(Logger::TimingMode mode, const QString& block)
1059{
1060 m_timingMode = mode;
1061 m_block = block;
1062 m_time.start();
1063}
1064
1065
1066LoggerTimingHelper::~LoggerTimingHelper()
1067{
1068 QString message;
1069 if (m_block.isEmpty())
1070 message = QString(QLatin1String("Function %1 finished in ")).arg(AbstractStringAppender::stripFunctionName(m_function));
1071 else
1072 message = QString(QLatin1String("\"%1\" finished in ")).arg(m_block);
1073
1074 qint64 elapsed = m_time.elapsed();
1075 if (elapsed >= 10000 && m_timingMode == Logger::TimingAuto)
1076 message += QString(QLatin1String("%1 s.")).arg(elapsed / 1000);
1077 else
1078 message += QString(QLatin1String("%1 ms.")).arg(elapsed);
1079
1080 m_logger->write(m_logLevel, m_file, m_line, m_function, nullptr, message);
1081}
1082
1083
1084CuteMessageLogger::~CuteMessageLogger()
1085{
1086 m_l->write(m_level, m_file, m_line, m_function, m_category, m_message);
1087}
1088
1089void CuteMessageLogger::write(const char* msg, ...)
1090{
1091 va_list va;
1092 va_start(va, msg);
1093 m_message = QString::vasprintf(msg, va);
1094 va_end(va);
1095}
1096
1097
1098void CuteMessageLogger::write(const QString& msg)
1099{
1100 m_message = msg;
1101}
1102
1103
1104QDebug CuteMessageLogger::write()
1105{
1106 QDebug d(&m_message);
1107 return d;
1108}
diff --git a/utils/rbutilqt/logger/src/OutputDebugAppender.cpp b/utils/rbutilqt/logger/src/OutputDebugAppender.cpp
new file mode 100644
index 0000000000..44d640512f
--- /dev/null
+++ b/utils/rbutilqt/logger/src/OutputDebugAppender.cpp
@@ -0,0 +1,43 @@
1/*
2 Copyright (c) 2010 Karl-Heinz Reichel (khreichel at googlemail dot com)
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License version 2.1
6 as published by the Free Software Foundation and appearing in the file
7 LICENSE.LGPL included in the packaging of this file.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13*/
14// Local
15#include "OutputDebugAppender.h"
16
17// STL
18#include <windows.h>
19
20
21/**
22 * \class OutputDebugAppender
23 *
24 * \brief Appender that writes the log records to the Microsoft Debug Log
25 */
26
27
28//! Writes the log record to the windows debug log.
29/**
30 * \sa AbstractStringAppender::format()
31 */
32void OutputDebugAppender::append(const QDateTime& timeStamp,
33 Logger::LogLevel logLevel,
34 const char* file,
35 int line,
36 const char* function,
37 const QString& category,
38 const QString& message)
39{
40 QString s = formattedString(timeStamp, logLevel, file, line, function, category, message);
41 OutputDebugStringW((LPCWSTR) s.utf16());
42}
43
diff --git a/utils/rbutilqt/main.cpp b/utils/rbutilqt/main.cpp
new file mode 100644
index 0000000000..47c625b54d
--- /dev/null
+++ b/utils/rbutilqt/main.cpp
@@ -0,0 +1,112 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19
20#include <QCoreApplication>
21#include <QSettings>
22#include <QStyleFactory>
23#include "rbutilqt.h"
24#include "systrace.h"
25#include "Logger.h"
26#include "ConsoleAppender.h"
27#include "FileAppender.h"
28
29#ifdef STATIC
30#if QT_VERSION < 0x050400
31/*
32 * accessibility is no longer a plugin after 5.4.0:
33 * <https://bugreports.qt.io/browse/QTBUG-37957#comment-239189>
34 */
35#include <QtPlugin>
36Q_IMPORT_PLUGIN(AccessibleFactory)
37#endif
38#endif
39
40
41int main( int argc, char ** argv ) {
42#if QT_VERSION >= 0x050600
43 QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
44 QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
45#endif
46 QApplication app( argc, argv );
47#ifdef Q_OS_WIN
48 qApp->setStyle(QStyleFactory::create("Fusion"));
49#endif
50 ConsoleAppender* consoleAppender = new ConsoleAppender();
51 consoleAppender->setFormat("[%{file}:%{line} %{type}] %{message}\n");
52 cuteLoggerInstance()->registerAppender(consoleAppender);
53 SysTrace::rotateTrace();
54 QString tracefile = QDir::tempPath() + "/rbutil-trace.log";
55 FileAppender* fileAppender = new FileAppender();
56 fileAppender->setFormat("[%{file}:%{line} %{type}] %{message}\n");
57 fileAppender->setFileName(tracefile);
58 cuteLoggerInstance()->registerAppender(fileAppender);
59 LOG_INFO() << "Starting trace at" << QDateTime::currentDateTime().toString(Qt::ISODate);
60
61#if defined(Q_OS_MAC)
62 QDir dir(QApplication::applicationDirPath());
63 dir.cdUp();
64 dir.cd("plugins");
65 QApplication::addLibraryPath(dir.absolutePath());
66#endif
67 QString absolutePath = QCoreApplication::instance()->applicationDirPath();
68 // portable installation:
69 // check for a configuration file in the program folder.
70 QSettings *user;
71 if(QFileInfo(absolutePath + "/RockboxUtility.ini").isFile())
72 user = new QSettings(absolutePath + "/RockboxUtility.ini", QSettings::IniFormat, nullptr);
73 else user = new QSettings(QSettings::IniFormat, QSettings::UserScope, "rockbox.org", "RockboxUtility");
74
75 QString applang = QLocale::system().name();
76 QTranslator translator;
77 QTranslator qttrans;
78 // install translator
79 if(!user->value("lang", "").toString().isEmpty()) {
80 applang = user->value("lang", "").toString();
81 }
82 if(!applang.isEmpty()) {
83 if(!translator.load("rbutil_" + applang, absolutePath))
84 translator.load("rbutil_" + applang, ":/lang");
85 if(!qttrans.load("qt_" + applang,
86 QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
87 qttrans.load("qt_" + applang, ":/lang");
88
89 QLocale::setDefault(QLocale(applang));
90 }
91 delete user;
92 app.installTranslator(&translator);
93 app.installTranslator(&qttrans);
94 //: This string is used to indicate the writing direction. Translate it
95 //: to "RTL" (without quotes) for RTL languages. Anything else will get
96 //: treated as LTR language.
97 if(QObject::tr("LTR") == "RTL")
98 app.setLayoutDirection(Qt::RightToLeft);
99
100 // keep a list of installed translators. Needed to be able uninstalling them
101 // later again (in case of translation changes)
102 QList<QTranslator*> translators;
103 translators.append(&translator);
104 translators.append(&qttrans);
105 RbUtilQt window(nullptr);
106 RbUtilQt::translators = translators;
107 window.show();
108
109// app.connect( &app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()) );
110 return app.exec();
111
112}
diff --git a/utils/rbutilqt/mspack/COPYING.LIB b/utils/rbutilqt/mspack/COPYING.LIB
new file mode 100644
index 0000000000..b1e3f5a263
--- /dev/null
+++ b/utils/rbutilqt/mspack/COPYING.LIB
@@ -0,0 +1,504 @@
1 GNU LESSER GENERAL PUBLIC LICENSE
2 Version 2.1, February 1999
3
4 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6 Everyone is permitted to copy and distribute verbatim copies
7 of this license document, but changing it is not allowed.
8
9[This is the first released version of the Lesser GPL. It also counts
10 as the successor of the GNU Library Public License, version 2, hence
11 the version number 2.1.]
12
13 Preamble
14
15 The licenses for most software are designed to take away your
16freedom to share and change it. By contrast, the GNU General Public
17Licenses are intended to guarantee your freedom to share and change
18free software--to make sure the software is free for all its users.
19
20 This license, the Lesser General Public License, applies to some
21specially designated software packages--typically libraries--of the
22Free Software Foundation and other authors who decide to use it. You
23can use it too, but we suggest you first think carefully about whether
24this license or the ordinary General Public License is the better
25strategy to use in any particular case, based on the explanations below.
26
27 When we speak of free software, we are referring to freedom of use,
28not price. Our General Public Licenses are designed to make sure that
29you have the freedom to distribute copies of free software (and charge
30for this service if you wish); that you receive source code or can get
31it if you want it; that you can change the software and use pieces of
32it in new free programs; and that you are informed that you can do
33these things.
34
35 To protect your rights, we need to make restrictions that forbid
36distributors to deny you these rights or to ask you to surrender these
37rights. These restrictions translate to certain responsibilities for
38you if you distribute copies of the library or if you modify it.
39
40 For example, if you distribute copies of the library, whether gratis
41or for a fee, you must give the recipients all the rights that we gave
42you. You must make sure that they, too, receive or can get the source
43code. If you link other code with the library, you must provide
44complete object files to the recipients, so that they can relink them
45with the library after making changes to the library and recompiling
46it. And you must show them these terms so they know their rights.
47
48 We protect your rights with a two-step method: (1) we copyright the
49library, and (2) we offer you this license, which gives you legal
50permission to copy, distribute and/or modify the library.
51
52 To protect each distributor, we want to make it very clear that
53there is no warranty for the free library. Also, if the library is
54modified by someone else and passed on, the recipients should know
55that what they have is not the original version, so that the original
56author's reputation will not be affected by problems that might be
57introduced by others.
58
59 Finally, software patents pose a constant threat to the existence of
60any free program. We wish to make sure that a company cannot
61effectively restrict the users of a free program by obtaining a
62restrictive license from a patent holder. Therefore, we insist that
63any patent license obtained for a version of the library must be
64consistent with the full freedom of use specified in this license.
65
66 Most GNU software, including some libraries, is covered by the
67ordinary GNU General Public License. This license, the GNU Lesser
68General Public License, applies to certain designated libraries, and
69is quite different from the ordinary General Public License. We use
70this license for certain libraries in order to permit linking those
71libraries into non-free programs.
72
73 When a program is linked with a library, whether statically or using
74a shared library, the combination of the two is legally speaking a
75combined work, a derivative of the original library. The ordinary
76General Public License therefore permits such linking only if the
77entire combination fits its criteria of freedom. The Lesser General
78Public License permits more lax criteria for linking other code with
79the library.
80
81 We call this license the "Lesser" General Public License because it
82does Less to protect the user's freedom than the ordinary General
83Public License. It also provides other free software developers Less
84of an advantage over competing non-free programs. These disadvantages
85are the reason we use the ordinary General Public License for many
86libraries. However, the Lesser license provides advantages in certain
87special circumstances.
88
89 For example, on rare occasions, there may be a special need to
90encourage the widest possible use of a certain library, so that it becomes
91a de-facto standard. To achieve this, non-free programs must be
92allowed to use the library. A more frequent case is that a free
93library does the same job as widely used non-free libraries. In this
94case, there is little to gain by limiting the free library to free
95software only, so we use the Lesser General Public License.
96
97 In other cases, permission to use a particular library in non-free
98programs enables a greater number of people to use a large body of
99free software. For example, permission to use the GNU C Library in
100non-free programs enables many more people to use the whole GNU
101operating system, as well as its variant, the GNU/Linux operating
102system.
103
104 Although the Lesser General Public License is Less protective of the
105users' freedom, it does ensure that the user of a program that is
106linked with the Library has the freedom and the wherewithal to run
107that program using a modified version of the Library.
108
109 The precise terms and conditions for copying, distribution and
110modification follow. Pay close attention to the difference between a
111"work based on the library" and a "work that uses the library". The
112former contains code derived from the library, whereas the latter must
113be combined with the library in order to run.
114
115 GNU LESSER GENERAL PUBLIC LICENSE
116 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
117
118 0. This License Agreement applies to any software library or other
119program which contains a notice placed by the copyright holder or
120other authorized party saying it may be distributed under the terms of
121this Lesser General Public License (also called "this License").
122Each licensee is addressed as "you".
123
124 A "library" means a collection of software functions and/or data
125prepared so as to be conveniently linked with application programs
126(which use some of those functions and data) to form executables.
127
128 The "Library", below, refers to any such software library or work
129which has been distributed under these terms. A "work based on the
130Library" means either the Library or any derivative work under
131copyright law: that is to say, a work containing the Library or a
132portion of it, either verbatim or with modifications and/or translated
133straightforwardly into another language. (Hereinafter, translation is
134included without limitation in the term "modification".)
135
136 "Source code" for a work means the preferred form of the work for
137making modifications to it. For a library, complete source code means
138all the source code for all modules it contains, plus any associated
139interface definition files, plus the scripts used to control compilation
140and installation of the library.
141
142 Activities other than copying, distribution and modification are not
143covered by this License; they are outside its scope. The act of
144running a program using the Library is not restricted, and output from
145such a program is covered only if its contents constitute a work based
146on the Library (independent of the use of the Library in a tool for
147writing it). Whether that is true depends on what the Library does
148and what the program that uses the Library does.
149
150 1. You may copy and distribute verbatim copies of the Library's
151complete source code as you receive it, in any medium, provided that
152you conspicuously and appropriately publish on each copy an
153appropriate copyright notice and disclaimer of warranty; keep intact
154all the notices that refer to this License and to the absence of any
155warranty; and distribute a copy of this License along with the
156Library.
157
158 You may charge a fee for the physical act of transferring a copy,
159and you may at your option offer warranty protection in exchange for a
160fee.
161
162 2. You may modify your copy or copies of the Library or any portion
163of it, thus forming a work based on the Library, and copy and
164distribute such modifications or work under the terms of Section 1
165above, provided that you also meet all of these conditions:
166
167 a) The modified work must itself be a software library.
168
169 b) You must cause the files modified to carry prominent notices
170 stating that you changed the files and the date of any change.
171
172 c) You must cause the whole of the work to be licensed at no
173 charge to all third parties under the terms of this License.
174
175 d) If a facility in the modified Library refers to a function or a
176 table of data to be supplied by an application program that uses
177 the facility, other than as an argument passed when the facility
178 is invoked, then you must make a good faith effort to ensure that,
179 in the event an application does not supply such function or
180 table, the facility still operates, and performs whatever part of
181 its purpose remains meaningful.
182
183 (For example, a function in a library to compute square roots has
184 a purpose that is entirely well-defined independent of the
185 application. Therefore, Subsection 2d requires that any
186 application-supplied function or table used by this function must
187 be optional: if the application does not supply it, the square
188 root function must still compute square roots.)
189
190These requirements apply to the modified work as a whole. If
191identifiable sections of that work are not derived from the Library,
192and can be reasonably considered independent and separate works in
193themselves, then this License, and its terms, do not apply to those
194sections when you distribute them as separate works. But when you
195distribute the same sections as part of a whole which is a work based
196on the Library, the distribution of the whole must be on the terms of
197this License, whose permissions for other licensees extend to the
198entire whole, and thus to each and every part regardless of who wrote
199it.
200
201Thus, it is not the intent of this section to claim rights or contest
202your rights to work written entirely by you; rather, the intent is to
203exercise the right to control the distribution of derivative or
204collective works based on the Library.
205
206In addition, mere aggregation of another work not based on the Library
207with the Library (or with a work based on the Library) on a volume of
208a storage or distribution medium does not bring the other work under
209the scope of this License.
210
211 3. You may opt to apply the terms of the ordinary GNU General Public
212License instead of this License to a given copy of the Library. To do
213this, you must alter all the notices that refer to this License, so
214that they refer to the ordinary GNU General Public License, version 2,
215instead of to this License. (If a newer version than version 2 of the
216ordinary GNU General Public License has appeared, then you can specify
217that version instead if you wish.) Do not make any other change in
218these notices.
219
220 Once this change is made in a given copy, it is irreversible for
221that copy, so the ordinary GNU General Public License applies to all
222subsequent copies and derivative works made from that copy.
223
224 This option is useful when you wish to copy part of the code of
225the Library into a program that is not a library.
226
227 4. You may copy and distribute the Library (or a portion or
228derivative of it, under Section 2) in object code or executable form
229under the terms of Sections 1 and 2 above provided that you accompany
230it with the complete corresponding machine-readable source code, which
231must be distributed under the terms of Sections 1 and 2 above on a
232medium customarily used for software interchange.
233
234 If distribution of object code is made by offering access to copy
235from a designated place, then offering equivalent access to copy the
236source code from the same place satisfies the requirement to
237distribute the source code, even though third parties are not
238compelled to copy the source along with the object code.
239
240 5. A program that contains no derivative of any portion of the
241Library, but is designed to work with the Library by being compiled or
242linked with it, is called a "work that uses the Library". Such a
243work, in isolation, is not a derivative work of the Library, and
244therefore falls outside the scope of this License.
245
246 However, linking a "work that uses the Library" with the Library
247creates an executable that is a derivative of the Library (because it
248contains portions of the Library), rather than a "work that uses the
249library". The executable is therefore covered by this License.
250Section 6 states terms for distribution of such executables.
251
252 When a "work that uses the Library" uses material from a header file
253that is part of the Library, the object code for the work may be a
254derivative work of the Library even though the source code is not.
255Whether this is true is especially significant if the work can be
256linked without the Library, or if the work is itself a library. The
257threshold for this to be true is not precisely defined by law.
258
259 If such an object file uses only numerical parameters, data
260structure layouts and accessors, and small macros and small inline
261functions (ten lines or less in length), then the use of the object
262file is unrestricted, regardless of whether it is legally a derivative
263work. (Executables containing this object code plus portions of the
264Library will still fall under Section 6.)
265
266 Otherwise, if the work is a derivative of the Library, you may
267distribute the object code for the work under the terms of Section 6.
268Any executables containing that work also fall under Section 6,
269whether or not they are linked directly with the Library itself.
270
271 6. As an exception to the Sections above, you may also combine or
272link a "work that uses the Library" with the Library to produce a
273work containing portions of the Library, and distribute that work
274under terms of your choice, provided that the terms permit
275modification of the work for the customer's own use and reverse
276engineering for debugging such modifications.
277
278 You must give prominent notice with each copy of the work that the
279Library is used in it and that the Library and its use are covered by
280this License. You must supply a copy of this License. If the work
281during execution displays copyright notices, you must include the
282copyright notice for the Library among them, as well as a reference
283directing the user to the copy of this License. Also, you must do one
284of these things:
285
286 a) Accompany the work with the complete corresponding
287 machine-readable source code for the Library including whatever
288 changes were used in the work (which must be distributed under
289 Sections 1 and 2 above); and, if the work is an executable linked
290 with the Library, with the complete machine-readable "work that
291 uses the Library", as object code and/or source code, so that the
292 user can modify the Library and then relink to produce a modified
293 executable containing the modified Library. (It is understood
294 that the user who changes the contents of definitions files in the
295 Library will not necessarily be able to recompile the application
296 to use the modified definitions.)
297
298 b) Use a suitable shared library mechanism for linking with the
299 Library. A suitable mechanism is one that (1) uses at run time a
300 copy of the library already present on the user's computer system,
301 rather than copying library functions into the executable, and (2)
302 will operate properly with a modified version of the library, if
303 the user installs one, as long as the modified version is
304 interface-compatible with the version that the work was made with.
305
306 c) Accompany the work with a written offer, valid for at
307 least three years, to give the same user the materials
308 specified in Subsection 6a, above, for a charge no more
309 than the cost of performing this distribution.
310
311 d) If distribution of the work is made by offering access to copy
312 from a designated place, offer equivalent access to copy the above
313 specified materials from the same place.
314
315 e) Verify that the user has already received a copy of these
316 materials or that you have already sent this user a copy.
317
318 For an executable, the required form of the "work that uses the
319Library" must include any data and utility programs needed for
320reproducing the executable from it. However, as a special exception,
321the materials to be distributed need not include anything that is
322normally distributed (in either source or binary form) with the major
323components (compiler, kernel, and so on) of the operating system on
324which the executable runs, unless that component itself accompanies
325the executable.
326
327 It may happen that this requirement contradicts the license
328restrictions of other proprietary libraries that do not normally
329accompany the operating system. Such a contradiction means you cannot
330use both them and the Library together in an executable that you
331distribute.
332
333 7. You may place library facilities that are a work based on the
334Library side-by-side in a single library together with other library
335facilities not covered by this License, and distribute such a combined
336library, provided that the separate distribution of the work based on
337the Library and of the other library facilities is otherwise
338permitted, and provided that you do these two things:
339
340 a) Accompany the combined library with a copy of the same work
341 based on the Library, uncombined with any other library
342 facilities. This must be distributed under the terms of the
343 Sections above.
344
345 b) Give prominent notice with the combined library of the fact
346 that part of it is a work based on the Library, and explaining
347 where to find the accompanying uncombined form of the same work.
348
349 8. You may not copy, modify, sublicense, link with, or distribute
350the Library except as expressly provided under this License. Any
351attempt otherwise to copy, modify, sublicense, link with, or
352distribute the Library is void, and will automatically terminate your
353rights under this License. However, parties who have received copies,
354or rights, from you under this License will not have their licenses
355terminated so long as such parties remain in full compliance.
356
357 9. You are not required to accept this License, since you have not
358signed it. However, nothing else grants you permission to modify or
359distribute the Library or its derivative works. These actions are
360prohibited by law if you do not accept this License. Therefore, by
361modifying or distributing the Library (or any work based on the
362Library), you indicate your acceptance of this License to do so, and
363all its terms and conditions for copying, distributing or modifying
364the Library or works based on it.
365
366 10. Each time you redistribute the Library (or any work based on the
367Library), the recipient automatically receives a license from the
368original licensor to copy, distribute, link with or modify the Library
369subject to these terms and conditions. You may not impose any further
370restrictions on the recipients' exercise of the rights granted herein.
371You are not responsible for enforcing compliance by third parties with
372this License.
373
374 11. If, as a consequence of a court judgment or allegation of patent
375infringement or for any other reason (not limited to patent issues),
376conditions are imposed on you (whether by court order, agreement or
377otherwise) that contradict the conditions of this License, they do not
378excuse you from the conditions of this License. If you cannot
379distribute so as to satisfy simultaneously your obligations under this
380License and any other pertinent obligations, then as a consequence you
381may not distribute the Library at all. For example, if a patent
382license would not permit royalty-free redistribution of the Library by
383all those who receive copies directly or indirectly through you, then
384the only way you could satisfy both it and this License would be to
385refrain entirely from distribution of the Library.
386
387If any portion of this section is held invalid or unenforceable under any
388particular circumstance, the balance of the section is intended to apply,
389and the section as a whole is intended to apply in other circumstances.
390
391It is not the purpose of this section to induce you to infringe any
392patents or other property right claims or to contest validity of any
393such claims; this section has the sole purpose of protecting the
394integrity of the free software distribution system which is
395implemented by public license practices. Many people have made
396generous contributions to the wide range of software distributed
397through that system in reliance on consistent application of that
398system; it is up to the author/donor to decide if he or she is willing
399to distribute software through any other system and a licensee cannot
400impose that choice.
401
402This section is intended to make thoroughly clear what is believed to
403be a consequence of the rest of this License.
404
405 12. If the distribution and/or use of the Library is restricted in
406certain countries either by patents or by copyrighted interfaces, the
407original copyright holder who places the Library under this License may add
408an explicit geographical distribution limitation excluding those countries,
409so that distribution is permitted only in or among countries not thus
410excluded. In such case, this License incorporates the limitation as if
411written in the body of this License.
412
413 13. The Free Software Foundation may publish revised and/or new
414versions of the Lesser General Public License from time to time.
415Such new versions will be similar in spirit to the present version,
416but may differ in detail to address new problems or concerns.
417
418Each version is given a distinguishing version number. If the Library
419specifies a version number of this License which applies to it and
420"any later version", you have the option of following the terms and
421conditions either of that version or of any later version published by
422the Free Software Foundation. If the Library does not specify a
423license version number, you may choose any version ever published by
424the Free Software Foundation.
425
426 14. If you wish to incorporate parts of the Library into other free
427programs whose distribution conditions are incompatible with these,
428write to the author to ask for permission. For software which is
429copyrighted by the Free Software Foundation, write to the Free
430Software Foundation; we sometimes make exceptions for this. Our
431decision will be guided by the two goals of preserving the free status
432of all derivatives of our free software and of promoting the sharing
433and reuse of software generally.
434
435 NO WARRANTY
436
437 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
438WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
439EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
440OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
441KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
442IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
444LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
445THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
446
447 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
448WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
449AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
450FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
451CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
452LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
453RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
454FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
455SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
456DAMAGES.
457
458 END OF TERMS AND CONDITIONS
459
460 How to Apply These Terms to Your New Libraries
461
462 If you develop a new library, and you want it to be of the greatest
463possible use to the public, we recommend making it free software that
464everyone can redistribute and change. You can do so by permitting
465redistribution under these terms (or, alternatively, under the terms of the
466ordinary General Public License).
467
468 To apply these terms, attach the following notices to the library. It is
469safest to attach them to the start of each source file to most effectively
470convey the exclusion of warranty; and each file should have at least the
471"copyright" line and a pointer to where the full notice is found.
472
473 <one line to give the library's name and a brief idea of what it does.>
474 Copyright (C) <year> <name of author>
475
476 This library is free software; you can redistribute it and/or
477 modify it under the terms of the GNU Lesser General Public
478 License as published by the Free Software Foundation; either
479 version 2.1 of the License, or (at your option) any later version.
480
481 This library is distributed in the hope that it will be useful,
482 but WITHOUT ANY WARRANTY; without even the implied warranty of
483 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
484 Lesser General Public License for more details.
485
486 You should have received a copy of the GNU Lesser General Public
487 License along with this library; if not, write to the Free Software
488 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
489
490Also add information on how to contact you by electronic and paper mail.
491
492You should also get your employer (if you work as a programmer) or your
493school, if any, to sign a "copyright disclaimer" for the library, if
494necessary. Here is a sample; alter the names:
495
496 Yoyodyne, Inc., hereby disclaims all copyright interest in the
497 library `Frob' (a library for tweaking knobs) written by James Random Hacker.
498
499 <signature of Ty Coon>, 1 April 1990
500 Ty Coon, President of Vice
501
502That's all there is to it!
503
504
diff --git a/utils/rbutilqt/mspack/README.ROCKBOX b/utils/rbutilqt/mspack/README.ROCKBOX
new file mode 100644
index 0000000000..220691af2c
--- /dev/null
+++ b/utils/rbutilqt/mspack/README.ROCKBOX
@@ -0,0 +1,6 @@
1This folder contains the mspack project for MS files compression/decompression.
2These files are distributed under the LGPL.
3
4The source files have been last synced with libmspack-0.10.1alpha
5https://www.cabextract.org.uk/libmspack/ on June 8, 2020
6
diff --git a/utils/rbutilqt/mspack/cab.h b/utils/rbutilqt/mspack/cab.h
new file mode 100644
index 0000000000..79d9951252
--- /dev/null
+++ b/utils/rbutilqt/mspack/cab.h
@@ -0,0 +1,140 @@
1/* This file is part of libmspack.
2 * (C) 2003-2018 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10#ifndef MSPACK_CAB_H
11#define MSPACK_CAB_H 1
12
13/* generic CAB definitions */
14
15/* structure offsets */
16#define cfhead_Signature (0x00)
17#define cfhead_CabinetSize (0x08)
18#define cfhead_FileOffset (0x10)
19#define cfhead_MinorVersion (0x18)
20#define cfhead_MajorVersion (0x19)
21#define cfhead_NumFolders (0x1A)
22#define cfhead_NumFiles (0x1C)
23#define cfhead_Flags (0x1E)
24#define cfhead_SetID (0x20)
25#define cfhead_CabinetIndex (0x22)
26#define cfhead_SIZEOF (0x24)
27#define cfheadext_HeaderReserved (0x00)
28#define cfheadext_FolderReserved (0x02)
29#define cfheadext_DataReserved (0x03)
30#define cfheadext_SIZEOF (0x04)
31#define cffold_DataOffset (0x00)
32#define cffold_NumBlocks (0x04)
33#define cffold_CompType (0x06)
34#define cffold_SIZEOF (0x08)
35#define cffile_UncompressedSize (0x00)
36#define cffile_FolderOffset (0x04)
37#define cffile_FolderIndex (0x08)
38#define cffile_Date (0x0A)
39#define cffile_Time (0x0C)
40#define cffile_Attribs (0x0E)
41#define cffile_SIZEOF (0x10)
42#define cfdata_CheckSum (0x00)
43#define cfdata_CompressedSize (0x04)
44#define cfdata_UncompressedSize (0x06)
45#define cfdata_SIZEOF (0x08)
46
47/* flags */
48#define cffoldCOMPTYPE_MASK (0x000f)
49#define cffoldCOMPTYPE_NONE (0x0000)
50#define cffoldCOMPTYPE_MSZIP (0x0001)
51#define cffoldCOMPTYPE_QUANTUM (0x0002)
52#define cffoldCOMPTYPE_LZX (0x0003)
53#define cfheadPREV_CABINET (0x0001)
54#define cfheadNEXT_CABINET (0x0002)
55#define cfheadRESERVE_PRESENT (0x0004)
56#define cffileCONTINUED_FROM_PREV (0xFFFD)
57#define cffileCONTINUED_TO_NEXT (0xFFFE)
58#define cffileCONTINUED_PREV_AND_NEXT (0xFFFF)
59
60/* CAB data blocks are <= 32768 bytes in uncompressed form. Uncompressed
61 * blocks have zero growth. MSZIP guarantees that it won't grow above
62 * uncompressed size by more than 12 bytes. LZX guarantees it won't grow
63 * more than 6144 bytes. Quantum has no documentation, but the largest
64 * block seen in the wild is 337 bytes above uncompressed size.
65 */
66#define CAB_BLOCKMAX (32768)
67#define CAB_INPUTMAX (CAB_BLOCKMAX+6144)
68
69/* input buffer needs to be CAB_INPUTMAX + 1 byte to allow for max-sized block
70 * plus 1 trailer byte added by cabd_sys_read_block() for Quantum alignment.
71 *
72 * When MSCABD_PARAM_SALVAGE is set, block size is not checked so can be
73 * up to 65535 bytes, so max input buffer size needed is 65535 + 1
74 */
75#define CAB_INPUTMAX_SALVAGE (65535)
76#define CAB_INPUTBUF (CAB_INPUTMAX_SALVAGE + 1)
77
78/* There are no more than 65535 data blocks per folder, so a folder cannot
79 * be more than 32768*65535 bytes in length. As files cannot span more than
80 * one folder, this is also their max offset, length and offset+length limit.
81 */
82#define CAB_FOLDERMAX (65535)
83#define CAB_LENGTHMAX (CAB_BLOCKMAX * CAB_FOLDERMAX)
84
85/* CAB compression definitions */
86
87struct mscab_compressor_p {
88 struct mscab_compressor base;
89 struct mspack_system *system;
90 /* todo */
91};
92
93/* CAB decompression definitions */
94
95struct mscabd_decompress_state {
96 struct mscabd_folder_p *folder; /* current folder we're extracting from */
97 struct mscabd_folder_data *data; /* current folder split we're in */
98 unsigned int offset; /* uncompressed offset within folder */
99 unsigned int block; /* which block are we decompressing? */
100 off_t outlen; /* cumulative sum of block output sizes */
101 struct mspack_system sys; /* special I/O code for decompressor */
102 int comp_type; /* type of compression used by folder */
103 int (*decompress)(void *, off_t); /* decompressor code */
104 void *state; /* decompressor state */
105 struct mscabd_cabinet_p *incab; /* cabinet where input data comes from */
106 struct mspack_file *infh; /* input file handle */
107 struct mspack_file *outfh; /* output file handle */
108 unsigned char *i_ptr, *i_end; /* input data consumed, end */
109 unsigned char input[CAB_INPUTBUF]; /* one input block of data */
110};
111
112struct mscab_decompressor_p {
113 struct mscab_decompressor base;
114 struct mscabd_decompress_state *d;
115 struct mspack_system *system;
116 int buf_size, searchbuf_size, fix_mszip, salvage; /* params */
117 int error, read_error;
118};
119
120struct mscabd_cabinet_p {
121 struct mscabd_cabinet base;
122 off_t blocks_off; /* offset to data blocks */
123 int block_resv; /* reserved space in data blocks */
124};
125
126/* there is one of these for every cabinet a folder spans */
127struct mscabd_folder_data {
128 struct mscabd_folder_data *next;
129 struct mscabd_cabinet_p *cab; /* cabinet file of this folder span */
130 off_t offset; /* cabinet offset of first datablock */
131};
132
133struct mscabd_folder_p {
134 struct mscabd_folder base;
135 struct mscabd_folder_data data; /* where are the data blocks? */
136 struct mscabd_file *merge_prev; /* first file needing backwards merge */
137 struct mscabd_file *merge_next; /* first file needing forwards merge */
138};
139
140#endif
diff --git a/utils/rbutilqt/mspack/cabc.c b/utils/rbutilqt/mspack/cabc.c
new file mode 100644
index 0000000000..eb85011056
--- /dev/null
+++ b/utils/rbutilqt/mspack/cabc.c
@@ -0,0 +1,24 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10/* CAB compression implementation */
11
12#include "system-mspack.h"
13#include "cab.h"
14
15struct mscab_compressor *
16 mspack_create_cab_compressor(struct mspack_system *sys)
17{
18 /* todo */
19 return NULL;
20}
21
22void mspack_destroy_cab_compressor(struct mscab_compressor *self) {
23 /* todo */
24}
diff --git a/utils/rbutilqt/mspack/cabd.c b/utils/rbutilqt/mspack/cabd.c
new file mode 100644
index 0000000000..ae66769b24
--- /dev/null
+++ b/utils/rbutilqt/mspack/cabd.c
@@ -0,0 +1,1508 @@
1/* This file is part of libmspack.
2 * (C) 2003-2018 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10/* Cabinet (.CAB) files are a form of file archive. Each cabinet contains
11 * "folders", which are compressed spans of data. Each cabinet has
12 * "files", whose metadata is in the cabinet header, but whose actual data
13 * is stored compressed in one of the "folders". Cabinets can span more
14 * than one physical file on disk, in which case they are a "cabinet set",
15 * and usually the last folder of each cabinet extends into the next
16 * cabinet.
17 *
18 * For a complete description of the format, see the MSDN site:
19 * http://msdn.microsoft.com/en-us/library/bb267310.aspx
20 */
21
22/* CAB decompression implementation */
23
24#include "system-mspack.h"
25#include "cab.h"
26#include "mszip.h"
27#include "lzx.h"
28#include "qtm.h"
29
30/* Notes on compliance with cabinet specification:
31 *
32 * One of the main changes between cabextract 0.6 and libmspack's cab
33 * decompressor is the move from block-oriented decompression to
34 * stream-oriented decompression.
35 *
36 * cabextract would read one data block from disk, decompress it with the
37 * appropriate method, then write the decompressed data. The CAB
38 * specification is specifically designed to work like this, as it ensures
39 * compression matches do not span the maximum decompressed block size
40 * limit of 32kb.
41 *
42 * However, the compression algorithms used are stream oriented, with
43 * specific hacks added to them to enforce the "individual 32kb blocks"
44 * rule in CABs. In other file formats, they do not have this limitation.
45 *
46 * In order to make more generalised decompressors, libmspack's CAB
47 * decompressor has moved from being block-oriented to more stream
48 * oriented. This also makes decompression slightly faster.
49 *
50 * However, this leads to incompliance with the CAB specification. The
51 * CAB controller can no longer ensure each block of input given to the
52 * decompressors is matched with their output. The "decompressed size" of
53 * each individual block is thrown away.
54 *
55 * Each CAB block is supposed to be seen as individually compressed. This
56 * means each consecutive data block can have completely different
57 * "uncompressed" sizes, ranging from 1 to 32768 bytes. However, in
58 * reality, all data blocks in a folder decompress to exactly 32768 bytes,
59 * excepting the final block.
60 *
61 * Given this situation, the decompression algorithms are designed to
62 * realign their input bitstreams on 32768 output-byte boundaries, and
63 * various other special cases have been made. libmspack will not
64 * correctly decompress LZX or Quantum compressed folders where the blocks
65 * do not follow this "32768 bytes until last block" pattern. It could be
66 * implemented if needed, but hopefully this is not necessary -- it has
67 * not been seen in over 3Gb of CAB archives.
68 */
69
70/* prototypes */
71static struct mscabd_cabinet * cabd_open(
72 struct mscab_decompressor *base, const char *filename);
73static void cabd_close(
74 struct mscab_decompressor *base, struct mscabd_cabinet *origcab);
75static int cabd_read_headers(
76 struct mspack_system *sys, struct mspack_file *fh,
77 struct mscabd_cabinet_p *cab, off_t offset, int salvage, int quiet);
78static char *cabd_read_string(
79 struct mspack_system *sys, struct mspack_file *fh, int *error);
80
81static struct mscabd_cabinet *cabd_search(
82 struct mscab_decompressor *base, const char *filename);
83static int cabd_find(
84 struct mscab_decompressor_p *self, unsigned char *buf,
85 struct mspack_file *fh, const char *filename, off_t flen,
86 off_t *firstlen, struct mscabd_cabinet_p **firstcab);
87
88static int cabd_prepend(
89 struct mscab_decompressor *base, struct mscabd_cabinet *cab,
90 struct mscabd_cabinet *prevcab);
91static int cabd_append(
92 struct mscab_decompressor *base, struct mscabd_cabinet *cab,
93 struct mscabd_cabinet *nextcab);
94static int cabd_merge(
95 struct mscab_decompressor *base, struct mscabd_cabinet *lcab,
96 struct mscabd_cabinet *rcab);
97static int cabd_can_merge_folders(
98 struct mspack_system *sys, struct mscabd_folder_p *lfol,
99 struct mscabd_folder_p *rfol);
100
101static int cabd_extract(
102 struct mscab_decompressor *base, struct mscabd_file *file,
103 const char *filename);
104static int cabd_init_decomp(
105 struct mscab_decompressor_p *self, unsigned int ct);
106static void cabd_free_decomp(
107 struct mscab_decompressor_p *self);
108static int cabd_sys_read(
109 struct mspack_file *file, void *buffer, int bytes);
110static int cabd_sys_write(
111 struct mspack_file *file, void *buffer, int bytes);
112static int cabd_sys_read_block(
113 struct mspack_system *sys, struct mscabd_decompress_state *d, int *out,
114 int ignore_cksum, int ignore_blocksize);
115static unsigned int cabd_checksum(
116 unsigned char *data, unsigned int bytes, unsigned int cksum);
117static struct noned_state *noned_init(
118 struct mspack_system *sys, struct mspack_file *in, struct mspack_file *out,
119 int bufsize);
120
121static int noned_decompress(
122 struct noned_state *s, off_t bytes);
123static void noned_free(
124 struct noned_state *state);
125
126static int cabd_param(
127 struct mscab_decompressor *base, int param, int value);
128
129static int cabd_error(
130 struct mscab_decompressor *base);
131
132
133/***************************************
134 * MSPACK_CREATE_CAB_DECOMPRESSOR
135 ***************************************
136 * constructor
137 */
138struct mscab_decompressor *
139 mspack_create_cab_decompressor(struct mspack_system *sys)
140{
141 struct mscab_decompressor_p *self = NULL;
142
143 if (!sys) sys = mspack_default_system;
144 if (!mspack_valid_system(sys)) return NULL;
145
146 if ((self = (struct mscab_decompressor_p *) sys->alloc(sys, sizeof(struct mscab_decompressor_p)))) {
147 self->base.open = &cabd_open;
148 self->base.close = &cabd_close;
149 self->base.search = &cabd_search;
150 self->base.extract = &cabd_extract;
151 self->base.prepend = &cabd_prepend;
152 self->base.append = &cabd_append;
153 self->base.set_param = &cabd_param;
154 self->base.last_error = &cabd_error;
155 self->system = sys;
156 self->d = NULL;
157 self->error = MSPACK_ERR_OK;
158
159 self->searchbuf_size = 32768;
160 self->fix_mszip = 0;
161 self->buf_size = 4096;
162 self->salvage = 0;
163 }
164 return (struct mscab_decompressor *) self;
165}
166
167/***************************************
168 * MSPACK_DESTROY_CAB_DECOMPRESSOR
169 ***************************************
170 * destructor
171 */
172void mspack_destroy_cab_decompressor(struct mscab_decompressor *base) {
173 struct mscab_decompressor_p *self = (struct mscab_decompressor_p *) base;
174 if (self) {
175 struct mspack_system *sys = self->system;
176 if (self->d) {
177 if (self->d->infh) sys->close(self->d->infh);
178 cabd_free_decomp(self);
179 sys->free(self->d);
180 }
181 sys->free(self);
182 }
183}
184
185
186/***************************************
187 * CABD_OPEN
188 ***************************************
189 * opens a file and tries to read it as a cabinet file
190 */
191static struct mscabd_cabinet *cabd_open(struct mscab_decompressor *base,
192 const char *filename)
193{
194 struct mscab_decompressor_p *self = (struct mscab_decompressor_p *) base;
195 struct mscabd_cabinet_p *cab = NULL;
196 struct mspack_system *sys;
197 struct mspack_file *fh;
198 int error;
199
200 if (!base) return NULL;
201 sys = self->system;
202
203 if ((fh = sys->open(sys, filename, MSPACK_SYS_OPEN_READ))) {
204 if ((cab = (struct mscabd_cabinet_p *) sys->alloc(sys, sizeof(struct mscabd_cabinet_p)))) {
205 cab->base.filename = filename;
206 error = cabd_read_headers(sys, fh, cab, (off_t) 0, self->salvage, 0);
207 if (error) {
208 cabd_close(base, (struct mscabd_cabinet *) cab);
209 cab = NULL;
210 }
211 self->error = error;
212 }
213 else {
214 self->error = MSPACK_ERR_NOMEMORY;
215 }
216 sys->close(fh);
217 }
218 else {
219 self->error = MSPACK_ERR_OPEN;
220 }
221 return (struct mscabd_cabinet *) cab;
222}
223
224/***************************************
225 * CABD_CLOSE
226 ***************************************
227 * frees all memory associated with a given mscabd_cabinet.
228 */
229static void cabd_close(struct mscab_decompressor *base,
230 struct mscabd_cabinet *origcab)
231{
232 struct mscab_decompressor_p *self = (struct mscab_decompressor_p *) base;
233 struct mscabd_folder_data *dat, *ndat;
234 struct mscabd_cabinet *cab, *ncab;
235 struct mscabd_folder *fol, *nfol;
236 struct mscabd_file *fi, *nfi;
237 struct mspack_system *sys;
238
239 if (!base) return;
240 sys = self->system;
241
242 self->error = MSPACK_ERR_OK;
243
244 while (origcab) {
245 /* free files */
246 for (fi = origcab->files; fi; fi = nfi) {
247 nfi = fi->next;
248 sys->free(fi->filename);
249 sys->free(fi);
250 }
251
252 /* free folders */
253 for (fol = origcab->folders; fol; fol = nfol) {
254 nfol = fol->next;
255
256 /* free folder decompression state if it has been decompressed */
257 if (self->d && (self->d->folder == (struct mscabd_folder_p *) fol)) {
258 if (self->d->infh) sys->close(self->d->infh);
259 cabd_free_decomp(self);
260 sys->free(self->d);
261 self->d = NULL;
262 }
263
264 /* free folder data segments */
265 for (dat = ((struct mscabd_folder_p *)fol)->data.next; dat; dat = ndat) {
266 ndat = dat->next;
267 sys->free(dat);
268 }
269 sys->free(fol);
270 }
271
272 /* free predecessor cabinets (and the original cabinet's strings) */
273 for (cab = origcab; cab; cab = ncab) {
274 ncab = cab->prevcab;
275 sys->free(cab->prevname);
276 sys->free(cab->nextname);
277 sys->free(cab->previnfo);
278 sys->free(cab->nextinfo);
279 if (cab != origcab) sys->free(cab);
280 }
281
282 /* free successor cabinets */
283 for (cab = origcab->nextcab; cab; cab = ncab) {
284 ncab = cab->nextcab;
285 sys->free(cab->prevname);
286 sys->free(cab->nextname);
287 sys->free(cab->previnfo);
288 sys->free(cab->nextinfo);
289 sys->free(cab);
290 }
291
292 /* free actual cabinet structure */
293 cab = origcab->next;
294 sys->free(origcab);
295
296 /* repeat full procedure again with the cab->next pointer (if set) */
297 origcab = cab;
298 }
299}
300
301/***************************************
302 * CABD_READ_HEADERS
303 ***************************************
304 * reads the cabinet file header, folder list and file list.
305 * fills out a pre-existing mscabd_cabinet structure, allocates memory
306 * for folders and files as necessary
307 */
308static int cabd_read_headers(struct mspack_system *sys,
309 struct mspack_file *fh,
310 struct mscabd_cabinet_p *cab,
311 off_t offset, int salvage, int quiet)
312{
313 int num_folders, num_files, folder_resv, i, x, err, fidx;
314 struct mscabd_folder_p *fol, *linkfol = NULL;
315 struct mscabd_file *file, *linkfile = NULL;
316 unsigned char buf[64];
317
318 /* initialise pointers */
319 cab->base.next = NULL;
320 cab->base.files = NULL;
321 cab->base.folders = NULL;
322 cab->base.prevcab = cab->base.nextcab = NULL;
323 cab->base.prevname = cab->base.nextname = NULL;
324 cab->base.previnfo = cab->base.nextinfo = NULL;
325
326 cab->base.base_offset = offset;
327
328 /* seek to CFHEADER */
329 if (sys->seek(fh, offset, MSPACK_SYS_SEEK_START)) {
330 return MSPACK_ERR_SEEK;
331 }
332
333 /* read in the CFHEADER */
334 if (sys->read(fh, &buf[0], cfhead_SIZEOF) != cfhead_SIZEOF) {
335 return MSPACK_ERR_READ;
336 }
337
338 /* check for "MSCF" signature */
339 if (EndGetI32(&buf[cfhead_Signature]) != 0x4643534D) {
340 return MSPACK_ERR_SIGNATURE;
341 }
342
343 /* some basic header fields */
344 cab->base.length = EndGetI32(&buf[cfhead_CabinetSize]);
345 cab->base.set_id = EndGetI16(&buf[cfhead_SetID]);
346 cab->base.set_index = EndGetI16(&buf[cfhead_CabinetIndex]);
347
348 /* get the number of folders */
349 num_folders = EndGetI16(&buf[cfhead_NumFolders]);
350 if (num_folders == 0) {
351 if (!quiet) sys->message(fh, "no folders in cabinet.");
352 return MSPACK_ERR_DATAFORMAT;
353 }
354
355 /* get the number of files */
356 num_files = EndGetI16(&buf[cfhead_NumFiles]);
357 if (num_files == 0) {
358 if (!quiet) sys->message(fh, "no files in cabinet.");
359 return MSPACK_ERR_DATAFORMAT;
360 }
361
362 /* check cabinet version */
363 if ((buf[cfhead_MajorVersion] != 1) && (buf[cfhead_MinorVersion] != 3)) {
364 if (!quiet) sys->message(fh, "WARNING; cabinet version is not 1.3");
365 }
366
367 /* read the reserved-sizes part of header, if present */
368 cab->base.flags = EndGetI16(&buf[cfhead_Flags]);
369
370 if (cab->base.flags & cfheadRESERVE_PRESENT) {
371 if (sys->read(fh, &buf[0], cfheadext_SIZEOF) != cfheadext_SIZEOF) {
372 return MSPACK_ERR_READ;
373 }
374 cab->base.header_resv = EndGetI16(&buf[cfheadext_HeaderReserved]);
375 folder_resv = buf[cfheadext_FolderReserved];
376 cab->block_resv = buf[cfheadext_DataReserved];
377
378 if (cab->base.header_resv > 60000) {
379 if (!quiet) sys->message(fh, "WARNING; reserved header > 60000.");
380 }
381
382 /* skip the reserved header */
383 if (cab->base.header_resv) {
384 if (sys->seek(fh, (off_t) cab->base.header_resv, MSPACK_SYS_SEEK_CUR)) {
385 return MSPACK_ERR_SEEK;
386 }
387 }
388 }
389 else {
390 cab->base.header_resv = 0;
391 folder_resv = 0;
392 cab->block_resv = 0;
393 }
394
395 /* read name and info of preceeding cabinet in set, if present */
396 if (cab->base.flags & cfheadPREV_CABINET) {
397 cab->base.prevname = cabd_read_string(sys, fh, &err);
398 if (err) return err;
399 cab->base.previnfo = cabd_read_string(sys, fh, &err);
400 if (err) return err;
401 }
402
403 /* read name and info of next cabinet in set, if present */
404 if (cab->base.flags & cfheadNEXT_CABINET) {
405 cab->base.nextname = cabd_read_string(sys, fh, &err);
406 if (err) return err;
407 cab->base.nextinfo = cabd_read_string(sys, fh, &err);
408 if (err) return err;
409 }
410
411 /* read folders */
412 for (i = 0; i < num_folders; i++) {
413 if (sys->read(fh, &buf[0], cffold_SIZEOF) != cffold_SIZEOF) {
414 return MSPACK_ERR_READ;
415 }
416 if (folder_resv) {
417 if (sys->seek(fh, (off_t) folder_resv, MSPACK_SYS_SEEK_CUR)) {
418 return MSPACK_ERR_SEEK;
419 }
420 }
421
422 if (!(fol = (struct mscabd_folder_p *) sys->alloc(sys, sizeof(struct mscabd_folder_p)))) {
423 return MSPACK_ERR_NOMEMORY;
424 }
425 fol->base.next = NULL;
426 fol->base.comp_type = EndGetI16(&buf[cffold_CompType]);
427 fol->base.num_blocks = EndGetI16(&buf[cffold_NumBlocks]);
428 fol->data.next = NULL;
429 fol->data.cab = (struct mscabd_cabinet_p *) cab;
430 fol->data.offset = offset + (off_t)
431 ( (unsigned int) EndGetI32(&buf[cffold_DataOffset]) );
432 fol->merge_prev = NULL;
433 fol->merge_next = NULL;
434
435 /* link folder into list of folders */
436 if (!linkfol) cab->base.folders = (struct mscabd_folder *) fol;
437 else linkfol->base.next = (struct mscabd_folder *) fol;
438 linkfol = fol;
439 }
440
441 /* read files */
442 for (i = 0; i < num_files; i++) {
443 if (sys->read(fh, &buf[0], cffile_SIZEOF) != cffile_SIZEOF) {
444 return MSPACK_ERR_READ;
445 }
446
447 if (!(file = (struct mscabd_file *) sys->alloc(sys, sizeof(struct mscabd_file)))) {
448 return MSPACK_ERR_NOMEMORY;
449 }
450
451 file->next = NULL;
452 file->length = EndGetI32(&buf[cffile_UncompressedSize]);
453 file->attribs = EndGetI16(&buf[cffile_Attribs]);
454 file->offset = EndGetI32(&buf[cffile_FolderOffset]);
455
456 /* set folder pointer */
457 fidx = EndGetI16(&buf[cffile_FolderIndex]);
458 if (fidx < cffileCONTINUED_FROM_PREV) {
459 /* normal folder index; count up to the correct folder */
460 if (fidx < num_folders) {
461 struct mscabd_folder *ifol = cab->base.folders;
462 while (fidx--) if (ifol) ifol = ifol->next;
463 file->folder = ifol;
464 }
465 else {
466 D(("invalid folder index"))
467 file->folder = NULL;
468 }
469 }
470 else {
471 /* either CONTINUED_TO_NEXT, CONTINUED_FROM_PREV or
472 * CONTINUED_PREV_AND_NEXT */
473 if ((fidx == cffileCONTINUED_TO_NEXT) ||
474 (fidx == cffileCONTINUED_PREV_AND_NEXT))
475 {
476 /* get last folder */
477 struct mscabd_folder *ifol = cab->base.folders;
478 while (ifol->next) ifol = ifol->next;
479 file->folder = ifol;
480
481 /* set "merge next" pointer */
482 fol = (struct mscabd_folder_p *) ifol;
483 if (!fol->merge_next) fol->merge_next = file;
484 }
485
486 if ((fidx == cffileCONTINUED_FROM_PREV) ||
487 (fidx == cffileCONTINUED_PREV_AND_NEXT))
488 {
489 /* get first folder */
490 file->folder = cab->base.folders;
491
492 /* set "merge prev" pointer */
493 fol = (struct mscabd_folder_p *) file->folder;
494 if (!fol->merge_prev) fol->merge_prev = file;
495 }
496 }
497
498 /* get time */
499 x = EndGetI16(&buf[cffile_Time]);
500 file->time_h = x >> 11;
501 file->time_m = (x >> 5) & 0x3F;
502 file->time_s = (x << 1) & 0x3E;
503
504 /* get date */
505 x = EndGetI16(&buf[cffile_Date]);
506 file->date_d = x & 0x1F;
507 file->date_m = (x >> 5) & 0xF;
508 file->date_y = (x >> 9) + 1980;
509
510 /* get filename */
511 file->filename = cabd_read_string(sys, fh, &err);
512
513 /* if folder index or filename are bad, either skip it or fail */
514 if (err || !file->folder) {
515 sys->free(file->filename);
516 sys->free(file);
517 if (salvage) continue;
518 return err ? err : MSPACK_ERR_DATAFORMAT;
519 }
520
521 /* link file entry into file list */
522 if (!linkfile) cab->base.files = file;
523 else linkfile->next = file;
524 linkfile = file;
525 }
526
527 if (cab->base.files == NULL) {
528 /* We never actually added any files to the file list. Something went wrong.
529 * The file header may have been invalid */
530 D(("No files found, even though header claimed to have %d files", num_files))
531 return MSPACK_ERR_DATAFORMAT;
532 }
533
534 return MSPACK_ERR_OK;
535}
536
537static char *cabd_read_string(struct mspack_system *sys,
538 struct mspack_file *fh, int *error)
539{
540 off_t base = sys->tell(fh);
541 char buf[256], *str;
542 int len, i, ok;
543
544 /* read up to 256 bytes */
545 if ((len = sys->read(fh, &buf[0], 256)) <= 0) {
546 *error = MSPACK_ERR_READ;
547 return NULL;
548 }
549
550 /* search for a null terminator in the buffer */
551 for (i = 0, ok = 0; i < len; i++) if (!buf[i]) { ok = 1; break; }
552 /* reject empty strings */
553 if (i == 0) ok = 0;
554
555 if (!ok) {
556 *error = MSPACK_ERR_DATAFORMAT;
557 return NULL;
558 }
559
560 len = i + 1;
561
562 /* set the data stream to just after the string and return */
563 if (sys->seek(fh, base + (off_t)len, MSPACK_SYS_SEEK_START)) {
564 *error = MSPACK_ERR_SEEK;
565 return NULL;
566 }
567
568 if (!(str = (char *) sys->alloc(sys, len))) {
569 *error = MSPACK_ERR_NOMEMORY;
570 return NULL;
571 }
572
573 sys->copy(&buf[0], str, len);
574 *error = MSPACK_ERR_OK;
575 return str;
576}
577
578/***************************************
579 * CABD_SEARCH, CABD_FIND
580 ***************************************
581 * cabd_search opens a file, finds its extent, allocates a search buffer,
582 * then reads through the whole file looking for possible cabinet headers.
583 * if it finds any, it tries to read them as real cabinets. returns a linked
584 * list of results
585 *
586 * cabd_find is the inner loop of cabd_search, to make it easier to
587 * break out of the loop and be sure that all resources are freed
588 */
589static struct mscabd_cabinet *cabd_search(struct mscab_decompressor *base,
590 const char *filename)
591{
592 struct mscab_decompressor_p *self = (struct mscab_decompressor_p *) base;
593 struct mscabd_cabinet_p *cab = NULL;
594 struct mspack_system *sys;
595 unsigned char *search_buf;
596 struct mspack_file *fh;
597 off_t filelen, firstlen = 0;
598
599 if (!base) return NULL;
600 sys = self->system;
601
602 /* allocate a search buffer */
603 search_buf = (unsigned char *) sys->alloc(sys, (size_t) self->searchbuf_size);
604 if (!search_buf) {
605 self->error = MSPACK_ERR_NOMEMORY;
606 return NULL;
607 }
608
609 /* open file and get its full file length */
610 if ((fh = sys->open(sys, filename, MSPACK_SYS_OPEN_READ))) {
611 if (!(self->error = mspack_sys_filelen(sys, fh, &filelen))) {
612 self->error = cabd_find(self, search_buf, fh, filename,
613 filelen, &firstlen, &cab);
614 }
615
616 /* truncated / extraneous data warning: */
617 if (firstlen && (firstlen != filelen) &&
618 (!cab || (cab->base.base_offset == 0)))
619 {
620 if (firstlen < filelen) {
621 sys->message(fh, "WARNING; possible %" LD
622 " extra bytes at end of file.",
623 filelen - firstlen);
624 }
625 else {
626 sys->message(fh, "WARNING; file possibly truncated by %" LD " bytes.",
627 firstlen - filelen);
628 }
629 }
630
631 sys->close(fh);
632 }
633 else {
634 self->error = MSPACK_ERR_OPEN;
635 }
636
637 /* free the search buffer */
638 sys->free(search_buf);
639
640 return (struct mscabd_cabinet *) cab;
641}
642
643static int cabd_find(struct mscab_decompressor_p *self, unsigned char *buf,
644 struct mspack_file *fh, const char *filename, off_t flen,
645 off_t *firstlen, struct mscabd_cabinet_p **firstcab)
646{
647 struct mscabd_cabinet_p *cab, *link = NULL;
648 off_t caboff, offset, length;
649 struct mspack_system *sys = self->system;
650 unsigned char *p, *pend, state = 0;
651 unsigned int cablen_u32 = 0, foffset_u32 = 0;
652 int false_cabs = 0;
653
654#if !LARGEFILE_SUPPORT
655 /* detect 32-bit off_t overflow */
656 if (flen < 0) {
657 sys->message(fh, largefile_msg);
658 return MSPACK_ERR_OK;
659 }
660#endif
661
662 /* search through the full file length */
663 for (offset = 0; offset < flen; offset += length) {
664 /* search length is either the full length of the search buffer, or the
665 * amount of data remaining to the end of the file, whichever is less. */
666 length = flen - offset;
667 if (length > self->searchbuf_size) {
668 length = self->searchbuf_size;
669 }
670
671 /* fill the search buffer with data from disk */
672 if (sys->read(fh, &buf[0], (int) length) != (int) length) {
673 return MSPACK_ERR_READ;
674 }
675
676 /* FAQ avoidance strategy */
677 if ((offset == 0) && (EndGetI32(&buf[0]) == 0x28635349)) {
678 sys->message(fh, "WARNING; found InstallShield header. Use unshield "
679 "(https://github.com/twogood/unshield) to unpack this file");
680 }
681
682 /* read through the entire buffer. */
683 for (p = &buf[0], pend = &buf[length]; p < pend; ) {
684 switch (state) {
685 /* starting state */
686 case 0:
687 /* we spend most of our time in this while loop, looking for
688 * a leading 'M' of the 'MSCF' signature */
689 while (p < pend && *p != 0x4D) p++;
690 /* if we found tht 'M', advance state */
691 if (p++ < pend) state = 1;
692 break;
693
694 /* verify that the next 3 bytes are 'S', 'C' and 'F' */
695 case 1: state = (*p++ == 0x53) ? 2 : 0; break;
696 case 2: state = (*p++ == 0x43) ? 3 : 0; break;
697 case 3: state = (*p++ == 0x46) ? 4 : 0; break;
698
699 /* we don't care about bytes 4-7 (see default: for action) */
700
701 /* bytes 8-11 are the overall length of the cabinet */
702 case 8: cablen_u32 = *p++; state++; break;
703 case 9: cablen_u32 |= *p++ << 8; state++; break;
704 case 10: cablen_u32 |= *p++ << 16; state++; break;
705 case 11: cablen_u32 |= *p++ << 24; state++; break;
706
707 /* we don't care about bytes 12-15 (see default: for action) */
708
709 /* bytes 16-19 are the offset within the cabinet of the filedata */
710 case 16: foffset_u32 = *p++; state++; break;
711 case 17: foffset_u32 |= *p++ << 8; state++; break;
712 case 18: foffset_u32 |= *p++ << 16; state++; break;
713 case 19: foffset_u32 |= *p++ << 24;
714 /* now we have recieved 20 bytes of potential cab header. work out
715 * the offset in the file of this potential cabinet */
716 caboff = offset + (p - &buf[0]) - 20;
717
718 /* should reading cabinet fail, restart search just after 'MSCF' */
719 offset = caboff + 4;
720
721 /* capture the "length of cabinet" field if there is a cabinet at
722 * offset 0 in the file, regardless of whether the cabinet can be
723 * read correctly or not */
724 if (caboff == 0) *firstlen = (off_t) cablen_u32;
725
726 /* check that the files offset is less than the alleged length of
727 * the cabinet, and that the offset + the alleged length are
728 * 'roughly' within the end of overall file length. In salvage
729 * mode, don't check the alleged length, allow it to be garbage */
730 if ((foffset_u32 < cablen_u32) &&
731 ((caboff + (off_t) foffset_u32) < (flen + 32)) &&
732 (((caboff + (off_t) cablen_u32) < (flen + 32)) || self->salvage))
733 {
734 /* likely cabinet found -- try reading it */
735 if (!(cab = (struct mscabd_cabinet_p *) sys->alloc(sys, sizeof(struct mscabd_cabinet_p)))) {
736 return MSPACK_ERR_NOMEMORY;
737 }
738 cab->base.filename = filename;
739 if (cabd_read_headers(sys, fh, cab, caboff, self->salvage, 1)) {
740 /* destroy the failed cabinet */
741 cabd_close((struct mscab_decompressor *) self,
742 (struct mscabd_cabinet *) cab);
743 false_cabs++;
744 }
745 else {
746 /* cabinet read correctly! */
747
748 /* link the cab into the list */
749 if (!link) *firstcab = cab;
750 else link->base.next = (struct mscabd_cabinet *) cab;
751 link = cab;
752
753 /* cause the search to restart after this cab's data. */
754 offset = caboff + (off_t) cablen_u32;
755
756#if !LARGEFILE_SUPPORT
757 /* detect 32-bit off_t overflow */
758 if (offset < caboff) {
759 sys->message(fh, largefile_msg);
760 return MSPACK_ERR_OK;
761 }
762#endif
763 }
764 }
765
766 /* restart search */
767 if (offset >= flen) return MSPACK_ERR_OK;
768 if (sys->seek(fh, offset, MSPACK_SYS_SEEK_START)) {
769 return MSPACK_ERR_SEEK;
770 }
771 length = 0;
772 p = pend;
773 state = 0;
774 break;
775
776 /* for bytes 4-7 and 12-15, just advance state/pointer */
777 default:
778 p++, state++;
779 } /* switch(state) */
780 } /* for (... p < pend ...) */
781 } /* for (... offset < length ...) */
782
783 if (false_cabs) {
784 D(("%d false cabinets found", false_cabs))
785 }
786
787 return MSPACK_ERR_OK;
788}
789
790/***************************************
791 * CABD_MERGE, CABD_PREPEND, CABD_APPEND
792 ***************************************
793 * joins cabinets together, also merges split folders between these two
794 * cabinets only. This includes freeing the duplicate folder and file(s)
795 * and allocating a further mscabd_folder_data structure to append to the
796 * merged folder's data parts list.
797 */
798static int cabd_prepend(struct mscab_decompressor *base,
799 struct mscabd_cabinet *cab,
800 struct mscabd_cabinet *prevcab)
801{
802 return cabd_merge(base, prevcab, cab);
803}
804
805static int cabd_append(struct mscab_decompressor *base,
806 struct mscabd_cabinet *cab,
807 struct mscabd_cabinet *nextcab)
808{
809 return cabd_merge(base, cab, nextcab);
810}
811
812static int cabd_merge(struct mscab_decompressor *base,
813 struct mscabd_cabinet *lcab,
814 struct mscabd_cabinet *rcab)
815{
816 struct mscab_decompressor_p *self = (struct mscab_decompressor_p *) base;
817 struct mscabd_folder_data *data, *ndata;
818 struct mscabd_folder_p *lfol, *rfol;
819 struct mscabd_file *fi, *rfi, *lfi;
820 struct mscabd_cabinet *cab;
821 struct mspack_system *sys;
822
823 if (!self) return MSPACK_ERR_ARGS;
824 sys = self->system;
825
826 /* basic args check */
827 if (!lcab || !rcab || (lcab == rcab)) {
828 D(("lcab NULL, rcab NULL or lcab = rcab"))
829 return self->error = MSPACK_ERR_ARGS;
830 }
831
832 /* check there's not already a cabinet attached */
833 if (lcab->nextcab || rcab->prevcab) {
834 D(("cabs already joined"))
835 return self->error = MSPACK_ERR_ARGS;
836 }
837
838 /* do not create circular cabinet chains */
839 for (cab = lcab->prevcab; cab; cab = cab->prevcab) {
840 if (cab == rcab) {D(("circular!")) return self->error = MSPACK_ERR_ARGS;}
841 }
842 for (cab = rcab->nextcab; cab; cab = cab->nextcab) {
843 if (cab == lcab) {D(("circular!")) return self->error = MSPACK_ERR_ARGS;}
844 }
845
846 /* warn about odd set IDs or indices */
847 if (lcab->set_id != rcab->set_id) {
848 sys->message(NULL, "WARNING; merged cabinets with differing Set IDs.");
849 }
850
851 if (lcab->set_index > rcab->set_index) {
852 sys->message(NULL, "WARNING; merged cabinets with odd order.");
853 }
854
855 /* merging the last folder in lcab with the first folder in rcab */
856 lfol = (struct mscabd_folder_p *) lcab->folders;
857 rfol = (struct mscabd_folder_p *) rcab->folders;
858 while (lfol->base.next) lfol = (struct mscabd_folder_p *) lfol->base.next;
859
860 /* do we need to merge folders? */
861 if (!lfol->merge_next && !rfol->merge_prev) {
862 /* no, at least one of the folders is not for merging */
863
864 /* attach cabs */
865 lcab->nextcab = rcab;
866 rcab->prevcab = lcab;
867
868 /* attach folders */
869 lfol->base.next = (struct mscabd_folder *) rfol;
870
871 /* attach files */
872 fi = lcab->files;
873 while (fi->next) fi = fi->next;
874 fi->next = rcab->files;
875 }
876 else {
877 /* folder merge required - do the files match? */
878 if (! cabd_can_merge_folders(sys, lfol, rfol)) {
879 return self->error = MSPACK_ERR_DATAFORMAT;
880 }
881
882 /* allocate a new folder data structure */
883 if (!(data = (struct mscabd_folder_data *) sys->alloc(sys, sizeof(struct mscabd_folder_data)))) {
884 return self->error = MSPACK_ERR_NOMEMORY;
885 }
886
887 /* attach cabs */
888 lcab->nextcab = rcab;
889 rcab->prevcab = lcab;
890
891 /* append rfol's data to lfol */
892 ndata = &lfol->data;
893 while (ndata->next) ndata = ndata->next;
894 ndata->next = data;
895 *data = rfol->data;
896 rfol->data.next = NULL;
897
898 /* lfol becomes rfol.
899 * NOTE: special case, don't merge if rfol is merge prev and next,
900 * rfol->merge_next is going to be deleted, so keep lfol's version
901 * instead */
902 lfol->base.num_blocks += rfol->base.num_blocks - 1;
903 if ((rfol->merge_next == NULL) ||
904 (rfol->merge_next->folder != (struct mscabd_folder *) rfol))
905 {
906 lfol->merge_next = rfol->merge_next;
907 }
908
909 /* attach the rfol's folder (except the merge folder) */
910 while (lfol->base.next) lfol = (struct mscabd_folder_p *) lfol->base.next;
911 lfol->base.next = rfol->base.next;
912
913 /* free disused merge folder */
914 sys->free(rfol);
915
916 /* attach rfol's files */
917 fi = lcab->files;
918 while (fi->next) fi = fi->next;
919 fi->next = rcab->files;
920
921 /* delete all files from rfol's merge folder */
922 lfi = NULL;
923 for (fi = lcab->files; fi ; fi = rfi) {
924 rfi = fi->next;
925 /* if file's folder matches the merge folder, unlink and free it */
926 if (fi->folder == (struct mscabd_folder *) rfol) {
927 if (lfi) lfi->next = rfi; else lcab->files = rfi;
928 sys->free(fi->filename);
929 sys->free(fi);
930 }
931 else lfi = fi;
932 }
933 }
934
935 /* all done! fix files and folders pointers in all cabs so they all
936 * point to the same list */
937 for (cab = lcab->prevcab; cab; cab = cab->prevcab) {
938 cab->files = lcab->files;
939 cab->folders = lcab->folders;
940 }
941
942 for (cab = lcab->nextcab; cab; cab = cab->nextcab) {
943 cab->files = lcab->files;
944 cab->folders = lcab->folders;
945 }
946
947 return self->error = MSPACK_ERR_OK;
948}
949
950/* decides if two folders are OK to merge */
951static int cabd_can_merge_folders(struct mspack_system *sys,
952 struct mscabd_folder_p *lfol,
953 struct mscabd_folder_p *rfol)
954{
955 struct mscabd_file *lfi, *rfi, *l, *r;
956 int matching = 1;
957
958 /* check that both folders use the same compression method/settings */
959 if (lfol->base.comp_type != rfol->base.comp_type) {
960 D(("folder merge: compression type mismatch"))
961 return 0;
962 }
963
964 /* check there are not too many data blocks after merging */
965 if ((lfol->base.num_blocks + rfol->base.num_blocks) > CAB_FOLDERMAX) {
966 D(("folder merge: too many data blocks in merged folders"))
967 return 0;
968 }
969
970 if (!(lfi = lfol->merge_next) || !(rfi = rfol->merge_prev)) {
971 D(("folder merge: one cabinet has no files to merge"))
972 return 0;
973 }
974
975 /* for all files in lfol (which is the last folder in whichever cab and
976 * only has files to merge), compare them to the files from rfol. They
977 * should be identical in number and order. to verify this, check the
978 * offset and length of each file. */
979 for (l=lfi, r=rfi; l; l=l->next, r=r->next) {
980 if (!r || (l->offset != r->offset) || (l->length != r->length)) {
981 matching = 0;
982 break;
983 }
984 }
985
986 if (matching) return 1;
987
988 /* if rfol does not begin with an identical copy of the files in lfol, make
989 * make a judgement call; if at least ONE file from lfol is in rfol, allow
990 * the merge with a warning about missing files. */
991 matching = 0;
992 for (l = lfi; l; l = l->next) {
993 for (r = rfi; r; r = r->next) {
994 if (l->offset == r->offset && l->length == r->length) break;
995 }
996 if (r) matching = 1; else sys->message(NULL,
997 "WARNING; merged file %s not listed in both cabinets", l->filename);
998 }
999 return matching;
1000}
1001
1002
1003/***************************************
1004 * CABD_EXTRACT
1005 ***************************************
1006 * extracts a file from a cabinet
1007 */
1008static int cabd_extract(struct mscab_decompressor *base,
1009 struct mscabd_file *file, const char *filename)
1010{
1011 struct mscab_decompressor_p *self = (struct mscab_decompressor_p *) base;
1012 struct mscabd_folder_p *fol;
1013 struct mspack_system *sys;
1014 struct mspack_file *fh;
1015 off_t filelen;
1016
1017 if (!self) return MSPACK_ERR_ARGS;
1018 if (!file) return self->error = MSPACK_ERR_ARGS;
1019
1020 sys = self->system;
1021 fol = (struct mscabd_folder_p *) file->folder;
1022
1023 /* if offset is beyond 2GB, nothing can be extracted */
1024 if (file->offset > CAB_LENGTHMAX) {
1025 return self->error = MSPACK_ERR_DATAFORMAT;
1026 }
1027
1028 /* if file claims to go beyond 2GB either error out,
1029 * or in salvage mode reduce file length so it fits 2GB limit
1030 */
1031 filelen = file->length;
1032 if (filelen > CAB_LENGTHMAX || (file->offset + filelen) > CAB_LENGTHMAX) {
1033 if (self->salvage) {
1034 filelen = CAB_LENGTHMAX - file->offset;
1035 }
1036 else {
1037 return self->error = MSPACK_ERR_DATAFORMAT;
1038 }
1039 }
1040
1041 /* extraction impossible if no folder, or folder needs predecessor */
1042 if (!fol || fol->merge_prev) {
1043 sys->message(NULL, "ERROR; file \"%s\" cannot be extracted, "
1044 "cabinet set is incomplete", file->filename);
1045 return self->error = MSPACK_ERR_DECRUNCH;
1046 }
1047
1048 /* if file goes beyond what can be decoded, given an error.
1049 * In salvage mode, don't assume block sizes, just try decoding
1050 */
1051 if (!self->salvage) {
1052 off_t maxlen = fol->base.num_blocks * CAB_BLOCKMAX;
1053 if ((file->offset + filelen) > maxlen) {
1054 sys->message(NULL, "ERROR; file \"%s\" cannot be extracted, "
1055 "cabinet set is incomplete", file->filename);
1056 return self->error = MSPACK_ERR_DECRUNCH;
1057 }
1058 }
1059
1060 /* allocate generic decompression state */
1061 if (!self->d) {
1062 self->d = (struct mscabd_decompress_state *) sys->alloc(sys, sizeof(struct mscabd_decompress_state));
1063 if (!self->d) return self->error = MSPACK_ERR_NOMEMORY;
1064 self->d->folder = NULL;
1065 self->d->data = NULL;
1066 self->d->sys = *sys;
1067 self->d->sys.read = &cabd_sys_read;
1068 self->d->sys.write = &cabd_sys_write;
1069 self->d->state = NULL;
1070 self->d->infh = NULL;
1071 self->d->incab = NULL;
1072 }
1073
1074 /* do we need to change folder or reset the current folder? */
1075 if ((self->d->folder != fol) || (self->d->offset > file->offset) ||
1076 !self->d->state)
1077 {
1078 /* free any existing decompressor */
1079 cabd_free_decomp(self);
1080
1081 /* do we need to open a new cab file? */
1082 if (!self->d->infh || (fol->data.cab != self->d->incab)) {
1083 /* close previous file handle if from a different cab */
1084 if (self->d->infh) sys->close(self->d->infh);
1085 self->d->incab = fol->data.cab;
1086 self->d->infh = sys->open(sys, fol->data.cab->base.filename,
1087 MSPACK_SYS_OPEN_READ);
1088 if (!self->d->infh) return self->error = MSPACK_ERR_OPEN;
1089 }
1090 /* seek to start of data blocks */
1091 if (sys->seek(self->d->infh, fol->data.offset, MSPACK_SYS_SEEK_START)) {
1092 return self->error = MSPACK_ERR_SEEK;
1093 }
1094
1095 /* set up decompressor */
1096 if (cabd_init_decomp(self, (unsigned int) fol->base.comp_type)) {
1097 return self->error;
1098 }
1099
1100 /* initialise new folder state */
1101 self->d->folder = fol;
1102 self->d->data = &fol->data;
1103 self->d->offset = 0;
1104 self->d->block = 0;
1105 self->d->outlen = 0;
1106 self->d->i_ptr = self->d->i_end = &self->d->input[0];
1107
1108 /* read_error lasts for the lifetime of a decompressor */
1109 self->read_error = MSPACK_ERR_OK;
1110 }
1111
1112 /* open file for output */
1113 if (!(fh = sys->open(sys, filename, MSPACK_SYS_OPEN_WRITE))) {
1114 return self->error = MSPACK_ERR_OPEN;
1115 }
1116
1117 self->error = MSPACK_ERR_OK;
1118
1119 /* if file has more than 0 bytes */
1120 if (filelen) {
1121 off_t bytes;
1122 int error;
1123 /* get to correct offset.
1124 * - use NULL fh to say 'no writing' to cabd_sys_write()
1125 * - if cabd_sys_read() has an error, it will set self->read_error
1126 * and pass back MSPACK_ERR_READ
1127 */
1128 self->d->outfh = NULL;
1129 if ((bytes = file->offset - self->d->offset)) {
1130 error = self->d->decompress(self->d->state, bytes);
1131 self->error = (error == MSPACK_ERR_READ) ? self->read_error : error;
1132 }
1133
1134 /* if getting to the correct offset was error free, unpack file */
1135 if (!self->error) {
1136 self->d->outfh = fh;
1137 error = self->d->decompress(self->d->state, filelen);
1138 self->error = (error == MSPACK_ERR_READ) ? self->read_error : error;
1139 }
1140 }
1141
1142 /* close output file */
1143 sys->close(fh);
1144 self->d->outfh = NULL;
1145
1146 return self->error;
1147}
1148
1149/***************************************
1150 * CABD_INIT_DECOMP, CABD_FREE_DECOMP
1151 ***************************************
1152 * cabd_init_decomp initialises decompression state, according to which
1153 * decompression method was used. relies on self->d->folder being the same
1154 * as when initialised.
1155 *
1156 * cabd_free_decomp frees decompression state, according to which method
1157 * was used.
1158 */
1159static int cabd_init_decomp(struct mscab_decompressor_p *self, unsigned int ct)
1160{
1161 struct mspack_file *fh = (struct mspack_file *) self;
1162
1163 self->d->comp_type = ct;
1164
1165 switch (ct & cffoldCOMPTYPE_MASK) {
1166 case cffoldCOMPTYPE_NONE:
1167 self->d->decompress = (int (*)(void *, off_t)) &noned_decompress;
1168 self->d->state = noned_init(&self->d->sys, fh, fh, self->buf_size);
1169 break;
1170 case cffoldCOMPTYPE_MSZIP:
1171 self->d->decompress = (int (*)(void *, off_t)) &mszipd_decompress;
1172 self->d->state = mszipd_init(&self->d->sys, fh, fh, self->buf_size,
1173 self->fix_mszip);
1174 break;
1175 case cffoldCOMPTYPE_QUANTUM:
1176 self->d->decompress = (int (*)(void *, off_t)) &qtmd_decompress;
1177 self->d->state = qtmd_init(&self->d->sys, fh, fh, (int) (ct >> 8) & 0x1f,
1178 self->buf_size);
1179 break;
1180 case cffoldCOMPTYPE_LZX:
1181 self->d->decompress = (int (*)(void *, off_t)) &lzxd_decompress;
1182 self->d->state = lzxd_init(&self->d->sys, fh, fh, (int) (ct >> 8) & 0x1f, 0,
1183 self->buf_size, (off_t)0,0);
1184 break;
1185 default:
1186 return self->error = MSPACK_ERR_DATAFORMAT;
1187 }
1188 return self->error = (self->d->state) ? MSPACK_ERR_OK : MSPACK_ERR_NOMEMORY;
1189}
1190
1191static void cabd_free_decomp(struct mscab_decompressor_p *self) {
1192 if (!self || !self->d || !self->d->state) return;
1193
1194 switch (self->d->comp_type & cffoldCOMPTYPE_MASK) {
1195 case cffoldCOMPTYPE_NONE: noned_free((struct noned_state *) self->d->state); break;
1196 case cffoldCOMPTYPE_MSZIP: mszipd_free((struct mszipd_stream *) self->d->state); break;
1197 case cffoldCOMPTYPE_QUANTUM: qtmd_free((struct qtmd_stream *) self->d->state); break;
1198 case cffoldCOMPTYPE_LZX: lzxd_free((struct lzxd_stream *) self->d->state); break;
1199 }
1200 self->d->decompress = NULL;
1201 self->d->state = NULL;
1202}
1203
1204/***************************************
1205 * CABD_SYS_READ, CABD_SYS_WRITE
1206 ***************************************
1207 * cabd_sys_read is the internal reader function which the decompressors
1208 * use. will read data blocks (and merge split blocks) from the cabinet
1209 * and serve the read bytes to the decompressors
1210 *
1211 * cabd_sys_write is the internal writer function which the decompressors
1212 * use. it either writes data to disk (self->d->outfh) with the real
1213 * sys->write() function, or does nothing with the data when
1214 * self->d->outfh == NULL. advances self->d->offset
1215 */
1216static int cabd_sys_read(struct mspack_file *file, void *buffer, int bytes) {
1217 struct mscab_decompressor_p *self = (struct mscab_decompressor_p *) file;
1218 unsigned char *buf = (unsigned char *) buffer;
1219 struct mspack_system *sys = self->system;
1220 int avail, todo, outlen, ignore_cksum, ignore_blocksize;
1221
1222 ignore_cksum = self->salvage ||
1223 (self->fix_mszip &&
1224 ((self->d->comp_type & cffoldCOMPTYPE_MASK) == cffoldCOMPTYPE_MSZIP));
1225 ignore_blocksize = self->salvage;
1226
1227 todo = bytes;
1228 while (todo > 0) {
1229 avail = self->d->i_end - self->d->i_ptr;
1230
1231 /* if out of input data, read a new block */
1232 if (avail) {
1233 /* copy as many input bytes available as possible */
1234 if (avail > todo) avail = todo;
1235 sys->copy(self->d->i_ptr, buf, (size_t) avail);
1236 self->d->i_ptr += avail;
1237 buf += avail;
1238 todo -= avail;
1239 }
1240 else {
1241 /* out of data, read a new block */
1242
1243 /* check if we're out of input blocks, advance block counter */
1244 if (self->d->block++ >= self->d->folder->base.num_blocks) {
1245 if (!self->salvage) {
1246 self->read_error = MSPACK_ERR_DATAFORMAT;
1247 }
1248 else {
1249 D(("Ran out of CAB input blocks prematurely"))
1250 }
1251 break;
1252 }
1253
1254 /* read a block */
1255 self->read_error = cabd_sys_read_block(sys, self->d, &outlen,
1256 ignore_cksum, ignore_blocksize);
1257 if (self->read_error) return -1;
1258 self->d->outlen += outlen;
1259
1260 /* special Quantum hack -- trailer byte to allow the decompressor
1261 * to realign itself. CAB Quantum blocks, unlike LZX blocks, can have
1262 * anything from 0 to 4 trailing null bytes. */
1263 if ((self->d->comp_type & cffoldCOMPTYPE_MASK)==cffoldCOMPTYPE_QUANTUM) {
1264 *self->d->i_end++ = 0xFF;
1265 }
1266
1267 /* is this the last block? */
1268 if (self->d->block >= self->d->folder->base.num_blocks) {
1269 if ((self->d->comp_type & cffoldCOMPTYPE_MASK) == cffoldCOMPTYPE_LZX) {
1270 /* special LZX hack -- on the last block, inform LZX of the
1271 * size of the output data stream. */
1272 lzxd_set_output_length((struct lzxd_stream *) self->d->state, self->d->outlen);
1273 }
1274 }
1275 } /* if (avail) */
1276 } /* while (todo > 0) */
1277 return bytes - todo;
1278}
1279
1280static int cabd_sys_write(struct mspack_file *file, void *buffer, int bytes) {
1281 struct mscab_decompressor_p *self = (struct mscab_decompressor_p *) file;
1282 self->d->offset += bytes;
1283 if (self->d->outfh) {
1284 return self->system->write(self->d->outfh, buffer, bytes);
1285 }
1286 return bytes;
1287}
1288
1289/***************************************
1290 * CABD_SYS_READ_BLOCK
1291 ***************************************
1292 * reads a whole data block from a cab file. the block may span more than
1293 * one cab file, if it does then the fragments will be reassembled
1294 */
1295static int cabd_sys_read_block(struct mspack_system *sys,
1296 struct mscabd_decompress_state *d,
1297 int *out, int ignore_cksum,
1298 int ignore_blocksize)
1299{
1300 unsigned char hdr[cfdata_SIZEOF];
1301 unsigned int cksum;
1302 int len, full_len;
1303
1304 /* reset the input block pointer and end of block pointer */
1305 d->i_ptr = d->i_end = &d->input[0];
1306
1307 do {
1308 /* read the block header */
1309 if (sys->read(d->infh, &hdr[0], cfdata_SIZEOF) != cfdata_SIZEOF) {
1310 return MSPACK_ERR_READ;
1311 }
1312
1313 /* skip any reserved block headers */
1314 if (d->data->cab->block_resv &&
1315 sys->seek(d->infh, (off_t) d->data->cab->block_resv,
1316 MSPACK_SYS_SEEK_CUR))
1317 {
1318 return MSPACK_ERR_SEEK;
1319 }
1320
1321 /* blocks must not be over CAB_INPUTMAX in size */
1322 len = EndGetI16(&hdr[cfdata_CompressedSize]);
1323 full_len = (d->i_end - d->i_ptr) + len; /* include cab-spanning blocks */
1324 if (full_len > CAB_INPUTMAX) {
1325 D(("block size %d > CAB_INPUTMAX", full_len));
1326 /* in salvage mode, blocks can be 65535 bytes but no more than that */
1327 if (!ignore_blocksize || full_len > CAB_INPUTMAX_SALVAGE) {
1328 return MSPACK_ERR_DATAFORMAT;
1329 }
1330 }
1331
1332 /* blocks must not expand to more than CAB_BLOCKMAX */
1333 if (EndGetI16(&hdr[cfdata_UncompressedSize]) > CAB_BLOCKMAX) {
1334 D(("block size > CAB_BLOCKMAX"))
1335 if (!ignore_blocksize) return MSPACK_ERR_DATAFORMAT;
1336 }
1337
1338 /* read the block data */
1339 if (sys->read(d->infh, d->i_end, len) != len) {
1340 return MSPACK_ERR_READ;
1341 }
1342
1343 /* perform checksum test on the block (if one is stored) */
1344 if ((cksum = EndGetI32(&hdr[cfdata_CheckSum]))) {
1345 unsigned int sum2 = cabd_checksum(d->i_end, (unsigned int) len, 0);
1346 if (cabd_checksum(&hdr[4], 4, sum2) != cksum) {
1347 if (!ignore_cksum) return MSPACK_ERR_CHECKSUM;
1348 sys->message(d->infh, "WARNING; bad block checksum found");
1349 }
1350 }
1351
1352 /* advance end of block pointer to include newly read data */
1353 d->i_end += len;
1354
1355 /* uncompressed size == 0 means this block was part of a split block
1356 * and it continues as the first block of the next cabinet in the set.
1357 * otherwise, this is the last part of the block, and no more block
1358 * reading needs to be done.
1359 */
1360 /* EXIT POINT OF LOOP -- uncompressed size != 0 */
1361 if ((*out = EndGetI16(&hdr[cfdata_UncompressedSize]))) {
1362 return MSPACK_ERR_OK;
1363 }
1364
1365 /* otherwise, advance to next cabinet */
1366
1367 /* close current file handle */
1368 sys->close(d->infh);
1369 d->infh = NULL;
1370
1371 /* advance to next member in the cabinet set */
1372 if (!(d->data = d->data->next)) {
1373 sys->message(d->infh, "WARNING; ran out of cabinets in set. Are any missing?");
1374 return MSPACK_ERR_DATAFORMAT;
1375 }
1376
1377 /* open next cab file */
1378 d->incab = d->data->cab;
1379 if (!(d->infh = sys->open(sys, d->incab->base.filename,
1380 MSPACK_SYS_OPEN_READ)))
1381 {
1382 return MSPACK_ERR_OPEN;
1383 }
1384
1385 /* seek to start of data blocks */
1386 if (sys->seek(d->infh, d->data->offset, MSPACK_SYS_SEEK_START)) {
1387 return MSPACK_ERR_SEEK;
1388 }
1389 } while (1);
1390
1391 /* not reached */
1392 return MSPACK_ERR_OK;
1393}
1394
1395static unsigned int cabd_checksum(unsigned char *data, unsigned int bytes,
1396 unsigned int cksum)
1397{
1398 unsigned int len, ul = 0;
1399
1400 for (len = bytes >> 2; len--; data += 4) {
1401 cksum ^= ((data[0]) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24));
1402 }
1403
1404 switch (bytes & 3) {
1405 case 3: ul |= *data++ << 16; /*@fallthrough@*/
1406 case 2: ul |= *data++ << 8; /*@fallthrough@*/
1407 case 1: ul |= *data;
1408 }
1409 cksum ^= ul;
1410
1411 return cksum;
1412}
1413
1414/***************************************
1415 * NONED_INIT, NONED_DECOMPRESS, NONED_FREE
1416 ***************************************
1417 * the "not compressed" method decompressor
1418 */
1419struct noned_state {
1420 struct mspack_system *sys;
1421 struct mspack_file *i;
1422 struct mspack_file *o;
1423 unsigned char *buf;
1424 int bufsize;
1425};
1426
1427static struct noned_state *noned_init(struct mspack_system *sys,
1428 struct mspack_file *in,
1429 struct mspack_file *out,
1430 int bufsize)
1431{
1432 struct noned_state *state = (struct noned_state *) sys->alloc(sys, sizeof(struct noned_state));
1433 unsigned char *buf = (unsigned char *) sys->alloc(sys, (size_t) bufsize);
1434 if (state && buf) {
1435 state->sys = sys;
1436 state->i = in;
1437 state->o = out;
1438 state->buf = buf;
1439 state->bufsize = bufsize;
1440 }
1441 else {
1442 sys->free(buf);
1443 sys->free(state);
1444 state = NULL;
1445 }
1446 return state;
1447}
1448
1449static int noned_decompress(struct noned_state *s, off_t bytes) {
1450 int run;
1451 while (bytes > 0) {
1452 run = (bytes > s->bufsize) ? s->bufsize : (int) bytes;
1453 if (s->sys->read(s->i, &s->buf[0], run) != run) return MSPACK_ERR_READ;
1454 if (s->sys->write(s->o, &s->buf[0], run) != run) return MSPACK_ERR_WRITE;
1455 bytes -= run;
1456 }
1457 return MSPACK_ERR_OK;
1458}
1459
1460static void noned_free(struct noned_state *state) {
1461 struct mspack_system *sys;
1462 if (state) {
1463 sys = state->sys;
1464 sys->free(state->buf);
1465 sys->free(state);
1466 }
1467}
1468
1469
1470/***************************************
1471 * CABD_PARAM
1472 ***************************************
1473 * allows a parameter to be set
1474 */
1475static int cabd_param(struct mscab_decompressor *base, int param, int value) {
1476 struct mscab_decompressor_p *self = (struct mscab_decompressor_p *) base;
1477 if (!self) return MSPACK_ERR_ARGS;
1478
1479 switch (param) {
1480 case MSCABD_PARAM_SEARCHBUF:
1481 if (value < 4) return MSPACK_ERR_ARGS;
1482 self->searchbuf_size = value;
1483 break;
1484 case MSCABD_PARAM_FIXMSZIP:
1485 self->fix_mszip = value;
1486 break;
1487 case MSCABD_PARAM_DECOMPBUF:
1488 if (value < 4) return MSPACK_ERR_ARGS;
1489 self->buf_size = value;
1490 break;
1491 case MSCABD_PARAM_SALVAGE:
1492 self->salvage = value;
1493 break;
1494 default:
1495 return MSPACK_ERR_ARGS;
1496 }
1497 return MSPACK_ERR_OK;
1498}
1499
1500/***************************************
1501 * CABD_ERROR
1502 ***************************************
1503 * returns the last error that occurred
1504 */
1505static int cabd_error(struct mscab_decompressor *base) {
1506 struct mscab_decompressor_p *self = (struct mscab_decompressor_p *) base;
1507 return (self) ? self->error : MSPACK_ERR_ARGS;
1508}
diff --git a/utils/rbutilqt/mspack/chm.h b/utils/rbutilqt/mspack/chm.h
new file mode 100644
index 0000000000..4b19f1505a
--- /dev/null
+++ b/utils/rbutilqt/mspack/chm.h
@@ -0,0 +1,122 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10#ifndef MSPACK_CHM_H
11#define MSPACK_CHM_H 1
12
13#include "lzx.h"
14
15/* generic CHM definitions */
16
17#define chmhead_Signature (0x0000)
18#define chmhead_Version (0x0004)
19#define chmhead_HeaderLen (0x0008)
20#define chmhead_Unknown1 (0x000C)
21#define chmhead_Timestamp (0x0010)
22#define chmhead_LanguageID (0x0014)
23#define chmhead_GUID1 (0x0018)
24#define chmhead_GUID2 (0x0028)
25#define chmhead_SIZEOF (0x0038)
26
27#define chmhst_OffsetHS0 (0x0000)
28#define chmhst_LengthHS0 (0x0008)
29#define chmhst_OffsetHS1 (0x0010)
30#define chmhst_LengthHS1 (0x0018)
31#define chmhst_SIZEOF (0x0020)
32#define chmhst3_OffsetCS0 (0x0020)
33#define chmhst3_SIZEOF (0x0028)
34
35#define chmhs0_Unknown1 (0x0000)
36#define chmhs0_Unknown2 (0x0004)
37#define chmhs0_FileLen (0x0008)
38#define chmhs0_Unknown3 (0x0010)
39#define chmhs0_Unknown4 (0x0014)
40#define chmhs0_SIZEOF (0x0018)
41
42#define chmhs1_Signature (0x0000)
43#define chmhs1_Version (0x0004)
44#define chmhs1_HeaderLen (0x0008)
45#define chmhs1_Unknown1 (0x000C)
46#define chmhs1_ChunkSize (0x0010)
47#define chmhs1_Density (0x0014)
48#define chmhs1_Depth (0x0018)
49#define chmhs1_IndexRoot (0x001C)
50#define chmhs1_FirstPMGL (0x0020)
51#define chmhs1_LastPMGL (0x0024)
52#define chmhs1_Unknown2 (0x0028)
53#define chmhs1_NumChunks (0x002C)
54#define chmhs1_LanguageID (0x0030)
55#define chmhs1_GUID (0x0034)
56#define chmhs1_Unknown3 (0x0044)
57#define chmhs1_Unknown4 (0x0048)
58#define chmhs1_Unknown5 (0x004C)
59#define chmhs1_Unknown6 (0x0050)
60#define chmhs1_SIZEOF (0x0054)
61
62#define pmgl_Signature (0x0000)
63#define pmgl_QuickRefSize (0x0004)
64#define pmgl_Unknown1 (0x0008)
65#define pmgl_PrevChunk (0x000C)
66#define pmgl_NextChunk (0x0010)
67#define pmgl_Entries (0x0014)
68#define pmgl_headerSIZEOF (0x0014)
69
70#define pmgi_Signature (0x0000)
71#define pmgi_QuickRefSize (0x0004)
72#define pmgi_Entries (0x0008)
73#define pmgi_headerSIZEOF (0x000C)
74
75#define lzxcd_Length (0x0000)
76#define lzxcd_Signature (0x0004)
77#define lzxcd_Version (0x0008)
78#define lzxcd_ResetInterval (0x000C)
79#define lzxcd_WindowSize (0x0010)
80#define lzxcd_CacheSize (0x0014)
81#define lzxcd_Unknown1 (0x0018)
82#define lzxcd_SIZEOF (0x001C)
83
84#define lzxrt_Unknown1 (0x0000)
85#define lzxrt_NumEntries (0x0004)
86#define lzxrt_EntrySize (0x0008)
87#define lzxrt_TableOffset (0x000C)
88#define lzxrt_UncompLen (0x0010)
89#define lzxrt_CompLen (0x0018)
90#define lzxrt_FrameLen (0x0020)
91#define lzxrt_Entries (0x0028)
92#define lzxrt_headerSIZEOF (0x0028)
93
94/* CHM compression definitions */
95
96struct mschm_compressor_p {
97 struct mschm_compressor base;
98 struct mspack_system *system;
99 char *temp_file;
100 int use_temp_file;
101 int error;
102};
103
104/* CHM decompression definitions */
105struct mschmd_decompress_state {
106 struct mschmd_header *chm; /* CHM file being decompressed */
107 off_t offset; /* uncompressed offset within folder */
108 off_t inoffset; /* offset in input file */
109 struct lzxd_stream *state; /* LZX decompressor state */
110 struct mspack_system sys; /* special I/O code for decompressor */
111 struct mspack_file *infh; /* input file handle */
112 struct mspack_file *outfh; /* output file handle */
113};
114
115struct mschm_decompressor_p {
116 struct mschm_decompressor base;
117 struct mspack_system *system;
118 struct mschmd_decompress_state *d;
119 int error;
120};
121
122#endif
diff --git a/utils/rbutilqt/mspack/chmc.c b/utils/rbutilqt/mspack/chmc.c
new file mode 100644
index 0000000000..b9a1d8856c
--- /dev/null
+++ b/utils/rbutilqt/mspack/chmc.c
@@ -0,0 +1,24 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10/* CHM compression implementation */
11
12#include "system-mspack.h"
13#include "chm.h"
14
15struct mschm_compressor *
16 mspack_create_chm_compressor(struct mspack_system *sys)
17{
18 /* todo */
19 return NULL;
20}
21
22void mspack_destroy_chm_compressor(struct mschm_compressor *self) {
23 /* todo */
24}
diff --git a/utils/rbutilqt/mspack/chmd.c b/utils/rbutilqt/mspack/chmd.c
new file mode 100644
index 0000000000..6c8481db14
--- /dev/null
+++ b/utils/rbutilqt/mspack/chmd.c
@@ -0,0 +1,1377 @@
1/* This file is part of libmspack.
2 * (C) 2003-2018 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10/* CHM decompression implementation */
11
12#include "system-mspack.h"
13#include "chm.h"
14
15/* prototypes */
16static struct mschmd_header * chmd_open(
17 struct mschm_decompressor *base, const char *filename);
18static struct mschmd_header * chmd_fast_open(
19 struct mschm_decompressor *base, const char *filename);
20static struct mschmd_header *chmd_real_open(
21 struct mschm_decompressor *base, const char *filename, int entire);
22static void chmd_close(
23 struct mschm_decompressor *base, struct mschmd_header *chm);
24static int chmd_read_headers(
25 struct mspack_system *sys, struct mspack_file *fh,
26 struct mschmd_header *chm, int entire);
27static int chmd_fast_find(
28 struct mschm_decompressor *base, struct mschmd_header *chm,
29 const char *filename, struct mschmd_file *f_ptr, int f_size);
30static unsigned char *read_chunk(
31 struct mschm_decompressor_p *self, struct mschmd_header *chm,
32 struct mspack_file *fh, unsigned int chunk);
33static int search_chunk(
34 struct mschmd_header *chm, const unsigned char *chunk, const char *filename,
35 const unsigned char **result, const unsigned char **result_end);
36static inline int compare(
37 const char *s1, const char *s2, int l1, int l2);
38static int chmd_extract(
39 struct mschm_decompressor *base, struct mschmd_file *file,
40 const char *filename);
41static int chmd_sys_write(
42 struct mspack_file *file, void *buffer, int bytes);
43static int chmd_init_decomp(
44 struct mschm_decompressor_p *self, struct mschmd_file *file);
45static int read_reset_table(
46 struct mschm_decompressor_p *self, struct mschmd_sec_mscompressed *sec,
47 unsigned int entry, off_t *length_ptr, off_t *offset_ptr);
48static int read_spaninfo(
49 struct mschm_decompressor_p *self, struct mschmd_sec_mscompressed *sec,
50 off_t *length_ptr);
51static int find_sys_file(
52 struct mschm_decompressor_p *self, struct mschmd_sec_mscompressed *sec,
53 struct mschmd_file **f_ptr, const char *name);
54static unsigned char *read_sys_file(
55 struct mschm_decompressor_p *self, struct mschmd_file *file);
56static int chmd_error(
57 struct mschm_decompressor *base);
58static int read_off64(
59 off_t *var, unsigned char *mem, struct mspack_system *sys,
60 struct mspack_file *fh);
61
62/* filenames of the system files used for decompression.
63 * Content and ControlData are essential.
64 * ResetTable is preferred, but SpanInfo can be used if not available
65 */
66static const char *content_name = "::DataSpace/Storage/MSCompressed/Content";
67static const char *control_name = "::DataSpace/Storage/MSCompressed/ControlData";
68static const char *spaninfo_name = "::DataSpace/Storage/MSCompressed/SpanInfo";
69static const char *rtable_name = "::DataSpace/Storage/MSCompressed/Transform/"
70 "{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/ResetTable";
71
72/***************************************
73 * MSPACK_CREATE_CHM_DECOMPRESSOR
74 ***************************************
75 * constructor
76 */
77struct mschm_decompressor *
78 mspack_create_chm_decompressor(struct mspack_system *sys)
79{
80 struct mschm_decompressor_p *self = NULL;
81
82 if (!sys) sys = mspack_default_system;
83 if (!mspack_valid_system(sys)) return NULL;
84
85 if ((self = (struct mschm_decompressor_p *) sys->alloc(sys, sizeof(struct mschm_decompressor_p)))) {
86 self->base.open = &chmd_open;
87 self->base.close = &chmd_close;
88 self->base.extract = &chmd_extract;
89 self->base.last_error = &chmd_error;
90 self->base.fast_open = &chmd_fast_open;
91 self->base.fast_find = &chmd_fast_find;
92 self->system = sys;
93 self->error = MSPACK_ERR_OK;
94 self->d = NULL;
95 }
96 return (struct mschm_decompressor *) self;
97}
98
99/***************************************
100 * MSPACK_DESTROY_CAB_DECOMPRESSOR
101 ***************************************
102 * destructor
103 */
104void mspack_destroy_chm_decompressor(struct mschm_decompressor *base) {
105 struct mschm_decompressor_p *self = (struct mschm_decompressor_p *) base;
106 if (self) {
107 struct mspack_system *sys = self->system;
108 if (self->d) {
109 if (self->d->infh) sys->close(self->d->infh);
110 if (self->d->state) lzxd_free(self->d->state);
111 sys->free(self->d);
112 }
113 sys->free(self);
114 }
115}
116
117/***************************************
118 * CHMD_OPEN
119 ***************************************
120 * opens a file and tries to read it as a CHM file.
121 * Calls chmd_real_open() with entire=1.
122 */
123static struct mschmd_header *chmd_open(struct mschm_decompressor *base,
124 const char *filename)
125{
126 return chmd_real_open(base, filename, 1);
127}
128
129/***************************************
130 * CHMD_FAST_OPEN
131 ***************************************
132 * opens a file and tries to read it as a CHM file, but does not read
133 * the file headers. Calls chmd_real_open() with entire=0
134 */
135static struct mschmd_header *chmd_fast_open(struct mschm_decompressor *base,
136 const char *filename)
137{
138 return chmd_real_open(base, filename, 0);
139}
140
141/***************************************
142 * CHMD_REAL_OPEN
143 ***************************************
144 * the real implementation of chmd_open() and chmd_fast_open(). It simply
145 * passes the "entire" parameter to chmd_read_headers(), which will then
146 * either read all headers, or a bare mininum.
147 */
148static struct mschmd_header *chmd_real_open(struct mschm_decompressor *base,
149 const char *filename, int entire)
150{
151 struct mschm_decompressor_p *self = (struct mschm_decompressor_p *) base;
152 struct mschmd_header *chm = NULL;
153 struct mspack_system *sys;
154 struct mspack_file *fh;
155 int error;
156
157 if (!base) return NULL;
158 sys = self->system;
159
160 if ((fh = sys->open(sys, filename, MSPACK_SYS_OPEN_READ))) {
161 if ((chm = (struct mschmd_header *) sys->alloc(sys, sizeof(struct mschmd_header)))) {
162 chm->filename = filename;
163 error = chmd_read_headers(sys, fh, chm, entire);
164 if (error) {
165 /* if the error is DATAFORMAT, and there are some results, return
166 * partial results with a warning, rather than nothing */
167 if (error == MSPACK_ERR_DATAFORMAT && (chm->files || chm->sysfiles)) {
168 sys->message(fh, "WARNING; contents are corrupt");
169 error = MSPACK_ERR_OK;
170 }
171 else {
172 chmd_close(base, chm);
173 chm = NULL;
174 }
175 }
176 self->error = error;
177 }
178 else {
179 self->error = MSPACK_ERR_NOMEMORY;
180 }
181 sys->close(fh);
182 }
183 else {
184 self->error = MSPACK_ERR_OPEN;
185 }
186 return chm;
187}
188
189/***************************************
190 * CHMD_CLOSE
191 ***************************************
192 * frees all memory associated with a given mschmd_header
193 */
194static void chmd_close(struct mschm_decompressor *base,
195 struct mschmd_header *chm)
196{
197 struct mschm_decompressor_p *self = (struct mschm_decompressor_p *) base;
198 struct mschmd_file *fi, *nfi;
199 struct mspack_system *sys;
200 unsigned int i;
201
202 if (!base) return;
203 sys = self->system;
204
205 self->error = MSPACK_ERR_OK;
206
207 /* free files */
208 for (fi = chm->files; fi; fi = nfi) {
209 nfi = fi->next;
210 sys->free(fi);
211 }
212 for (fi = chm->sysfiles; fi; fi = nfi) {
213 nfi = fi->next;
214 sys->free(fi);
215 }
216
217 /* if this CHM was being decompressed, free decompression state */
218 if (self->d && (self->d->chm == chm)) {
219 if (self->d->infh) sys->close(self->d->infh);
220 if (self->d->state) lzxd_free(self->d->state);
221 sys->free(self->d);
222 self->d = NULL;
223 }
224
225 /* if this CHM had a chunk cache, free it and contents */
226 if (chm->chunk_cache) {
227 for (i = 0; i < chm->num_chunks; i++) sys->free(chm->chunk_cache[i]);
228 sys->free(chm->chunk_cache);
229 }
230
231 sys->free(chm);
232}
233
234/***************************************
235 * CHMD_READ_HEADERS
236 ***************************************
237 * reads the basic CHM file headers. If the "entire" parameter is
238 * non-zero, all file entries will also be read. fills out a pre-existing
239 * mschmd_header structure, allocates memory for files as necessary
240 */
241
242/* The GUIDs found in CHM headers */
243static const unsigned char guids[32] = {
244 /* {7C01FD10-7BAA-11D0-9E0C-00A0-C922-E6EC} */
245 0x10, 0xFD, 0x01, 0x7C, 0xAA, 0x7B, 0xD0, 0x11,
246 0x9E, 0x0C, 0x00, 0xA0, 0xC9, 0x22, 0xE6, 0xEC,
247 /* {7C01FD11-7BAA-11D0-9E0C-00A0-C922-E6EC} */
248 0x11, 0xFD, 0x01, 0x7C, 0xAA, 0x7B, 0xD0, 0x11,
249 0x9E, 0x0C, 0x00, 0xA0, 0xC9, 0x22, 0xE6, 0xEC
250};
251
252/* reads an encoded integer into a variable; 7 bits of data per byte,
253 * the high bit is used to indicate that there is another byte */
254#define READ_ENCINT(var) do { \
255 (var) = 0; \
256 do { \
257 if (p >= end) goto chunk_end; \
258 (var) = ((var) << 7) | (*p & 0x7F); \
259 } while (*p++ & 0x80); \
260} while (0)
261
262static int chmd_read_headers(struct mspack_system *sys, struct mspack_file *fh,
263 struct mschmd_header *chm, int entire)
264{
265 unsigned int section, name_len, x, errors, num_chunks;
266 unsigned char buf[0x54], *chunk = NULL, *name, *p, *end;
267 struct mschmd_file *fi, *link = NULL;
268 off_t offset, length;
269 int num_entries;
270
271 /* initialise pointers */
272 chm->files = NULL;
273 chm->sysfiles = NULL;
274 chm->chunk_cache = NULL;
275 chm->sec0.base.chm = chm;
276 chm->sec0.base.id = 0;
277 chm->sec1.base.chm = chm;
278 chm->sec1.base.id = 1;
279 chm->sec1.content = NULL;
280 chm->sec1.control = NULL;
281 chm->sec1.spaninfo = NULL;
282 chm->sec1.rtable = NULL;
283
284 /* read the first header */
285 if (sys->read(fh, &buf[0], chmhead_SIZEOF) != chmhead_SIZEOF) {
286 return MSPACK_ERR_READ;
287 }
288
289 /* check ITSF signature */
290 if (EndGetI32(&buf[chmhead_Signature]) != 0x46535449) {
291 return MSPACK_ERR_SIGNATURE;
292 }
293
294 /* check both header GUIDs */
295 if (memcmp(&buf[chmhead_GUID1], &guids[0], 32L) != 0) {
296 D(("incorrect GUIDs"))
297 return MSPACK_ERR_SIGNATURE;
298 }
299
300 chm->version = EndGetI32(&buf[chmhead_Version]);
301 chm->timestamp = EndGetM32(&buf[chmhead_Timestamp]);
302 chm->language = EndGetI32(&buf[chmhead_LanguageID]);
303 if (chm->version > 3) {
304 sys->message(fh, "WARNING; CHM version > 3");
305 }
306
307 /* read the header section table */
308 if (sys->read(fh, &buf[0], chmhst3_SIZEOF) != chmhst3_SIZEOF) {
309 return MSPACK_ERR_READ;
310 }
311
312 /* chmhst3_OffsetCS0 does not exist in version 1 or 2 CHM files.
313 * The offset will be corrected later, once HS1 is read.
314 */
315 if (read_off64(&offset, &buf[chmhst_OffsetHS0], sys, fh) ||
316 read_off64(&chm->dir_offset, &buf[chmhst_OffsetHS1], sys, fh) ||
317 read_off64(&chm->sec0.offset, &buf[chmhst3_OffsetCS0], sys, fh))
318 {
319 return MSPACK_ERR_DATAFORMAT;
320 }
321
322 /* seek to header section 0 */
323 if (sys->seek(fh, offset, MSPACK_SYS_SEEK_START)) {
324 return MSPACK_ERR_SEEK;
325 }
326
327 /* read header section 0 */
328 if (sys->read(fh, &buf[0], chmhs0_SIZEOF) != chmhs0_SIZEOF) {
329 return MSPACK_ERR_READ;
330 }
331 if (read_off64(&chm->length, &buf[chmhs0_FileLen], sys, fh)) {
332 return MSPACK_ERR_DATAFORMAT;
333 }
334
335 /* seek to header section 1 */
336 if (sys->seek(fh, chm->dir_offset, MSPACK_SYS_SEEK_START)) {
337 return MSPACK_ERR_SEEK;
338 }
339
340 /* read header section 1 */
341 if (sys->read(fh, &buf[0], chmhs1_SIZEOF) != chmhs1_SIZEOF) {
342 return MSPACK_ERR_READ;
343 }
344
345 chm->dir_offset = sys->tell(fh);
346 chm->chunk_size = EndGetI32(&buf[chmhs1_ChunkSize]);
347 chm->density = EndGetI32(&buf[chmhs1_Density]);
348 chm->depth = EndGetI32(&buf[chmhs1_Depth]);
349 chm->index_root = EndGetI32(&buf[chmhs1_IndexRoot]);
350 chm->num_chunks = EndGetI32(&buf[chmhs1_NumChunks]);
351 chm->first_pmgl = EndGetI32(&buf[chmhs1_FirstPMGL]);
352 chm->last_pmgl = EndGetI32(&buf[chmhs1_LastPMGL]);
353
354 if (chm->version < 3) {
355 /* versions before 3 don't have chmhst3_OffsetCS0 */
356 chm->sec0.offset = chm->dir_offset + (chm->chunk_size * chm->num_chunks);
357 }
358
359 /* check if content offset or file size is wrong */
360 if (chm->sec0.offset > chm->length) {
361 D(("content section begins after file has ended"))
362 return MSPACK_ERR_DATAFORMAT;
363 }
364
365 /* ensure there are chunks and that chunk size is
366 * large enough for signature and num_entries */
367 if (chm->chunk_size < (pmgl_Entries + 2)) {
368 D(("chunk size not large enough"))
369 return MSPACK_ERR_DATAFORMAT;
370 }
371 if (chm->num_chunks == 0) {
372 D(("no chunks"))
373 return MSPACK_ERR_DATAFORMAT;
374 }
375
376 /* The chunk_cache data structure is not great; large values for num_chunks
377 * or num_chunks*chunk_size can exhaust all memory. Until a better chunk
378 * cache is implemented, put arbitrary limits on num_chunks and chunk size.
379 */
380 if (chm->num_chunks > 100000) {
381 D(("more than 100,000 chunks"))
382 return MSPACK_ERR_DATAFORMAT;
383 }
384 if (chm->chunk_size > 8192) {
385 D(("chunk size over 8192 (get in touch if this is valid)"))
386 return MSPACK_ERR_DATAFORMAT;
387 }
388 if ((off_t)chm->chunk_size * (off_t)chm->num_chunks > chm->length) {
389 D(("chunks larger than entire file"))
390 return MSPACK_ERR_DATAFORMAT;
391 }
392
393 /* common sense checks on header section 1 fields */
394 if (chm->chunk_size != 4096) {
395 sys->message(fh, "WARNING; chunk size is not 4096");
396 }
397 if (chm->first_pmgl != 0) {
398 sys->message(fh, "WARNING; first PMGL chunk is not zero");
399 }
400 if (chm->first_pmgl > chm->last_pmgl) {
401 D(("first pmgl chunk is after last pmgl chunk"))
402 return MSPACK_ERR_DATAFORMAT;
403 }
404 if (chm->index_root != 0xFFFFFFFF && chm->index_root >= chm->num_chunks) {
405 D(("index_root outside valid range"))
406 return MSPACK_ERR_DATAFORMAT;
407 }
408
409 /* if we are doing a quick read, stop here! */
410 if (!entire) {
411 return MSPACK_ERR_OK;
412 }
413
414 /* seek to the first PMGL chunk, and reduce the number of chunks to read */
415 if ((x = chm->first_pmgl) != 0) {
416 if (sys->seek(fh,(off_t) (x * chm->chunk_size), MSPACK_SYS_SEEK_CUR)) {
417 return MSPACK_ERR_SEEK;
418 }
419 }
420 num_chunks = chm->last_pmgl - x + 1;
421
422 if (!(chunk = (unsigned char *) sys->alloc(sys, (size_t)chm->chunk_size))) {
423 return MSPACK_ERR_NOMEMORY;
424 }
425
426 /* read and process all chunks from FirstPMGL to LastPMGL */
427 errors = 0;
428 while (num_chunks--) {
429 /* read next chunk */
430 if (sys->read(fh, chunk, (int)chm->chunk_size) != (int)chm->chunk_size) {
431 sys->free(chunk);
432 return MSPACK_ERR_READ;
433 }
434
435 /* process only directory (PMGL) chunks */
436 if (EndGetI32(&chunk[pmgl_Signature]) != 0x4C474D50) continue;
437
438 if (EndGetI32(&chunk[pmgl_QuickRefSize]) < 2) {
439 sys->message(fh, "WARNING; PMGL quickref area is too small");
440 }
441 if (EndGetI32(&chunk[pmgl_QuickRefSize]) >
442 (chm->chunk_size - pmgl_Entries))
443 {
444 sys->message(fh, "WARNING; PMGL quickref area is too large");
445 }
446
447 p = &chunk[pmgl_Entries];
448 end = &chunk[chm->chunk_size - 2];
449 num_entries = EndGetI16(end);
450
451 while (num_entries--) {
452 READ_ENCINT(name_len);
453 if (name_len > (unsigned int) (end - p)) goto chunk_end;
454 name = p; p += name_len;
455 READ_ENCINT(section);
456 READ_ENCINT(offset);
457 READ_ENCINT(length);
458
459 /* ignore blank or one-char (e.g. "/") filenames we'd return as blank */
460 if (name_len < 2 || !name[0] || !name[1]) continue;
461
462 /* empty files and directory names are stored as a file entry at
463 * offset 0 with length 0. We want to keep empty files, but not
464 * directory names, which end with a "/" */
465 if ((offset == 0) && (length == 0)) {
466 if ((name_len > 0) && (name[name_len-1] == '/')) continue;
467 }
468
469 if (section > 1) {
470 sys->message(fh, "invalid section number '%u'.", section);
471 continue;
472 }
473
474 if (!(fi = (struct mschmd_file *) sys->alloc(sys, sizeof(struct mschmd_file) + name_len + 1))) {
475 sys->free(chunk);
476 return MSPACK_ERR_NOMEMORY;
477 }
478
479 fi->next = NULL;
480 fi->filename = (char *) &fi[1];
481 fi->section = ((section == 0) ? (struct mschmd_section *) (&chm->sec0)
482 : (struct mschmd_section *) (&chm->sec1));
483 fi->offset = offset;
484 fi->length = length;
485 sys->copy(name, fi->filename, (size_t) name_len);
486 fi->filename[name_len] = '\0';
487
488 if (name[0] == ':' && name[1] == ':') {
489 /* system file */
490 if (name_len == 40 && memcmp(name, content_name, 40) == 0) {
491 chm->sec1.content = fi;
492 }
493 else if (name_len == 44 && memcmp(name, control_name, 44) == 0) {
494 chm->sec1.control = fi;
495 }
496 else if (name_len == 41 && memcmp(name, spaninfo_name, 41) == 0) {
497 chm->sec1.spaninfo = fi;
498 }
499 else if (name_len == 105 && memcmp(name, rtable_name, 105) == 0) {
500 chm->sec1.rtable = fi;
501 }
502 fi->next = chm->sysfiles;
503 chm->sysfiles = fi;
504 }
505 else {
506 /* normal file */
507 if (link) link->next = fi; else chm->files = fi;
508 link = fi;
509 }
510 }
511
512 /* this is reached either when num_entries runs out, or if
513 * reading data from the chunk reached a premature end of chunk */
514 chunk_end:
515 if (num_entries >= 0) {
516 D(("chunk ended before all entries could be read"))
517 errors++;
518 }
519
520 }
521 sys->free(chunk);
522 return (errors > 0) ? MSPACK_ERR_DATAFORMAT : MSPACK_ERR_OK;
523}
524
525/***************************************
526 * CHMD_FAST_FIND
527 ***************************************
528 * uses PMGI index chunks and quickref data to quickly locate a file
529 * directly from the on-disk index.
530 *
531 * TODO: protect against infinite loops in chunks (where pgml_NextChunk
532 * or a PMGI index entry point to an already visited chunk)
533 */
534static int chmd_fast_find(struct mschm_decompressor *base,
535 struct mschmd_header *chm, const char *filename,
536 struct mschmd_file *f_ptr, int f_size)
537{
538 struct mschm_decompressor_p *self = (struct mschm_decompressor_p *) base;
539 struct mspack_system *sys;
540 struct mspack_file *fh;
541 /* p and end are initialised to prevent MSVC warning about "potentially"
542 * uninitialised usage. This is provably untrue, but MS won't fix:
543 * https://developercommunity.visualstudio.com/content/problem/363489/c4701-false-positive-warning.html */
544 const unsigned char *chunk, *p = NULL, *end = NULL;
545 int err = MSPACK_ERR_OK, result = -1;
546 unsigned int n, sec;
547
548 if (!self || !chm || !f_ptr || (f_size != sizeof(struct mschmd_file))) {
549 return MSPACK_ERR_ARGS;
550 }
551 sys = self->system;
552
553 /* clear the results structure */
554 memset(f_ptr, 0, f_size);
555
556 if (!(fh = sys->open(sys, chm->filename, MSPACK_SYS_OPEN_READ))) {
557 return MSPACK_ERR_OPEN;
558 }
559
560 /* go through PMGI chunk hierarchy to reach PMGL chunk */
561 if (chm->index_root < chm->num_chunks) {
562 n = chm->index_root;
563 for (;;) {
564 if (!(chunk = read_chunk(self, chm, fh, n))) {
565 sys->close(fh);
566 return self->error;
567 }
568
569 /* search PMGI/PMGL chunk. exit early if no entry found */
570 if ((result = search_chunk(chm, chunk, filename, &p, &end)) <= 0) {
571 break;
572 }
573
574 /* found result. loop around for next chunk if this is PMGI */
575 if (chunk[3] == 0x4C) break; else READ_ENCINT(n);
576 }
577 }
578 else {
579 /* PMGL chunks only, search from first_pmgl to last_pmgl */
580 for (n = chm->first_pmgl; n <= chm->last_pmgl;
581 n = EndGetI32(&chunk[pmgl_NextChunk]))
582 {
583 if (!(chunk = read_chunk(self, chm, fh, n))) {
584 err = self->error;
585 break;
586 }
587
588 /* search PMGL chunk. exit if file found */
589 if ((result = search_chunk(chm, chunk, filename, &p, &end)) > 0) {
590 break;
591 }
592
593 /* stop simple infinite loops: can't visit the same chunk twice */
594 if (n == EndGetI32(&chunk[pmgl_NextChunk])) {
595 break;
596 }
597 }
598 }
599
600 /* if we found a file, read it */
601 if (result > 0) {
602 READ_ENCINT(sec);
603 f_ptr->section = (sec == 0) ? (struct mschmd_section *) &chm->sec0
604 : (struct mschmd_section *) &chm->sec1;
605 READ_ENCINT(f_ptr->offset);
606 READ_ENCINT(f_ptr->length);
607 }
608 else if (result < 0) {
609 err = MSPACK_ERR_DATAFORMAT;
610 }
611
612 sys->close(fh);
613 return self->error = err;
614
615 chunk_end:
616 D(("read beyond end of chunk entries"))
617 sys->close(fh);
618 return self->error = MSPACK_ERR_DATAFORMAT;
619}
620
621/* reads the given chunk into memory, storing it in a chunk cache
622 * so it doesn't need to be read from disk more than once
623 */
624static unsigned char *read_chunk(struct mschm_decompressor_p *self,
625 struct mschmd_header *chm,
626 struct mspack_file *fh,
627 unsigned int chunk_num)
628{
629 struct mspack_system *sys = self->system;
630 unsigned char *buf;
631
632 /* check arguments - most are already checked by chmd_fast_find */
633 if (chunk_num >= chm->num_chunks) return NULL;
634
635 /* ensure chunk cache is available */
636 if (!chm->chunk_cache) {
637 size_t size = sizeof(unsigned char *) * chm->num_chunks;
638 if (!(chm->chunk_cache = (unsigned char **) sys->alloc(sys, size))) {
639 self->error = MSPACK_ERR_NOMEMORY;
640 return NULL;
641 }
642 memset(chm->chunk_cache, 0, size);
643 }
644
645 /* try to answer out of chunk cache */
646 if (chm->chunk_cache[chunk_num]) return chm->chunk_cache[chunk_num];
647
648 /* need to read chunk - allocate memory for it */
649 if (!(buf = (unsigned char *) sys->alloc(sys, chm->chunk_size))) {
650 self->error = MSPACK_ERR_NOMEMORY;
651 return NULL;
652 }
653
654 /* seek to block and read it */
655 if (sys->seek(fh, (off_t) (chm->dir_offset + (chunk_num * chm->chunk_size)),
656 MSPACK_SYS_SEEK_START))
657 {
658 self->error = MSPACK_ERR_SEEK;
659 sys->free(buf);
660 return NULL;
661 }
662 if (sys->read(fh, buf, (int)chm->chunk_size) != (int)chm->chunk_size) {
663 self->error = MSPACK_ERR_READ;
664 sys->free(buf);
665 return NULL;
666 }
667
668 /* check the signature. Is is PMGL or PMGI? */
669 if (!((buf[0] == 0x50) && (buf[1] == 0x4D) && (buf[2] == 0x47) &&
670 ((buf[3] == 0x4C) || (buf[3] == 0x49))))
671 {
672 self->error = MSPACK_ERR_SEEK;
673 sys->free(buf);
674 return NULL;
675 }
676
677 /* all OK. Store chunk in cache and return it */
678 return chm->chunk_cache[chunk_num] = buf;
679}
680
681/* searches a PMGI/PMGL chunk for a given filename entry. Returns -1 on
682 * data format error, 0 if entry definitely not found, 1 if entry
683 * found. In the latter case, *result and *result_end are set pointing
684 * to that entry's data (either the "next chunk" ENCINT for a PMGI or
685 * the section, offset and length ENCINTs for a PMGL).
686 *
687 * In the case of PMGL chunks, the entry has definitely been
688 * found. In the case of PMGI chunks, the entry which points to the
689 * chunk that may eventually contain that entry has been found.
690 */
691static int search_chunk(struct mschmd_header *chm,
692 const unsigned char *chunk,
693 const char *filename,
694 const unsigned char **result,
695 const unsigned char **result_end)
696{
697 const unsigned char *start, *end, *p;
698 unsigned int qr_size, num_entries, qr_entries, qr_density, name_len;
699 unsigned int L, R, M, fname_len, entries_off, is_pmgl;
700 int cmp;
701
702 fname_len = strlen(filename);
703
704 /* PMGL chunk or PMGI chunk? (note: read_chunk() has already
705 * checked the rest of the characters in the chunk signature) */
706 if (chunk[3] == 0x4C) {
707 is_pmgl = 1;
708 entries_off = pmgl_Entries;
709 }
710 else {
711 is_pmgl = 0;
712 entries_off = pmgi_Entries;
713 }
714
715 /* Step 1: binary search first filename of each QR entry
716 * - target filename == entry
717 * found file
718 * - target filename < all entries
719 * file not found
720 * - target filename > all entries
721 * proceed to step 2 using final entry
722 * - target filename between two searched entries
723 * proceed to step 2
724 */
725 qr_size = EndGetI32(&chunk[pmgl_QuickRefSize]);
726 start = &chunk[chm->chunk_size - 2];
727 end = &chunk[chm->chunk_size - qr_size];
728 num_entries = EndGetI16(start);
729 qr_density = 1 + (1 << chm->density);
730 qr_entries = (num_entries + qr_density-1) / qr_density;
731
732 if (num_entries == 0) {
733 D(("chunk has no entries"))
734 return -1;
735 }
736
737 if (qr_size > chm->chunk_size) {
738 D(("quickref size > chunk size"))
739 return -1;
740 }
741
742 *result_end = end;
743
744 if (((int)qr_entries * 2) > (start - end)) {
745 D(("WARNING; more quickrefs than quickref space"))
746 qr_entries = 0; /* but we can live with it */
747 }
748
749 if (qr_entries > 0) {
750 L = 0;
751 R = qr_entries - 1;
752 do {
753 /* pick new midpoint */
754 M = (L + R) >> 1;
755
756 /* compare filename with entry QR points to */
757 p = &chunk[entries_off + (M ? EndGetI16(start - (M << 1)) : 0)];
758 READ_ENCINT(name_len);
759 if (name_len > (unsigned int) (end - p)) goto chunk_end;
760 cmp = compare(filename, (char *)p, fname_len, name_len);
761
762 if (cmp == 0) break;
763 else if (cmp < 0) { if (M) R = M - 1; else return 0; }
764 else if (cmp > 0) L = M + 1;
765 } while (L <= R);
766 M = (L + R) >> 1;
767
768 if (cmp == 0) {
769 /* exact match! */
770 p += name_len;
771 *result = p;
772 return 1;
773 }
774
775 /* otherwise, read the group of entries for QR entry M */
776 p = &chunk[entries_off + (M ? EndGetI16(start - (M << 1)) : 0)];
777 num_entries -= (M * qr_density);
778 if (num_entries > qr_density) num_entries = qr_density;
779 }
780 else {
781 p = &chunk[entries_off];
782 }
783
784 /* Step 2: linear search through the set of entries reached in step 1.
785 * - filename == any entry
786 * found entry
787 * - filename < all entries (PMGI) or any entry (PMGL)
788 * entry not found, stop now
789 * - filename > all entries
790 * entry not found (PMGL) / maybe found (PMGI)
791 * -
792 */
793 *result = NULL;
794 while (num_entries-- > 0) {
795 READ_ENCINT(name_len);
796 if (name_len > (unsigned int) (end - p)) goto chunk_end;
797 cmp = compare(filename, (char *)p, fname_len, name_len);
798 p += name_len;
799
800 if (cmp == 0) {
801 /* entry found */
802 *result = p;
803 return 1;
804 }
805
806 if (cmp < 0) {
807 /* entry not found (PMGL) / maybe found (PMGI) */
808 break;
809 }
810
811 /* read and ignore the rest of this entry */
812 if (is_pmgl) {
813 READ_ENCINT(R); /* skip section */
814 READ_ENCINT(R); /* skip offset */
815 READ_ENCINT(R); /* skip length */
816 }
817 else {
818 *result = p; /* store potential final result */
819 READ_ENCINT(R); /* skip chunk number */
820 }
821 }
822
823 /* PMGL? not found. PMGI? maybe found */
824 return (is_pmgl) ? 0 : (*result ? 1 : 0);
825
826 chunk_end:
827 D(("reached end of chunk data while searching"))
828 return -1;
829}
830
831#if HAVE_TOWLOWER
832# include <wctype.h>
833# define TOLOWER(x) towlower(x)
834#else
835# include <ctype.h>
836# define TOLOWER(x) tolower(x)
837#endif
838
839/* decodes a UTF-8 character from s[] into c. Will not read past e.
840 * doesn't test that extension bytes are %10xxxxxx.
841 * allows some overlong encodings.
842 */
843#define GET_UTF8_CHAR(s, e, c) do { \
844 unsigned char x = *s++; \
845 if (x < 0x80) c = x; \
846 else if (x >= 0xC2 && x < 0xE0 && s < e) { \
847 c = (x & 0x1F) << 6 | (*s++ & 0x3F); \
848 } \
849 else if (x >= 0xE0 && x < 0xF0 && s+1 < e) { \
850 c = (x & 0x0F) << 12 | (s[0] & 0x3F) << 6 | (s[1] & 0x3F); \
851 s += 2; \
852 } \
853 else if (x >= 0xF0 && x <= 0xF5 && s+2 < e) { \
854 c = (x & 0x07) << 18 | (s[0] & 0x3F) << 12 | \
855 (s[1] & 0x3F) << 6 | (s[2] & 0x3F); \
856 if (c > 0x10FFFF) c = 0xFFFD; \
857 s += 3; \
858 } \
859 else c = 0xFFFD; \
860} while (0)
861
862/* case-insensitively compares two UTF8 encoded strings. String length for
863 * both strings must be provided, null bytes are not terminators */
864static inline int compare(const char *s1, const char *s2, int l1, int l2) {
865 register const unsigned char *p1 = (const unsigned char *) s1;
866 register const unsigned char *p2 = (const unsigned char *) s2;
867 register const unsigned char *e1 = p1 + l1, *e2 = p2 + l2;
868 int c1, c2;
869
870 while (p1 < e1 && p2 < e2) {
871 GET_UTF8_CHAR(p1, e1, c1);
872 GET_UTF8_CHAR(p2, e2, c2);
873 if (c1 == c2) continue;
874 c1 = TOLOWER(c1);
875 c2 = TOLOWER(c2);
876 if (c1 != c2) return c1 - c2;
877 }
878 return l1 - l2;
879}
880
881
882/***************************************
883 * CHMD_EXTRACT
884 ***************************************
885 * extracts a file from a CHM helpfile
886 */
887static int chmd_extract(struct mschm_decompressor *base,
888 struct mschmd_file *file, const char *filename)
889{
890 struct mschm_decompressor_p *self = (struct mschm_decompressor_p *) base;
891 struct mspack_system *sys;
892 struct mschmd_header *chm;
893 struct mspack_file *fh;
894 off_t bytes;
895
896 if (!self) return MSPACK_ERR_ARGS;
897 if (!file || !file->section) return self->error = MSPACK_ERR_ARGS;
898 sys = self->system;
899 chm = file->section->chm;
900
901 /* create decompression state if it doesn't exist */
902 if (!self->d) {
903 self->d = (struct mschmd_decompress_state *) sys->alloc(sys, sizeof(struct mschmd_decompress_state));
904 if (!self->d) return self->error = MSPACK_ERR_NOMEMORY;
905 self->d->chm = chm;
906 self->d->offset = 0;
907 self->d->state = NULL;
908 self->d->sys = *sys;
909 self->d->sys.write = &chmd_sys_write;
910 self->d->infh = NULL;
911 self->d->outfh = NULL;
912 }
913
914 /* open input chm file if not open, or the open one is a different chm */
915 if (!self->d->infh || (self->d->chm != chm)) {
916 if (self->d->infh) sys->close(self->d->infh);
917 if (self->d->state) lzxd_free(self->d->state);
918 self->d->chm = chm;
919 self->d->offset = 0;
920 self->d->state = NULL;
921 self->d->infh = sys->open(sys, chm->filename, MSPACK_SYS_OPEN_READ);
922 if (!self->d->infh) return self->error = MSPACK_ERR_OPEN;
923 }
924
925 /* open file for output */
926 if (!(fh = sys->open(sys, filename, MSPACK_SYS_OPEN_WRITE))) {
927 return self->error = MSPACK_ERR_OPEN;
928 }
929
930 /* if file is empty, simply creating it is enough */
931 if (!file->length) {
932 sys->close(fh);
933 return self->error = MSPACK_ERR_OK;
934 }
935
936 self->error = MSPACK_ERR_OK;
937
938 switch (file->section->id) {
939 case 0: /* Uncompressed section file */
940 /* simple seek + copy */
941 if (sys->seek(self->d->infh, file->section->chm->sec0.offset
942 + file->offset, MSPACK_SYS_SEEK_START))
943 {
944 self->error = MSPACK_ERR_SEEK;
945 }
946 else {
947 unsigned char buf[512];
948 off_t length = file->length;
949 while (length > 0) {
950 int run = sizeof(buf);
951 if ((off_t)run > length) run = (int)length;
952 if (sys->read(self->d->infh, &buf[0], run) != run) {
953 self->error = MSPACK_ERR_READ;
954 break;
955 }
956 if (sys->write(fh, &buf[0], run) != run) {
957 self->error = MSPACK_ERR_WRITE;
958 break;
959 }
960 length -= run;
961 }
962 }
963 break;
964
965 case 1: /* MSCompressed section file */
966 /* (re)initialise compression state if we it is not yet initialised,
967 * or we have advanced too far and have to backtrack
968 */
969 if (!self->d->state || (file->offset < self->d->offset)) {
970 if (self->d->state) {
971 lzxd_free(self->d->state);
972 self->d->state = NULL;
973 }
974 if (chmd_init_decomp(self, file)) break;
975 }
976
977 /* seek to input data */
978 if (sys->seek(self->d->infh, self->d->inoffset, MSPACK_SYS_SEEK_START)) {
979 self->error = MSPACK_ERR_SEEK;
980 break;
981 }
982
983 /* get to correct offset. */
984 self->d->outfh = NULL;
985 if ((bytes = file->offset - self->d->offset)) {
986 self->error = lzxd_decompress(self->d->state, bytes);
987 }
988
989 /* if getting to the correct offset was error free, unpack file */
990 if (!self->error) {
991 self->d->outfh = fh;
992 self->error = lzxd_decompress(self->d->state, file->length);
993 }
994
995 /* save offset in input source stream, in case there is a section 0
996 * file between now and the next section 1 file extracted */
997 self->d->inoffset = sys->tell(self->d->infh);
998
999 /* if an LZX error occured, the LZX decompressor is now useless */
1000 if (self->error) {
1001 if (self->d->state) lzxd_free(self->d->state);
1002 self->d->state = NULL;
1003 }
1004 break;
1005 }
1006
1007 sys->close(fh);
1008 return self->error;
1009}
1010
1011/***************************************
1012 * CHMD_SYS_WRITE
1013 ***************************************
1014 * chmd_sys_write is the internal writer function which the decompressor
1015 * uses. If either writes data to disk (self->d->outfh) with the real
1016 * sys->write() function, or does nothing with the data when
1017 * self->d->outfh == NULL. advances self->d->offset.
1018 */
1019static int chmd_sys_write(struct mspack_file *file, void *buffer, int bytes) {
1020 struct mschm_decompressor_p *self = (struct mschm_decompressor_p *) file;
1021 self->d->offset += bytes;
1022 if (self->d->outfh) {
1023 return self->system->write(self->d->outfh, buffer, bytes);
1024 }
1025 return bytes;
1026}
1027
1028/***************************************
1029 * CHMD_INIT_DECOMP
1030 ***************************************
1031 * Initialises the LZX decompressor to decompress the compressed stream,
1032 * from the nearest reset offset and length that is needed for the given
1033 * file.
1034 */
1035static int chmd_init_decomp(struct mschm_decompressor_p *self,
1036 struct mschmd_file *file)
1037{
1038 int window_size, window_bits, reset_interval, entry, err;
1039 struct mspack_system *sys = self->system;
1040 struct mschmd_sec_mscompressed *sec;
1041 unsigned char *data;
1042 off_t length, offset;
1043
1044 sec = (struct mschmd_sec_mscompressed *) file->section;
1045
1046 /* ensure we have a mscompressed content section */
1047 err = find_sys_file(self, sec, &sec->content, content_name);
1048 if (err) return self->error = err;
1049
1050 /* ensure we have a ControlData file */
1051 err = find_sys_file(self, sec, &sec->control, control_name);
1052 if (err) return self->error = err;
1053
1054 /* read ControlData */
1055 if (sec->control->length < lzxcd_SIZEOF) {
1056 D(("ControlData file is too short"))
1057 return self->error = MSPACK_ERR_DATAFORMAT;
1058 }
1059 if (!(data = read_sys_file(self, sec->control))) {
1060 D(("can't read mscompressed control data file"))
1061 return self->error;
1062 }
1063
1064 /* check LZXC signature */
1065 if (EndGetI32(&data[lzxcd_Signature]) != 0x43585A4C) {
1066 sys->free(data);
1067 return self->error = MSPACK_ERR_SIGNATURE;
1068 }
1069
1070 /* read reset_interval and window_size and validate version number */
1071 switch (EndGetI32(&data[lzxcd_Version])) {
1072 case 1:
1073 reset_interval = EndGetI32(&data[lzxcd_ResetInterval]);
1074 window_size = EndGetI32(&data[lzxcd_WindowSize]);
1075 break;
1076 case 2:
1077 reset_interval = EndGetI32(&data[lzxcd_ResetInterval]) * LZX_FRAME_SIZE;
1078 window_size = EndGetI32(&data[lzxcd_WindowSize]) * LZX_FRAME_SIZE;
1079 break;
1080 default:
1081 D(("bad controldata version"))
1082 sys->free(data);
1083 return self->error = MSPACK_ERR_DATAFORMAT;
1084 }
1085
1086 /* free ControlData */
1087 sys->free(data);
1088
1089 /* find window_bits from window_size */
1090 switch (window_size) {
1091 case 0x008000: window_bits = 15; break;
1092 case 0x010000: window_bits = 16; break;
1093 case 0x020000: window_bits = 17; break;
1094 case 0x040000: window_bits = 18; break;
1095 case 0x080000: window_bits = 19; break;
1096 case 0x100000: window_bits = 20; break;
1097 case 0x200000: window_bits = 21; break;
1098 default:
1099 D(("bad controldata window size"))
1100 return self->error = MSPACK_ERR_DATAFORMAT;
1101 }
1102
1103 /* validate reset_interval */
1104 if (reset_interval == 0 || reset_interval % LZX_FRAME_SIZE) {
1105 D(("bad controldata reset interval"))
1106 return self->error = MSPACK_ERR_DATAFORMAT;
1107 }
1108
1109 /* which reset table entry would we like? */
1110 entry = file->offset / reset_interval;
1111 /* convert from reset interval multiple (usually 64k) to 32k frames */
1112 entry *= reset_interval / LZX_FRAME_SIZE;
1113
1114 /* read the reset table entry */
1115 if (read_reset_table(self, sec, entry, &length, &offset)) {
1116 /* the uncompressed length given in the reset table is dishonest.
1117 * the uncompressed data is always padded out from the given
1118 * uncompressed length up to the next reset interval */
1119 length += reset_interval - 1;
1120 length &= -reset_interval;
1121 }
1122 else {
1123 /* if we can't read the reset table entry, just start from
1124 * the beginning. Use spaninfo to get the uncompressed length */
1125 entry = 0;
1126 offset = 0;
1127 err = read_spaninfo(self, sec, &length);
1128 }
1129 if (err) return self->error = err;
1130
1131 /* get offset of compressed data stream:
1132 * = offset of uncompressed section from start of file
1133 * + offset of compressed stream from start of uncompressed section
1134 * + offset of chosen reset interval from start of compressed stream */
1135 self->d->inoffset = file->section->chm->sec0.offset + sec->content->offset + offset;
1136
1137 /* set start offset and overall remaining stream length */
1138 self->d->offset = entry * LZX_FRAME_SIZE;
1139 length -= self->d->offset;
1140
1141 /* initialise LZX stream */
1142 self->d->state = lzxd_init(&self->d->sys, self->d->infh,
1143 (struct mspack_file *) self, window_bits,
1144 reset_interval / LZX_FRAME_SIZE,
1145 4096, length, 0);
1146 if (!self->d->state) self->error = MSPACK_ERR_NOMEMORY;
1147 return self->error;
1148}
1149
1150/***************************************
1151 * READ_RESET_TABLE
1152 ***************************************
1153 * Reads one entry out of the reset table. Also reads the uncompressed
1154 * data length. Writes these to offset_ptr and length_ptr respectively.
1155 * Returns non-zero for success, zero for failure.
1156 */
1157static int read_reset_table(struct mschm_decompressor_p *self,
1158 struct mschmd_sec_mscompressed *sec,
1159 unsigned int entry,
1160 off_t *length_ptr, off_t *offset_ptr)
1161{
1162 struct mspack_system *sys = self->system;
1163 unsigned char *data;
1164 unsigned int pos, entrysize;
1165
1166 /* do we have a ResetTable file? */
1167 int err = find_sys_file(self, sec, &sec->rtable, rtable_name);
1168 if (err) return 0;
1169
1170 /* read ResetTable file */
1171 if (sec->rtable->length < lzxrt_headerSIZEOF) {
1172 D(("ResetTable file is too short"))
1173 return 0;
1174 }
1175 if (!(data = read_sys_file(self, sec->rtable))) {
1176 D(("can't read reset table"))
1177 return 0;
1178 }
1179
1180 /* check sanity of reset table */
1181 if (EndGetI32(&data[lzxrt_FrameLen]) != LZX_FRAME_SIZE) {
1182 D(("bad reset table frame length"))
1183 sys->free(data);
1184 return 0;
1185 }
1186
1187 /* get the uncompressed length of the LZX stream */
1188 if (read_off64(length_ptr, &data[lzxrt_UncompLen], sys, self->d->infh)) {
1189 sys->free(data);
1190 return 0;
1191 }
1192
1193 entrysize = EndGetI32(&data[lzxrt_EntrySize]);
1194 pos = EndGetI32(&data[lzxrt_TableOffset]) + (entry * entrysize);
1195
1196 /* ensure reset table entry for this offset exists */
1197 if (entry < EndGetI32(&data[lzxrt_NumEntries]) &&
1198 pos <= (sec->rtable->length - entrysize))
1199 {
1200 switch (entrysize) {
1201 case 4:
1202 *offset_ptr = EndGetI32(&data[pos]);
1203 err = 0;
1204 break;
1205 case 8:
1206 err = read_off64(offset_ptr, &data[pos], sys, self->d->infh);
1207 break;
1208 default:
1209 D(("reset table entry size neither 4 nor 8"))
1210 err = 1;
1211 break;
1212 }
1213 }
1214 else {
1215 D(("bad reset interval"))
1216 err = 1;
1217 }
1218
1219 /* free the reset table */
1220 sys->free(data);
1221
1222 /* return success */
1223 return (err == 0);
1224}
1225
1226/***************************************
1227 * READ_SPANINFO
1228 ***************************************
1229 * Reads the uncompressed data length from the spaninfo file.
1230 * Returns zero for success or a non-zero error code for failure.
1231 */
1232static int read_spaninfo(struct mschm_decompressor_p *self,
1233 struct mschmd_sec_mscompressed *sec,
1234 off_t *length_ptr)
1235{
1236 struct mspack_system *sys = self->system;
1237 unsigned char *data;
1238
1239 /* find SpanInfo file */
1240 int err = find_sys_file(self, sec, &sec->spaninfo, spaninfo_name);
1241 if (err) return MSPACK_ERR_DATAFORMAT;
1242
1243 /* check it's large enough */
1244 if (sec->spaninfo->length != 8) {
1245 D(("SpanInfo file is wrong size"))
1246 return MSPACK_ERR_DATAFORMAT;
1247 }
1248
1249 /* read the SpanInfo file */
1250 if (!(data = read_sys_file(self, sec->spaninfo))) {
1251 D(("can't read SpanInfo file"))
1252 return self->error;
1253 }
1254
1255 /* get the uncompressed length of the LZX stream */
1256 err = read_off64(length_ptr, data, sys, self->d->infh);
1257 sys->free(data);
1258 if (err) return MSPACK_ERR_DATAFORMAT;
1259
1260 if (*length_ptr <= 0) {
1261 D(("output length is invalid"))
1262 return MSPACK_ERR_DATAFORMAT;
1263 }
1264
1265 return MSPACK_ERR_OK;
1266}
1267
1268/***************************************
1269 * FIND_SYS_FILE
1270 ***************************************
1271 * Uses chmd_fast_find to locate a system file, and fills out that system
1272 * file's entry and links it into the list of system files. Returns zero
1273 * for success, non-zero for both failure and the file not existing.
1274 */
1275static int find_sys_file(struct mschm_decompressor_p *self,
1276 struct mschmd_sec_mscompressed *sec,
1277 struct mschmd_file **f_ptr, const char *name)
1278{
1279 struct mspack_system *sys = self->system;
1280 struct mschmd_file result;
1281
1282 /* already loaded */
1283 if (*f_ptr) return MSPACK_ERR_OK;
1284
1285 /* try using fast_find to find the file - return DATAFORMAT error if
1286 * it fails, or successfully doesn't find the file */
1287 if (chmd_fast_find((struct mschm_decompressor *) self, sec->base.chm,
1288 name, &result, (int)sizeof(result)) || !result.section)
1289 {
1290 return MSPACK_ERR_DATAFORMAT;
1291 }
1292
1293 if (!(*f_ptr = (struct mschmd_file *) sys->alloc(sys, sizeof(result)))) {
1294 return MSPACK_ERR_NOMEMORY;
1295 }
1296
1297 /* copy result */
1298 *(*f_ptr) = result;
1299 (*f_ptr)->filename = (char *) name;
1300
1301 /* link file into sysfiles list */
1302 (*f_ptr)->next = sec->base.chm->sysfiles;
1303 sec->base.chm->sysfiles = *f_ptr;
1304 return MSPACK_ERR_OK;
1305}
1306
1307/***************************************
1308 * READ_SYS_FILE
1309 ***************************************
1310 * Allocates memory for a section 0 (uncompressed) file and reads it into
1311 * memory.
1312 */
1313static unsigned char *read_sys_file(struct mschm_decompressor_p *self,
1314 struct mschmd_file *file)
1315{
1316 struct mspack_system *sys = self->system;
1317 unsigned char *data = NULL;
1318 int len;
1319
1320 if (!file || !file->section || (file->section->id != 0)) {
1321 self->error = MSPACK_ERR_DATAFORMAT;
1322 return NULL;
1323 }
1324
1325 len = (int) file->length;
1326
1327 if (!(data = (unsigned char *) sys->alloc(sys, (size_t) len))) {
1328 self->error = MSPACK_ERR_NOMEMORY;
1329 return NULL;
1330 }
1331 if (sys->seek(self->d->infh, file->section->chm->sec0.offset
1332 + file->offset, MSPACK_SYS_SEEK_START))
1333 {
1334 self->error = MSPACK_ERR_SEEK;
1335 sys->free(data);
1336 return NULL;
1337 }
1338 if (sys->read(self->d->infh, data, len) != len) {
1339 self->error = MSPACK_ERR_READ;
1340 sys->free(data);
1341 return NULL;
1342 }
1343 return data;
1344}
1345
1346/***************************************
1347 * CHMD_ERROR
1348 ***************************************
1349 * returns the last error that occurred
1350 */
1351static int chmd_error(struct mschm_decompressor *base) {
1352 struct mschm_decompressor_p *self = (struct mschm_decompressor_p *) base;
1353 return (self) ? self->error : MSPACK_ERR_ARGS;
1354}
1355
1356/***************************************
1357 * READ_OFF64
1358 ***************************************
1359 * Reads a 64-bit signed integer from memory in Intel byte order.
1360 * If running on a system with a 64-bit off_t, this is simply done.
1361 * If running on a system with a 32-bit off_t, offsets up to 0x7FFFFFFF
1362 * are accepted, offsets beyond that cause an error message.
1363 */
1364static int read_off64(off_t *var, unsigned char *mem,
1365 struct mspack_system *sys, struct mspack_file *fh)
1366{
1367#if LARGEFILE_SUPPORT
1368 *var = EndGetI64(mem);
1369#else
1370 *var = EndGetI32(mem);
1371 if ((*var & 0x80000000) || EndGetI32(mem+4)) {
1372 sys->message(fh, (char *)largefile_msg);
1373 return 1;
1374 }
1375#endif
1376 return 0;
1377}
diff --git a/utils/rbutilqt/mspack/des.h b/utils/rbutilqt/mspack/des.h
new file mode 100644
index 0000000000..64a1ed27e4
--- /dev/null
+++ b/utils/rbutilqt/mspack/des.h
@@ -0,0 +1,15 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10#ifndef MSPACK_DES_H
11#define MSPACK_DES_H 1
12
13/* DES encryption / decryption definitions */
14
15#endif
diff --git a/utils/rbutilqt/mspack/hlp.h b/utils/rbutilqt/mspack/hlp.h
new file mode 100644
index 0000000000..a6e3abc7ff
--- /dev/null
+++ b/utils/rbutilqt/mspack/hlp.h
@@ -0,0 +1,33 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10#ifndef MSPACK_HLP_H
11#define MSPACK_HLP_H 1
12
13#include "lzss.h"
14
15/* generic HLP definitions */
16
17/* HLP compression definitions */
18
19struct mshlp_compressor_p {
20 struct mshlp_compressor base;
21 struct mspack_system *system;
22 /* todo */
23};
24
25/* HLP decompression definitions */
26
27struct mshlp_decompressor_p {
28 struct mshlp_decompressor base;
29 struct mspack_system *system;
30 /* todo */
31};
32
33#endif
diff --git a/utils/rbutilqt/mspack/hlpc.c b/utils/rbutilqt/mspack/hlpc.c
new file mode 100644
index 0000000000..b33e499f65
--- /dev/null
+++ b/utils/rbutilqt/mspack/hlpc.c
@@ -0,0 +1,24 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10/* HLP compression implementation */
11
12#include "system-mspack.h"
13#include "hlp.h"
14
15struct mshlp_compressor *
16 mspack_create_hlp_compressor(struct mspack_system *sys)
17{
18 /* todo */
19 return NULL;
20}
21
22void mspack_destroy_hlp_compressor(struct mshlp_compressor *self) {
23 /* todo */
24}
diff --git a/utils/rbutilqt/mspack/hlpd.c b/utils/rbutilqt/mspack/hlpd.c
new file mode 100644
index 0000000000..ae1f2efba8
--- /dev/null
+++ b/utils/rbutilqt/mspack/hlpd.c
@@ -0,0 +1,24 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10/* HLP decompression implementation */
11
12#include "system-mspack.h"
13#include "hlp.h"
14
15struct mshlp_decompressor *
16 mspack_create_hlp_decompressor(struct mspack_system *sys)
17{
18 /* todo */
19 return NULL;
20}
21
22void mspack_destroy_hlp_decompressor(struct mshlp_decompressor *self) {
23 /* todo */
24}
diff --git a/utils/rbutilqt/mspack/kwaj.h b/utils/rbutilqt/mspack/kwaj.h
new file mode 100644
index 0000000000..75425d958a
--- /dev/null
+++ b/utils/rbutilqt/mspack/kwaj.h
@@ -0,0 +1,118 @@
1/* This file is part of libmspack.
2 * (C) 2003-2010 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10#ifndef MSPACK_KWAJ_H
11#define MSPACK_KWAJ_H 1
12
13#include "lzss.h"
14
15/* generic KWAJ definitions */
16#define kwajh_Signature1 (0x00)
17#define kwajh_Signature2 (0x04)
18#define kwajh_CompMethod (0x08)
19#define kwajh_DataOffset (0x0a)
20#define kwajh_Flags (0x0c)
21#define kwajh_SIZEOF (0x0e)
22
23/* KWAJ compression definitions */
24
25struct mskwaj_compressor_p {
26 struct mskwaj_compressor base;
27 struct mspack_system *system;
28 /* todo */
29 int param[2]; /* !!! MATCH THIS TO NUM OF PARAMS IN MSPACK.H !!! */
30 int error;
31};
32
33/* KWAJ decompression definitions */
34
35struct mskwaj_decompressor_p {
36 struct mskwaj_decompressor base;
37 struct mspack_system *system;
38 int error;
39};
40
41struct mskwajd_header_p {
42 struct mskwajd_header base;
43 struct mspack_file *fh;
44};
45
46/* input buffer size during decompression - not worth parameterising IMHO */
47#define KWAJ_INPUT_SIZE (2048)
48
49/* huffman codes that are 9 bits or less are decoded immediately */
50#define KWAJ_TABLEBITS (9)
51
52/* number of codes in each huffman table */
53#define KWAJ_MATCHLEN1_SYMS (16)
54#define KWAJ_MATCHLEN2_SYMS (16)
55#define KWAJ_LITLEN_SYMS (32)
56#define KWAJ_OFFSET_SYMS (64)
57#define KWAJ_LITERAL_SYMS (256)
58
59/* define decoding table sizes */
60#define KWAJ_TABLESIZE (1 << KWAJ_TABLEBITS)
61#if KWAJ_TABLESIZE < (KWAJ_MATCHLEN1_SYMS * 2)
62# define KWAJ_MATCHLEN1_TBLSIZE (KWAJ_MATCHLEN1_SYMS * 4)
63#else
64# define KWAJ_MATCHLEN1_TBLSIZE (KWAJ_TABLESIZE + (KWAJ_MATCHLEN1_SYMS * 2))
65#endif
66#if KWAJ_TABLESIZE < (KWAJ_MATCHLEN2_SYMS * 2)
67# define KWAJ_MATCHLEN2_TBLSIZE (KWAJ_MATCHLEN2_SYMS * 4)
68#else
69# define KWAJ_MATCHLEN2_TBLSIZE (KWAJ_TABLESIZE + (KWAJ_MATCHLEN2_SYMS * 2))
70#endif
71#if KWAJ_TABLESIZE < (KWAJ_LITLEN_SYMS * 2)
72# define KWAJ_LITLEN_TBLSIZE (KWAJ_LITLEN_SYMS * 4)
73#else
74# define KWAJ_LITLEN_TBLSIZE (KWAJ_TABLESIZE + (KWAJ_LITLEN_SYMS * 2))
75#endif
76#if KWAJ_TABLESIZE < (KWAJ_OFFSET_SYMS * 2)
77# define KWAJ_OFFSET_TBLSIZE (KWAJ_OFFSET_SYMS * 4)
78#else
79# define KWAJ_OFFSET_TBLSIZE (KWAJ_TABLESIZE + (KWAJ_OFFSET_SYMS * 2))
80#endif
81#if KWAJ_TABLESIZE < (KWAJ_LITERAL_SYMS * 2)
82# define KWAJ_LITERAL_TBLSIZE (KWAJ_LITERAL_SYMS * 4)
83#else
84# define KWAJ_LITERAL_TBLSIZE (KWAJ_TABLESIZE + (KWAJ_LITERAL_SYMS * 2))
85#endif
86
87struct kwajd_stream {
88 /* I/O buffering */
89 struct mspack_system *sys;
90 struct mspack_file *input;
91 struct mspack_file *output;
92 unsigned char *i_ptr, *i_end;
93 unsigned int bit_buffer, bits_left;
94 int input_end;
95
96 /* huffman code lengths */
97 unsigned char MATCHLEN1_len [KWAJ_MATCHLEN1_SYMS];
98 unsigned char MATCHLEN2_len [KWAJ_MATCHLEN2_SYMS];
99 unsigned char LITLEN_len [KWAJ_LITLEN_SYMS];
100 unsigned char OFFSET_len [KWAJ_OFFSET_SYMS];
101 unsigned char LITERAL_len [KWAJ_LITERAL_SYMS];
102
103 /* huffman decoding tables */
104 unsigned short MATCHLEN1_table [KWAJ_MATCHLEN1_TBLSIZE];
105 unsigned short MATCHLEN2_table [KWAJ_MATCHLEN2_TBLSIZE];
106 unsigned short LITLEN_table [KWAJ_LITLEN_TBLSIZE];
107 unsigned short OFFSET_table [KWAJ_OFFSET_TBLSIZE];
108 unsigned short LITERAL_table [KWAJ_LITERAL_TBLSIZE];
109
110 /* input buffer */
111 unsigned char inbuf[KWAJ_INPUT_SIZE];
112
113 /* history window */
114 unsigned char window[LZSS_WINDOW_SIZE];
115};
116
117
118#endif
diff --git a/utils/rbutilqt/mspack/kwajc.c b/utils/rbutilqt/mspack/kwajc.c
new file mode 100644
index 0000000000..52ca29432a
--- /dev/null
+++ b/utils/rbutilqt/mspack/kwajc.c
@@ -0,0 +1,24 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10/* KWAJ compression implementation */
11
12#include "system-mspack.h"
13#include "kwaj.h"
14
15struct mskwaj_compressor *
16 mspack_create_kwaj_compressor(struct mspack_system *sys)
17{
18 /* todo */
19 return NULL;
20}
21
22void mspack_destroy_kwaj_compressor(struct mskwaj_compressor *self) {
23 /* todo */
24}
diff --git a/utils/rbutilqt/mspack/kwajd.c b/utils/rbutilqt/mspack/kwajd.c
new file mode 100644
index 0000000000..24e0b0613b
--- /dev/null
+++ b/utils/rbutilqt/mspack/kwajd.c
@@ -0,0 +1,566 @@
1/* This file is part of libmspack.
2 * (C) 2003-2011 Stuart Caie.
3 *
4 * KWAJ is a format very similar to SZDD. KWAJ method 3 (LZH) was
5 * written by Jeff Johnson.
6 *
7 * libmspack is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
9 *
10 * For further details, see the file COPYING.LIB distributed with libmspack
11 */
12
13/* KWAJ decompression implementation */
14
15#include "system-mspack.h"
16#include "kwaj.h"
17#include "mszip.h"
18
19/* prototypes */
20static struct mskwajd_header *kwajd_open(
21 struct mskwaj_decompressor *base, const char *filename);
22static void kwajd_close(
23 struct mskwaj_decompressor *base, struct mskwajd_header *hdr);
24static int kwajd_read_headers(
25 struct mspack_system *sys, struct mspack_file *fh,
26 struct mskwajd_header *hdr);
27static int kwajd_extract(
28 struct mskwaj_decompressor *base, struct mskwajd_header *hdr,
29 const char *filename);
30static int kwajd_decompress(
31 struct mskwaj_decompressor *base, const char *input, const char *output);
32static int kwajd_error(
33 struct mskwaj_decompressor *base);
34
35static struct kwajd_stream *lzh_init(
36 struct mspack_system *sys, struct mspack_file *in, struct mspack_file *out);
37static int lzh_decompress(
38 struct kwajd_stream *kwaj);
39static void lzh_free(
40 struct kwajd_stream *kwaj);
41static int lzh_read_lens(
42 struct kwajd_stream *kwaj,
43 unsigned int type, unsigned int numsyms,
44 unsigned char *lens);
45static int lzh_read_input(
46 struct kwajd_stream *kwaj);
47
48
49/***************************************
50 * MSPACK_CREATE_KWAJ_DECOMPRESSOR
51 ***************************************
52 * constructor
53 */
54struct mskwaj_decompressor *
55 mspack_create_kwaj_decompressor(struct mspack_system *sys)
56{
57 struct mskwaj_decompressor_p *self = NULL;
58
59 if (!sys) sys = mspack_default_system;
60 if (!mspack_valid_system(sys)) return NULL;
61
62 if ((self = (struct mskwaj_decompressor_p *) sys->alloc(sys, sizeof(struct mskwaj_decompressor_p)))) {
63 self->base.open = &kwajd_open;
64 self->base.close = &kwajd_close;
65 self->base.extract = &kwajd_extract;
66 self->base.decompress = &kwajd_decompress;
67 self->base.last_error = &kwajd_error;
68 self->system = sys;
69 self->error = MSPACK_ERR_OK;
70 }
71 return (struct mskwaj_decompressor *) self;
72}
73
74/***************************************
75 * MSPACK_DESTROY_KWAJ_DECOMPRESSOR
76 ***************************************
77 * destructor
78 */
79void mspack_destroy_kwaj_decompressor(struct mskwaj_decompressor *base)
80{
81 struct mskwaj_decompressor_p *self = (struct mskwaj_decompressor_p *) base;
82 if (self) {
83 struct mspack_system *sys = self->system;
84 sys->free(self);
85 }
86}
87
88/***************************************
89 * KWAJD_OPEN
90 ***************************************
91 * opens a KWAJ file without decompressing, reads header
92 */
93static struct mskwajd_header *kwajd_open(struct mskwaj_decompressor *base,
94 const char *filename)
95{
96 struct mskwaj_decompressor_p *self = (struct mskwaj_decompressor_p *) base;
97 struct mskwajd_header *hdr;
98 struct mspack_system *sys;
99 struct mspack_file *fh;
100
101 if (!self) return NULL;
102 sys = self->system;
103
104 fh = sys->open(sys, filename, MSPACK_SYS_OPEN_READ);
105 hdr = (struct mskwajd_header *) sys->alloc(sys, sizeof(struct mskwajd_header_p));
106 if (fh && hdr) {
107 ((struct mskwajd_header_p *) hdr)->fh = fh;
108 self->error = kwajd_read_headers(sys, fh, hdr);
109 }
110 else {
111 if (!fh) self->error = MSPACK_ERR_OPEN;
112 if (!hdr) self->error = MSPACK_ERR_NOMEMORY;
113 }
114
115 if (self->error) {
116 if (fh) sys->close(fh);
117 sys->free(hdr);
118 hdr = NULL;
119 }
120
121 return hdr;
122}
123
124/***************************************
125 * KWAJD_CLOSE
126 ***************************************
127 * closes a KWAJ file
128 */
129static void kwajd_close(struct mskwaj_decompressor *base,
130 struct mskwajd_header *hdr)
131{
132 struct mskwaj_decompressor_p *self = (struct mskwaj_decompressor_p *) base;
133 struct mskwajd_header_p *hdr_p = (struct mskwajd_header_p *) hdr;
134
135 if (!self || !self->system) return;
136
137 /* close the file handle associated */
138 self->system->close(hdr_p->fh);
139
140 /* free the memory associated */
141 self->system->free(hdr);
142
143 self->error = MSPACK_ERR_OK;
144}
145
146/***************************************
147 * KWAJD_READ_HEADERS
148 ***************************************
149 * reads the headers of a KWAJ format file
150 */
151static int kwajd_read_headers(struct mspack_system *sys,
152 struct mspack_file *fh,
153 struct mskwajd_header *hdr)
154{
155 unsigned char buf[16];
156 int i;
157
158 /* read in the header */
159 if (sys->read(fh, &buf[0], kwajh_SIZEOF) != kwajh_SIZEOF) {
160 return MSPACK_ERR_READ;
161 }
162
163 /* check for "KWAJ" signature */
164 if (((unsigned int) EndGetI32(&buf[kwajh_Signature1]) != 0x4A41574B) ||
165 ((unsigned int) EndGetI32(&buf[kwajh_Signature2]) != 0xD127F088))
166 {
167 return MSPACK_ERR_SIGNATURE;
168 }
169
170 /* basic header fields */
171 hdr->comp_type = EndGetI16(&buf[kwajh_CompMethod]);
172 hdr->data_offset = EndGetI16(&buf[kwajh_DataOffset]);
173 hdr->headers = EndGetI16(&buf[kwajh_Flags]);
174 hdr->length = 0;
175 hdr->filename = NULL;
176 hdr->extra = NULL;
177 hdr->extra_length = 0;
178
179 /* optional headers */
180
181 /* 4 bytes: length of unpacked file */
182 if (hdr->headers & MSKWAJ_HDR_HASLENGTH) {
183 if (sys->read(fh, &buf[0], 4) != 4) return MSPACK_ERR_READ;
184 hdr->length = EndGetI32(&buf[0]);
185 }
186
187 /* 2 bytes: unknown purpose */
188 if (hdr->headers & MSKWAJ_HDR_HASUNKNOWN1) {
189 if (sys->read(fh, &buf[0], 2) != 2) return MSPACK_ERR_READ;
190 }
191
192 /* 2 bytes: length of section, then [length] bytes: unknown purpose */
193 if (hdr->headers & MSKWAJ_HDR_HASUNKNOWN2) {
194 if (sys->read(fh, &buf[0], 2) != 2) return MSPACK_ERR_READ;
195 i = EndGetI16(&buf[0]);
196 if (sys->seek(fh, (off_t)i, MSPACK_SYS_SEEK_CUR)) return MSPACK_ERR_SEEK;
197 }
198
199 /* filename and extension */
200 if (hdr->headers & (MSKWAJ_HDR_HASFILENAME | MSKWAJ_HDR_HASFILEEXT)) {
201 int len;
202 /* allocate memory for maximum length filename */
203 char *fn = (char *) sys->alloc(sys, (size_t) 13);
204 if (!(hdr->filename = fn)) return MSPACK_ERR_NOMEMORY;
205
206 /* copy filename if present */
207 if (hdr->headers & MSKWAJ_HDR_HASFILENAME) {
208 /* read and copy up to 9 bytes of a null terminated string */
209 if ((len = sys->read(fh, &buf[0], 9)) < 2) return MSPACK_ERR_READ;
210 for (i = 0; i < len; i++) if (!(*fn++ = buf[i])) break;
211 /* if string was 9 bytes with no null terminator, reject it */
212 if (i == 9 && buf[8] != '\0') return MSPACK_ERR_DATAFORMAT;
213 /* seek to byte after string ended in file */
214 if (sys->seek(fh, (off_t)(i + 1 - len), MSPACK_SYS_SEEK_CUR))
215 return MSPACK_ERR_SEEK;
216 fn--; /* remove the null terminator */
217 }
218
219 /* copy extension if present */
220 if (hdr->headers & MSKWAJ_HDR_HASFILEEXT) {
221 *fn++ = '.';
222 /* read and copy up to 4 bytes of a null terminated string */
223 if ((len = sys->read(fh, &buf[0], 4)) < 2) return MSPACK_ERR_READ;
224 for (i = 0; i < len; i++) if (!(*fn++ = buf[i])) break;
225 /* if string was 4 bytes with no null terminator, reject it */
226 if (i == 4 && buf[3] != '\0') return MSPACK_ERR_DATAFORMAT;
227 /* seek to byte after string ended in file */
228 if (sys->seek(fh, (off_t)(i + 1 - len), MSPACK_SYS_SEEK_CUR))
229 return MSPACK_ERR_SEEK;
230 fn--; /* remove the null terminator */
231 }
232 *fn = '\0';
233 }
234
235 /* 2 bytes: extra text length then [length] bytes of extra text data */
236 if (hdr->headers & MSKWAJ_HDR_HASEXTRATEXT) {
237 if (sys->read(fh, &buf[0], 2) != 2) return MSPACK_ERR_READ;
238 i = EndGetI16(&buf[0]);
239 hdr->extra = (char *) sys->alloc(sys, (size_t)i+1);
240 if (! hdr->extra) return MSPACK_ERR_NOMEMORY;
241 if (sys->read(fh, hdr->extra, i) != i) return MSPACK_ERR_READ;
242 hdr->extra[i] = '\0';
243 hdr->extra_length = i;
244 }
245 return MSPACK_ERR_OK;
246}
247
248/***************************************
249 * KWAJD_EXTRACT
250 ***************************************
251 * decompresses a KWAJ file
252 */
253static int kwajd_extract(struct mskwaj_decompressor *base,
254 struct mskwajd_header *hdr, const char *filename)
255{
256 struct mskwaj_decompressor_p *self = (struct mskwaj_decompressor_p *) base;
257 struct mspack_system *sys;
258 struct mspack_file *fh, *outfh;
259
260 if (!self) return MSPACK_ERR_ARGS;
261 if (!hdr) return self->error = MSPACK_ERR_ARGS;
262
263 sys = self->system;
264 fh = ((struct mskwajd_header_p *) hdr)->fh;
265
266 /* seek to the compressed data */
267 if (sys->seek(fh, hdr->data_offset, MSPACK_SYS_SEEK_START)) {
268 return self->error = MSPACK_ERR_SEEK;
269 }
270
271 /* open file for output */
272 if (!(outfh = sys->open(sys, filename, MSPACK_SYS_OPEN_WRITE))) {
273 return self->error = MSPACK_ERR_OPEN;
274 }
275
276 self->error = MSPACK_ERR_OK;
277
278 /* decompress based on format */
279 if (hdr->comp_type == MSKWAJ_COMP_NONE ||
280 hdr->comp_type == MSKWAJ_COMP_XOR)
281 {
282 /* NONE is a straight copy. XOR is a copy xored with 0xFF */
283 unsigned char *buf = (unsigned char *) sys->alloc(sys, (size_t) KWAJ_INPUT_SIZE);
284 if (buf) {
285 int read, i;
286 while ((read = sys->read(fh, buf, KWAJ_INPUT_SIZE)) > 0) {
287 if (hdr->comp_type == MSKWAJ_COMP_XOR) {
288 for (i = 0; i < read; i++) buf[i] ^= 0xFF;
289 }
290 if (sys->write(outfh, buf, read) != read) {
291 self->error = MSPACK_ERR_WRITE;
292 break;
293 }
294 }
295 if (read < 0) self->error = MSPACK_ERR_READ;
296 sys->free(buf);
297 }
298 else {
299 self->error = MSPACK_ERR_NOMEMORY;
300 }
301 }
302 else if (hdr->comp_type == MSKWAJ_COMP_SZDD) {
303 self->error = lzss_decompress(sys, fh, outfh, KWAJ_INPUT_SIZE,
304 LZSS_MODE_EXPAND);
305 }
306 else if (hdr->comp_type == MSKWAJ_COMP_LZH) {
307 struct kwajd_stream *lzh = lzh_init(sys, fh, outfh);
308 self->error = (lzh) ? lzh_decompress(lzh) : MSPACK_ERR_NOMEMORY;
309 lzh_free(lzh);
310 }
311 else if (hdr->comp_type == MSKWAJ_COMP_MSZIP) {
312 struct mszipd_stream *zip = mszipd_init(sys,fh,outfh,KWAJ_INPUT_SIZE,0);
313 self->error = (zip) ? mszipd_decompress_kwaj(zip) : MSPACK_ERR_NOMEMORY;
314 mszipd_free(zip);
315 }
316 else {
317 self->error = MSPACK_ERR_DATAFORMAT;
318 }
319
320 /* close output file */
321 sys->close(outfh);
322
323 return self->error;
324}
325
326/***************************************
327 * KWAJD_DECOMPRESS
328 ***************************************
329 * unpacks directly from input to output
330 */
331static int kwajd_decompress(struct mskwaj_decompressor *base,
332 const char *input, const char *output)
333{
334 struct mskwaj_decompressor_p *self = (struct mskwaj_decompressor_p *) base;
335 struct mskwajd_header *hdr;
336 int error;
337
338 if (!self) return MSPACK_ERR_ARGS;
339
340 if (!(hdr = kwajd_open(base, input))) return self->error;
341 error = kwajd_extract(base, hdr, output);
342 kwajd_close(base, hdr);
343 return self->error = error;
344}
345
346/***************************************
347 * KWAJD_ERROR
348 ***************************************
349 * returns the last error that occurred
350 */
351static int kwajd_error(struct mskwaj_decompressor *base)
352{
353 struct mskwaj_decompressor_p *self = (struct mskwaj_decompressor_p *) base;
354 return (self) ? self->error : MSPACK_ERR_ARGS;
355}
356
357/***************************************
358 * LZH_INIT, LZH_DECOMPRESS, LZH_FREE
359 ***************************************
360 * unpacks KWAJ method 3 files
361 */
362
363/* import bit-reading macros and code */
364#define BITS_TYPE struct kwajd_stream
365#define BITS_VAR lzh
366#define BITS_ORDER_MSB
367#define BITS_NO_READ_INPUT
368#define READ_BYTES do { \
369 if (i_ptr >= i_end) { \
370 if ((err = lzh_read_input(lzh))) return err; \
371 i_ptr = lzh->i_ptr; \
372 i_end = lzh->i_end; \
373 } \
374 INJECT_BITS(*i_ptr++, 8); \
375} while (0)
376#include <readbits.h>
377
378/* import huffman-reading macros and code */
379#define TABLEBITS(tbl) KWAJ_TABLEBITS
380#define MAXSYMBOLS(tbl) KWAJ_##tbl##_SYMS
381#define HUFF_TABLE(tbl,idx) lzh->tbl##_table[idx]
382#define HUFF_LEN(tbl,idx) lzh->tbl##_len[idx]
383#define HUFF_ERROR return MSPACK_ERR_DATAFORMAT
384#include <readhuff.h>
385
386/* In the KWAJ LZH format, there is no special 'eof' marker, it just
387 * ends. Depending on how many bits are left in the final byte when
388 * the stream ends, that might be enough to start another literal or
389 * match. The only easy way to detect that we've come to an end is to
390 * guard all bit-reading. We allow fake bits to be read once we reach
391 * the end of the stream, but we check if we then consumed any of
392 * those fake bits, after doing the READ_BITS / READ_HUFFSYM. This
393 * isn't how the default readbits.h read_input() works (it simply lets
394 * 2 fake bytes in then stops), so we implement our own.
395 */
396#define READ_BITS_SAFE(val, n) do { \
397 READ_BITS(val, n); \
398 if (lzh->input_end && bits_left < lzh->input_end) \
399 return MSPACK_ERR_OK; \
400} while (0)
401
402#define READ_HUFFSYM_SAFE(tbl, val) do { \
403 READ_HUFFSYM(tbl, val); \
404 if (lzh->input_end && bits_left < lzh->input_end) \
405 return MSPACK_ERR_OK; \
406} while (0)
407
408#define BUILD_TREE(tbl, type) \
409 STORE_BITS; \
410 err = lzh_read_lens(lzh, type, MAXSYMBOLS(tbl), &HUFF_LEN(tbl,0)); \
411 if (err) return err; \
412 RESTORE_BITS; \
413 if (make_decode_table(MAXSYMBOLS(tbl), TABLEBITS(tbl), \
414 &HUFF_LEN(tbl,0), &HUFF_TABLE(tbl,0))) \
415 return MSPACK_ERR_DATAFORMAT;
416
417#define WRITE_BYTE do { \
418 if (lzh->sys->write(lzh->output, &lzh->window[pos], 1) != 1) \
419 return MSPACK_ERR_WRITE; \
420} while (0)
421
422static struct kwajd_stream *lzh_init(struct mspack_system *sys,
423 struct mspack_file *in, struct mspack_file *out)
424{
425 struct kwajd_stream *lzh;
426
427 if (!sys || !in || !out) return NULL;
428 if (!(lzh = (struct kwajd_stream *) sys->alloc(sys, sizeof(struct kwajd_stream)))) return NULL;
429
430 lzh->sys = sys;
431 lzh->input = in;
432 lzh->output = out;
433 return lzh;
434}
435
436static int lzh_decompress(struct kwajd_stream *lzh)
437{
438 register unsigned int bit_buffer;
439 register int bits_left, i;
440 register unsigned short sym;
441 unsigned char *i_ptr, *i_end, lit_run = 0;
442 int j, pos = 0, len, offset, err;
443 unsigned int types[6];
444
445 /* reset global state */
446 INIT_BITS;
447 RESTORE_BITS;
448 memset(&lzh->window[0], LZSS_WINDOW_FILL, (size_t) LZSS_WINDOW_SIZE);
449
450 /* read 6 encoding types (for byte alignment) but only 5 are needed */
451 for (i = 0; i < 6; i++) READ_BITS_SAFE(types[i], 4);
452
453 /* read huffman table symbol lengths and build huffman trees */
454 BUILD_TREE(MATCHLEN1, types[0]);
455 BUILD_TREE(MATCHLEN2, types[1]);
456 BUILD_TREE(LITLEN, types[2]);
457 BUILD_TREE(OFFSET, types[3]);
458 BUILD_TREE(LITERAL, types[4]);
459
460 while (!lzh->input_end) {
461 if (lit_run) READ_HUFFSYM_SAFE(MATCHLEN2, len);
462 else READ_HUFFSYM_SAFE(MATCHLEN1, len);
463
464 if (len > 0) {
465 len += 2;
466 lit_run = 0; /* not the end of a literal run */
467 READ_HUFFSYM_SAFE(OFFSET, j); offset = j << 6;
468 READ_BITS_SAFE(j, 6); offset |= j;
469
470 /* copy match as output and into the ring buffer */
471 while (len-- > 0) {
472 lzh->window[pos] = lzh->window[(pos+4096-offset) & 4095];
473 WRITE_BYTE;
474 pos++; pos &= 4095;
475 }
476 }
477 else {
478 READ_HUFFSYM_SAFE(LITLEN, len); len++;
479 lit_run = (len == 32) ? 0 : 1; /* end of a literal run? */
480 while (len-- > 0) {
481 READ_HUFFSYM_SAFE(LITERAL, j);
482 /* copy as output and into the ring buffer */
483 lzh->window[pos] = j;
484 WRITE_BYTE;
485 pos++; pos &= 4095;
486 }
487 }
488 }
489 return MSPACK_ERR_OK;
490}
491
492static void lzh_free(struct kwajd_stream *lzh)
493{
494 struct mspack_system *sys;
495 if (!lzh || !lzh->sys) return;
496 sys = lzh->sys;
497 sys->free(lzh);
498}
499
500static int lzh_read_lens(struct kwajd_stream *lzh,
501 unsigned int type, unsigned int numsyms,
502 unsigned char *lens)
503{
504 register unsigned int bit_buffer;
505 register int bits_left;
506 unsigned char *i_ptr, *i_end;
507 unsigned int i, c, sel;
508 int err;
509
510 RESTORE_BITS;
511 switch (type) {
512 case 0:
513 i = numsyms; c = (i==16)?4: (i==32)?5: (i==64)?6: (i==256)?8 :0;
514 for (i = 0; i < numsyms; i++) lens[i] = c;
515 break;
516
517 case 1:
518 READ_BITS_SAFE(c, 4); lens[0] = c;
519 for (i = 1; i < numsyms; i++) {
520 READ_BITS_SAFE(sel, 1); if (sel == 0) lens[i] = c;
521 else { READ_BITS_SAFE(sel, 1); if (sel == 0) lens[i] = ++c;
522 else { READ_BITS_SAFE(c, 4); lens[i] = c; }}
523 }
524 break;
525
526 case 2:
527 READ_BITS_SAFE(c, 4); lens[0] = c;
528 for (i = 1; i < numsyms; i++) {
529 READ_BITS_SAFE(sel, 2);
530 if (sel == 3) READ_BITS_SAFE(c, 4); else c += (char) sel-1;
531 lens[i] = c;
532 }
533 break;
534
535 case 3:
536 for (i = 0; i < numsyms; i++) {
537 READ_BITS_SAFE(c, 4); lens[i] = c;
538 }
539 break;
540 }
541 STORE_BITS;
542 return MSPACK_ERR_OK;
543}
544
545static int lzh_read_input(struct kwajd_stream *lzh) {
546 int read;
547 if (lzh->input_end) {
548 lzh->input_end += 8;
549 lzh->inbuf[0] = 0;
550 read = 1;
551 }
552 else {
553 read = lzh->sys->read(lzh->input, &lzh->inbuf[0], KWAJ_INPUT_SIZE);
554 if (read < 0) return MSPACK_ERR_READ;
555 if (read == 0) {
556 lzh->input_end = 8;
557 lzh->inbuf[0] = 0;
558 read = 1;
559 }
560 }
561
562 /* update i_ptr and i_end */
563 lzh->i_ptr = &lzh->inbuf[0];
564 lzh->i_end = &lzh->inbuf[read];
565 return MSPACK_ERR_OK;
566}
diff --git a/utils/rbutilqt/mspack/lit.h b/utils/rbutilqt/mspack/lit.h
new file mode 100644
index 0000000000..2ccc7dd7f3
--- /dev/null
+++ b/utils/rbutilqt/mspack/lit.h
@@ -0,0 +1,35 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10#ifndef MSPACK_LIT_H
11#define MSPACK_LIT_H 1
12
13#include "lzx.h"
14#include "des.h"
15#include "sha.h"
16
17/* generic LIT definitions */
18
19/* LIT compression definitions */
20
21struct mslit_compressor_p {
22 struct mslit_compressor base;
23 struct mspack_system *system;
24 /* todo */
25};
26
27/* LIT decompression definitions */
28
29struct mslit_decompressor_p {
30 struct mslit_decompressor base;
31 struct mspack_system *system;
32 /* todo */
33};
34
35#endif
diff --git a/utils/rbutilqt/mspack/litc.c b/utils/rbutilqt/mspack/litc.c
new file mode 100644
index 0000000000..4959a81d36
--- /dev/null
+++ b/utils/rbutilqt/mspack/litc.c
@@ -0,0 +1,24 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10/* LIT compression implementation */
11
12#include "system-mspack.h"
13#include "lit.h"
14
15struct mslit_compressor *
16 mspack_create_lit_compressor(struct mspack_system *sys)
17{
18 /* todo */
19 return NULL;
20}
21
22void mspack_destroy_lit_compressor(struct mslit_compressor *self) {
23 /* todo */
24}
diff --git a/utils/rbutilqt/mspack/litd.c b/utils/rbutilqt/mspack/litd.c
new file mode 100644
index 0000000000..93cbf1765a
--- /dev/null
+++ b/utils/rbutilqt/mspack/litd.c
@@ -0,0 +1,24 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10/* LIT decompression implementation */
11
12#include "system-mspack.h"
13#include "lit.h"
14
15struct mslit_decompressor *
16 mspack_create_lit_decompressor(struct mspack_system *sys)
17{
18 /* todo */
19 return NULL;
20}
21
22void mspack_destroy_lit_decompressor(struct mslit_decompressor *self) {
23 /* todo */
24}
diff --git a/utils/rbutilqt/mspack/lzss.h b/utils/rbutilqt/mspack/lzss.h
new file mode 100644
index 0000000000..aa946e52ae
--- /dev/null
+++ b/utils/rbutilqt/mspack/lzss.h
@@ -0,0 +1,66 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10#ifndef MSPACK_LZSS_H
11#define MSPACK_LZSS_H 1
12
13#ifdef __cplusplus
14extern "C" {
15#endif
16
17/* LZSS compression / decompression definitions */
18
19#define LZSS_WINDOW_SIZE (4096)
20#define LZSS_WINDOW_FILL (0x20)
21
22#define LZSS_MODE_EXPAND (0)
23#define LZSS_MODE_MSHELP (1)
24#define LZSS_MODE_QBASIC (2)
25
26/**
27 * Decompresses an LZSS stream.
28 *
29 * Input bytes will be read in as necessary using the system->read()
30 * function with the input file handle given. This will continue until
31 * system->read() returns 0 bytes, or an error. Errors will be passed
32 * out of the function as MSPACK_ERR_READ errors. Input streams should
33 * convey an "end of input stream" by refusing to supply all the bytes
34 * that LZSS asks for when they reach the end of the stream, rather
35 * than return an error code.
36 *
37 * Output bytes will be passed to the system->write() function, using
38 * the output file handle given. More than one call may be made to
39 * system->write().
40 *
41 * As EXPAND.EXE (SZDD/KWAJ), Microsoft Help and QBasic have slightly
42 * different encodings for the control byte and matches, a "mode"
43 * parameter is allowed, to choose the encoding.
44 *
45 * @param system an mspack_system structure used to read from
46 * the input stream and write to the output
47 * stream, also to allocate and free memory.
48 * @param input an input stream with the LZSS data.
49 * @param output an output stream to write the decoded data to.
50 * @param input_buffer_size the number of bytes to use as an input
51 * bitstream buffer.
52 * @param mode one of #LZSS_MODE_EXPAND, #LZSS_MODE_MSHELP or
53 * #LZSS_MODE_QBASIC
54 * @return an error code, or MSPACK_ERR_OK if successful
55 */
56extern int lzss_decompress(struct mspack_system *system,
57 struct mspack_file *input,
58 struct mspack_file *output,
59 int input_buffer_size,
60 int mode);
61
62#ifdef __cplusplus
63}
64#endif
65
66#endif
diff --git a/utils/rbutilqt/mspack/lzssd.c b/utils/rbutilqt/mspack/lzssd.c
new file mode 100644
index 0000000000..63716d414a
--- /dev/null
+++ b/utils/rbutilqt/mspack/lzssd.c
@@ -0,0 +1,93 @@
1/* This file is part of libmspack.
2 * (C) 2003-2010 Stuart Caie.
3 *
4 * LZSS is a derivative of LZ77 and was created by James Storer and
5 * Thomas Szymanski in 1982. Haruhiko Okumura wrote a very popular C
6 * implementation.
7 *
8 * libmspack is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
10 *
11 * For further details, see the file COPYING.LIB distributed with libmspack
12 */
13
14#include "system-mspack.h"
15#include "lzss.h"
16
17#define ENSURE_BYTES do { \
18 if (i_ptr >= i_end) { \
19 read = system->read(input, &inbuf[0], \
20 input_buffer_size); \
21 if (read <= 0) { \
22 system->free(window); \
23 return (read < 0) ? MSPACK_ERR_READ \
24 : MSPACK_ERR_OK; \
25 } \
26 i_ptr = &inbuf[0]; i_end = &inbuf[read]; \
27 } \
28} while (0)
29
30#define WRITE_BYTE do { \
31 if (system->write(output, &window[pos], 1) != 1) { \
32 system->free(window); \
33 return MSPACK_ERR_WRITE; \
34 } \
35} while (0)
36
37int lzss_decompress(struct mspack_system *system,
38 struct mspack_file *input,
39 struct mspack_file *output,
40 int input_buffer_size,
41 int mode)
42{
43 unsigned char *window, *inbuf, *i_ptr, *i_end;
44 unsigned int pos, i, c, invert, mpos, len;
45 int read;
46
47 /* check parameters */
48 if (!system || input_buffer_size < 1 || (mode != LZSS_MODE_EXPAND &&
49 mode != LZSS_MODE_MSHELP && mode != LZSS_MODE_QBASIC))
50 {
51 return MSPACK_ERR_ARGS;
52 }
53
54 /* allocate memory */
55 window = (unsigned char *) system->alloc(system, LZSS_WINDOW_SIZE + input_buffer_size);
56 if (!window) return MSPACK_ERR_NOMEMORY;
57
58 /* initialise decompression */
59 inbuf = &window[LZSS_WINDOW_SIZE];
60 memset(window, LZSS_WINDOW_FILL, (size_t) LZSS_WINDOW_SIZE);
61 pos = LZSS_WINDOW_SIZE - ((mode == LZSS_MODE_QBASIC) ? 18 : 16);
62 invert = (mode == LZSS_MODE_MSHELP) ? ~0 : 0;
63 i_ptr = i_end = &inbuf[0];
64
65 /* loop forever; exit condition is in ENSURE_BYTES macro */
66 for (;;) {
67 ENSURE_BYTES; c = *i_ptr++ ^ invert;
68 for (i = 0x01; i & 0xFF; i <<= 1) {
69 if (c & i) {
70 /* literal */
71 ENSURE_BYTES; window[pos] = *i_ptr++;
72 WRITE_BYTE;
73 pos++; pos &= LZSS_WINDOW_SIZE - 1;
74 }
75 else {
76 /* match */
77 ENSURE_BYTES; mpos = *i_ptr++;
78 ENSURE_BYTES; mpos |= (*i_ptr & 0xF0) << 4;
79 len = (*i_ptr++ & 0x0F) + 3;
80 while (len--) {
81 window[pos] = window[mpos];
82 WRITE_BYTE;
83 pos++; pos &= LZSS_WINDOW_SIZE - 1;
84 mpos++; mpos &= LZSS_WINDOW_SIZE - 1;
85 }
86 }
87 }
88 }
89
90 /* not reached */
91 system->free(window);
92 return MSPACK_ERR_OK;
93}
diff --git a/utils/rbutilqt/mspack/lzx.h b/utils/rbutilqt/mspack/lzx.h
new file mode 100644
index 0000000000..a6152f622b
--- /dev/null
+++ b/utils/rbutilqt/mspack/lzx.h
@@ -0,0 +1,221 @@
1/* This file is part of libmspack.
2 * (C) 2003-2013 Stuart Caie.
3 *
4 * The LZX method was created by Jonathan Forbes and Tomi Poutanen, adapted
5 * by Microsoft Corporation.
6 *
7 * libmspack is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
9 *
10 * For further details, see the file COPYING.LIB distributed with libmspack
11 */
12
13#ifndef MSPACK_LZX_H
14#define MSPACK_LZX_H 1
15
16#ifdef __cplusplus
17extern "C" {
18#endif
19
20/* LZX compression / decompression definitions */
21
22/* some constants defined by the LZX specification */
23#define LZX_MIN_MATCH (2)
24#define LZX_MAX_MATCH (257)
25#define LZX_NUM_CHARS (256)
26#define LZX_BLOCKTYPE_INVALID (0) /* also blocktypes 4-7 invalid */
27#define LZX_BLOCKTYPE_VERBATIM (1)
28#define LZX_BLOCKTYPE_ALIGNED (2)
29#define LZX_BLOCKTYPE_UNCOMPRESSED (3)
30#define LZX_PRETREE_NUM_ELEMENTS (20)
31#define LZX_ALIGNED_NUM_ELEMENTS (8) /* aligned offset tree #elements */
32#define LZX_NUM_PRIMARY_LENGTHS (7) /* this one missing from spec! */
33#define LZX_NUM_SECONDARY_LENGTHS (249) /* length tree #elements */
34
35/* LZX huffman defines: tweak tablebits as desired */
36#define LZX_PRETREE_MAXSYMBOLS (LZX_PRETREE_NUM_ELEMENTS)
37#define LZX_PRETREE_TABLEBITS (6)
38#define LZX_MAINTREE_MAXSYMBOLS (LZX_NUM_CHARS + 290*8)
39#define LZX_MAINTREE_TABLEBITS (12)
40#define LZX_LENGTH_MAXSYMBOLS (LZX_NUM_SECONDARY_LENGTHS+1)
41#define LZX_LENGTH_TABLEBITS (12)
42#define LZX_ALIGNED_MAXSYMBOLS (LZX_ALIGNED_NUM_ELEMENTS)
43#define LZX_ALIGNED_TABLEBITS (7)
44#define LZX_LENTABLE_SAFETY (64) /* table decoding overruns are allowed */
45
46#define LZX_FRAME_SIZE (32768) /* the size of a frame in LZX */
47
48struct lzxd_stream {
49 struct mspack_system *sys; /* I/O routines */
50 struct mspack_file *input; /* input file handle */
51 struct mspack_file *output; /* output file handle */
52
53 off_t offset; /* number of bytes actually output */
54 off_t length; /* overall decompressed length of stream */
55
56 unsigned char *window; /* decoding window */
57 unsigned int window_size; /* window size */
58 unsigned int ref_data_size; /* LZX DELTA reference data size */
59 unsigned int num_offsets; /* number of match_offset entries in table */
60 unsigned int window_posn; /* decompression offset within window */
61 unsigned int frame_posn; /* current frame offset within in window */
62 unsigned int frame; /* the number of 32kb frames processed */
63 unsigned int reset_interval; /* which frame do we reset the compressor? */
64
65 unsigned int R0, R1, R2; /* for the LRU offset system */
66 unsigned int block_length; /* uncompressed length of this LZX block */
67 unsigned int block_remaining; /* uncompressed bytes still left to decode */
68
69 signed int intel_filesize; /* magic header value used for transform */
70 signed int intel_curpos; /* current offset in transform space */
71
72 unsigned char intel_started; /* has intel E8 decoding started? */
73 unsigned char block_type; /* type of the current block */
74 unsigned char header_read; /* have we started decoding at all yet? */
75 unsigned char input_end; /* have we reached the end of input? */
76 unsigned char is_delta; /* does stream follow LZX DELTA spec? */
77
78 int error;
79
80 /* I/O buffering */
81 unsigned char *inbuf, *i_ptr, *i_end, *o_ptr, *o_end;
82 unsigned int bit_buffer, bits_left, inbuf_size;
83
84 /* huffman code lengths */
85 unsigned char PRETREE_len [LZX_PRETREE_MAXSYMBOLS + LZX_LENTABLE_SAFETY];
86 unsigned char MAINTREE_len [LZX_MAINTREE_MAXSYMBOLS + LZX_LENTABLE_SAFETY];
87 unsigned char LENGTH_len [LZX_LENGTH_MAXSYMBOLS + LZX_LENTABLE_SAFETY];
88 unsigned char ALIGNED_len [LZX_ALIGNED_MAXSYMBOLS + LZX_LENTABLE_SAFETY];
89
90 /* huffman decoding tables */
91 unsigned short PRETREE_table [(1 << LZX_PRETREE_TABLEBITS) +
92 (LZX_PRETREE_MAXSYMBOLS * 2)];
93 unsigned short MAINTREE_table[(1 << LZX_MAINTREE_TABLEBITS) +
94 (LZX_MAINTREE_MAXSYMBOLS * 2)];
95 unsigned short LENGTH_table [(1 << LZX_LENGTH_TABLEBITS) +
96 (LZX_LENGTH_MAXSYMBOLS * 2)];
97 unsigned short ALIGNED_table [(1 << LZX_ALIGNED_TABLEBITS) +
98 (LZX_ALIGNED_MAXSYMBOLS * 2)];
99 unsigned char LENGTH_empty;
100
101 /* this is used purely for doing the intel E8 transform */
102 unsigned char e8_buf[LZX_FRAME_SIZE];
103};
104
105/**
106 * Allocates and initialises LZX decompression state for decoding an LZX
107 * stream.
108 *
109 * This routine uses system->alloc() to allocate memory. If memory
110 * allocation fails, or the parameters to this function are invalid,
111 * NULL is returned.
112 *
113 * @param system an mspack_system structure used to read from
114 * the input stream and write to the output
115 * stream, also to allocate and free memory.
116 * @param input an input stream with the LZX data.
117 * @param output an output stream to write the decoded data to.
118 * @param window_bits the size of the decoding window, which must be
119 * between 15 and 21 inclusive for regular LZX
120 * data, or between 17 and 25 inclusive for
121 * LZX DELTA data.
122 * @param reset_interval the interval at which the LZX bitstream is
123 * reset, in multiples of LZX frames (32678
124 * bytes), e.g. a value of 2 indicates the input
125 * stream resets after every 65536 output bytes.
126 * A value of 0 indicates that the bitstream never
127 * resets, such as in CAB LZX streams.
128 * @param input_buffer_size the number of bytes to use as an input
129 * bitstream buffer.
130 * @param output_length the length in bytes of the entirely
131 * decompressed output stream, if known in
132 * advance. It is used to correctly perform the
133 * Intel E8 transformation, which must stop 6
134 * bytes before the very end of the
135 * decompressed stream. It is not otherwise used
136 * or adhered to. If the full decompressed
137 * length is known in advance, set it here.
138 * If it is NOT known, use the value 0, and call
139 * lzxd_set_output_length() once it is
140 * known. If never set, 4 of the final 6 bytes
141 * of the output stream may be incorrect.
142 * @param is_delta should be zero for all regular LZX data,
143 * non-zero for LZX DELTA encoded data.
144 * @return a pointer to an initialised lzxd_stream structure, or NULL if
145 * there was not enough memory or parameters to the function were wrong.
146 */
147extern struct lzxd_stream *lzxd_init(struct mspack_system *system,
148 struct mspack_file *input,
149 struct mspack_file *output,
150 int window_bits,
151 int reset_interval,
152 int input_buffer_size,
153 off_t output_length,
154 char is_delta);
155
156/* see description of output_length in lzxd_init() */
157extern void lzxd_set_output_length(struct lzxd_stream *lzx,
158 off_t output_length);
159
160/**
161 * Reads LZX DELTA reference data into the window and allows
162 * lzxd_decompress() to reference it.
163 *
164 * Call this before the first call to lzxd_decompress().
165
166 * @param lzx the LZX stream to apply this reference data to
167 * @param system an mspack_system implementation to use with the
168 * input param. Only read() will be called.
169 * @param input an input file handle to read reference data using
170 * system->read().
171 * @param length the length of the reference data. Cannot be longer
172 * than the LZX window size.
173 * @return an error code, or MSPACK_ERR_OK if successful
174 */
175extern int lzxd_set_reference_data(struct lzxd_stream *lzx,
176 struct mspack_system *system,
177 struct mspack_file *input,
178 unsigned int length);
179
180/**
181 * Decompresses entire or partial LZX streams.
182 *
183 * The number of bytes of data that should be decompressed is given as the
184 * out_bytes parameter. If more bytes are decoded than are needed, they
185 * will be kept over for a later invocation.
186 *
187 * The output bytes will be passed to the system->write() function given in
188 * lzxd_init(), using the output file handle given in lzxd_init(). More than
189 * one call may be made to system->write().
190
191 * Input bytes will be read in as necessary using the system->read()
192 * function given in lzxd_init(), using the input file handle given in
193 * lzxd_init(). This will continue until system->read() returns 0 bytes,
194 * or an error. Errors will be passed out of the function as
195 * MSPACK_ERR_READ errors. Input streams should convey an "end of input
196 * stream" by refusing to supply all the bytes that LZX asks for when they
197 * reach the end of the stream, rather than return an error code.
198 *
199 * If any error code other than MSPACK_ERR_OK is returned, the stream
200 * should be considered unusable and lzxd_decompress() should not be
201 * called again on this stream.
202 *
203 * @param lzx LZX decompression state, as allocated by lzxd_init().
204 * @param out_bytes the number of bytes of data to decompress.
205 * @return an error code, or MSPACK_ERR_OK if successful
206 */
207extern int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes);
208
209/**
210 * Frees all state associated with an LZX data stream. This will call
211 * system->free() using the system pointer given in lzxd_init().
212 *
213 * @param lzx LZX decompression state to free.
214 */
215void lzxd_free(struct lzxd_stream *lzx);
216
217#ifdef __cplusplus
218}
219#endif
220
221#endif
diff --git a/utils/rbutilqt/mspack/lzxc.c b/utils/rbutilqt/mspack/lzxc.c
new file mode 100644
index 0000000000..89d8c610ea
--- /dev/null
+++ b/utils/rbutilqt/mspack/lzxc.c
@@ -0,0 +1,18 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * The LZX method was created by Jonathan Forbes and Tomi Poutanen, adapted
5 * by Microsoft Corporation.
6 *
7 * libmspack is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
9 *
10 * For further details, see the file COPYING.LIB distributed with libmspack
11 */
12
13/* LZX compression implementation */
14
15#include "system-mspack.h"
16#include "lzx.h"
17
18/* todo */
diff --git a/utils/rbutilqt/mspack/lzxd.c b/utils/rbutilqt/mspack/lzxd.c
new file mode 100644
index 0000000000..88cfd90c2a
--- /dev/null
+++ b/utils/rbutilqt/mspack/lzxd.c
@@ -0,0 +1,905 @@
1/* This file is part of libmspack.
2 * (C) 2003-2013 Stuart Caie.
3 *
4 * The LZX method was created by Jonathan Forbes and Tomi Poutanen, adapted
5 * by Microsoft Corporation.
6 *
7 * libmspack is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
9 *
10 * For further details, see the file COPYING.LIB distributed with libmspack
11 */
12
13/* LZX decompression implementation */
14
15#include "system-mspack.h"
16#include "lzx.h"
17
18/* Microsoft's LZX document (in cab-sdk.exe) and their implementation
19 * of the com.ms.util.cab Java package do not concur.
20 *
21 * In the LZX document, there is a table showing the correlation between
22 * window size and the number of position slots. It states that the 1MB
23 * window = 40 slots and the 2MB window = 42 slots. In the implementation,
24 * 1MB = 42 slots, 2MB = 50 slots. The actual calculation is 'find the
25 * first slot whose position base is equal to or more than the required
26 * window size'. This would explain why other tables in the document refer
27 * to 50 slots rather than 42.
28 *
29 * The constant NUM_PRIMARY_LENGTHS used in the decompression pseudocode
30 * is not defined in the specification.
31 *
32 * The LZX document does not state the uncompressed block has an
33 * uncompressed length field. Where does this length field come from, so
34 * we can know how large the block is? The implementation has it as the 24
35 * bits following after the 3 blocktype bits, before the alignment
36 * padding.
37 *
38 * The LZX document states that aligned offset blocks have their aligned
39 * offset huffman tree AFTER the main and length trees. The implementation
40 * suggests that the aligned offset tree is BEFORE the main and length
41 * trees.
42 *
43 * The LZX document decoding algorithm states that, in an aligned offset
44 * block, if an extra_bits value is 1, 2 or 3, then that number of bits
45 * should be read and the result added to the match offset. This is
46 * correct for 1 and 2, but not 3, where just a huffman symbol (using the
47 * aligned tree) should be read.
48 *
49 * Regarding the E8 preprocessing, the LZX document states 'No translation
50 * may be performed on the last 6 bytes of the input block'. This is
51 * correct. However, the pseudocode provided checks for the *E8 leader*
52 * up to the last 6 bytes. If the leader appears between -10 and -7 bytes
53 * from the end, this would cause the next four bytes to be modified, at
54 * least one of which would be in the last 6 bytes, which is not allowed
55 * according to the spec.
56 *
57 * The specification states that the huffman trees must always contain at
58 * least one element. However, many CAB files contain blocks where the
59 * length tree is completely empty (because there are no matches), and
60 * this is expected to succeed.
61 *
62 * The errors in LZX documentation appear have been corrected in the
63 * new documentation for the LZX DELTA format.
64 *
65 * http://msdn.microsoft.com/en-us/library/cc483133.aspx
66 *
67 * However, this is a different format, an extension of regular LZX.
68 * I have noticed the following differences, there may be more:
69 *
70 * The maximum window size has increased from 2MB to 32MB. This also
71 * increases the maximum number of position slots, etc.
72 *
73 * If the match length is 257 (the maximum possible), this signals
74 * a further length decoding step, that allows for matches up to
75 * 33024 bytes long.
76 *
77 * The format now allows for "reference data", supplied by the caller.
78 * If match offsets go further back than the number of bytes
79 * decompressed so far, that is them accessing the reference data.
80 */
81
82/* import bit-reading macros and code */
83#define BITS_TYPE struct lzxd_stream
84#define BITS_VAR lzx
85#define BITS_ORDER_MSB
86#define READ_BYTES do { \
87 unsigned char b0, b1; \
88 READ_IF_NEEDED; b0 = *i_ptr++; \
89 READ_IF_NEEDED; b1 = *i_ptr++; \
90 INJECT_BITS((b1 << 8) | b0, 16); \
91} while (0)
92#include "readbits.h"
93
94/* import huffman-reading macros and code */
95#define TABLEBITS(tbl) LZX_##tbl##_TABLEBITS
96#define MAXSYMBOLS(tbl) LZX_##tbl##_MAXSYMBOLS
97#define HUFF_TABLE(tbl,idx) lzx->tbl##_table[idx]
98#define HUFF_LEN(tbl,idx) lzx->tbl##_len[idx]
99#define HUFF_ERROR return lzx->error = MSPACK_ERR_DECRUNCH
100#include "readhuff.h"
101
102/* BUILD_TABLE(tbl) builds a huffman lookup table from code lengths */
103#define BUILD_TABLE(tbl) \
104 if (make_decode_table(MAXSYMBOLS(tbl), TABLEBITS(tbl), \
105 &HUFF_LEN(tbl,0), &HUFF_TABLE(tbl,0))) \
106 { \
107 D(("failed to build %s table", #tbl)) \
108 return lzx->error = MSPACK_ERR_DECRUNCH; \
109 }
110
111#define BUILD_TABLE_MAYBE_EMPTY(tbl) do { \
112 lzx->tbl##_empty = 0; \
113 if (make_decode_table(MAXSYMBOLS(tbl), TABLEBITS(tbl), \
114 &HUFF_LEN(tbl,0), &HUFF_TABLE(tbl,0))) \
115 { \
116 for (i = 0; i < MAXSYMBOLS(tbl); i++) { \
117 if (HUFF_LEN(tbl, i) > 0) { \
118 D(("failed to build %s table", #tbl)) \
119 return lzx->error = MSPACK_ERR_DECRUNCH; \
120 } \
121 } \
122 /* empty tree - allow it, but don't decode symbols with it */ \
123 lzx->tbl##_empty = 1; \
124 } \
125} while (0)
126
127/* READ_LENGTHS(tablename, first, last) reads in code lengths for symbols
128 * first to last in the given table. The code lengths are stored in their
129 * own special LZX way.
130 */
131#define READ_LENGTHS(tbl, first, last) do { \
132 STORE_BITS; \
133 if (lzxd_read_lens(lzx, &HUFF_LEN(tbl, 0), (first), \
134 (unsigned int)(last))) return lzx->error; \
135 RESTORE_BITS; \
136} while (0)
137
138static int lzxd_read_lens(struct lzxd_stream *lzx, unsigned char *lens,
139 unsigned int first, unsigned int last)
140{
141 /* bit buffer and huffman symbol decode variables */
142 register unsigned int bit_buffer;
143 register int bits_left, i;
144 register unsigned short sym;
145 unsigned char *i_ptr, *i_end;
146
147 unsigned int x, y;
148 int z;
149
150 RESTORE_BITS;
151
152 /* read lengths for pretree (20 symbols, lengths stored in fixed 4 bits) */
153 for (x = 0; x < 20; x++) {
154 READ_BITS(y, 4);
155 lzx->PRETREE_len[x] = y;
156 }
157 BUILD_TABLE(PRETREE);
158
159 for (x = first; x < last; ) {
160 READ_HUFFSYM(PRETREE, z);
161 if (z == 17) {
162 /* code = 17, run of ([read 4 bits]+4) zeros */
163 READ_BITS(y, 4); y += 4;
164 while (y--) lens[x++] = 0;
165 }
166 else if (z == 18) {
167 /* code = 18, run of ([read 5 bits]+20) zeros */
168 READ_BITS(y, 5); y += 20;
169 while (y--) lens[x++] = 0;
170 }
171 else if (z == 19) {
172 /* code = 19, run of ([read 1 bit]+4) [read huffman symbol] */
173 READ_BITS(y, 1); y += 4;
174 READ_HUFFSYM(PRETREE, z);
175 z = lens[x] - z; if (z < 0) z += 17;
176 while (y--) lens[x++] = z;
177 }
178 else {
179 /* code = 0 to 16, delta current length entry */
180 z = lens[x] - z; if (z < 0) z += 17;
181 lens[x++] = z;
182 }
183 }
184
185 STORE_BITS;
186
187 return MSPACK_ERR_OK;
188}
189
190/* LZX static data tables:
191 *
192 * LZX uses 'position slots' to represent match offsets. For every match,
193 * a small 'position slot' number and a small offset from that slot are
194 * encoded instead of one large offset.
195 *
196 * The number of slots is decided by how many are needed to encode the
197 * largest offset for a given window size. This is easy when the gap between
198 * slots is less than 128Kb, it's a linear relationship. But when extra_bits
199 * reaches its limit of 17 (because LZX can only ensure reading 17 bits of
200 * data at a time), we can only jump 128Kb at a time and have to start
201 * using more and more position slots as each window size doubles.
202 *
203 * position_base[] is an index to the position slot bases
204 *
205 * extra_bits[] states how many bits of offset-from-base data is needed.
206 *
207 * They are calculated as follows:
208 * extra_bits[i] = 0 where i < 4
209 * extra_bits[i] = floor(i/2)-1 where i >= 4 && i < 36
210 * extra_bits[i] = 17 where i >= 36
211 * position_base[0] = 0
212 * position_base[i] = position_base[i-1] + (1 << extra_bits[i-1])
213 */
214static const unsigned int position_slots[11] = {
215 30, 32, 34, 36, 38, 42, 50, 66, 98, 162, 290
216};
217static const unsigned char extra_bits[36] = {
218 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
219 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16
220};
221static const unsigned int position_base[290] = {
222 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512,
223 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576, 32768,
224 49152, 65536, 98304, 131072, 196608, 262144, 393216, 524288, 655360,
225 786432, 917504, 1048576, 1179648, 1310720, 1441792, 1572864, 1703936,
226 1835008, 1966080, 2097152, 2228224, 2359296, 2490368, 2621440, 2752512,
227 2883584, 3014656, 3145728, 3276800, 3407872, 3538944, 3670016, 3801088,
228 3932160, 4063232, 4194304, 4325376, 4456448, 4587520, 4718592, 4849664,
229 4980736, 5111808, 5242880, 5373952, 5505024, 5636096, 5767168, 5898240,
230 6029312, 6160384, 6291456, 6422528, 6553600, 6684672, 6815744, 6946816,
231 7077888, 7208960, 7340032, 7471104, 7602176, 7733248, 7864320, 7995392,
232 8126464, 8257536, 8388608, 8519680, 8650752, 8781824, 8912896, 9043968,
233 9175040, 9306112, 9437184, 9568256, 9699328, 9830400, 9961472, 10092544,
234 10223616, 10354688, 10485760, 10616832, 10747904, 10878976, 11010048,
235 11141120, 11272192, 11403264, 11534336, 11665408, 11796480, 11927552,
236 12058624, 12189696, 12320768, 12451840, 12582912, 12713984, 12845056,
237 12976128, 13107200, 13238272, 13369344, 13500416, 13631488, 13762560,
238 13893632, 14024704, 14155776, 14286848, 14417920, 14548992, 14680064,
239 14811136, 14942208, 15073280, 15204352, 15335424, 15466496, 15597568,
240 15728640, 15859712, 15990784, 16121856, 16252928, 16384000, 16515072,
241 16646144, 16777216, 16908288, 17039360, 17170432, 17301504, 17432576,
242 17563648, 17694720, 17825792, 17956864, 18087936, 18219008, 18350080,
243 18481152, 18612224, 18743296, 18874368, 19005440, 19136512, 19267584,
244 19398656, 19529728, 19660800, 19791872, 19922944, 20054016, 20185088,
245 20316160, 20447232, 20578304, 20709376, 20840448, 20971520, 21102592,
246 21233664, 21364736, 21495808, 21626880, 21757952, 21889024, 22020096,
247 22151168, 22282240, 22413312, 22544384, 22675456, 22806528, 22937600,
248 23068672, 23199744, 23330816, 23461888, 23592960, 23724032, 23855104,
249 23986176, 24117248, 24248320, 24379392, 24510464, 24641536, 24772608,
250 24903680, 25034752, 25165824, 25296896, 25427968, 25559040, 25690112,
251 25821184, 25952256, 26083328, 26214400, 26345472, 26476544, 26607616,
252 26738688, 26869760, 27000832, 27131904, 27262976, 27394048, 27525120,
253 27656192, 27787264, 27918336, 28049408, 28180480, 28311552, 28442624,
254 28573696, 28704768, 28835840, 28966912, 29097984, 29229056, 29360128,
255 29491200, 29622272, 29753344, 29884416, 30015488, 30146560, 30277632,
256 30408704, 30539776, 30670848, 30801920, 30932992, 31064064, 31195136,
257 31326208, 31457280, 31588352, 31719424, 31850496, 31981568, 32112640,
258 32243712, 32374784, 32505856, 32636928, 32768000, 32899072, 33030144,
259 33161216, 33292288, 33423360
260};
261
262static void lzxd_reset_state(struct lzxd_stream *lzx) {
263 int i;
264
265 lzx->R0 = 1;
266 lzx->R1 = 1;
267 lzx->R2 = 1;
268 lzx->header_read = 0;
269 lzx->block_remaining = 0;
270 lzx->block_type = LZX_BLOCKTYPE_INVALID;
271
272 /* initialise tables to 0 (because deltas will be applied to them) */
273 for (i = 0; i < LZX_MAINTREE_MAXSYMBOLS; i++) lzx->MAINTREE_len[i] = 0;
274 for (i = 0; i < LZX_LENGTH_MAXSYMBOLS; i++) lzx->LENGTH_len[i] = 0;
275}
276
277/*-------- main LZX code --------*/
278
279struct lzxd_stream *lzxd_init(struct mspack_system *system,
280 struct mspack_file *input,
281 struct mspack_file *output,
282 int window_bits,
283 int reset_interval,
284 int input_buffer_size,
285 off_t output_length,
286 char is_delta)
287{
288 unsigned int window_size = 1 << window_bits;
289 struct lzxd_stream *lzx;
290
291 if (!system) return NULL;
292
293 /* LZX DELTA window sizes are between 2^17 (128KiB) and 2^25 (32MiB),
294 * regular LZX windows are between 2^15 (32KiB) and 2^21 (2MiB)
295 */
296 if (is_delta) {
297 if (window_bits < 17 || window_bits > 25) return NULL;
298 }
299 else {
300 if (window_bits < 15 || window_bits > 21) return NULL;
301 }
302
303 if (reset_interval < 0 || output_length < 0) {
304 D(("reset interval or output length < 0"))
305 return NULL;
306 }
307
308 /* round up input buffer size to multiple of two */
309 input_buffer_size = (input_buffer_size + 1) & -2;
310 if (input_buffer_size < 2) return NULL;
311
312 /* allocate decompression state */
313 if (!(lzx = (struct lzxd_stream *) system->alloc(system, sizeof(struct lzxd_stream)))) {
314 return NULL;
315 }
316
317 /* allocate decompression window and input buffer */
318 lzx->window = (unsigned char *) system->alloc(system, (size_t) window_size);
319 lzx->inbuf = (unsigned char *) system->alloc(system, (size_t) input_buffer_size);
320 if (!lzx->window || !lzx->inbuf) {
321 system->free(lzx->window);
322 system->free(lzx->inbuf);
323 system->free(lzx);
324 return NULL;
325 }
326
327 /* initialise decompression state */
328 lzx->sys = system;
329 lzx->input = input;
330 lzx->output = output;
331 lzx->offset = 0;
332 lzx->length = output_length;
333
334 lzx->inbuf_size = input_buffer_size;
335 lzx->window_size = 1 << window_bits;
336 lzx->ref_data_size = 0;
337 lzx->window_posn = 0;
338 lzx->frame_posn = 0;
339 lzx->frame = 0;
340 lzx->reset_interval = reset_interval;
341 lzx->intel_filesize = 0;
342 lzx->intel_curpos = 0;
343 lzx->intel_started = 0;
344 lzx->error = MSPACK_ERR_OK;
345 lzx->num_offsets = position_slots[window_bits - 15] << 3;
346 lzx->is_delta = is_delta;
347
348 lzx->o_ptr = lzx->o_end = &lzx->e8_buf[0];
349 lzxd_reset_state(lzx);
350 INIT_BITS;
351 return lzx;
352}
353
354int lzxd_set_reference_data(struct lzxd_stream *lzx,
355 struct mspack_system *system,
356 struct mspack_file *input,
357 unsigned int length)
358{
359 if (!lzx) return MSPACK_ERR_ARGS;
360
361 if (!lzx->is_delta) {
362 D(("only LZX DELTA streams support reference data"))
363 return MSPACK_ERR_ARGS;
364 }
365 if (lzx->offset) {
366 D(("too late to set reference data after decoding starts"))
367 return MSPACK_ERR_ARGS;
368 }
369 if (length > lzx->window_size) {
370 D(("reference length (%u) is longer than the window", length))
371 return MSPACK_ERR_ARGS;
372 }
373 if (length > 0 && (!system || !input)) {
374 D(("length > 0 but no system or input"))
375 return MSPACK_ERR_ARGS;
376 }
377
378 lzx->ref_data_size = length;
379 if (length > 0) {
380 /* copy reference data */
381 unsigned char *pos = &lzx->window[lzx->window_size - length];
382 int bytes = system->read(input, pos, length);
383 /* length can't be more than 2^25, so no signedness problem */
384 if (bytes < (int)length) return MSPACK_ERR_READ;
385 }
386 lzx->ref_data_size = length;
387 return MSPACK_ERR_OK;
388}
389
390void lzxd_set_output_length(struct lzxd_stream *lzx, off_t out_bytes) {
391 if (lzx && out_bytes > 0) lzx->length = out_bytes;
392}
393
394int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
395 /* bitstream and huffman reading variables */
396 register unsigned int bit_buffer;
397 register int bits_left, i=0;
398 unsigned char *i_ptr, *i_end;
399 register unsigned short sym;
400
401 int match_length, length_footer, extra, verbatim_bits, bytes_todo;
402 int this_run, main_element, aligned_bits, j, warned = 0;
403 unsigned char *window, *runsrc, *rundest, buf[12];
404 unsigned int frame_size=0, end_frame, match_offset, window_posn;
405 unsigned int R0, R1, R2;
406
407 /* easy answers */
408 if (!lzx || (out_bytes < 0)) return MSPACK_ERR_ARGS;
409 if (lzx->error) return lzx->error;
410
411 /* flush out any stored-up bytes before we begin */
412 i = lzx->o_end - lzx->o_ptr;
413 if ((off_t) i > out_bytes) i = (int) out_bytes;
414 if (i) {
415 if (lzx->sys->write(lzx->output, lzx->o_ptr, i) != i) {
416 return lzx->error = MSPACK_ERR_WRITE;
417 }
418 lzx->o_ptr += i;
419 lzx->offset += i;
420 out_bytes -= i;
421 }
422 if (out_bytes == 0) return MSPACK_ERR_OK;
423
424 /* restore local state */
425 RESTORE_BITS;
426 window = lzx->window;
427 window_posn = lzx->window_posn;
428 R0 = lzx->R0;
429 R1 = lzx->R1;
430 R2 = lzx->R2;
431
432 end_frame = (unsigned int)((lzx->offset + out_bytes) / LZX_FRAME_SIZE) + 1;
433
434 while (lzx->frame < end_frame) {
435 /* have we reached the reset interval? (if there is one?) */
436 if (lzx->reset_interval && ((lzx->frame % lzx->reset_interval) == 0)) {
437 if (lzx->block_remaining) {
438 /* this is a file format error, we can make a best effort to extract what we can */
439 D(("%d bytes remaining at reset interval", lzx->block_remaining))
440 if (!warned) {
441 lzx->sys->message(NULL, "WARNING; invalid reset interval detected during LZX decompression");
442 warned++;
443 }
444 }
445
446 /* re-read the intel header and reset the huffman lengths */
447 lzxd_reset_state(lzx);
448 R0 = lzx->R0;
449 R1 = lzx->R1;
450 R2 = lzx->R2;
451 }
452
453 /* LZX DELTA format has chunk_size, not present in LZX format */
454 if (lzx->is_delta) {
455 ENSURE_BITS(16);
456 REMOVE_BITS(16);
457 }
458
459 /* read header if necessary */
460 if (!lzx->header_read) {
461 /* read 1 bit. if bit=0, intel filesize = 0.
462 * if bit=1, read intel filesize (32 bits) */
463 j = 0; READ_BITS(i, 1); if (i) { READ_BITS(i, 16); READ_BITS(j, 16); }
464 lzx->intel_filesize = (i << 16) | j;
465 lzx->header_read = 1;
466 }
467
468 /* calculate size of frame: all frames are 32k except the final frame
469 * which is 32kb or less. this can only be calculated when lzx->length
470 * has been filled in. */
471 frame_size = LZX_FRAME_SIZE;
472 if (lzx->length && (lzx->length - lzx->offset) < (off_t)frame_size) {
473 frame_size = lzx->length - lzx->offset;
474 }
475
476 /* decode until one more frame is available */
477 bytes_todo = lzx->frame_posn + frame_size - window_posn;
478 while (bytes_todo > 0) {
479 /* initialise new block, if one is needed */
480 if (lzx->block_remaining == 0) {
481 /* realign if previous block was an odd-sized UNCOMPRESSED block */
482 if ((lzx->block_type == LZX_BLOCKTYPE_UNCOMPRESSED) &&
483 (lzx->block_length & 1))
484 {
485 READ_IF_NEEDED;
486 i_ptr++;
487 }
488
489 /* read block type (3 bits) and block length (24 bits) */
490 READ_BITS(lzx->block_type, 3);
491 READ_BITS(i, 16); READ_BITS(j, 8);
492 lzx->block_remaining = lzx->block_length = (i << 8) | j;
493 /*D(("new block t%d len %u", lzx->block_type, lzx->block_length))*/
494
495 /* read individual block headers */
496 switch (lzx->block_type) {
497 case LZX_BLOCKTYPE_ALIGNED:
498 /* read lengths of and build aligned huffman decoding tree */
499 for (i = 0; i < 8; i++) { READ_BITS(j, 3); lzx->ALIGNED_len[i] = j; }
500 BUILD_TABLE(ALIGNED);
501 /* rest of aligned header is same as verbatim */ /*@fallthrough@*/
502 case LZX_BLOCKTYPE_VERBATIM:
503 /* read lengths of and build main huffman decoding tree */
504 READ_LENGTHS(MAINTREE, 0, 256);
505 READ_LENGTHS(MAINTREE, 256, LZX_NUM_CHARS + lzx->num_offsets);
506 BUILD_TABLE(MAINTREE);
507 /* if the literal 0xE8 is anywhere in the block... */
508 if (lzx->MAINTREE_len[0xE8] != 0) lzx->intel_started = 1;
509 /* read lengths of and build lengths huffman decoding tree */
510 READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS);
511 BUILD_TABLE_MAYBE_EMPTY(LENGTH);
512 break;
513
514 case LZX_BLOCKTYPE_UNCOMPRESSED:
515 /* because we can't assume otherwise */
516 lzx->intel_started = 1;
517
518 /* read 1-16 (not 0-15) bits to align to bytes */
519 if (bits_left == 0) ENSURE_BITS(16);
520 bits_left = 0; bit_buffer = 0;
521
522 /* read 12 bytes of stored R0 / R1 / R2 values */
523 for (rundest = &buf[0], i = 0; i < 12; i++) {
524 READ_IF_NEEDED;
525 *rundest++ = *i_ptr++;
526 }
527 R0 = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
528 R1 = buf[4] | (buf[5] << 8) | (buf[6] << 16) | (buf[7] << 24);
529 R2 = buf[8] | (buf[9] << 8) | (buf[10] << 16) | (buf[11] << 24);
530 break;
531
532 default:
533 D(("bad block type"))
534 return lzx->error = MSPACK_ERR_DECRUNCH;
535 }
536 }
537
538 /* decode more of the block:
539 * run = min(what's available, what's needed) */
540 this_run = lzx->block_remaining;
541 if (this_run > bytes_todo) this_run = bytes_todo;
542
543 /* assume we decode exactly this_run bytes, for now */
544 bytes_todo -= this_run;
545 lzx->block_remaining -= this_run;
546
547 /* decode at least this_run bytes */
548 switch (lzx->block_type) {
549 case LZX_BLOCKTYPE_VERBATIM:
550 while (this_run > 0) {
551 READ_HUFFSYM(MAINTREE, main_element);
552 if (main_element < LZX_NUM_CHARS) {
553 /* literal: 0 to LZX_NUM_CHARS-1 */
554 window[window_posn++] = main_element;
555 this_run--;
556 }
557 else {
558 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
559 main_element -= LZX_NUM_CHARS;
560
561 /* get match length */
562 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
563 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
564 if (lzx->LENGTH_empty) {
565 D(("LENGTH symbol needed but tree is empty"))
566 return lzx->error = MSPACK_ERR_DECRUNCH;
567 }
568 READ_HUFFSYM(LENGTH, length_footer);
569 match_length += length_footer;
570 }
571 match_length += LZX_MIN_MATCH;
572
573 /* get match offset */
574 switch ((match_offset = (main_element >> 3))) {
575 case 0: match_offset = R0; break;
576 case 1: match_offset = R1; R1=R0; R0 = match_offset; break;
577 case 2: match_offset = R2; R2=R0; R0 = match_offset; break;
578 case 3: match_offset = 1; R2=R1; R1=R0; R0 = match_offset; break;
579 default:
580 extra = (match_offset >= 36) ? 17 : extra_bits[match_offset];
581 READ_BITS(verbatim_bits, extra);
582 match_offset = position_base[match_offset] - 2 + verbatim_bits;
583 R2 = R1; R1 = R0; R0 = match_offset;
584 }
585
586 /* LZX DELTA uses max match length to signal even longer match */
587 if (match_length == LZX_MAX_MATCH && lzx->is_delta) {
588 int extra_len = 0;
589 ENSURE_BITS(3); /* 4 entry huffman tree */
590 if (PEEK_BITS(1) == 0) {
591 REMOVE_BITS(1); /* '0' -> 8 extra length bits */
592 READ_BITS(extra_len, 8);
593 }
594 else if (PEEK_BITS(2) == 2) {
595 REMOVE_BITS(2); /* '10' -> 10 extra length bits + 0x100 */
596 READ_BITS(extra_len, 10);
597 extra_len += 0x100;
598 }
599 else if (PEEK_BITS(3) == 6) {
600 REMOVE_BITS(3); /* '110' -> 12 extra length bits + 0x500 */
601 READ_BITS(extra_len, 12);
602 extra_len += 0x500;
603 }
604 else {
605 REMOVE_BITS(3); /* '111' -> 15 extra length bits */
606 READ_BITS(extra_len, 15);
607 }
608 match_length += extra_len;
609 }
610
611 if ((window_posn + match_length) > lzx->window_size) {
612 D(("match ran over window wrap"))
613 return lzx->error = MSPACK_ERR_DECRUNCH;
614 }
615
616 /* copy match */
617 rundest = &window[window_posn];
618 i = match_length;
619 /* does match offset wrap the window? */
620 if (match_offset > window_posn) {
621 if (match_offset > lzx->offset &&
622 (match_offset - window_posn) > lzx->ref_data_size)
623 {
624 D(("match offset beyond LZX stream"))
625 return lzx->error = MSPACK_ERR_DECRUNCH;
626 }
627 /* j = length from match offset to end of window */
628 j = match_offset - window_posn;
629 if (j > (int) lzx->window_size) {
630 D(("match offset beyond window boundaries"))
631 return lzx->error = MSPACK_ERR_DECRUNCH;
632 }
633 runsrc = &window[lzx->window_size - j];
634 if (j < i) {
635 /* if match goes over the window edge, do two copy runs */
636 i -= j; while (j-- > 0) *rundest++ = *runsrc++;
637 runsrc = window;
638 }
639 while (i-- > 0) *rundest++ = *runsrc++;
640 }
641 else {
642 runsrc = rundest - match_offset;
643 while (i-- > 0) *rundest++ = *runsrc++;
644 }
645
646 this_run -= match_length;
647 window_posn += match_length;
648 }
649 } /* while (this_run > 0) */
650 break;
651
652 case LZX_BLOCKTYPE_ALIGNED:
653 while (this_run > 0) {
654 READ_HUFFSYM(MAINTREE, main_element);
655 if (main_element < LZX_NUM_CHARS) {
656 /* literal: 0 to LZX_NUM_CHARS-1 */
657 window[window_posn++] = main_element;
658 this_run--;
659 }
660 else {
661 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
662 main_element -= LZX_NUM_CHARS;
663
664 /* get match length */
665 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
666 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
667 if (lzx->LENGTH_empty) {
668 D(("LENGTH symbol needed but tree is empty"))
669 return lzx->error = MSPACK_ERR_DECRUNCH;
670 }
671 READ_HUFFSYM(LENGTH, length_footer);
672 match_length += length_footer;
673 }
674 match_length += LZX_MIN_MATCH;
675
676 /* get match offset */
677 switch ((match_offset = (main_element >> 3))) {
678 case 0: match_offset = R0; break;
679 case 1: match_offset = R1; R1 = R0; R0 = match_offset; break;
680 case 2: match_offset = R2; R2 = R0; R0 = match_offset; break;
681 default:
682 extra = (match_offset >= 36) ? 17 : extra_bits[match_offset];
683 match_offset = position_base[match_offset] - 2;
684 if (extra > 3) {
685 /* verbatim and aligned bits */
686 extra -= 3;
687 READ_BITS(verbatim_bits, extra);
688 match_offset += (verbatim_bits << 3);
689 READ_HUFFSYM(ALIGNED, aligned_bits);
690 match_offset += aligned_bits;
691 }
692 else if (extra == 3) {
693 /* aligned bits only */
694 READ_HUFFSYM(ALIGNED, aligned_bits);
695 match_offset += aligned_bits;
696 }
697 else if (extra > 0) { /* extra==1, extra==2 */
698 /* verbatim bits only */
699 READ_BITS(verbatim_bits, extra);
700 match_offset += verbatim_bits;
701 }
702 else /* extra == 0 */ {
703 /* ??? not defined in LZX specification! */
704 match_offset = 1;
705 }
706 /* update repeated offset LRU queue */
707 R2 = R1; R1 = R0; R0 = match_offset;
708 }
709
710 /* LZX DELTA uses max match length to signal even longer match */
711 if (match_length == LZX_MAX_MATCH && lzx->is_delta) {
712 int extra_len = 0;
713 ENSURE_BITS(3); /* 4 entry huffman tree */
714 if (PEEK_BITS(1) == 0) {
715 REMOVE_BITS(1); /* '0' -> 8 extra length bits */
716 READ_BITS(extra_len, 8);
717 }
718 else if (PEEK_BITS(2) == 2) {
719 REMOVE_BITS(2); /* '10' -> 10 extra length bits + 0x100 */
720 READ_BITS(extra_len, 10);
721 extra_len += 0x100;
722 }
723 else if (PEEK_BITS(3) == 6) {
724 REMOVE_BITS(3); /* '110' -> 12 extra length bits + 0x500 */
725 READ_BITS(extra_len, 12);
726 extra_len += 0x500;
727 }
728 else {
729 REMOVE_BITS(3); /* '111' -> 15 extra length bits */
730 READ_BITS(extra_len, 15);
731 }
732 match_length += extra_len;
733 }
734
735 if ((window_posn + match_length) > lzx->window_size) {
736 D(("match ran over window wrap"))
737 return lzx->error = MSPACK_ERR_DECRUNCH;
738 }
739
740 /* copy match */
741 rundest = &window[window_posn];
742 i = match_length;
743 /* does match offset wrap the window? */
744 if (match_offset > window_posn) {
745 if (match_offset > lzx->offset &&
746 (match_offset - window_posn) > lzx->ref_data_size)
747 {
748 D(("match offset beyond LZX stream"))
749 return lzx->error = MSPACK_ERR_DECRUNCH;
750 }
751 /* j = length from match offset to end of window */
752 j = match_offset - window_posn;
753 if (j > (int) lzx->window_size) {
754 D(("match offset beyond window boundaries"))
755 return lzx->error = MSPACK_ERR_DECRUNCH;
756 }
757 runsrc = &window[lzx->window_size - j];
758 if (j < i) {
759 /* if match goes over the window edge, do two copy runs */
760 i -= j; while (j-- > 0) *rundest++ = *runsrc++;
761 runsrc = window;
762 }
763 while (i-- > 0) *rundest++ = *runsrc++;
764 }
765 else {
766 runsrc = rundest - match_offset;
767 while (i-- > 0) *rundest++ = *runsrc++;
768 }
769
770 this_run -= match_length;
771 window_posn += match_length;
772 }
773 } /* while (this_run > 0) */
774 break;
775
776 case LZX_BLOCKTYPE_UNCOMPRESSED:
777 /* as this_run is limited not to wrap a frame, this also means it
778 * won't wrap the window (as the window is a multiple of 32k) */
779 rundest = &window[window_posn];
780 window_posn += this_run;
781 while (this_run > 0) {
782 if ((i = i_end - i_ptr) == 0) {
783 READ_IF_NEEDED;
784 }
785 else {
786 if (i > this_run) i = this_run;
787 lzx->sys->copy(i_ptr, rundest, (size_t) i);
788 rundest += i;
789 i_ptr += i;
790 this_run -= i;
791 }
792 }
793 break;
794
795 default:
796 return lzx->error = MSPACK_ERR_DECRUNCH; /* might as well */
797 }
798
799 /* did the final match overrun our desired this_run length? */
800 if (this_run < 0) {
801 if ((unsigned int)(-this_run) > lzx->block_remaining) {
802 D(("overrun went past end of block by %d (%d remaining)",
803 -this_run, lzx->block_remaining ))
804 return lzx->error = MSPACK_ERR_DECRUNCH;
805 }
806 lzx->block_remaining -= -this_run;
807 }
808 } /* while (bytes_todo > 0) */
809
810 /* streams don't extend over frame boundaries */
811 if ((window_posn - lzx->frame_posn) != frame_size) {
812 D(("decode beyond output frame limits! %d != %d",
813 window_posn - lzx->frame_posn, frame_size))
814 return lzx->error = MSPACK_ERR_DECRUNCH;
815 }
816
817 /* re-align input bitstream */
818 if (bits_left > 0) ENSURE_BITS(16);
819 if (bits_left & 15) REMOVE_BITS(bits_left & 15);
820
821 /* check that we've used all of the previous frame first */
822 if (lzx->o_ptr != lzx->o_end) {
823 D(("%ld avail bytes, new %d frame",
824 (long)(lzx->o_end - lzx->o_ptr), frame_size))
825 return lzx->error = MSPACK_ERR_DECRUNCH;
826 }
827
828 /* does this intel block _really_ need decoding? */
829 if (lzx->intel_started && lzx->intel_filesize &&
830 (lzx->frame <= 32768) && (frame_size > 10))
831 {
832 unsigned char *data = &lzx->e8_buf[0];
833 unsigned char *dataend = &lzx->e8_buf[frame_size - 10];
834 signed int curpos = lzx->intel_curpos;
835 signed int filesize = lzx->intel_filesize;
836 signed int abs_off, rel_off;
837
838 /* copy e8 block to the e8 buffer and tweak if needed */
839 lzx->o_ptr = data;
840 lzx->sys->copy(&lzx->window[lzx->frame_posn], data, frame_size);
841
842 while (data < dataend) {
843 if (*data++ != 0xE8) { curpos++; continue; }
844 abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
845 if ((abs_off >= -curpos) && (abs_off < filesize)) {
846 rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
847 data[0] = (unsigned char) rel_off;
848 data[1] = (unsigned char) (rel_off >> 8);
849 data[2] = (unsigned char) (rel_off >> 16);
850 data[3] = (unsigned char) (rel_off >> 24);
851 }
852 data += 4;
853 curpos += 5;
854 }
855 lzx->intel_curpos += frame_size;
856 }
857 else {
858 lzx->o_ptr = &lzx->window[lzx->frame_posn];
859 if (lzx->intel_filesize) lzx->intel_curpos += frame_size;
860 }
861 lzx->o_end = &lzx->o_ptr[frame_size];
862
863 /* write a frame */
864 i = (out_bytes < (off_t)frame_size) ? (unsigned int)out_bytes : frame_size;
865 if (lzx->sys->write(lzx->output, lzx->o_ptr, i) != i) {
866 return lzx->error = MSPACK_ERR_WRITE;
867 }
868 lzx->o_ptr += i;
869 lzx->offset += i;
870 out_bytes -= i;
871
872 /* advance frame start position */
873 lzx->frame_posn += frame_size;
874 lzx->frame++;
875
876 /* wrap window / frame position pointers */
877 if (window_posn == lzx->window_size) window_posn = 0;
878 if (lzx->frame_posn == lzx->window_size) lzx->frame_posn = 0;
879
880 } /* while (lzx->frame < end_frame) */
881
882 if (out_bytes) {
883 D(("bytes left to output"))
884 return lzx->error = MSPACK_ERR_DECRUNCH;
885 }
886
887 /* store local state */
888 STORE_BITS;
889 lzx->window_posn = window_posn;
890 lzx->R0 = R0;
891 lzx->R1 = R1;
892 lzx->R2 = R2;
893
894 return MSPACK_ERR_OK;
895}
896
897void lzxd_free(struct lzxd_stream *lzx) {
898 struct mspack_system *sys;
899 if (lzx) {
900 sys = lzx->sys;
901 sys->free(lzx->inbuf);
902 sys->free(lzx->window);
903 sys->free(lzx);
904 }
905}
diff --git a/utils/rbutilqt/mspack/mspack.h b/utils/rbutilqt/mspack/mspack.h
new file mode 100644
index 0000000000..3e99624463
--- /dev/null
+++ b/utils/rbutilqt/mspack/mspack.h
@@ -0,0 +1,2385 @@
1/* libmspack -- a library for working with Microsoft compression formats.
2 * (C) 2003-2019 Stuart Caie <kyzer@cabextract.org.uk>
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/** \mainpage
18 *
19 * \section intro Introduction
20 *
21 * libmspack is a library which provides compressors and decompressors,
22 * archivers and dearchivers for Microsoft compression formats.
23 *
24 * \section formats Formats supported
25 *
26 * The following file formats are supported:
27 * - SZDD files, which use LZSS compression
28 * - KWAJ files, which use LZSS, LZSS+Huffman or deflate compression
29 * - .HLP (MS Help) files, which use LZSS compression
30 * - .CAB (MS Cabinet) files, which use deflate, LZX or Quantum compression
31 * - .CHM (HTML Help) files, which use LZX compression
32 * - .LIT (MS EBook) files, which use LZX compression and DES encryption
33 * - .LZX (Exchange Offline Addressbook) files, which use LZX compression
34 *
35 * To determine the capabilities of the library, and the binary
36 * compatibility version of any particular compressor or decompressor, use
37 * the mspack_version() function. The UNIX library interface version is
38 * defined as the highest-versioned library component.
39 *
40 * \section starting Getting started
41 *
42 * The macro MSPACK_SYS_SELFTEST() should be used to ensure the library can
43 * be used. In particular, it checks if the caller is using 32-bit file I/O
44 * when the library is compiled for 64-bit file I/O and vice versa.
45 *
46 * If compiled normally, the library includes basic file I/O and memory
47 * management functionality using the standard C library. This can be
48 * customised and replaced entirely by creating a mspack_system structure.
49 *
50 * A compressor or decompressor for the required format must be
51 * instantiated before it can be used. Each construction function takes
52 * one parameter, which is either a pointer to a custom mspack_system
53 * structure, or NULL to use the default. The instantiation returned, if
54 * not NULL, contains function pointers (methods) to work with the given
55 * file format.
56 *
57 * For compression:
58 * - mspack_create_cab_compressor() creates a mscab_compressor
59 * - mspack_create_chm_compressor() creates a mschm_compressor
60 * - mspack_create_lit_compressor() creates a mslit_compressor
61 * - mspack_create_hlp_compressor() creates a mshlp_compressor
62 * - mspack_create_szdd_compressor() creates a msszdd_compressor
63 * - mspack_create_kwaj_compressor() creates a mskwaj_compressor
64 * - mspack_create_oab_compressor() creates a msoab_compressor
65 *
66 * For decompression:
67 * - mspack_create_cab_decompressor() creates a mscab_decompressor
68 * - mspack_create_chm_decompressor() creates a mschm_decompressor
69 * - mspack_create_lit_decompressor() creates a mslit_decompressor
70 * - mspack_create_hlp_decompressor() creates a mshlp_decompressor
71 * - mspack_create_szdd_decompressor() creates a msszdd_decompressor
72 * - mspack_create_kwaj_decompressor() creates a mskwaj_decompressor
73 * - mspack_create_oab_decompressor() creates a msoab_decompressor
74 *
75 * Once finished working with a format, each kind of
76 * compressor/decompressor has its own specific destructor:
77 * - mspack_destroy_cab_compressor()
78 * - mspack_destroy_cab_decompressor()
79 * - mspack_destroy_chm_compressor()
80 * - mspack_destroy_chm_decompressor()
81 * - mspack_destroy_lit_compressor()
82 * - mspack_destroy_lit_decompressor()
83 * - mspack_destroy_hlp_compressor()
84 * - mspack_destroy_hlp_decompressor()
85 * - mspack_destroy_szdd_compressor()
86 * - mspack_destroy_szdd_decompressor()
87 * - mspack_destroy_kwaj_compressor()
88 * - mspack_destroy_kwaj_decompressor()
89 * - mspack_destroy_oab_compressor()
90 * - mspack_destroy_oab_decompressor()
91 *
92 * Destroying a compressor or decompressor does not destroy any objects,
93 * structures or handles that have been created using that compressor or
94 * decompressor. Ensure that everything created or opened is destroyed or
95 * closed before compressor/decompressor is itself destroyed.
96 *
97 * \section errors Error codes
98 *
99 * All compressors and decompressors use the same set of error codes. Most
100 * methods return an error code directly. For methods which do not
101 * return error codes directly, the error code can be obtained with the
102 * last_error() method.
103 *
104 * - #MSPACK_ERR_OK is used to indicate success. This error code is defined
105 * as zero, all other code are non-zero.
106 * - #MSPACK_ERR_ARGS indicates that a method was called with inappropriate
107 * arguments.
108 * - #MSPACK_ERR_OPEN indicates that mspack_system::open() failed.
109 * - #MSPACK_ERR_READ indicates that mspack_system::read() failed.
110 * - #MSPACK_ERR_WRITE indicates that mspack_system::write() failed.
111 * - #MSPACK_ERR_SEEK indicates that mspack_system::seek() failed.
112 * - #MSPACK_ERR_NOMEMORY indicates that mspack_system::alloc() failed.
113 * - #MSPACK_ERR_SIGNATURE indicates that the file being read does not
114 * have the correct "signature". It is probably not a valid file for
115 * whatever format is being read.
116 * - #MSPACK_ERR_DATAFORMAT indicates that the file being used or read
117 * is corrupt.
118 * - #MSPACK_ERR_CHECKSUM indicates that a data checksum has failed.
119 * - #MSPACK_ERR_CRUNCH indicates an error occured during compression.
120 * - #MSPACK_ERR_DECRUNCH indicates an error occured during decompression.
121 *
122 * \section threading Multi-threading
123 *
124 * libmspack methods are reentrant and multithreading-safe when each
125 * thread has its own compressor or decompressor.
126
127 * You should not call multiple methods simultaneously on a single
128 * compressor or decompressor instance.
129 *
130 * If this may happen, you can either use one compressor or
131 * decompressor per thread, or you can use your preferred lock,
132 * semaphore or mutex library to ensure no more than one method on a
133 * compressor/decompressor is called simultaneously. libmspack will
134 * not do this locking for you.
135 *
136 * Example of incorrect behaviour:
137 * - thread 1 calls mspack_create_cab_decompressor()
138 * - thread 1 calls open()
139 * - thread 1 calls extract() for one file
140 * - thread 2 simultaneously calls extract() for another file
141 *
142 * Correct behaviour:
143 * - thread 1 calls mspack_create_cab_decompressor()
144 * - thread 2 calls mspack_create_cab_decompressor()
145 * - thread 1 calls its own open() / extract()
146 * - thread 2 simultaneously calls its own open() / extract()
147 *
148 * Also correct behaviour:
149 * - thread 1 calls mspack_create_cab_decompressor()
150 * - thread 1 locks a mutex for with the decompressor before
151 * calling any methods on it, and unlocks the mutex after each
152 * method returns.
153 * - thread 1 can share the results of open() with thread 2, and both
154 * can call extract(), provided they both guard against simultaneous
155 * use of extract(), and any other methods, with the mutex
156 */
157
158#ifndef LIB_MSPACK_H
159#define LIB_MSPACK_H 1
160
161#ifdef __cplusplus
162extern "C" {
163#endif
164
165#include <sys/types.h>
166#include <stdlib.h>
167
168/**
169 * System self-test function, to ensure both library and calling program
170 * can use one another.
171 *
172 * A result of MSPACK_ERR_OK means the library and caller are
173 * compatible. Any other result indicates that the library and caller are
174 * not compatible and should not be used. In particular, a value of
175 * MSPACK_ERR_SEEK means the library and caller use different off_t
176 * datatypes.
177 *
178 * It should be used like so:
179 *
180 * @code
181 * int selftest_result;
182 * MSPACK_SYS_SELFTEST(selftest_result);
183 * if (selftest_result != MSPACK_ERR_OK) {
184 * fprintf(stderr, "incompatible with this build of libmspack\n");
185 * exit(0);
186 * }
187 * @endcode
188 *
189 * @param result an int variable to store the result of the self-test
190 */
191#define MSPACK_SYS_SELFTEST(result) do { \
192 (result) = mspack_sys_selftest_internal(sizeof(off_t)); \
193} while (0)
194
195/** Part of the MSPACK_SYS_SELFTEST() macro, must not be used directly. */
196extern int mspack_sys_selftest_internal(int);
197
198/**
199 * Enquire about the binary compatibility version of a specific interface in
200 * the library. Currently, the following interfaces are defined:
201 *
202 * - #MSPACK_VER_LIBRARY: the overall library
203 * - #MSPACK_VER_SYSTEM: the mspack_system interface
204 * - #MSPACK_VER_MSCABD: the mscab_decompressor interface
205 * - #MSPACK_VER_MSCABC: the mscab_compressor interface
206 * - #MSPACK_VER_MSCHMD: the mschm_decompressor interface
207 * - #MSPACK_VER_MSCHMC: the mschm_compressor interface
208 * - #MSPACK_VER_MSLITD: the mslit_decompressor interface
209 * - #MSPACK_VER_MSLITC: the mslit_compressor interface
210 * - #MSPACK_VER_MSHLPD: the mshlp_decompressor interface
211 * - #MSPACK_VER_MSHLPC: the mshlp_compressor interface
212 * - #MSPACK_VER_MSSZDDD: the msszdd_decompressor interface
213 * - #MSPACK_VER_MSSZDDC: the msszdd_compressor interface
214 * - #MSPACK_VER_MSKWAJD: the mskwaj_decompressor interface
215 * - #MSPACK_VER_MSKWAJC: the mskwaj_compressor interface
216 * - #MSPACK_VER_MSOABD: the msoab_decompressor interface
217 * - #MSPACK_VER_MSOABC: the msoab_compressor interface
218 *
219 * The result of the function should be interpreted as follows:
220 * - -1: this interface is completely unknown to the library
221 * - 0: this interface is known, but non-functioning
222 * - 1: this interface has all basic functionality
223 * - 2, 3, ...: this interface has additional functionality, clearly marked
224 * in the documentation as "version 2", "version 3" and so on.
225 *
226 * @param entity the interface to request current version of
227 * @return the version of the requested interface
228 */
229extern int mspack_version(int entity);
230
231/** Pass to mspack_version() to get the overall library version */
232#define MSPACK_VER_LIBRARY (0)
233/** Pass to mspack_version() to get the mspack_system version */
234#define MSPACK_VER_SYSTEM (1)
235/** Pass to mspack_version() to get the mscab_decompressor version */
236#define MSPACK_VER_MSCABD (2)
237/** Pass to mspack_version() to get the mscab_compressor version */
238#define MSPACK_VER_MSCABC (3)
239/** Pass to mspack_version() to get the mschm_decompressor version */
240#define MSPACK_VER_MSCHMD (4)
241/** Pass to mspack_version() to get the mschm_compressor version */
242#define MSPACK_VER_MSCHMC (5)
243/** Pass to mspack_version() to get the mslit_decompressor version */
244#define MSPACK_VER_MSLITD (6)
245/** Pass to mspack_version() to get the mslit_compressor version */
246#define MSPACK_VER_MSLITC (7)
247/** Pass to mspack_version() to get the mshlp_decompressor version */
248#define MSPACK_VER_MSHLPD (8)
249/** Pass to mspack_version() to get the mshlp_compressor version */
250#define MSPACK_VER_MSHLPC (9)
251/** Pass to mspack_version() to get the msszdd_decompressor version */
252#define MSPACK_VER_MSSZDDD (10)
253/** Pass to mspack_version() to get the msszdd_compressor version */
254#define MSPACK_VER_MSSZDDC (11)
255/** Pass to mspack_version() to get the mskwaj_decompressor version */
256#define MSPACK_VER_MSKWAJD (12)
257/** Pass to mspack_version() to get the mskwaj_compressor version */
258#define MSPACK_VER_MSKWAJC (13)
259/** Pass to mspack_version() to get the msoab_decompressor version */
260#define MSPACK_VER_MSOABD (14)
261/** Pass to mspack_version() to get the msoab_compressor version */
262#define MSPACK_VER_MSOABC (15)
263
264/* --- file I/O abstraction ------------------------------------------------ */
265
266/**
267 * A structure which abstracts file I/O and memory management.
268 *
269 * The library always uses the mspack_system structure for interaction
270 * with the file system and to allocate, free and copy all memory. It also
271 * uses it to send literal messages to the library user.
272 *
273 * When the library is compiled normally, passing NULL to a compressor or
274 * decompressor constructor will result in a default mspack_system being
275 * used, where all methods are implemented with the standard C library.
276 * However, all constructors support being given a custom created
277 * mspack_system structure, with the library user's own methods. This
278 * allows for more abstract interaction, such as reading and writing files
279 * directly to memory, or from a network socket or pipe.
280 *
281 * Implementors of an mspack_system structure should read all
282 * documentation entries for every structure member, and write methods
283 * which conform to those standards.
284 */
285struct mspack_system {
286 /**
287 * Opens a file for reading, writing, appending or updating.
288 *
289 * @param self a self-referential pointer to the mspack_system
290 * structure whose open() method is being called. If
291 * this pointer is required by close(), read(), write(),
292 * seek() or tell(), it should be stored in the result
293 * structure at this time.
294 * @param filename the file to be opened. It is passed directly from the
295 * library caller without being modified, so it is up to
296 * the caller what this parameter actually represents.
297 * @param mode one of #MSPACK_SYS_OPEN_READ (open an existing file
298 * for reading), #MSPACK_SYS_OPEN_WRITE (open a new file
299 * for writing), #MSPACK_SYS_OPEN_UPDATE (open an existing
300 * file for reading/writing from the start of the file) or
301 * #MSPACK_SYS_OPEN_APPEND (open an existing file for
302 * reading/writing from the end of the file)
303 * @return a pointer to a mspack_file structure. This structure officially
304 * contains no members, its true contents are up to the
305 * mspack_system implementor. It should contain whatever is needed
306 * for other mspack_system methods to operate. Returning the NULL
307 * pointer indicates an error condition.
308 * @see close(), read(), write(), seek(), tell(), message()
309 */
310 struct mspack_file * (*open)(struct mspack_system *self,
311 const char *filename,
312 int mode);
313
314 /**
315 * Closes a previously opened file. If any memory was allocated for this
316 * particular file handle, it should be freed at this time.
317 *
318 * @param file the file to close
319 * @see open()
320 */
321 void (*close)(struct mspack_file *file);
322
323 /**
324 * Reads a given number of bytes from an open file.
325 *
326 * @param file the file to read from
327 * @param buffer the location where the read bytes should be stored
328 * @param bytes the number of bytes to read from the file.
329 * @return the number of bytes successfully read (this can be less than
330 * the number requested), zero to mark the end of file, or less
331 * than zero to indicate an error. The library does not "retry"
332 * reads and assumes short reads are due to EOF, so you should
333 * avoid returning short reads because of transient errors.
334 * @see open(), write()
335 */
336 int (*read)(struct mspack_file *file,
337 void *buffer,
338 int bytes);
339
340 /**
341 * Writes a given number of bytes to an open file.
342 *
343 * @param file the file to write to
344 * @param buffer the location where the written bytes should be read from
345 * @param bytes the number of bytes to write to the file.
346 * @return the number of bytes successfully written, this can be less
347 * than the number requested. Zero or less can indicate an error
348 * where no bytes at all could be written. All cases where less
349 * bytes were written than requested are considered by the library
350 * to be an error.
351 * @see open(), read()
352 */
353 int (*write)(struct mspack_file *file,
354 void *buffer,
355 int bytes);
356
357 /**
358 * Seeks to a specific file offset within an open file.
359 *
360 * Sometimes the library needs to know the length of a file. It does
361 * this by seeking to the end of the file with seek(file, 0,
362 * MSPACK_SYS_SEEK_END), then calling tell(). Implementations may want
363 * to make a special case for this.
364 *
365 * Due to the potentially varying 32/64 bit datatype off_t on some
366 * architectures, the #MSPACK_SYS_SELFTEST macro MUST be used before
367 * using the library. If not, the error caused by the library passing an
368 * inappropriate stackframe to seek() is subtle and hard to trace.
369 *
370 * @param file the file to be seeked
371 * @param offset an offset to seek, measured in bytes
372 * @param mode one of #MSPACK_SYS_SEEK_START (the offset should be
373 * measured from the start of the file), #MSPACK_SYS_SEEK_CUR
374 * (the offset should be measured from the current file offset)
375 * or #MSPACK_SYS_SEEK_END (the offset should be measured from
376 * the end of the file)
377 * @return zero for success, non-zero for an error
378 * @see open(), tell()
379 */
380 int (*seek)(struct mspack_file *file,
381 off_t offset,
382 int mode);
383
384 /**
385 * Returns the current file position (in bytes) of the given file.
386 *
387 * @param file the file whose file position is wanted
388 * @return the current file position of the file
389 * @see open(), seek()
390 */
391 off_t (*tell)(struct mspack_file *file);
392
393 /**
394 * Used to send messages from the library to the user.
395 *
396 * Occasionally, the library generates warnings or other messages in
397 * plain english to inform the human user. These are informational only
398 * and can be ignored if not wanted.
399 *
400 * @param file may be a file handle returned from open() if this message
401 * pertains to a specific open file, or NULL if not related to
402 * a specific file.
403 * @param format a printf() style format string. It does NOT include a
404 * trailing newline.
405 * @see open()
406 */
407 void (*message)(struct mspack_file *file,
408 const char *format,
409 ...);
410
411 /**
412 * Allocates memory.
413 *
414 * @param self a self-referential pointer to the mspack_system
415 * structure whose alloc() method is being called.
416 * @param bytes the number of bytes to allocate
417 * @result a pointer to the requested number of bytes, or NULL if
418 * not enough memory is available
419 * @see free()
420 */
421 void * (*alloc)(struct mspack_system *self,
422 size_t bytes);
423
424 /**
425 * Frees memory.
426 *
427 * @param ptr the memory to be freed. NULL is accepted and ignored.
428 * @see alloc()
429 */
430 void (*free)(void *ptr);
431
432 /**
433 * Copies from one region of memory to another.
434 *
435 * The regions of memory are guaranteed not to overlap, are usually less
436 * than 256 bytes, and may not be aligned. Please note that the source
437 * parameter comes before the destination parameter, unlike the standard
438 * C function memcpy().
439 *
440 * @param src the region of memory to copy from
441 * @param dest the region of memory to copy to
442 * @param bytes the size of the memory region, in bytes
443 */
444 void (*copy)(void *src,
445 void *dest,
446 size_t bytes);
447
448 /**
449 * A null pointer to mark the end of mspack_system. It must equal NULL.
450 *
451 * Should the mspack_system structure extend in the future, this NULL
452 * will be seen, rather than have an invalid method pointer called.
453 */
454 void *null_ptr;
455};
456
457/** mspack_system::open() mode: open existing file for reading. */
458#define MSPACK_SYS_OPEN_READ (0)
459/** mspack_system::open() mode: open new file for writing */
460#define MSPACK_SYS_OPEN_WRITE (1)
461/** mspack_system::open() mode: open existing file for writing */
462#define MSPACK_SYS_OPEN_UPDATE (2)
463/** mspack_system::open() mode: open existing file for writing */
464#define MSPACK_SYS_OPEN_APPEND (3)
465
466/** mspack_system::seek() mode: seek relative to start of file */
467#define MSPACK_SYS_SEEK_START (0)
468/** mspack_system::seek() mode: seek relative to current offset */
469#define MSPACK_SYS_SEEK_CUR (1)
470/** mspack_system::seek() mode: seek relative to end of file */
471#define MSPACK_SYS_SEEK_END (2)
472
473/**
474 * A structure which represents an open file handle. The contents of this
475 * structure are determined by the implementation of the
476 * mspack_system::open() method.
477 */
478struct mspack_file {
479 int dummy;
480};
481
482/* --- error codes --------------------------------------------------------- */
483
484/** Error code: no error */
485#define MSPACK_ERR_OK (0)
486/** Error code: bad arguments to method */
487#define MSPACK_ERR_ARGS (1)
488/** Error code: error opening file */
489#define MSPACK_ERR_OPEN (2)
490/** Error code: error reading file */
491#define MSPACK_ERR_READ (3)
492/** Error code: error writing file */
493#define MSPACK_ERR_WRITE (4)
494/** Error code: seek error */
495#define MSPACK_ERR_SEEK (5)
496/** Error code: out of memory */
497#define MSPACK_ERR_NOMEMORY (6)
498/** Error code: bad "magic id" in file */
499#define MSPACK_ERR_SIGNATURE (7)
500/** Error code: bad or corrupt file format */
501#define MSPACK_ERR_DATAFORMAT (8)
502/** Error code: bad checksum or CRC */
503#define MSPACK_ERR_CHECKSUM (9)
504/** Error code: error during compression */
505#define MSPACK_ERR_CRUNCH (10)
506/** Error code: error during decompression */
507#define MSPACK_ERR_DECRUNCH (11)
508
509/* --- functions available in library -------------------------------------- */
510
511/** Creates a new CAB compressor.
512 * @param sys a custom mspack_system structure, or NULL to use the default
513 * @return a #mscab_compressor or NULL
514 */
515extern struct mscab_compressor *
516 mspack_create_cab_compressor(struct mspack_system *sys);
517
518/** Creates a new CAB decompressor.
519 * @param sys a custom mspack_system structure, or NULL to use the default
520 * @return a #mscab_decompressor or NULL
521 */
522extern struct mscab_decompressor *
523 mspack_create_cab_decompressor(struct mspack_system *sys);
524
525/** Destroys an existing CAB compressor.
526 * @param self the #mscab_compressor to destroy
527 */
528extern void mspack_destroy_cab_compressor(struct mscab_compressor *self);
529
530/** Destroys an existing CAB decompressor.
531 * @param self the #mscab_decompressor to destroy
532 */
533extern void mspack_destroy_cab_decompressor(struct mscab_decompressor *self);
534
535
536/** Creates a new CHM compressor.
537 * @param sys a custom mspack_system structure, or NULL to use the default
538 * @return a #mschm_compressor or NULL
539 */
540extern struct mschm_compressor *
541 mspack_create_chm_compressor(struct mspack_system *sys);
542
543/** Creates a new CHM decompressor.
544 * @param sys a custom mspack_system structure, or NULL to use the default
545 * @return a #mschm_decompressor or NULL
546 */
547extern struct mschm_decompressor *
548 mspack_create_chm_decompressor(struct mspack_system *sys);
549
550/** Destroys an existing CHM compressor.
551 * @param self the #mschm_compressor to destroy
552 */
553extern void mspack_destroy_chm_compressor(struct mschm_compressor *self);
554
555/** Destroys an existing CHM decompressor.
556 * @param self the #mschm_decompressor to destroy
557 */
558extern void mspack_destroy_chm_decompressor(struct mschm_decompressor *self);
559
560
561/** Creates a new LIT compressor.
562 * @param sys a custom mspack_system structure, or NULL to use the default
563 * @return a #mslit_compressor or NULL
564 */
565extern struct mslit_compressor *
566 mspack_create_lit_compressor(struct mspack_system *sys);
567
568/** Creates a new LIT decompressor.
569 * @param sys a custom mspack_system structure, or NULL to use the default
570 * @return a #mslit_decompressor or NULL
571 */
572extern struct mslit_decompressor *
573 mspack_create_lit_decompressor(struct mspack_system *sys);
574
575/** Destroys an existing LIT compressor.
576 * @param self the #mslit_compressor to destroy
577 */
578extern void mspack_destroy_lit_compressor(struct mslit_compressor *self);
579
580/** Destroys an existing LIT decompressor.
581 * @param self the #mslit_decompressor to destroy
582 */
583extern void mspack_destroy_lit_decompressor(struct mslit_decompressor *self);
584
585
586/** Creates a new HLP compressor.
587 * @param sys a custom mspack_system structure, or NULL to use the default
588 * @return a #mshlp_compressor or NULL
589 */
590extern struct mshlp_compressor *
591 mspack_create_hlp_compressor(struct mspack_system *sys);
592
593/** Creates a new HLP decompressor.
594 * @param sys a custom mspack_system structure, or NULL to use the default
595 * @return a #mshlp_decompressor or NULL
596 */
597extern struct mshlp_decompressor *
598 mspack_create_hlp_decompressor(struct mspack_system *sys);
599
600/** Destroys an existing hlp compressor.
601 * @param self the #mshlp_compressor to destroy
602 */
603extern void mspack_destroy_hlp_compressor(struct mshlp_compressor *self);
604
605/** Destroys an existing hlp decompressor.
606 * @param self the #mshlp_decompressor to destroy
607 */
608extern void mspack_destroy_hlp_decompressor(struct mshlp_decompressor *self);
609
610
611/** Creates a new SZDD compressor.
612 * @param sys a custom mspack_system structure, or NULL to use the default
613 * @return a #msszdd_compressor or NULL
614 */
615extern struct msszdd_compressor *
616 mspack_create_szdd_compressor(struct mspack_system *sys);
617
618/** Creates a new SZDD decompressor.
619 * @param sys a custom mspack_system structure, or NULL to use the default
620 * @return a #msszdd_decompressor or NULL
621 */
622extern struct msszdd_decompressor *
623 mspack_create_szdd_decompressor(struct mspack_system *sys);
624
625/** Destroys an existing SZDD compressor.
626 * @param self the #msszdd_compressor to destroy
627 */
628extern void mspack_destroy_szdd_compressor(struct msszdd_compressor *self);
629
630/** Destroys an existing SZDD decompressor.
631 * @param self the #msszdd_decompressor to destroy
632 */
633extern void mspack_destroy_szdd_decompressor(struct msszdd_decompressor *self);
634
635
636/** Creates a new KWAJ compressor.
637 * @param sys a custom mspack_system structure, or NULL to use the default
638 * @return a #mskwaj_compressor or NULL
639 */
640extern struct mskwaj_compressor *
641 mspack_create_kwaj_compressor(struct mspack_system *sys);
642
643/** Creates a new KWAJ decompressor.
644 * @param sys a custom mspack_system structure, or NULL to use the default
645 * @return a #mskwaj_decompressor or NULL
646 */
647extern struct mskwaj_decompressor *
648 mspack_create_kwaj_decompressor(struct mspack_system *sys);
649
650/** Destroys an existing KWAJ compressor.
651 * @param self the #mskwaj_compressor to destroy
652 */
653extern void mspack_destroy_kwaj_compressor(struct mskwaj_compressor *self);
654
655/** Destroys an existing KWAJ decompressor.
656 * @param self the #mskwaj_decompressor to destroy
657 */
658extern void mspack_destroy_kwaj_decompressor(struct mskwaj_decompressor *self);
659
660
661/** Creates a new OAB compressor.
662 * @param sys a custom mspack_system structure, or NULL to use the default
663 * @return a #msoab_compressor or NULL
664 */
665extern struct msoab_compressor *
666 mspack_create_oab_compressor(struct mspack_system *sys);
667
668/** Creates a new OAB decompressor.
669 * @param sys a custom mspack_system structure, or NULL to use the default
670 * @return a #msoab_decompressor or NULL
671 */
672extern struct msoab_decompressor *
673 mspack_create_oab_decompressor(struct mspack_system *sys);
674
675/** Destroys an existing OAB compressor.
676 * @param self the #msoab_compressor to destroy
677 */
678extern void mspack_destroy_oab_compressor(struct msoab_compressor *self);
679
680/** Destroys an existing OAB decompressor.
681 * @param self the #msoab_decompressor to destroy
682 */
683extern void mspack_destroy_oab_decompressor(struct msoab_decompressor *self);
684
685
686/* --- support for .CAB (MS Cabinet) file format --------------------------- */
687
688/**
689 * A structure which represents a single cabinet file.
690 *
691 * All fields are READ ONLY.
692 *
693 * If this cabinet is part of a merged cabinet set, the #files and #folders
694 * fields are common to all cabinets in the set, and will be identical.
695 *
696 * @see mscab_decompressor::open(), mscab_decompressor::close(),
697 * mscab_decompressor::search()
698 */
699struct mscabd_cabinet {
700 /**
701 * The next cabinet in a chained list, if this cabinet was opened with
702 * mscab_decompressor::search(). May be NULL to mark the end of the
703 * list.
704 */
705 struct mscabd_cabinet *next;
706
707 /**
708 * The filename of the cabinet. More correctly, the filename of the
709 * physical file that the cabinet resides in. This is given by the
710 * library user and may be in any format.
711 */
712 const char *filename;
713
714 /** The file offset of cabinet within the physical file it resides in. */
715 off_t base_offset;
716
717 /** The length of the cabinet file in bytes. */
718 unsigned int length;
719
720 /** The previous cabinet in a cabinet set, or NULL. */
721 struct mscabd_cabinet *prevcab;
722
723 /** The next cabinet in a cabinet set, or NULL. */
724 struct mscabd_cabinet *nextcab;
725
726 /** The filename of the previous cabinet in a cabinet set, or NULL. */
727 char *prevname;
728
729 /** The filename of the next cabinet in a cabinet set, or NULL. */
730 char *nextname;
731
732 /** The name of the disk containing the previous cabinet in a cabinet
733 * set, or NULL.
734 */
735 char *previnfo;
736
737 /** The name of the disk containing the next cabinet in a cabinet set,
738 * or NULL.
739 */
740 char *nextinfo;
741
742 /** A list of all files in the cabinet or cabinet set. */
743 struct mscabd_file *files;
744
745 /** A list of all folders in the cabinet or cabinet set. */
746 struct mscabd_folder *folders;
747
748 /**
749 * The set ID of the cabinet. All cabinets in the same set should have
750 * the same set ID.
751 */
752 unsigned short set_id;
753
754 /**
755 * The index number of the cabinet within the set. Numbering should
756 * start from 0 for the first cabinet in the set, and increment by 1 for
757 * each following cabinet.
758 */
759 unsigned short set_index;
760
761 /**
762 * The number of bytes reserved in the header area of the cabinet.
763 *
764 * If this is non-zero and flags has MSCAB_HDR_RESV set, this data can
765 * be read by the calling application. It is of the given length,
766 * located at offset (base_offset + MSCAB_HDR_RESV_OFFSET) in the
767 * cabinet file.
768 *
769 * @see flags
770 */
771 unsigned short header_resv;
772
773 /**
774 * Header flags.
775 *
776 * - MSCAB_HDR_PREVCAB indicates the cabinet is part of a cabinet set, and
777 * has a predecessor cabinet.
778 * - MSCAB_HDR_NEXTCAB indicates the cabinet is part of a cabinet set, and
779 * has a successor cabinet.
780 * - MSCAB_HDR_RESV indicates the cabinet has reserved header space.
781 *
782 * @see prevname, previnfo, nextname, nextinfo, header_resv
783 */
784 int flags;
785};
786
787/** Offset from start of cabinet to the reserved header data (if present). */
788#define MSCAB_HDR_RESV_OFFSET (0x28)
789
790/** Cabinet header flag: cabinet has a predecessor */
791#define MSCAB_HDR_PREVCAB (0x01)
792/** Cabinet header flag: cabinet has a successor */
793#define MSCAB_HDR_NEXTCAB (0x02)
794/** Cabinet header flag: cabinet has reserved header space */
795#define MSCAB_HDR_RESV (0x04)
796
797/**
798 * A structure which represents a single folder in a cabinet or cabinet set.
799 *
800 * All fields are READ ONLY.
801 *
802 * A folder is a single compressed stream of data. When uncompressed, it
803 * holds the data of one or more files. A folder may be split across more
804 * than one cabinet.
805 */
806struct mscabd_folder {
807 /**
808 * A pointer to the next folder in this cabinet or cabinet set, or NULL
809 * if this is the final folder.
810 */
811 struct mscabd_folder *next;
812
813 /**
814 * The compression format used by this folder.
815 *
816 * The macro MSCABD_COMP_METHOD() should be used on this field to get
817 * the algorithm used. The macro MSCABD_COMP_LEVEL() should be used to get
818 * the "compression level".
819 *
820 * @see MSCABD_COMP_METHOD(), MSCABD_COMP_LEVEL()
821 */
822 int comp_type;
823
824 /**
825 * The total number of data blocks used by this folder. This includes
826 * data blocks present in other files, if this folder spans more than
827 * one cabinet.
828 */
829 unsigned int num_blocks;
830};
831
832/**
833 * Returns the compression method used by a folder.
834 *
835 * @param comp_type a mscabd_folder::comp_type value
836 * @return one of #MSCAB_COMP_NONE, #MSCAB_COMP_MSZIP, #MSCAB_COMP_QUANTUM
837 * or #MSCAB_COMP_LZX
838 */
839#define MSCABD_COMP_METHOD(comp_type) ((comp_type) & 0x0F)
840/**
841 * Returns the compression level used by a folder.
842 *
843 * @param comp_type a mscabd_folder::comp_type value
844 * @return the compression level. This is only defined by LZX and Quantum
845 * compression
846 */
847#define MSCABD_COMP_LEVEL(comp_type) (((comp_type) >> 8) & 0x1F)
848
849/** Compression mode: no compression. */
850#define MSCAB_COMP_NONE (0)
851/** Compression mode: MSZIP (deflate) compression. */
852#define MSCAB_COMP_MSZIP (1)
853/** Compression mode: Quantum compression */
854#define MSCAB_COMP_QUANTUM (2)
855/** Compression mode: LZX compression */
856#define MSCAB_COMP_LZX (3)
857
858/**
859 * A structure which represents a single file in a cabinet or cabinet set.
860 *
861 * All fields are READ ONLY.
862 */
863struct mscabd_file {
864 /**
865 * The next file in the cabinet or cabinet set, or NULL if this is the
866 * final file.
867 */
868 struct mscabd_file *next;
869
870 /**
871 * The filename of the file.
872 *
873 * A null terminated string of up to 255 bytes in length, it may be in
874 * either ISO-8859-1 or UTF8 format, depending on the file attributes.
875 *
876 * @see attribs
877 */
878 char *filename;
879
880 /** The uncompressed length of the file, in bytes. */
881 unsigned int length;
882
883 /**
884 * File attributes.
885 *
886 * The following attributes are defined:
887 * - #MSCAB_ATTRIB_RDONLY indicates the file is write protected.
888 * - #MSCAB_ATTRIB_HIDDEN indicates the file is hidden.
889 * - #MSCAB_ATTRIB_SYSTEM indicates the file is a operating system file.
890 * - #MSCAB_ATTRIB_ARCH indicates the file is "archived".
891 * - #MSCAB_ATTRIB_EXEC indicates the file is an executable program.
892 * - #MSCAB_ATTRIB_UTF_NAME indicates the filename is in UTF8 format rather
893 * than ISO-8859-1.
894 */
895 int attribs;
896
897 /** File's last modified time, hour field. */
898 char time_h;
899 /** File's last modified time, minute field. */
900 char time_m;
901 /** File's last modified time, second field. */
902 char time_s;
903
904 /** File's last modified date, day field. */
905 char date_d;
906 /** File's last modified date, month field. */
907 char date_m;
908 /** File's last modified date, year field. */
909 int date_y;
910
911 /** A pointer to the folder that contains this file. */
912 struct mscabd_folder *folder;
913
914 /** The uncompressed offset of this file in its folder. */
915 unsigned int offset;
916};
917
918/** mscabd_file::attribs attribute: file is read-only. */
919#define MSCAB_ATTRIB_RDONLY (0x01)
920/** mscabd_file::attribs attribute: file is hidden. */
921#define MSCAB_ATTRIB_HIDDEN (0x02)
922/** mscabd_file::attribs attribute: file is an operating system file. */
923#define MSCAB_ATTRIB_SYSTEM (0x04)
924/** mscabd_file::attribs attribute: file is "archived". */
925#define MSCAB_ATTRIB_ARCH (0x20)
926/** mscabd_file::attribs attribute: file is an executable program. */
927#define MSCAB_ATTRIB_EXEC (0x40)
928/** mscabd_file::attribs attribute: filename is UTF8, not ISO-8859-1. */
929#define MSCAB_ATTRIB_UTF_NAME (0x80)
930
931/** mscab_decompressor::set_param() parameter: search buffer size. */
932#define MSCABD_PARAM_SEARCHBUF (0)
933/** mscab_decompressor::set_param() parameter: repair MS-ZIP streams? */
934#define MSCABD_PARAM_FIXMSZIP (1)
935/** mscab_decompressor::set_param() parameter: size of decompression buffer */
936#define MSCABD_PARAM_DECOMPBUF (2)
937/** mscab_decompressor::set_param() parameter: salvage data from bad cabinets?
938 * If enabled, open() will skip file with bad folder indices or filenames
939 * rather than reject the whole cabinet, and extract() will limit rather than
940 * reject files with invalid offsets and lengths, and bad data block checksums
941 * will be ignored. Available only in CAB decoder version 2 and above.
942 */
943#define MSCABD_PARAM_SALVAGE (3)
944
945/** TODO */
946struct mscab_compressor {
947 int dummy;
948};
949
950/**
951 * A decompressor for .CAB (Microsoft Cabinet) files
952 *
953 * All fields are READ ONLY.
954 *
955 * @see mspack_create_cab_decompressor(), mspack_destroy_cab_decompressor()
956 */
957struct mscab_decompressor {
958 /**
959 * Opens a cabinet file and reads its contents.
960 *
961 * If the file opened is a valid cabinet file, all headers will be read
962 * and a mscabd_cabinet structure will be returned, with a full list of
963 * folders and files.
964 *
965 * In the case of an error occuring, NULL is returned and the error code
966 * is available from last_error().
967 *
968 * The filename pointer should be considered "in use" until close() is
969 * called on the cabinet.
970 *
971 * @param self a self-referential pointer to the mscab_decompressor
972 * instance being called
973 * @param filename the filename of the cabinet file. This is passed
974 * directly to mspack_system::open().
975 * @return a pointer to a mscabd_cabinet structure, or NULL on failure
976 * @see close(), search(), last_error()
977 */
978 struct mscabd_cabinet * (*open) (struct mscab_decompressor *self,
979 const char *filename);
980
981 /**
982 * Closes a previously opened cabinet or cabinet set.
983 *
984 * This closes a cabinet, all cabinets associated with it via the
985 * mscabd_cabinet::next, mscabd_cabinet::prevcab and
986 * mscabd_cabinet::nextcab pointers, and all folders and files. All
987 * memory used by these entities is freed.
988 *
989 * The cabinet pointer is now invalid and cannot be used again. All
990 * mscabd_folder and mscabd_file pointers from that cabinet or cabinet
991 * set are also now invalid, and cannot be used again.
992 *
993 * If the cabinet pointer given was created using search(), it MUST be
994 * the cabinet pointer returned by search() and not one of the later
995 * cabinet pointers further along the mscabd_cabinet::next chain.
996
997 * If extra cabinets have been added using append() or prepend(), these
998 * will all be freed, even if the cabinet pointer given is not the first
999 * cabinet in the set. Do NOT close() more than one cabinet in the set.
1000 *
1001 * The mscabd_cabinet::filename is not freed by the library, as it is
1002 * not allocated by the library. The caller should free this itself if
1003 * necessary, before it is lost forever.
1004 *
1005 * @param self a self-referential pointer to the mscab_decompressor
1006 * instance being called
1007 * @param cab the cabinet to close
1008 * @see open(), search(), append(), prepend()
1009 */
1010 void (*close)(struct mscab_decompressor *self,
1011 struct mscabd_cabinet *cab);
1012
1013 /**
1014 * Searches a regular file for embedded cabinets.
1015 *
1016 * This opens a normal file with the given filename and will search the
1017 * entire file for embedded cabinet files
1018 *
1019 * If any cabinets are found, the equivalent of open() is called on each
1020 * potential cabinet file at the offset it was found. All successfully
1021 * open()ed cabinets are kept in a list.
1022 *
1023 * The first cabinet found will be returned directly as the result of
1024 * this method. Any further cabinets found will be chained in a list
1025 * using the mscabd_cabinet::next field.
1026 *
1027 * In the case of an error occuring anywhere other than the simulated
1028 * open(), NULL is returned and the error code is available from
1029 * last_error().
1030 *
1031 * If no error occurs, but no cabinets can be found in the file, NULL is
1032 * returned and last_error() returns MSPACK_ERR_OK.
1033 *
1034 * The filename pointer should be considered in use until close() is
1035 * called on the cabinet.
1036 *
1037 * close() should only be called on the result of search(), not on any
1038 * subsequent cabinets in the mscabd_cabinet::next chain.
1039 *
1040 * @param self a self-referential pointer to the mscab_decompressor
1041 * instance being called
1042 * @param filename the filename of the file to search for cabinets. This
1043 * is passed directly to mspack_system::open().
1044 * @return a pointer to a mscabd_cabinet structure, or NULL
1045 * @see close(), open(), last_error()
1046 */
1047 struct mscabd_cabinet * (*search) (struct mscab_decompressor *self,
1048 const char *filename);
1049
1050 /**
1051 * Appends one mscabd_cabinet to another, forming or extending a cabinet
1052 * set.
1053 *
1054 * This will attempt to append one cabinet to another such that
1055 * <tt>(cab->nextcab == nextcab) && (nextcab->prevcab == cab)</tt> and
1056 * any folders split between the two cabinets are merged.
1057 *
1058 * The cabinets MUST be part of a cabinet set -- a cabinet set is a
1059 * cabinet that spans more than one physical cabinet file on disk -- and
1060 * must be appropriately matched.
1061 *
1062 * It can be determined if a cabinet has further parts to load by
1063 * examining the mscabd_cabinet::flags field:
1064 *
1065 * - if <tt>(flags & MSCAB_HDR_PREVCAB)</tt> is non-zero, there is a
1066 * predecessor cabinet to open() and prepend(). Its MS-DOS
1067 * case-insensitive filename is mscabd_cabinet::prevname
1068 * - if <tt>(flags & MSCAB_HDR_NEXTCAB)</tt> is non-zero, there is a
1069 * successor cabinet to open() and append(). Its MS-DOS case-insensitive
1070 * filename is mscabd_cabinet::nextname
1071 *
1072 * If the cabinets do not match, an error code will be returned. Neither
1073 * cabinet has been altered, and both should be closed seperately.
1074 *
1075 * Files and folders in a cabinet set are a single entity. All cabinets
1076 * in a set use the same file list, which is updated as cabinets in the
1077 * set are added. All pointers to mscabd_folder and mscabd_file
1078 * structures in either cabinet must be discarded and re-obtained after
1079 * merging.
1080 *
1081 * @param self a self-referential pointer to the mscab_decompressor
1082 * instance being called
1083 * @param cab the cabinet which will be appended to,
1084 * predecessor of nextcab
1085 * @param nextcab the cabinet which will be appended,
1086 * successor of cab
1087 * @return an error code, or MSPACK_ERR_OK if successful
1088 * @see prepend(), open(), close()
1089 */
1090 int (*append) (struct mscab_decompressor *self,
1091 struct mscabd_cabinet *cab,
1092 struct mscabd_cabinet *nextcab);
1093
1094 /**
1095 * Prepends one mscabd_cabinet to another, forming or extending a
1096 * cabinet set.
1097 *
1098 * This will attempt to prepend one cabinet to another, such that
1099 * <tt>(cab->prevcab == prevcab) && (prevcab->nextcab == cab)</tt>. In
1100 * all other respects, it is identical to append(). See append() for the
1101 * full documentation.
1102 *
1103 * @param self a self-referential pointer to the mscab_decompressor
1104 * instance being called
1105 * @param cab the cabinet which will be prepended to,
1106 * successor of prevcab
1107 * @param prevcab the cabinet which will be prepended,
1108 * predecessor of cab
1109 * @return an error code, or MSPACK_ERR_OK if successful
1110 * @see append(), open(), close()
1111 */
1112 int (*prepend) (struct mscab_decompressor *self,
1113 struct mscabd_cabinet *cab,
1114 struct mscabd_cabinet *prevcab);
1115
1116 /**
1117 * Extracts a file from a cabinet or cabinet set.
1118 *
1119 * This extracts a compressed file in a cabinet and writes it to the given
1120 * filename.
1121 *
1122 * The MS-DOS filename of the file, mscabd_file::filename, is NOT USED
1123 * by extract(). The caller must examine this MS-DOS filename, copy and
1124 * change it as necessary, create directories as necessary, and provide
1125 * the correct filename as a parameter, which will be passed unchanged
1126 * to the decompressor's mspack_system::open()
1127 *
1128 * If the file belongs to a split folder in a multi-part cabinet set,
1129 * and not enough parts of the cabinet set have been loaded and appended
1130 * or prepended, an error will be returned immediately.
1131 *
1132 * @param self a self-referential pointer to the mscab_decompressor
1133 * instance being called
1134 * @param file the file to be decompressed
1135 * @param filename the filename of the file being written to
1136 * @return an error code, or MSPACK_ERR_OK if successful
1137 */
1138 int (*extract)(struct mscab_decompressor *self,
1139 struct mscabd_file *file,
1140 const char *filename);
1141
1142 /**
1143 * Sets a CAB decompression engine parameter.
1144 *
1145 * The following parameters are defined:
1146 * - #MSCABD_PARAM_SEARCHBUF: How many bytes should be allocated as a
1147 * buffer when using search()? The minimum value is 4. The default
1148 * value is 32768.
1149 * - #MSCABD_PARAM_FIXMSZIP: If non-zero, extract() will ignore bad
1150 * checksums and recover from decompression errors in MS-ZIP
1151 * compressed folders. The default value is 0 (don't recover).
1152 * - #MSCABD_PARAM_DECOMPBUF: How many bytes should be used as an input
1153 * bit buffer by decompressors? The minimum value is 4. The default
1154 * value is 4096.
1155 *
1156 * @param self a self-referential pointer to the mscab_decompressor
1157 * instance being called
1158 * @param param the parameter to set
1159 * @param value the value to set the parameter to
1160 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there
1161 * is a problem with either parameter or value.
1162 * @see search(), extract()
1163 */
1164 int (*set_param)(struct mscab_decompressor *self,
1165 int param,
1166 int value);
1167
1168 /**
1169 * Returns the error code set by the most recently called method.
1170 *
1171 * This is useful for open() and search(), which do not return an error
1172 * code directly.
1173 *
1174 * @param self a self-referential pointer to the mscab_decompressor
1175 * instance being called
1176 * @return the most recent error code
1177 * @see open(), search()
1178 */
1179 int (*last_error)(struct mscab_decompressor *self);
1180};
1181
1182/* --- support for .CHM (HTMLHelp) file format ----------------------------- */
1183
1184/**
1185 * A structure which represents a file to be placed in a CHM helpfile.
1186 *
1187 * A contiguous array of these structures should be passed to
1188 * mschm_compressor::generate(). The array list is terminated with an
1189 * entry whose mschmc_file::section field is set to #MSCHMC_ENDLIST, the
1190 * other fields in this entry are ignored.
1191 */
1192struct mschmc_file {
1193 /** One of #MSCHMC_ENDLIST, #MSCHMC_UNCOMP or #MSCHMC_MSCOMP. */
1194 int section;
1195
1196 /** The filename of the source file that will be added to the CHM. This
1197 * is passed directly to mspack_system::open(). */
1198 const char *filename;
1199
1200 /** The full path and filename of the file within the CHM helpfile, a
1201 * UTF-1 encoded null-terminated string. */
1202 char *chm_filename;
1203
1204 /** The length of the file, in bytes. This will be adhered to strictly
1205 * and a read error will be issued if this many bytes cannot be read
1206 * from the real file at CHM generation time. */
1207 off_t length;
1208};
1209
1210/**
1211 * A structure which represents a section of a CHM helpfile.
1212 *
1213 * All fields are READ ONLY.
1214 *
1215 * Not used directly, but used as a generic base type for
1216 * mschmd_sec_uncompressed and mschmd_sec_mscompressed.
1217 */
1218struct mschmd_section {
1219 /** A pointer to the CHM helpfile that contains this section. */
1220 struct mschmd_header *chm;
1221
1222 /**
1223 * The section ID. Either 0 for the uncompressed section
1224 * mschmd_sec_uncompressed, or 1 for the LZX compressed section
1225 * mschmd_sec_mscompressed. No other section IDs are known.
1226 */
1227 unsigned int id;
1228};
1229
1230/**
1231 * A structure which represents the uncompressed section of a CHM helpfile.
1232 *
1233 * All fields are READ ONLY.
1234 */
1235struct mschmd_sec_uncompressed {
1236 /** Generic section data. */
1237 struct mschmd_section base;
1238
1239 /** The file offset of where this section begins in the CHM helpfile. */
1240 off_t offset;
1241};
1242
1243/**
1244 * A structure which represents the LZX compressed section of a CHM helpfile.
1245 *
1246 * All fields are READ ONLY.
1247 */
1248struct mschmd_sec_mscompressed {
1249 /** Generic section data. */
1250 struct mschmd_section base;
1251
1252 /** A pointer to the meta-file which represents all LZX compressed data. */
1253 struct mschmd_file *content;
1254
1255 /** A pointer to the file which contains the LZX control data. */
1256 struct mschmd_file *control;
1257
1258 /** A pointer to the file which contains the LZX reset table. */
1259 struct mschmd_file *rtable;
1260
1261 /** A pointer to the file which contains the LZX span information.
1262 * Available only in CHM decoder version 2 and above.
1263 */
1264 struct mschmd_file *spaninfo;
1265};
1266
1267/**
1268 * A structure which represents a CHM helpfile.
1269 *
1270 * All fields are READ ONLY.
1271 */
1272struct mschmd_header {
1273 /** The version of the CHM file format used in this file. */
1274 unsigned int version;
1275
1276 /**
1277 * The "timestamp" of the CHM helpfile.
1278 *
1279 * It is the lower 32 bits of a 64-bit value representing the number of
1280 * centiseconds since 1601-01-01 00:00:00 UTC, plus 42. It is not useful
1281 * as a timestamp, but it is useful as a semi-unique ID.
1282 */
1283 unsigned int timestamp;
1284
1285 /**
1286 * The default Language and Country ID (LCID) of the user who ran the
1287 * HTMLHelp Compiler. This is not the language of the CHM file itself.
1288 */
1289 unsigned int language;
1290
1291 /**
1292 * The filename of the CHM helpfile. This is given by the library user
1293 * and may be in any format.
1294 */
1295 const char *filename;
1296
1297 /** The length of the CHM helpfile, in bytes. */
1298 off_t length;
1299
1300 /** A list of all non-system files in the CHM helpfile. */
1301 struct mschmd_file *files;
1302
1303 /**
1304 * A list of all system files in the CHM helpfile.
1305 *
1306 * System files are files which begin with "::". They are meta-files
1307 * generated by the CHM creation process.
1308 */
1309 struct mschmd_file *sysfiles;
1310
1311 /** The section 0 (uncompressed) data in this CHM helpfile. */
1312 struct mschmd_sec_uncompressed sec0;
1313
1314 /** The section 1 (MSCompressed) data in this CHM helpfile. */
1315 struct mschmd_sec_mscompressed sec1;
1316
1317 /** The file offset of the first PMGL/PMGI directory chunk. */
1318 off_t dir_offset;
1319
1320 /** The number of PMGL/PMGI directory chunks in this CHM helpfile. */
1321 unsigned int num_chunks;
1322
1323 /** The size of each PMGL/PMGI chunk, in bytes. */
1324 unsigned int chunk_size;
1325
1326 /** The "density" of the quick-reference section in PMGL/PMGI chunks. */
1327 unsigned int density;
1328
1329 /** The depth of the index tree.
1330 *
1331 * - if 1, there are no PMGI chunks, only PMGL chunks.
1332 * - if 2, there is 1 PMGI chunk. All chunk indices point to PMGL chunks.
1333 * - if 3, the root PMGI chunk points to secondary PMGI chunks, which in
1334 * turn point to PMGL chunks.
1335 * - and so on...
1336 */
1337 unsigned int depth;
1338
1339 /**
1340 * The number of the root PMGI chunk.
1341 *
1342 * If there is no index in the CHM helpfile, this will be 0xFFFFFFFF.
1343 */
1344 unsigned int index_root;
1345
1346 /**
1347 * The number of the first PMGL chunk. Usually zero.
1348 * Available only in CHM decoder version 2 and above.
1349 */
1350 unsigned int first_pmgl;
1351
1352 /**
1353 * The number of the last PMGL chunk. Usually num_chunks-1.
1354 * Available only in CHM decoder version 2 and above.
1355 */
1356 unsigned int last_pmgl;
1357
1358 /**
1359 * A cache of loaded chunks, filled in by mschm_decoder::fast_find().
1360 * Available only in CHM decoder version 2 and above.
1361 */
1362 unsigned char **chunk_cache;
1363};
1364
1365/**
1366 * A structure which represents a file stored in a CHM helpfile.
1367 *
1368 * All fields are READ ONLY.
1369 */
1370struct mschmd_file {
1371 /**
1372 * A pointer to the next file in the list, or NULL if this is the final
1373 * file.
1374 */
1375 struct mschmd_file *next;
1376
1377 /**
1378 * A pointer to the section that this file is located in. Indirectly,
1379 * it also points to the CHM helpfile the file is located in.
1380 */
1381 struct mschmd_section *section;
1382
1383 /** The offset within the section data that this file is located at. */
1384 off_t offset;
1385
1386 /** The length of this file, in bytes */
1387 off_t length;
1388
1389 /** The filename of this file -- a null terminated string in UTF-8. */
1390 char *filename;
1391};
1392
1393/** mschmc_file::section value: end of CHM file list */
1394#define MSCHMC_ENDLIST (0)
1395/** mschmc_file::section value: this file is in the Uncompressed section */
1396#define MSCHMC_UNCOMP (1)
1397/** mschmc_file::section value: this file is in the MSCompressed section */
1398#define MSCHMC_MSCOMP (2)
1399
1400/** mschm_compressor::set_param() parameter: "timestamp" header */
1401#define MSCHMC_PARAM_TIMESTAMP (0)
1402/** mschm_compressor::set_param() parameter: "language" header */
1403#define MSCHMC_PARAM_LANGUAGE (1)
1404/** mschm_compressor::set_param() parameter: LZX window size */
1405#define MSCHMC_PARAM_LZXWINDOW (2)
1406/** mschm_compressor::set_param() parameter: intra-chunk quickref density */
1407#define MSCHMC_PARAM_DENSITY (3)
1408/** mschm_compressor::set_param() parameter: whether to create indices */
1409#define MSCHMC_PARAM_INDEX (4)
1410
1411/**
1412 * A compressor for .CHM (Microsoft HTMLHelp) files.
1413 *
1414 * All fields are READ ONLY.
1415 *
1416 * @see mspack_create_chm_compressor(), mspack_destroy_chm_compressor()
1417 */
1418struct mschm_compressor {
1419 /**
1420 * Generates a CHM help file.
1421 *
1422 * The help file will contain up to two sections, an Uncompressed
1423 * section and potentially an MSCompressed (LZX compressed)
1424 * section.
1425 *
1426 * While the contents listing of a CHM file is always in lexical order,
1427 * the file list passed in will be taken as the correct order for files
1428 * within the sections. It is in your interest to place similar files
1429 * together for better compression.
1430 *
1431 * There are two modes of generation, to use a temporary file or not to
1432 * use one. See use_temporary_file() for the behaviour of generate() in
1433 * these two different modes.
1434 *
1435 * @param self a self-referential pointer to the mschm_compressor
1436 * instance being called
1437 * @param file_list an array of mschmc_file structures, terminated
1438 * with an entry whose mschmc_file::section field is
1439 * #MSCHMC_ENDLIST. The order of the list is
1440 * preserved within each section. The length of any
1441 * mschmc_file::chm_filename string cannot exceed
1442 * roughly 4096 bytes. Each source file must be able
1443 * to supply as many bytes as given in the
1444 * mschmc_file::length field.
1445 * @param output_file the file to write the generated CHM helpfile to.
1446 * This is passed directly to mspack_system::open()
1447 * @return an error code, or MSPACK_ERR_OK if successful
1448 * @see use_temporary_file() set_param()
1449 */
1450 int (*generate)(struct mschm_compressor *self,
1451 struct mschmc_file file_list[],
1452 const char *output_file);
1453
1454 /**
1455 * Specifies whether a temporary file is used during CHM generation.
1456 *
1457 * The CHM file format includes data about the compressed section (such
1458 * as its overall size) that is stored in the output CHM file prior to
1459 * the compressed section itself. This unavoidably requires that the
1460 * compressed section has to be generated, before these details can be
1461 * set. There are several ways this can be handled. Firstly, the
1462 * compressed section could be generated entirely in memory before
1463 * writing any of the output CHM file. This approach is not used in
1464 * libmspack, as the compressed section can exceed the addressable
1465 * memory space on most architectures.
1466 *
1467 * libmspack has two options, either to write these unknowable sections
1468 * with blank data, generate the compressed section, then re-open the
1469 * output file for update once the compressed section has been
1470 * completed, or to write the compressed section to a temporary file,
1471 * then write the entire output file at once, performing a simple
1472 * file-to-file copy for the compressed section.
1473 *
1474 * The simple solution of buffering the entire compressed section in
1475 * memory can still be used, if desired. As the temporary file's
1476 * filename is passed directly to mspack_system::open(), it is possible
1477 * for a custom mspack_system implementation to hold this file in memory,
1478 * without writing to a disk.
1479 *
1480 * If a temporary file is set, generate() performs the following
1481 * sequence of events: the temporary file is opened for writing, the
1482 * compression algorithm writes to the temporary file, the temporary
1483 * file is closed. Then the output file is opened for writing and the
1484 * temporary file is re-opened for reading. The output file is written
1485 * and the temporary file is read from. Both files are then closed. The
1486 * temporary file itself is not deleted. If that is desired, the
1487 * temporary file should be deleted after the completion of generate(),
1488 * if it exists.
1489 *
1490 * If a temporary file is set not to be used, generate() performs the
1491 * following sequence of events: the output file is opened for writing,
1492 * then it is written and closed. The output file is then re-opened for
1493 * update, the appropriate sections are seek()ed to and re-written, then
1494 * the output file is closed.
1495 *
1496 * @param self a self-referential pointer to the
1497 * mschm_compressor instance being called
1498 * @param use_temp_file non-zero if the temporary file should be used,
1499 * zero if the temporary file should not be used.
1500 * @param temp_file a file to temporarily write compressed data to,
1501 * before opening it for reading and copying the
1502 * contents to the output file. This is passed
1503 * directly to mspack_system::open().
1504 * @return an error code, or MSPACK_ERR_OK if successful
1505 * @see generate()
1506 */
1507 int (*use_temporary_file)(struct mschm_compressor *self,
1508 int use_temp_file,
1509 const char *temp_file);
1510 /**
1511 * Sets a CHM compression engine parameter.
1512 *
1513 * The following parameters are defined:
1514
1515 * - #MSCHMC_PARAM_TIMESTAMP: Sets the "timestamp" of the CHM file
1516 * generated. This is not a timestamp, see mschmd_header::timestamp
1517 * for a description. If this timestamp is 0, generate() will use its
1518 * own algorithm for making a unique ID, based on the lengths and
1519 * names of files in the CHM itself. Defaults to 0, any value between
1520 * 0 and (2^32)-1 is valid.
1521 * - #MSCHMC_PARAM_LANGUAGE: Sets the "language" of the CHM file
1522 * generated. This is not the language used in the CHM file, but the
1523 * language setting of the user who ran the HTMLHelp compiler. It
1524 * defaults to 0x0409. The valid range is between 0x0000 and 0x7F7F.
1525 * - #MSCHMC_PARAM_LZXWINDOW: Sets the size of the LZX history window,
1526 * which is also the interval at which the compressed data stream can be
1527 * randomly accessed. The value is not a size in bytes, but a power of
1528 * two. The default value is 16 (which makes the window 2^16 bytes, or
1529 * 64 kilobytes), the valid range is from 15 (32 kilobytes) to 21 (2
1530 * megabytes).
1531 * - #MSCHMC_PARAM_DENSITY: Sets the "density" of quick reference
1532 * entries stored at the end of directory listing chunk. Each chunk is
1533 * 4096 bytes in size, and contains as many file entries as there is
1534 * room for. At the other end of the chunk, a list of "quick reference"
1535 * pointers is included. The offset of every 'N'th file entry is given a
1536 * quick reference, where N = (2^density) + 1. The default density is
1537 * 2. The smallest density is 0 (N=2), the maximum is 10 (N=1025). As
1538 * each file entry requires at least 5 bytes, the maximum number of
1539 * entries in a single chunk is roughly 800, so the maximum value 10
1540 * can be used to indicate there are no quickrefs at all.
1541 * - #MSCHMC_PARAM_INDEX: Sets whether or not to include quick lookup
1542 * index chunk(s), in addition to normal directory listing chunks. A
1543 * value of zero means no index chunks will be created, a non-zero value
1544 * means index chunks will be created. The default is zero, "don't
1545 * create an index".
1546 *
1547 * @param self a self-referential pointer to the mschm_compressor
1548 * instance being called
1549 * @param param the parameter to set
1550 * @param value the value to set the parameter to
1551 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there
1552 * is a problem with either parameter or value.
1553 * @see generate()
1554 */
1555 int (*set_param)(struct mschm_compressor *self,
1556 int param,
1557 int value);
1558
1559 /**
1560 * Returns the error code set by the most recently called method.
1561 *
1562 * @param self a self-referential pointer to the mschm_compressor
1563 * instance being called
1564 * @return the most recent error code
1565 * @see set_param(), generate()
1566 */
1567 int (*last_error)(struct mschm_compressor *self);
1568};
1569
1570/**
1571 * A decompressor for .CHM (Microsoft HTMLHelp) files
1572 *
1573 * All fields are READ ONLY.
1574 *
1575 * @see mspack_create_chm_decompressor(), mspack_destroy_chm_decompressor()
1576 */
1577struct mschm_decompressor {
1578 /**
1579 * Opens a CHM helpfile and reads its contents.
1580 *
1581 * If the file opened is a valid CHM helpfile, all headers will be read
1582 * and a mschmd_header structure will be returned, with a full list of
1583 * files.
1584 *
1585 * In the case of an error occuring, NULL is returned and the error code
1586 * is available from last_error().
1587 *
1588 * The filename pointer should be considered "in use" until close() is
1589 * called on the CHM helpfile.
1590 *
1591 * @param self a self-referential pointer to the mschm_decompressor
1592 * instance being called
1593 * @param filename the filename of the CHM helpfile. This is passed
1594 * directly to mspack_system::open().
1595 * @return a pointer to a mschmd_header structure, or NULL on failure
1596 * @see close()
1597 */
1598 struct mschmd_header *(*open)(struct mschm_decompressor *self,
1599 const char *filename);
1600
1601 /**
1602 * Closes a previously opened CHM helpfile.
1603 *
1604 * This closes a CHM helpfile, frees the mschmd_header and all
1605 * mschmd_file structures associated with it (if any). This works on
1606 * both helpfiles opened with open() and helpfiles opened with
1607 * fast_open().
1608 *
1609 * The CHM header pointer is now invalid and cannot be used again. All
1610 * mschmd_file pointers referencing that CHM are also now invalid, and
1611 * cannot be used again.
1612 *
1613 * @param self a self-referential pointer to the mschm_decompressor
1614 * instance being called
1615 * @param chm the CHM helpfile to close
1616 * @see open(), fast_open()
1617 */
1618 void (*close)(struct mschm_decompressor *self,
1619 struct mschmd_header *chm);
1620
1621 /**
1622 * Extracts a file from a CHM helpfile.
1623 *
1624 * This extracts a file from a CHM helpfile and writes it to the given
1625 * filename. The filename of the file, mscabd_file::filename, is not
1626 * used by extract(), but can be used by the caller as a guide for
1627 * constructing an appropriate filename.
1628 *
1629 * This method works both with files found in the mschmd_header::files
1630 * and mschmd_header::sysfiles list and mschmd_file structures generated
1631 * on the fly by fast_find().
1632 *
1633 * @param self a self-referential pointer to the mschm_decompressor
1634 * instance being called
1635 * @param file the file to be decompressed
1636 * @param filename the filename of the file being written to
1637 * @return an error code, or MSPACK_ERR_OK if successful
1638 */
1639 int (*extract)(struct mschm_decompressor *self,
1640 struct mschmd_file *file,
1641 const char *filename);
1642
1643 /**
1644 * Returns the error code set by the most recently called method.
1645 *
1646 * This is useful for open() and fast_open(), which do not return an
1647 * error code directly.
1648 *
1649 * @param self a self-referential pointer to the mschm_decompressor
1650 * instance being called
1651 * @return the most recent error code
1652 * @see open(), extract()
1653 */
1654 int (*last_error)(struct mschm_decompressor *self);
1655
1656 /**
1657 * Opens a CHM helpfile quickly.
1658 *
1659 * If the file opened is a valid CHM helpfile, only essential headers
1660 * will be read. A mschmd_header structure will be still be returned, as
1661 * with open(), but the mschmd_header::files field will be NULL. No
1662 * files details will be automatically read. The fast_find() method
1663 * must be used to obtain file details.
1664 *
1665 * In the case of an error occuring, NULL is returned and the error code
1666 * is available from last_error().
1667 *
1668 * The filename pointer should be considered "in use" until close() is
1669 * called on the CHM helpfile.
1670 *
1671 * @param self a self-referential pointer to the mschm_decompressor
1672 * instance being called
1673 * @param filename the filename of the CHM helpfile. This is passed
1674 * directly to mspack_system::open().
1675 * @return a pointer to a mschmd_header structure, or NULL on failure
1676 * @see open(), close(), fast_find(), extract()
1677 */
1678 struct mschmd_header *(*fast_open)(struct mschm_decompressor *self,
1679 const char *filename);
1680
1681 /**
1682 * Finds file details quickly.
1683 *
1684 * Instead of reading all CHM helpfile headers and building a list of
1685 * files, fast_open() and fast_find() are intended for finding file
1686 * details only when they are needed. The CHM file format includes an
1687 * on-disk file index to allow this.
1688 *
1689 * Given a case-sensitive filename, fast_find() will search the on-disk
1690 * index for that file.
1691 *
1692 * If the file was found, the caller-provided mschmd_file structure will
1693 * be filled out like so:
1694 * - section: the correct value for the found file
1695 * - offset: the correct value for the found file
1696 * - length: the correct value for the found file
1697 * - all other structure elements: NULL or 0
1698 *
1699 * If the file was not found, MSPACK_ERR_OK will still be returned as the
1700 * result, but the caller-provided structure will be filled out like so:
1701 * - section: NULL
1702 * - offset: 0
1703 * - length: 0
1704 * - all other structure elements: NULL or 0
1705 *
1706 * This method is intended to be used in conjunction with CHM helpfiles
1707 * opened with fast_open(), but it also works with helpfiles opened
1708 * using the regular open().
1709 *
1710 * @param self a self-referential pointer to the mschm_decompressor
1711 * instance being called
1712 * @param chm the CHM helpfile to search for the file
1713 * @param filename the filename of the file to search for
1714 * @param f_ptr a pointer to a caller-provded mschmd_file structure
1715 * @param f_size <tt>sizeof(struct mschmd_file)</tt>
1716 * @return an error code, or MSPACK_ERR_OK if successful
1717 * @see open(), close(), fast_find(), extract()
1718 */
1719 int (*fast_find)(struct mschm_decompressor *self,
1720 struct mschmd_header *chm,
1721 const char *filename,
1722 struct mschmd_file *f_ptr,
1723 int f_size);
1724};
1725
1726/* --- support for .LIT (EBook) file format -------------------------------- */
1727
1728/** TODO */
1729struct mslit_compressor {
1730 int dummy;
1731};
1732
1733/** TODO */
1734struct mslit_decompressor {
1735 int dummy;
1736};
1737
1738
1739/* --- support for .HLP (MS Help) file format ------------------------------ */
1740
1741/** TODO */
1742struct mshlp_compressor {
1743 int dummy;
1744};
1745
1746/** TODO */
1747struct mshlp_decompressor {
1748 int dummy;
1749};
1750
1751
1752/* --- support for SZDD file format ---------------------------------------- */
1753
1754/** msszdd_compressor::set_param() parameter: the missing character */
1755#define MSSZDDC_PARAM_MISSINGCHAR (0)
1756
1757/** msszddd_header::format value - a regular SZDD file */
1758#define MSSZDD_FMT_NORMAL (0)
1759
1760/** msszddd_header::format value - a special QBasic SZDD file */
1761#define MSSZDD_FMT_QBASIC (1)
1762
1763/**
1764 * A structure which represents an SZDD compressed file.
1765 *
1766 * All fields are READ ONLY.
1767 */
1768struct msszddd_header {
1769 /** The file format; either #MSSZDD_FMT_NORMAL or #MSSZDD_FMT_QBASIC */
1770 int format;
1771
1772 /** The amount of data in the SZDD file once uncompressed. */
1773 off_t length;
1774
1775 /**
1776 * The last character in the filename, traditionally replaced with an
1777 * underscore to show the file is compressed. The null character is used
1778 * to show that this character has not been stored (e.g. because the
1779 * filename is not known). Generally, only characters that may appear in
1780 * an MS-DOS filename (except ".") are valid.
1781 */
1782 char missing_char;
1783};
1784
1785/**
1786 * A compressor for the SZDD file format.
1787 *
1788 * All fields are READ ONLY.
1789 *
1790 * @see mspack_create_szdd_compressor(), mspack_destroy_szdd_compressor()
1791 */
1792struct msszdd_compressor {
1793 /**
1794 * Reads an input file and creates a compressed output file in the
1795 * SZDD compressed file format. The SZDD compression format is quick
1796 * but gives poor compression. It is possible for the compressed output
1797 * file to be larger than the input file.
1798 *
1799 * Conventionally, SZDD compressed files have the final character in
1800 * their filename replaced with an underscore, to show they are
1801 * compressed. The missing character is stored in the compressed file
1802 * itself. This is due to the restricted filename conventions of MS-DOS,
1803 * most operating systems, such as UNIX, simply append another file
1804 * extension to the existing filename. As mspack does not deal with
1805 * filenames, this is left up to you. If you wish to set the missing
1806 * character stored in the file header, use set_param() with the
1807 * #MSSZDDC_PARAM_MISSINGCHAR parameter.
1808 *
1809 * "Stream" compression (where the length of the input data is not
1810 * known) is not possible. The length of the input data is stored in the
1811 * header of the SZDD file and must therefore be known before any data
1812 * is compressed. Due to technical limitations of the file format, the
1813 * maximum size of uncompressed file that will be accepted is 2147483647
1814 * bytes.
1815 *
1816 * @param self a self-referential pointer to the msszdd_compressor
1817 * instance being called
1818 * @param input the name of the file to compressed. This is passed
1819 * passed directly to mspack_system::open()
1820 * @param output the name of the file to write compressed data to.
1821 * This is passed directly to mspack_system::open().
1822 * @param length the length of the uncompressed file, or -1 to indicate
1823 * that this should be determined automatically by using
1824 * mspack_system::seek() on the input file.
1825 * @return an error code, or MSPACK_ERR_OK if successful
1826 * @see set_param()
1827 */
1828 int (*compress)(struct msszdd_compressor *self,
1829 const char *input,
1830 const char *output,
1831 off_t length);
1832
1833 /**
1834 * Sets an SZDD compression engine parameter.
1835 *
1836 * The following parameters are defined:
1837
1838 * - #MSSZDDC_PARAM_CHARACTER: the "missing character", the last character
1839 * in the uncompressed file's filename, which is traditionally replaced
1840 * with an underscore to show the file is compressed. Traditionally,
1841 * this can only be a character that is a valid part of an MS-DOS,
1842 * filename, but libmspack permits any character between 0x00 and 0xFF
1843 * to be stored. 0x00 is the default, and it represents "no character
1844 * stored".
1845 *
1846 * @param self a self-referential pointer to the msszdd_compressor
1847 * instance being called
1848 * @param param the parameter to set
1849 * @param value the value to set the parameter to
1850 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there
1851 * is a problem with either parameter or value.
1852 * @see compress()
1853 */
1854 int (*set_param)(struct msszdd_compressor *self,
1855 int param,
1856 int value);
1857
1858 /**
1859 * Returns the error code set by the most recently called method.
1860 *
1861 * @param self a self-referential pointer to the msszdd_compressor
1862 * instance being called
1863 * @return the most recent error code
1864 * @see compress()
1865 */
1866 int (*last_error)(struct mschm_decompressor *self);
1867};
1868
1869/**
1870 * A decompressor for SZDD compressed files.
1871 *
1872 * All fields are READ ONLY.
1873 *
1874 * @see mspack_create_szdd_decompressor(), mspack_destroy_szdd_decompressor()
1875 */
1876struct msszdd_decompressor {
1877 /**
1878 * Opens a SZDD file and reads the header.
1879 *
1880 * If the file opened is a valid SZDD file, all headers will be read and
1881 * a msszddd_header structure will be returned.
1882 *
1883 * In the case of an error occuring, NULL is returned and the error code
1884 * is available from last_error().
1885 *
1886 * The filename pointer should be considered "in use" until close() is
1887 * called on the SZDD file.
1888 *
1889 * @param self a self-referential pointer to the msszdd_decompressor
1890 * instance being called
1891 * @param filename the filename of the SZDD compressed file. This is
1892 * passed directly to mspack_system::open().
1893 * @return a pointer to a msszddd_header structure, or NULL on failure
1894 * @see close()
1895 */
1896 struct msszddd_header *(*open)(struct msszdd_decompressor *self,
1897 const char *filename);
1898
1899 /**
1900 * Closes a previously opened SZDD file.
1901 *
1902 * This closes a SZDD file and frees the msszddd_header associated with
1903 * it.
1904 *
1905 * The SZDD header pointer is now invalid and cannot be used again.
1906 *
1907 * @param self a self-referential pointer to the msszdd_decompressor
1908 * instance being called
1909 * @param szdd the SZDD file to close
1910 * @see open()
1911 */
1912 void (*close)(struct msszdd_decompressor *self,
1913 struct msszddd_header *szdd);
1914
1915 /**
1916 * Extracts the compressed data from a SZDD file.
1917 *
1918 * This decompresses the compressed SZDD data stream and writes it to
1919 * an output file.
1920 *
1921 * @param self a self-referential pointer to the msszdd_decompressor
1922 * instance being called
1923 * @param szdd the SZDD file to extract data from
1924 * @param filename the filename to write the decompressed data to. This
1925 * is passed directly to mspack_system::open().
1926 * @return an error code, or MSPACK_ERR_OK if successful
1927 */
1928 int (*extract)(struct msszdd_decompressor *self,
1929 struct msszddd_header *szdd,
1930 const char *filename);
1931
1932 /**
1933 * Decompresses an SZDD file to an output file in one step.
1934 *
1935 * This opens an SZDD file as input, reads the header, then decompresses
1936 * the compressed data immediately to an output file, finally closing
1937 * both the input and output file. It is more convenient to use than
1938 * open() then extract() then close(), if you do not need to know the
1939 * SZDD output size or missing character.
1940 *
1941 * @param self a self-referential pointer to the msszdd_decompressor
1942 * instance being called
1943 * @param input the filename of the input SZDD file. This is passed
1944 * directly to mspack_system::open().
1945 * @param output the filename to write the decompressed data to. This
1946 * is passed directly to mspack_system::open().
1947 * @return an error code, or MSPACK_ERR_OK if successful
1948 */
1949 int (*decompress)(struct msszdd_decompressor *self,
1950 const char *input,
1951 const char *output);
1952
1953 /**
1954 * Returns the error code set by the most recently called method.
1955 *
1956 * This is useful for open() which does not return an
1957 * error code directly.
1958 *
1959 * @param self a self-referential pointer to the msszdd_decompressor
1960 * instance being called
1961 * @return the most recent error code
1962 * @see open(), extract(), decompress()
1963 */
1964 int (*last_error)(struct msszdd_decompressor *self);
1965};
1966
1967/* --- support for KWAJ file format ---------------------------------------- */
1968
1969/** mskwaj_compressor::set_param() parameter: compression type */
1970#define MSKWAJC_PARAM_COMP_TYPE (0)
1971
1972/** mskwaj_compressor::set_param() parameter: include the length of the
1973 * uncompressed file in the header?
1974 */
1975#define MSKWAJC_PARAM_INCLUDE_LENGTH (1)
1976
1977/** KWAJ compression type: no compression. */
1978#define MSKWAJ_COMP_NONE (0)
1979/** KWAJ compression type: no compression, 0xFF XOR "encryption". */
1980#define MSKWAJ_COMP_XOR (1)
1981/** KWAJ compression type: LZSS (same method as SZDD) */
1982#define MSKWAJ_COMP_SZDD (2)
1983/** KWAJ compression type: LZ+Huffman compression */
1984#define MSKWAJ_COMP_LZH (3)
1985/** KWAJ compression type: MSZIP */
1986#define MSKWAJ_COMP_MSZIP (4)
1987
1988/** KWAJ optional header flag: decompressed file length is included */
1989#define MSKWAJ_HDR_HASLENGTH (0x01)
1990
1991/** KWAJ optional header flag: unknown 2-byte structure is included */
1992#define MSKWAJ_HDR_HASUNKNOWN1 (0x02)
1993
1994/** KWAJ optional header flag: unknown multi-sized structure is included */
1995#define MSKWAJ_HDR_HASUNKNOWN2 (0x04)
1996
1997/** KWAJ optional header flag: file name (no extension) is included */
1998#define MSKWAJ_HDR_HASFILENAME (0x08)
1999
2000/** KWAJ optional header flag: file extension is included */
2001#define MSKWAJ_HDR_HASFILEEXT (0x10)
2002
2003/** KWAJ optional header flag: extra text is included */
2004#define MSKWAJ_HDR_HASEXTRATEXT (0x20)
2005
2006/**
2007 * A structure which represents an KWAJ compressed file.
2008 *
2009 * All fields are READ ONLY.
2010 */
2011struct mskwajd_header {
2012 /** The compression type; should be one of #MSKWAJ_COMP_NONE,
2013 * #MSKWAJ_COMP_XOR, #MSKWAJ_COMP_SZDD or #MSKWAJ_COMP_LZH
2014 */
2015 unsigned short comp_type;
2016
2017 /** The offset in the file where the compressed data stream begins */
2018 off_t data_offset;
2019
2020 /** Flags indicating which optional headers were included. */
2021 int headers;
2022
2023 /** The amount of uncompressed data in the file, or 0 if not present. */
2024 off_t length;
2025
2026 /** output filename, or NULL if not present */
2027 char *filename;
2028
2029 /** extra uncompressed data (usually text) in the header.
2030 * This data can contain nulls so use extra_length to get the size.
2031 */
2032 char *extra;
2033
2034 /** length of extra uncompressed data in the header */
2035 unsigned short extra_length;
2036};
2037
2038/**
2039 * A compressor for the KWAJ file format.
2040 *
2041 * All fields are READ ONLY.
2042 *
2043 * @see mspack_create_kwaj_compressor(), mspack_destroy_kwaj_compressor()
2044 */
2045struct mskwaj_compressor {
2046 /**
2047 * Reads an input file and creates a compressed output file in the
2048 * KWAJ compressed file format. The KWAJ compression format is quick
2049 * but gives poor compression. It is possible for the compressed output
2050 * file to be larger than the input file.
2051 *
2052 * @param self a self-referential pointer to the mskwaj_compressor
2053 * instance being called
2054 * @param input the name of the file to compressed. This is passed
2055 * passed directly to mspack_system::open()
2056 * @param output the name of the file to write compressed data to.
2057 * This is passed directly to mspack_system::open().
2058 * @param length the length of the uncompressed file, or -1 to indicate
2059 * that this should be determined automatically by using
2060 * mspack_system::seek() on the input file.
2061 * @return an error code, or MSPACK_ERR_OK if successful
2062 * @see set_param()
2063 */
2064 int (*compress)(struct mskwaj_compressor *self,
2065 const char *input,
2066 const char *output,
2067 off_t length);
2068
2069 /**
2070 * Sets an KWAJ compression engine parameter.
2071 *
2072 * The following parameters are defined:
2073 *
2074 * - #MSKWAJC_PARAM_COMP_TYPE: the compression method to use. Must
2075 * be one of #MSKWAJC_COMP_NONE, #MSKWAJC_COMP_XOR, #MSKWAJ_COMP_SZDD
2076 * or #MSKWAJ_COMP_LZH. The default is #MSKWAJ_COMP_LZH.
2077 *
2078 * - #MSKWAJC_PARAM_INCLUDE_LENGTH: a boolean; should the compressed
2079 * output file should include the uncompressed length of the input
2080 * file in the header? This adds 4 bytes to the size of the output
2081 * file. A value of zero says "no", non-zero says "yes". The default
2082 * is "no".
2083 *
2084 * @param self a self-referential pointer to the mskwaj_compressor
2085 * instance being called
2086 * @param param the parameter to set
2087 * @param value the value to set the parameter to
2088 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there
2089 * is a problem with either parameter or value.
2090 * @see generate()
2091 */
2092 int (*set_param)(struct mskwaj_compressor *self,
2093 int param,
2094 int value);
2095
2096
2097 /**
2098 * Sets the original filename of the file before compression,
2099 * which will be stored in the header of the output file.
2100 *
2101 * The filename should be a null-terminated string, it must be an
2102 * MS-DOS "8.3" type filename (up to 8 bytes for the filename, then
2103 * optionally a "." and up to 3 bytes for a filename extension).
2104 *
2105 * If NULL is passed as the filename, no filename is included in the
2106 * header. This is the default.
2107 *
2108 * @param self a self-referential pointer to the mskwaj_compressor
2109 * instance being called
2110 * @param filename the original filename to use
2111 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if the
2112 * filename is too long
2113 */
2114 int (*set_filename)(struct mskwaj_compressor *self,
2115 const char *filename);
2116
2117 /**
2118 * Sets arbitrary data that will be stored in the header of the
2119 * output file, uncompressed. It can be up to roughly 64 kilobytes,
2120 * as the overall size of the header must not exceed 65535 bytes.
2121 * The data can contain null bytes if desired.
2122 *
2123 * If NULL is passed as the data pointer, or zero is passed as the
2124 * length, no extra data is included in the header. This is the
2125 * default.
2126 *
2127 * @param self a self-referential pointer to the mskwaj_compressor
2128 * instance being called
2129 * @param data a pointer to the data to be stored in the header
2130 * @param bytes the length of the data in bytes
2131 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS extra data
2132 * is too long
2133 */
2134 int (*set_extra_data)(struct mskwaj_compressor *self,
2135 void *data,
2136 size_t bytes);
2137
2138 /**
2139 * Returns the error code set by the most recently called method.
2140 *
2141 * @param self a self-referential pointer to the mskwaj_compressor
2142 * instance being called
2143 * @return the most recent error code
2144 * @see compress()
2145 */
2146 int (*last_error)(struct mschm_decompressor *self);
2147};
2148
2149/**
2150 * A decompressor for KWAJ compressed files.
2151 *
2152 * All fields are READ ONLY.
2153 *
2154 * @see mspack_create_kwaj_decompressor(), mspack_destroy_kwaj_decompressor()
2155 */
2156struct mskwaj_decompressor {
2157 /**
2158 * Opens a KWAJ file and reads the header.
2159 *
2160 * If the file opened is a valid KWAJ file, all headers will be read and
2161 * a mskwajd_header structure will be returned.
2162 *
2163 * In the case of an error occuring, NULL is returned and the error code
2164 * is available from last_error().
2165 *
2166 * The filename pointer should be considered "in use" until close() is
2167 * called on the KWAJ file.
2168 *
2169 * @param self a self-referential pointer to the mskwaj_decompressor
2170 * instance being called
2171 * @param filename the filename of the KWAJ compressed file. This is
2172 * passed directly to mspack_system::open().
2173 * @return a pointer to a mskwajd_header structure, or NULL on failure
2174 * @see close()
2175 */
2176 struct mskwajd_header *(*open)(struct mskwaj_decompressor *self,
2177 const char *filename);
2178
2179 /**
2180 * Closes a previously opened KWAJ file.
2181 *
2182 * This closes a KWAJ file and frees the mskwajd_header associated
2183 * with it. The KWAJ header pointer is now invalid and cannot be
2184 * used again.
2185 *
2186 * @param self a self-referential pointer to the mskwaj_decompressor
2187 * instance being called
2188 * @param kwaj the KWAJ file to close
2189 * @see open()
2190 */
2191 void (*close)(struct mskwaj_decompressor *self,
2192 struct mskwajd_header *kwaj);
2193
2194 /**
2195 * Extracts the compressed data from a KWAJ file.
2196 *
2197 * This decompresses the compressed KWAJ data stream and writes it to
2198 * an output file.
2199 *
2200 * @param self a self-referential pointer to the mskwaj_decompressor
2201 * instance being called
2202 * @param kwaj the KWAJ file to extract data from
2203 * @param filename the filename to write the decompressed data to. This
2204 * is passed directly to mspack_system::open().
2205 * @return an error code, or MSPACK_ERR_OK if successful
2206 */
2207 int (*extract)(struct mskwaj_decompressor *self,
2208 struct mskwajd_header *kwaj,
2209 const char *filename);
2210
2211 /**
2212 * Decompresses an KWAJ file to an output file in one step.
2213 *
2214 * This opens an KWAJ file as input, reads the header, then decompresses
2215 * the compressed data immediately to an output file, finally closing
2216 * both the input and output file. It is more convenient to use than
2217 * open() then extract() then close(), if you do not need to know the
2218 * KWAJ output size or output filename.
2219 *
2220 * @param self a self-referential pointer to the mskwaj_decompressor
2221 * instance being called
2222 * @param input the filename of the input KWAJ file. This is passed
2223 * directly to mspack_system::open().
2224 * @param output the filename to write the decompressed data to. This
2225 * is passed directly to mspack_system::open().
2226 * @return an error code, or MSPACK_ERR_OK if successful
2227 */
2228 int (*decompress)(struct mskwaj_decompressor *self,
2229 const char *input,
2230 const char *output);
2231
2232 /**
2233 * Returns the error code set by the most recently called method.
2234 *
2235 * This is useful for open() which does not return an
2236 * error code directly.
2237 *
2238 * @param self a self-referential pointer to the mskwaj_decompressor
2239 * instance being called
2240 * @return the most recent error code
2241 * @see open(), search()
2242 */
2243 int (*last_error)(struct mskwaj_decompressor *self);
2244};
2245
2246/* --- support for .LZX (Offline Address Book) file format ----------------- */
2247
2248/**
2249 * A compressor for the Offline Address Book (OAB) format.
2250 *
2251 * All fields are READ ONLY.
2252 *
2253 * @see mspack_create_oab_compressor(), mspack_destroy_oab_compressor()
2254 */
2255struct msoab_compressor {
2256 /**
2257 * Compress a full OAB file.
2258 *
2259 * The input file will be read and the compressed contents written to the
2260 * output file.
2261 *
2262 * @param self a self-referential pointer to the msoab_decompressor
2263 * instance being called
2264 * @param input the filename of the input file. This is passed
2265 * directly to mspack_system::open().
2266 * @param output the filename of the output file. This is passed
2267 * directly to mspack_system::open().
2268 * @return an error code, or MSPACK_ERR_OK if successful
2269 */
2270 int (*compress) (struct msoab_compressor *self,
2271 const char *input,
2272 const char *output);
2273
2274 /**
2275 * Generate a compressed incremental OAB patch file.
2276 *
2277 * The two uncompressed files "input" and "base" will be read, and an
2278 * incremental patch to generate "input" from "base" will be written to
2279 * the output file.
2280 *
2281 * @param self a self-referential pointer to the msoab_compressor
2282 * instance being called
2283 * @param input the filename of the input file containing the new
2284 * version of its contents. This is passed directly
2285 * to mspack_system::open().
2286 * @param base the filename of the original base file containing
2287 * the old version of its contents, against which the
2288 * incremental patch shall generated. This is passed
2289 * directly to mspack_system::open().
2290 * @param output the filename of the output file. This is passed
2291 * directly to mspack_system::open().
2292 * @return an error code, or MSPACK_ERR_OK if successful
2293 */
2294 int (*compress_incremental) (struct msoab_compressor *self,
2295 const char *input,
2296 const char *base,
2297 const char *output);
2298};
2299
2300/**
2301 * A decompressor for .LZX (Offline Address Book) files
2302 *
2303 * All fields are READ ONLY.
2304 *
2305 * @see mspack_create_oab_decompressor(), mspack_destroy_oab_decompressor()
2306 */
2307struct msoab_decompressor {
2308 /**
2309 * Decompresses a full Offline Address Book file.
2310 *
2311 * If the input file is a valid compressed Offline Address Book file,
2312 * it will be read and the decompressed contents will be written to
2313 * the output file.
2314 *
2315 * @param self a self-referential pointer to the msoab_decompressor
2316 * instance being called
2317 * @param input the filename of the input file. This is passed
2318 * directly to mspack_system::open().
2319 * @param output the filename of the output file. This is passed
2320 * directly to mspack_system::open().
2321 * @return an error code, or MSPACK_ERR_OK if successful
2322 */
2323 int (*decompress) (struct msoab_decompressor *self,
2324 const char *input,
2325 const char *output);
2326
2327 /**
2328 * Decompresses an Offline Address Book with an incremental patch file.
2329 *
2330 * This requires both a full UNCOMPRESSED Offline Address Book file to
2331 * act as the "base", and a compressed incremental patch file as input.
2332 * If the input file is valid, it will be decompressed with reference to
2333 * the base file, and the decompressed contents will be written to the
2334 * output file.
2335 *
2336 * There is no way to tell what the right base file is for the given
2337 * incremental patch, but if you get it wrong, this will usually result
2338 * in incorrect data being decompressed, which will then fail a checksum
2339 * test.
2340 *
2341 * @param self a self-referential pointer to the msoab_decompressor
2342 * instance being called
2343 * @param input the filename of the input file. This is passed
2344 * directly to mspack_system::open().
2345 * @param base the filename of the base file to which the
2346 * incremental patch shall be applied. This is passed
2347 * directly to mspack_system::open().
2348 * @param output the filename of the output file. This is passed
2349 * directly to mspack_system::open().
2350 * @return an error code, or MSPACK_ERR_OK if successful
2351 */
2352 int (*decompress_incremental) (struct msoab_decompressor *self,
2353 const char *input,
2354 const char *base,
2355 const char *output);
2356
2357 /**
2358 * Sets an OAB decompression engine parameter. Available only in OAB
2359 * decompressor version 2 and above.
2360 *
2361 * - #MSOABD_PARAM_DECOMPBUF: How many bytes should be used as an input
2362 * buffer by decompressors? The minimum value is 16. The default value
2363 * is 4096.
2364 *
2365 * @param self a self-referential pointer to the msoab_decompressor
2366 * instance being called
2367 * @param param the parameter to set
2368 * @param value the value to set the parameter to
2369 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there
2370 * is a problem with either parameter or value.
2371 */
2372 int (*set_param)(struct msoab_decompressor *self,
2373 int param,
2374 int value);
2375
2376};
2377
2378/** msoab_decompressor::set_param() parameter: size of decompression buffer */
2379#define MSOABD_PARAM_DECOMPBUF (0)
2380
2381#ifdef __cplusplus
2382}
2383#endif
2384
2385#endif
diff --git a/utils/rbutilqt/mspack/mszip.h b/utils/rbutilqt/mspack/mszip.h
new file mode 100644
index 0000000000..2cd608234e
--- /dev/null
+++ b/utils/rbutilqt/mspack/mszip.h
@@ -0,0 +1,126 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * The deflate method was created by Phil Katz. MSZIP is equivalent to the
5 * deflate method.
6 *
7 * libmspack is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
9 *
10 * For further details, see the file COPYING.LIB distributed with libmspack
11 */
12
13#ifndef MSPACK_MSZIP_H
14#define MSPACK_MSZIP_H 1
15
16#ifdef __cplusplus
17extern "C" {
18#endif
19
20/* MSZIP (deflate) compression / (inflate) decompression definitions */
21
22#define MSZIP_FRAME_SIZE (32768) /* size of LZ history window */
23#define MSZIP_LITERAL_MAXSYMBOLS (288) /* literal/length huffman tree */
24#define MSZIP_LITERAL_TABLEBITS (9)
25#define MSZIP_DISTANCE_MAXSYMBOLS (32) /* distance huffman tree */
26#define MSZIP_DISTANCE_TABLEBITS (6)
27
28/* if there are less direct lookup entries than symbols, the longer
29 * code pointers will be <= maxsymbols. This must not happen, or we
30 * will decode entries badly */
31#if (1 << MSZIP_LITERAL_TABLEBITS) < (MSZIP_LITERAL_MAXSYMBOLS * 2)
32# define MSZIP_LITERAL_TABLESIZE (MSZIP_LITERAL_MAXSYMBOLS * 4)
33#else
34# define MSZIP_LITERAL_TABLESIZE ((1 << MSZIP_LITERAL_TABLEBITS) + \
35 (MSZIP_LITERAL_MAXSYMBOLS * 2))
36#endif
37
38#if (1 << MSZIP_DISTANCE_TABLEBITS) < (MSZIP_DISTANCE_MAXSYMBOLS * 2)
39# define MSZIP_DISTANCE_TABLESIZE (MSZIP_DISTANCE_MAXSYMBOLS * 4)
40#else
41# define MSZIP_DISTANCE_TABLESIZE ((1 << MSZIP_DISTANCE_TABLEBITS) + \
42 (MSZIP_DISTANCE_MAXSYMBOLS * 2))
43#endif
44
45struct mszipd_stream {
46 struct mspack_system *sys; /* I/O routines */
47 struct mspack_file *input; /* input file handle */
48 struct mspack_file *output; /* output file handle */
49 unsigned int window_posn; /* offset within window */
50
51 /* inflate() will call this whenever the window should be emptied. */
52 int (*flush_window)(struct mszipd_stream *, unsigned int);
53
54 int error, repair_mode, bytes_output;
55
56 /* I/O buffering */
57 unsigned char *inbuf, *i_ptr, *i_end, *o_ptr, *o_end, input_end;
58 unsigned int bit_buffer, bits_left, inbuf_size;
59
60
61 /* huffman code lengths */
62 unsigned char LITERAL_len[MSZIP_LITERAL_MAXSYMBOLS];
63 unsigned char DISTANCE_len[MSZIP_DISTANCE_MAXSYMBOLS];
64
65 /* huffman decoding tables */
66 unsigned short LITERAL_table [MSZIP_LITERAL_TABLESIZE];
67 unsigned short DISTANCE_table[MSZIP_DISTANCE_TABLESIZE];
68
69 /* 32kb history window */
70 unsigned char window[MSZIP_FRAME_SIZE];
71};
72
73/* allocates MS-ZIP decompression stream for decoding the given stream.
74 *
75 * - uses system->alloc() to allocate memory
76 *
77 * - returns NULL if not enough memory
78 *
79 * - input_buffer_size is how many bytes to use as an input bitstream buffer
80 *
81 * - if repair_mode is non-zero, errors in decompression will be skipped
82 * and 'holes' left will be filled with zero bytes. This allows at least
83 * a partial recovery of erroneous data.
84 */
85extern struct mszipd_stream *mszipd_init(struct mspack_system *system,
86 struct mspack_file *input,
87 struct mspack_file *output,
88 int input_buffer_size,
89 int repair_mode);
90
91/* decompresses, or decompresses more of, an MS-ZIP stream.
92 *
93 * - out_bytes of data will be decompressed and the function will return
94 * with an MSPACK_ERR_OK return code.
95 *
96 * - decompressing will stop as soon as out_bytes is reached. if the true
97 * amount of bytes decoded spills over that amount, they will be kept for
98 * a later invocation of mszipd_decompress().
99 *
100 * - the output bytes will be passed to the system->write() function given in
101 * mszipd_init(), using the output file handle given in mszipd_init(). More
102 * than one call may be made to system->write()
103 *
104 * - MS-ZIP will read input bytes as necessary using the system->read()
105 * function given in mszipd_init(), using the input file handle given in
106 * mszipd_init(). This will continue until system->read() returns 0 bytes,
107 * or an error.
108 */
109extern int mszipd_decompress(struct mszipd_stream *zip, off_t out_bytes);
110
111/* decompresses an entire MS-ZIP stream in a KWAJ file. Acts very much
112 * like mszipd_decompress(), but doesn't take an out_bytes parameter
113 */
114extern int mszipd_decompress_kwaj(struct mszipd_stream *zip);
115
116/* frees all stream associated with an MS-ZIP data stream
117 *
118 * - calls system->free() using the system pointer given in mszipd_init()
119 */
120void mszipd_free(struct mszipd_stream *zip);
121
122#ifdef __cplusplus
123}
124#endif
125
126#endif
diff --git a/utils/rbutilqt/mspack/mszipc.c b/utils/rbutilqt/mspack/mszipc.c
new file mode 100644
index 0000000000..2f14b9ac83
--- /dev/null
+++ b/utils/rbutilqt/mspack/mszipc.c
@@ -0,0 +1,18 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * The deflate method was created by Phil Katz. MSZIP is equivalent to the
5 * deflate method.
6 *
7 * libmspack is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
9 *
10 * For further details, see the file COPYING.LIB distributed with libmspack
11 */
12
13/* MS-ZIP compression implementation */
14
15#include "system-mspack.h"
16#include "mszip.h"
17
18/* todo */
diff --git a/utils/rbutilqt/mspack/mszipd.c b/utils/rbutilqt/mspack/mszipd.c
new file mode 100644
index 0000000000..c1b02b1207
--- /dev/null
+++ b/utils/rbutilqt/mspack/mszipd.c
@@ -0,0 +1,515 @@
1/* This file is part of libmspack.
2 * (C) 2003-2010 Stuart Caie.
3 *
4 * The deflate method was created by Phil Katz. MSZIP is equivalent to the
5 * deflate method.
6 *
7 * libmspack is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
9 *
10 * For further details, see the file COPYING.LIB distributed with libmspack
11 */
12
13/* MS-ZIP decompression implementation. */
14
15#include "system-mspack.h"
16#include "mszip.h"
17
18/* import bit-reading macros and code */
19#define BITS_TYPE struct mszipd_stream
20#define BITS_VAR zip
21#define BITS_ORDER_LSB
22#define BITS_LSB_TABLE
23#define READ_BYTES do { \
24 READ_IF_NEEDED; \
25 INJECT_BITS(*i_ptr++, 8); \
26} while (0)
27#include "readbits.h"
28
29/* import huffman macros and code */
30#define TABLEBITS(tbl) MSZIP_##tbl##_TABLEBITS
31#define MAXSYMBOLS(tbl) MSZIP_##tbl##_MAXSYMBOLS
32#define HUFF_TABLE(tbl,idx) zip->tbl##_table[idx]
33#define HUFF_LEN(tbl,idx) zip->tbl##_len[idx]
34#define HUFF_ERROR return INF_ERR_HUFFSYM
35#include "readhuff.h"
36
37#define FLUSH_IF_NEEDED do { \
38 if (zip->window_posn == MSZIP_FRAME_SIZE) { \
39 if (zip->flush_window(zip, MSZIP_FRAME_SIZE)) { \
40 return INF_ERR_FLUSH; \
41 } \
42 zip->window_posn = 0; \
43 } \
44} while (0)
45
46/* match lengths for literal codes 257.. 285 */
47static const unsigned short lit_lengths[29] = {
48 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27,
49 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258
50};
51
52/* match offsets for distance codes 0 .. 29 */
53static const unsigned short dist_offsets[30] = {
54 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385,
55 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
56};
57
58/* extra bits required for literal codes 257.. 285 */
59static const unsigned char lit_extrabits[29] = {
60 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2,
61 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
62};
63
64/* extra bits required for distance codes 0 .. 29 */
65static const unsigned char dist_extrabits[30] = {
66 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6,
67 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13
68};
69
70/* the order of the bit length Huffman code lengths */
71static const unsigned char bitlen_order[19] = {
72 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
73};
74
75/* inflate() error codes */
76#define INF_ERR_BLOCKTYPE (-1) /* unknown block type */
77#define INF_ERR_COMPLEMENT (-2) /* block size complement mismatch */
78#define INF_ERR_FLUSH (-3) /* error from flush_window() callback */
79#define INF_ERR_BITBUF (-4) /* too many bits in bit buffer */
80#define INF_ERR_SYMLENS (-5) /* too many symbols in blocktype 2 header */
81#define INF_ERR_BITLENTBL (-6) /* failed to build bitlens huffman table */
82#define INF_ERR_LITERALTBL (-7) /* failed to build literals huffman table */
83#define INF_ERR_DISTANCETBL (-8) /* failed to build distance huffman table */
84#define INF_ERR_BITOVERRUN (-9) /* bitlen RLE code goes over table size */
85#define INF_ERR_BADBITLEN (-10) /* invalid bit-length code */
86#define INF_ERR_LITCODE (-11) /* out-of-range literal code */
87#define INF_ERR_DISTCODE (-12) /* out-of-range distance code */
88#define INF_ERR_DISTANCE (-13) /* somehow, distance is beyond 32k */
89#define INF_ERR_HUFFSYM (-14) /* out of bits decoding huffman symbol */
90
91static int zip_read_lens(struct mszipd_stream *zip) {
92 /* for the bit buffer and huffman decoding */
93 register unsigned int bit_buffer;
94 register int bits_left;
95 unsigned char *i_ptr, *i_end;
96
97 /* bitlen Huffman codes -- immediate lookup, 7 bit max code length */
98 unsigned short bl_table[(1 << 7)];
99 unsigned char bl_len[19];
100
101 unsigned char lens[MSZIP_LITERAL_MAXSYMBOLS + MSZIP_DISTANCE_MAXSYMBOLS];
102 unsigned int lit_codes, dist_codes, code, last_code=0, bitlen_codes, i, run;
103
104 RESTORE_BITS;
105
106 /* read the number of codes */
107 READ_BITS(lit_codes, 5); lit_codes += 257;
108 READ_BITS(dist_codes, 5); dist_codes += 1;
109 READ_BITS(bitlen_codes, 4); bitlen_codes += 4;
110 if (lit_codes > MSZIP_LITERAL_MAXSYMBOLS) return INF_ERR_SYMLENS;
111 if (dist_codes > MSZIP_DISTANCE_MAXSYMBOLS) return INF_ERR_SYMLENS;
112
113 /* read in the bit lengths in their unusual order */
114 for (i = 0; i < bitlen_codes; i++) READ_BITS(bl_len[bitlen_order[i]], 3);
115 while (i < 19) bl_len[bitlen_order[i++]] = 0;
116
117 /* create decoding table with an immediate lookup */
118 if (make_decode_table(19, 7, &bl_len[0], &bl_table[0])) {
119 return INF_ERR_BITLENTBL;
120 }
121
122 /* read literal / distance code lengths */
123 for (i = 0; i < (lit_codes + dist_codes); i++) {
124 /* single-level huffman lookup */
125 ENSURE_BITS(7);
126 code = bl_table[PEEK_BITS(7)];
127 REMOVE_BITS(bl_len[code]);
128
129 if (code < 16) lens[i] = last_code = code;
130 else {
131 switch (code) {
132 case 16: READ_BITS(run, 2); run += 3; code = last_code; break;
133 case 17: READ_BITS(run, 3); run += 3; code = 0; break;
134 case 18: READ_BITS(run, 7); run += 11; code = 0; break;
135 default: D(("bad code!: %u", code)) return INF_ERR_BADBITLEN;
136 }
137 if ((i + run) > (lit_codes + dist_codes)) return INF_ERR_BITOVERRUN;
138 while (run--) lens[i++] = code;
139 i--;
140 }
141 }
142
143 /* copy LITERAL code lengths and clear any remaining */
144 i = lit_codes;
145 zip->sys->copy(&lens[0], &zip->LITERAL_len[0], i);
146 while (i < MSZIP_LITERAL_MAXSYMBOLS) zip->LITERAL_len[i++] = 0;
147
148 i = dist_codes;
149 zip->sys->copy(&lens[lit_codes], &zip->DISTANCE_len[0], i);
150 while (i < MSZIP_DISTANCE_MAXSYMBOLS) zip->DISTANCE_len[i++] = 0;
151
152 STORE_BITS;
153 return 0;
154}
155
156/* a clean implementation of RFC 1951 / inflate */
157static int inflate(struct mszipd_stream *zip) {
158 unsigned int last_block, block_type, distance, length, this_run, i;
159
160 /* for the bit buffer and huffman decoding */
161 register unsigned int bit_buffer;
162 register int bits_left;
163 register unsigned short sym;
164 unsigned char *i_ptr, *i_end;
165
166 RESTORE_BITS;
167
168 do {
169 /* read in last block bit */
170 READ_BITS(last_block, 1);
171
172 /* read in block type */
173 READ_BITS(block_type, 2);
174
175 if (block_type == 0) {
176 /* uncompressed block */
177 unsigned char lens_buf[4];
178
179 /* go to byte boundary */
180 i = bits_left & 7; REMOVE_BITS(i);
181
182 /* read 4 bytes of data, emptying the bit-buffer if necessary */
183 for (i = 0; (bits_left >= 8); i++) {
184 if (i == 4) return INF_ERR_BITBUF;
185 lens_buf[i] = PEEK_BITS(8);
186 REMOVE_BITS(8);
187 }
188 if (bits_left != 0) return INF_ERR_BITBUF;
189 while (i < 4) {
190 READ_IF_NEEDED;
191 lens_buf[i++] = *i_ptr++;
192 }
193
194 /* get the length and its complement */
195 length = lens_buf[0] | (lens_buf[1] << 8);
196 i = lens_buf[2] | (lens_buf[3] << 8);
197 if (length != (~i & 0xFFFF)) return INF_ERR_COMPLEMENT;
198
199 /* read and copy the uncompressed data into the window */
200 while (length > 0) {
201 READ_IF_NEEDED;
202
203 this_run = length;
204 if (this_run > (unsigned int)(i_end - i_ptr)) this_run = i_end - i_ptr;
205 if (this_run > (MSZIP_FRAME_SIZE - zip->window_posn))
206 this_run = MSZIP_FRAME_SIZE - zip->window_posn;
207
208 zip->sys->copy(i_ptr, &zip->window[zip->window_posn], this_run);
209 zip->window_posn += this_run;
210 i_ptr += this_run;
211 length -= this_run;
212 FLUSH_IF_NEEDED;
213 }
214 }
215 else if ((block_type == 1) || (block_type == 2)) {
216 /* Huffman-compressed LZ77 block */
217 unsigned int match_posn, code;
218
219 if (block_type == 1) {
220 /* block with fixed Huffman codes */
221 i = 0;
222 while (i < 144) zip->LITERAL_len[i++] = 8;
223 while (i < 256) zip->LITERAL_len[i++] = 9;
224 while (i < 280) zip->LITERAL_len[i++] = 7;
225 while (i < 288) zip->LITERAL_len[i++] = 8;
226 for (i = 0; i < 32; i++) zip->DISTANCE_len[i] = 5;
227 }
228 else {
229 /* block with dynamic Huffman codes */
230 STORE_BITS;
231 if ((i = zip_read_lens(zip))) return i;
232 RESTORE_BITS;
233 }
234
235 /* now huffman lengths are read for either kind of block,
236 * create huffman decoding tables */
237 if (make_decode_table(MSZIP_LITERAL_MAXSYMBOLS, MSZIP_LITERAL_TABLEBITS,
238 &zip->LITERAL_len[0], &zip->LITERAL_table[0]))
239 {
240 return INF_ERR_LITERALTBL;
241 }
242
243 if (make_decode_table(MSZIP_DISTANCE_MAXSYMBOLS,MSZIP_DISTANCE_TABLEBITS,
244 &zip->DISTANCE_len[0], &zip->DISTANCE_table[0]))
245 {
246 return INF_ERR_DISTANCETBL;
247 }
248
249 /* decode forever until end of block code */
250 for (;;) {
251 READ_HUFFSYM(LITERAL, code);
252 if (code < 256) {
253 zip->window[zip->window_posn++] = (unsigned char) code;
254 FLUSH_IF_NEEDED;
255 }
256 else if (code == 256) {
257 /* END OF BLOCK CODE: loop break point */
258 break;
259 }
260 else {
261 code -= 257; /* codes 257-285 are matches */
262 if (code >= 29) return INF_ERR_LITCODE; /* codes 286-287 are illegal */
263 READ_BITS_T(length, lit_extrabits[code]);
264 length += lit_lengths[code];
265
266 READ_HUFFSYM(DISTANCE, code);
267 if (code >= 30) return INF_ERR_DISTCODE;
268 READ_BITS_T(distance, dist_extrabits[code]);
269 distance += dist_offsets[code];
270
271 /* match position is window position minus distance. If distance
272 * is more than window position numerically, it must 'wrap
273 * around' the frame size. */
274 match_posn = ((distance > zip->window_posn) ? MSZIP_FRAME_SIZE : 0)
275 + zip->window_posn - distance;
276
277 /* copy match */
278 if (length < 12) {
279 /* short match, use slower loop but no loop setup code */
280 while (length--) {
281 zip->window[zip->window_posn++] = zip->window[match_posn++];
282 match_posn &= MSZIP_FRAME_SIZE - 1;
283 FLUSH_IF_NEEDED;
284 }
285 }
286 else {
287 /* longer match, use faster loop but with setup expense */
288 unsigned char *runsrc, *rundest;
289 do {
290 this_run = length;
291 if ((match_posn + this_run) > MSZIP_FRAME_SIZE)
292 this_run = MSZIP_FRAME_SIZE - match_posn;
293 if ((zip->window_posn + this_run) > MSZIP_FRAME_SIZE)
294 this_run = MSZIP_FRAME_SIZE - zip->window_posn;
295
296 rundest = &zip->window[zip->window_posn]; zip->window_posn += this_run;
297 runsrc = &zip->window[match_posn]; match_posn += this_run;
298 length -= this_run;
299 while (this_run--) *rundest++ = *runsrc++;
300 if (match_posn == MSZIP_FRAME_SIZE) match_posn = 0;
301 FLUSH_IF_NEEDED;
302 } while (length > 0);
303 }
304
305 } /* else (code >= 257) */
306
307 } /* for(;;) -- break point at 'code == 256' */
308 }
309 else {
310 /* block_type == 3 -- bad block type */
311 return INF_ERR_BLOCKTYPE;
312 }
313 } while (!last_block);
314
315 /* flush the remaining data */
316 if (zip->window_posn) {
317 if (zip->flush_window(zip, zip->window_posn)) return INF_ERR_FLUSH;
318 }
319 STORE_BITS;
320
321 /* return success */
322 return 0;
323}
324
325/* inflate() calls this whenever the window should be flushed. As
326 * MSZIP only expands to the size of the window, the implementation used
327 * simply keeps track of the amount of data flushed, and if more than 32k
328 * is flushed, an error is raised.
329 */
330static int mszipd_flush_window(struct mszipd_stream *zip,
331 unsigned int data_flushed)
332{
333 zip->bytes_output += data_flushed;
334 if (zip->bytes_output > MSZIP_FRAME_SIZE) {
335 D(("overflow: %u bytes flushed, total is now %u",
336 data_flushed, zip->bytes_output))
337 return 1;
338 }
339 return 0;
340}
341
342struct mszipd_stream *mszipd_init(struct mspack_system *system,
343 struct mspack_file *input,
344 struct mspack_file *output,
345 int input_buffer_size,
346 int repair_mode)
347{
348 struct mszipd_stream *zip;
349
350 if (!system) return NULL;
351
352 /* round up input buffer size to multiple of two */
353 input_buffer_size = (input_buffer_size + 1) & -2;
354 if (input_buffer_size < 2) return NULL;
355
356 /* allocate decompression state */
357 if (!(zip = (struct mszipd_stream *) system->alloc(system, sizeof(struct mszipd_stream)))) {
358 return NULL;
359 }
360
361 /* allocate input buffer */
362 zip->inbuf = (unsigned char *) system->alloc(system, (size_t) input_buffer_size);
363 if (!zip->inbuf) {
364 system->free(zip);
365 return NULL;
366 }
367
368 /* initialise decompression state */
369 zip->sys = system;
370 zip->input = input;
371 zip->output = output;
372 zip->inbuf_size = input_buffer_size;
373 zip->input_end = 0;
374 zip->error = MSPACK_ERR_OK;
375 zip->repair_mode = repair_mode;
376 zip->flush_window = &mszipd_flush_window;
377
378 zip->i_ptr = zip->i_end = &zip->inbuf[0];
379 zip->o_ptr = zip->o_end = NULL;
380 zip->bit_buffer = 0; zip->bits_left = 0;
381 return zip;
382}
383
384int mszipd_decompress(struct mszipd_stream *zip, off_t out_bytes) {
385 /* for the bit buffer */
386 register unsigned int bit_buffer;
387 register int bits_left;
388 unsigned char *i_ptr, *i_end;
389
390 int i, state, error;
391
392 /* easy answers */
393 if (!zip || (out_bytes < 0)) return MSPACK_ERR_ARGS;
394 if (zip->error) return zip->error;
395
396 /* flush out any stored-up bytes before we begin */
397 i = zip->o_end - zip->o_ptr;
398 if ((off_t) i > out_bytes) i = (int) out_bytes;
399 if (i) {
400 if (zip->sys->write(zip->output, zip->o_ptr, i) != i) {
401 return zip->error = MSPACK_ERR_WRITE;
402 }
403 zip->o_ptr += i;
404 out_bytes -= i;
405 }
406 if (out_bytes == 0) return MSPACK_ERR_OK;
407
408
409 while (out_bytes > 0) {
410 /* unpack another block */
411 RESTORE_BITS;
412
413 /* skip to next read 'CK' header */
414 i = bits_left & 7; REMOVE_BITS(i); /* align to bytestream */
415 state = 0;
416 do {
417 READ_BITS(i, 8);
418 if (i == 'C') state = 1;
419 else if ((state == 1) && (i == 'K')) state = 2;
420 else state = 0;
421 } while (state != 2);
422
423 /* inflate a block, repair and realign if necessary */
424 zip->window_posn = 0;
425 zip->bytes_output = 0;
426 STORE_BITS;
427 if ((error = inflate(zip))) {
428 D(("inflate error %d", error))
429 if (zip->repair_mode) {
430 /* recover partially-inflated buffers */
431 if (zip->bytes_output == 0 && zip->window_posn > 0) {
432 zip->flush_window(zip, zip->window_posn);
433 }
434 zip->sys->message(NULL, "MSZIP error, %u bytes of data lost.",
435 MSZIP_FRAME_SIZE - zip->bytes_output);
436 for (i = zip->bytes_output; i < MSZIP_FRAME_SIZE; i++) {
437 zip->window[i] = '\0';
438 }
439 zip->bytes_output = MSZIP_FRAME_SIZE;
440 }
441 else {
442 return zip->error = (error > 0) ? error : MSPACK_ERR_DECRUNCH;
443 }
444 }
445 zip->o_ptr = &zip->window[0];
446 zip->o_end = &zip->o_ptr[zip->bytes_output];
447
448 /* write a frame */
449 i = (out_bytes < (off_t)zip->bytes_output) ?
450 (int)out_bytes : zip->bytes_output;
451 if (zip->sys->write(zip->output, zip->o_ptr, i) != i) {
452 return zip->error = MSPACK_ERR_WRITE;
453 }
454
455 /* mspack errors (i.e. read errors) are fatal and can't be recovered */
456 if ((error > 0) && zip->repair_mode) return error;
457
458 zip->o_ptr += i;
459 out_bytes -= i;
460 }
461
462 if (out_bytes) {
463 D(("bytes left to output"))
464 return zip->error = MSPACK_ERR_DECRUNCH;
465 }
466 return MSPACK_ERR_OK;
467}
468
469int mszipd_decompress_kwaj(struct mszipd_stream *zip) {
470 /* for the bit buffer */
471 register unsigned int bit_buffer;
472 register int bits_left;
473 unsigned char *i_ptr, *i_end;
474
475 int i, error, block_len;
476
477 /* unpack blocks until block_len == 0 */
478 for (;;) {
479 RESTORE_BITS;
480
481 /* align to bytestream, read block_len */
482 i = bits_left & 7; REMOVE_BITS(i);
483 READ_BITS(block_len, 8);
484 READ_BITS(i, 8); block_len |= i << 8;
485
486 if (block_len == 0) break;
487
488 /* read "CK" header */
489 READ_BITS(i, 8); if (i != 'C') return MSPACK_ERR_DATAFORMAT;
490 READ_BITS(i, 8); if (i != 'K') return MSPACK_ERR_DATAFORMAT;
491
492 /* inflate block */
493 zip->window_posn = 0;
494 zip->bytes_output = 0;
495 STORE_BITS;
496 if ((error = inflate(zip))) {
497 D(("inflate error %d", error))
498 return zip->error = (error > 0) ? error : MSPACK_ERR_DECRUNCH;
499 }
500
501 /* write inflated block */
502 if (zip->sys->write(zip->output, &zip->window[0], zip->bytes_output)
503 != zip->bytes_output) return zip->error = MSPACK_ERR_WRITE;
504 }
505 return MSPACK_ERR_OK;
506}
507
508void mszipd_free(struct mszipd_stream *zip) {
509 struct mspack_system *sys;
510 if (zip) {
511 sys = zip->sys;
512 sys->free(zip->inbuf);
513 sys->free(zip);
514 }
515}
diff --git a/utils/rbutilqt/mspack/qtm.h b/utils/rbutilqt/mspack/qtm.h
new file mode 100644
index 0000000000..20a38538a2
--- /dev/null
+++ b/utils/rbutilqt/mspack/qtm.h
@@ -0,0 +1,128 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * The Quantum method was created by David Stafford, adapted by Microsoft
5 * Corporation.
6 *
7 * libmspack is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
9 *
10 * For further details, see the file COPYING.LIB distributed with libmspack
11 */
12
13#ifndef MSPACK_QTM_H
14#define MSPACK_QTM_H 1
15
16#ifdef __cplusplus
17extern "C" {
18#endif
19
20/* Quantum compression / decompression definitions */
21
22#define QTM_FRAME_SIZE (32768)
23
24struct qtmd_modelsym {
25 unsigned short sym, cumfreq;
26};
27
28struct qtmd_model {
29 int shiftsleft, entries;
30 struct qtmd_modelsym *syms;
31};
32
33struct qtmd_stream {
34 struct mspack_system *sys; /* I/O routines */
35 struct mspack_file *input; /* input file handle */
36 struct mspack_file *output; /* output file handle */
37
38 unsigned char *window; /* decoding window */
39 unsigned int window_size; /* window size */
40 unsigned int window_posn; /* decompression offset within window */
41 unsigned int frame_todo; /* bytes remaining for current frame */
42
43 unsigned short H, L, C; /* high/low/current: arith coding state */
44 unsigned char header_read; /* have we started decoding a new frame? */
45
46 int error;
47
48 /* I/O buffers */
49 unsigned char *inbuf, *i_ptr, *i_end, *o_ptr, *o_end;
50 unsigned int bit_buffer, inbuf_size;
51 unsigned char bits_left, input_end;
52
53 /* four literal models, each representing 64 symbols
54 * model0 for literals from 0 to 63 (selector = 0)
55 * model1 for literals from 64 to 127 (selector = 1)
56 * model2 for literals from 128 to 191 (selector = 2)
57 * model3 for literals from 129 to 255 (selector = 3) */
58 struct qtmd_model model0, model1, model2, model3;
59
60 /* three match models.
61 * model4 for match with fixed length of 3 bytes
62 * model5 for match with fixed length of 4 bytes
63 * model6 for variable length match, encoded with model6len model */
64 struct qtmd_model model4, model5, model6, model6len;
65
66 /* selector model. 0-6 to say literal (0,1,2,3) or match (4,5,6) */
67 struct qtmd_model model7;
68
69 /* symbol arrays for all models */
70 struct qtmd_modelsym m0sym[64 + 1];
71 struct qtmd_modelsym m1sym[64 + 1];
72 struct qtmd_modelsym m2sym[64 + 1];
73 struct qtmd_modelsym m3sym[64 + 1];
74 struct qtmd_modelsym m4sym[24 + 1];
75 struct qtmd_modelsym m5sym[36 + 1];
76 struct qtmd_modelsym m6sym[42 + 1], m6lsym[27 + 1];
77 struct qtmd_modelsym m7sym[7 + 1];
78};
79
80/* allocates Quantum decompression state for decoding the given stream.
81 *
82 * - returns NULL if window_bits is outwith the range 10 to 21 (inclusive).
83 *
84 * - uses system->alloc() to allocate memory
85 *
86 * - returns NULL if not enough memory
87 *
88 * - window_bits is the size of the Quantum window, from 1Kb (10) to 2Mb (21).
89 *
90 * - input_buffer_size is the number of bytes to use to store bitstream data.
91 */
92extern struct qtmd_stream *qtmd_init(struct mspack_system *system,
93 struct mspack_file *input,
94 struct mspack_file *output,
95 int window_bits,
96 int input_buffer_size);
97
98/* decompresses, or decompresses more of, a Quantum stream.
99 *
100 * - out_bytes of data will be decompressed and the function will return
101 * with an MSPACK_ERR_OK return code.
102 *
103 * - decompressing will stop as soon as out_bytes is reached. if the true
104 * amount of bytes decoded spills over that amount, they will be kept for
105 * a later invocation of qtmd_decompress().
106 *
107 * - the output bytes will be passed to the system->write() function given in
108 * qtmd_init(), using the output file handle given in qtmd_init(). More
109 * than one call may be made to system->write()
110 *
111 * - Quantum will read input bytes as necessary using the system->read()
112 * function given in qtmd_init(), using the input file handle given in
113 * qtmd_init(). This will continue until system->read() returns 0 bytes,
114 * or an error.
115 */
116extern int qtmd_decompress(struct qtmd_stream *qtm, off_t out_bytes);
117
118/* frees all state associated with a Quantum data stream
119 *
120 * - calls system->free() using the system pointer given in qtmd_init()
121 */
122void qtmd_free(struct qtmd_stream *qtm);
123
124#ifdef __cplusplus
125}
126#endif
127
128#endif
diff --git a/utils/rbutilqt/mspack/qtmd.c b/utils/rbutilqt/mspack/qtmd.c
new file mode 100644
index 0000000000..58e4787b7f
--- /dev/null
+++ b/utils/rbutilqt/mspack/qtmd.c
@@ -0,0 +1,490 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * The Quantum method was created by David Stafford, adapted by Microsoft
5 * Corporation.
6 *
7 * This decompressor is based on an implementation by Matthew Russotto, used
8 * with permission.
9 *
10 * libmspack is free software; you can redistribute it and/or modify it under
11 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
12 *
13 * For further details, see the file COPYING.LIB distributed with libmspack
14 */
15
16/* Quantum decompression implementation */
17
18/* This decompressor was researched and implemented by Matthew Russotto. It
19 * has since been tidied up by Stuart Caie. More information can be found at
20 * http://www.speakeasy.org/~russotto/quantumcomp.html
21 */
22
23#include "system-mspack.h"
24#include "qtm.h"
25
26/* import bit-reading macros and code */
27#define BITS_TYPE struct qtmd_stream
28#define BITS_VAR qtm
29#define BITS_ORDER_MSB
30#define READ_BYTES do { \
31 unsigned char b0, b1; \
32 READ_IF_NEEDED; b0 = *i_ptr++; \
33 READ_IF_NEEDED; b1 = *i_ptr++; \
34 INJECT_BITS((b0 << 8) | b1, 16); \
35} while (0)
36#include "readbits.h"
37
38/* Quantum static data tables:
39 *
40 * Quantum uses 'position slots' to represent match offsets. For every
41 * match, a small 'position slot' number and a small offset from that slot
42 * are encoded instead of one large offset.
43 *
44 * position_base[] is an index to the position slot bases
45 *
46 * extra_bits[] states how many bits of offset-from-base data is needed.
47 *
48 * length_base[] and length_extra[] are equivalent in function, but are
49 * used for encoding selector 6 (variable length match) match lengths,
50 * instead of match offsets.
51 *
52 * They are generated with the following code:
53 * unsigned int i, offset;
54 * for (i = 0, offset = 0; i < 42; i++) {
55 * position_base[i] = offset;
56 * extra_bits[i] = ((i < 2) ? 0 : (i - 2)) >> 1;
57 * offset += 1 << extra_bits[i];
58 * }
59 * for (i = 0, offset = 0; i < 26; i++) {
60 * length_base[i] = offset;
61 * length_extra[i] = (i < 2 ? 0 : i - 2) >> 2;
62 * offset += 1 << length_extra[i];
63 * }
64 * length_base[26] = 254; length_extra[26] = 0;
65 */
66static const unsigned int position_base[42] = {
67 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
68 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152,
69 65536, 98304, 131072, 196608, 262144, 393216, 524288, 786432, 1048576, 1572864
70};
71static const unsigned char extra_bits[42] = {
72 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10,
73 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19
74};
75static const unsigned char length_base[27] = {
76 0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 18, 22, 26,
77 30, 38, 46, 54, 62, 78, 94, 110, 126, 158, 190, 222, 254
78};
79static const unsigned char length_extra[27] = {
80 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
81 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
82};
83
84
85/* Arithmetic decoder:
86 *
87 * GET_SYMBOL(model, var) fetches the next symbol from the stated model
88 * and puts it in var.
89 *
90 * If necessary, qtmd_update_model() is called.
91 */
92#define GET_SYMBOL(model, var) do { \
93 range = ((H - L) & 0xFFFF) + 1; \
94 symf = ((((C - L + 1) * model.syms[0].cumfreq)-1) / range) & 0xFFFF; \
95 \
96 for (i = 1; i < model.entries; i++) { \
97 if (model.syms[i].cumfreq <= symf) break; \
98 } \
99 (var) = model.syms[i-1].sym; \
100 \
101 range = (H - L) + 1; \
102 symf = model.syms[0].cumfreq; \
103 H = L + ((model.syms[i-1].cumfreq * range) / symf) - 1; \
104 L = L + ((model.syms[i].cumfreq * range) / symf); \
105 \
106 do { model.syms[--i].cumfreq += 8; } while (i > 0); \
107 if (model.syms[0].cumfreq > 3800) qtmd_update_model(&model); \
108 \
109 while (1) { \
110 if ((L & 0x8000) != (H & 0x8000)) { \
111 if ((L & 0x4000) && !(H & 0x4000)) { \
112 /* underflow case */ \
113 C ^= 0x4000; L &= 0x3FFF; H |= 0x4000; \
114 } \
115 else break; \
116 } \
117 L <<= 1; H = (H << 1) | 1; \
118 ENSURE_BITS(1); \
119 C = (C << 1) | PEEK_BITS(1); \
120 REMOVE_BITS(1); \
121 } \
122} while (0)
123
124static void qtmd_update_model(struct qtmd_model *model) {
125 struct qtmd_modelsym tmp;
126 int i, j;
127
128 if (--model->shiftsleft) {
129 for (i = model->entries - 1; i >= 0; i--) {
130 /* -1, not -2; the 0 entry saves this */
131 model->syms[i].cumfreq >>= 1;
132 if (model->syms[i].cumfreq <= model->syms[i+1].cumfreq) {
133 model->syms[i].cumfreq = model->syms[i+1].cumfreq + 1;
134 }
135 }
136 }
137 else {
138 model->shiftsleft = 50;
139 for (i = 0; i < model->entries; i++) {
140 /* no -1, want to include the 0 entry */
141 /* this converts cumfreqs into frequencies, then shifts right */
142 model->syms[i].cumfreq -= model->syms[i+1].cumfreq;
143 model->syms[i].cumfreq++; /* avoid losing things entirely */
144 model->syms[i].cumfreq >>= 1;
145 }
146
147 /* now sort by frequencies, decreasing order -- this must be an
148 * inplace selection sort, or a sort with the same (in)stability
149 * characteristics */
150 for (i = 0; i < model->entries - 1; i++) {
151 for (j = i + 1; j < model->entries; j++) {
152 if (model->syms[i].cumfreq < model->syms[j].cumfreq) {
153 tmp = model->syms[i];
154 model->syms[i] = model->syms[j];
155 model->syms[j] = tmp;
156 }
157 }
158 }
159
160 /* then convert frequencies back to cumfreq */
161 for (i = model->entries - 1; i >= 0; i--) {
162 model->syms[i].cumfreq += model->syms[i+1].cumfreq;
163 }
164 }
165}
166
167/* Initialises a model to decode symbols from [start] to [start]+[len]-1 */
168static void qtmd_init_model(struct qtmd_model *model,
169 struct qtmd_modelsym *syms, int start, int len)
170{
171 int i;
172
173 model->shiftsleft = 4;
174 model->entries = len;
175 model->syms = syms;
176
177 for (i = 0; i <= len; i++) {
178 syms[i].sym = start + i; /* actual symbol */
179 syms[i].cumfreq = len - i; /* current frequency of that symbol */
180 }
181}
182
183
184/*-------- main Quantum code --------*/
185
186struct qtmd_stream *qtmd_init(struct mspack_system *system,
187 struct mspack_file *input,
188 struct mspack_file *output,
189 int window_bits, int input_buffer_size)
190{
191 unsigned int window_size = 1 << window_bits;
192 struct qtmd_stream *qtm;
193 int i;
194
195 if (!system) return NULL;
196
197 /* Quantum supports window sizes of 2^10 (1Kb) through 2^21 (2Mb) */
198 if (window_bits < 10 || window_bits > 21) return NULL;
199
200 /* round up input buffer size to multiple of two */
201 input_buffer_size = (input_buffer_size + 1) & -2;
202 if (input_buffer_size < 2) return NULL;
203
204 /* allocate decompression state */
205 if (!(qtm = (struct qtmd_stream *) system->alloc(system, sizeof(struct qtmd_stream)))) {
206 return NULL;
207 }
208
209 /* allocate decompression window and input buffer */
210 qtm->window = (unsigned char *) system->alloc(system, (size_t) window_size);
211 qtm->inbuf = (unsigned char *) system->alloc(system, (size_t) input_buffer_size);
212 if (!qtm->window || !qtm->inbuf) {
213 system->free(qtm->window);
214 system->free(qtm->inbuf);
215 system->free(qtm);
216 return NULL;
217 }
218
219 /* initialise decompression state */
220 qtm->sys = system;
221 qtm->input = input;
222 qtm->output = output;
223 qtm->inbuf_size = input_buffer_size;
224 qtm->window_size = window_size;
225 qtm->window_posn = 0;
226 qtm->frame_todo = QTM_FRAME_SIZE;
227 qtm->header_read = 0;
228 qtm->error = MSPACK_ERR_OK;
229
230 qtm->i_ptr = qtm->i_end = &qtm->inbuf[0];
231 qtm->o_ptr = qtm->o_end = &qtm->window[0];
232 qtm->input_end = 0;
233 qtm->bits_left = 0;
234 qtm->bit_buffer = 0;
235
236 /* initialise arithmetic coding models
237 * - model 4 depends on window size, ranges from 20 to 24
238 * - model 5 depends on window size, ranges from 20 to 36
239 * - model 6pos depends on window size, ranges from 20 to 42
240 */
241 i = window_bits * 2;
242 qtmd_init_model(&qtm->model0, &qtm->m0sym[0], 0, 64);
243 qtmd_init_model(&qtm->model1, &qtm->m1sym[0], 64, 64);
244 qtmd_init_model(&qtm->model2, &qtm->m2sym[0], 128, 64);
245 qtmd_init_model(&qtm->model3, &qtm->m3sym[0], 192, 64);
246 qtmd_init_model(&qtm->model4, &qtm->m4sym[0], 0, (i > 24) ? 24 : i);
247 qtmd_init_model(&qtm->model5, &qtm->m5sym[0], 0, (i > 36) ? 36 : i);
248 qtmd_init_model(&qtm->model6, &qtm->m6sym[0], 0, i);
249 qtmd_init_model(&qtm->model6len, &qtm->m6lsym[0], 0, 27);
250 qtmd_init_model(&qtm->model7, &qtm->m7sym[0], 0, 7);
251
252 /* all ok */
253 return qtm;
254}
255
256int qtmd_decompress(struct qtmd_stream *qtm, off_t out_bytes) {
257 unsigned int frame_todo, frame_end, window_posn, match_offset, range;
258 unsigned char *window, *i_ptr, *i_end, *runsrc, *rundest;
259 int i, j, selector, extra, sym, match_length;
260 unsigned short H, L, C, symf;
261
262 register unsigned int bit_buffer;
263 register unsigned char bits_left;
264
265 /* easy answers */
266 if (!qtm || (out_bytes < 0)) return MSPACK_ERR_ARGS;
267 if (qtm->error) return qtm->error;
268
269 /* flush out any stored-up bytes before we begin */
270 i = qtm->o_end - qtm->o_ptr;
271 if ((off_t) i > out_bytes) i = (int) out_bytes;
272 if (i) {
273 if (qtm->sys->write(qtm->output, qtm->o_ptr, i) != i) {
274 return qtm->error = MSPACK_ERR_WRITE;
275 }
276 qtm->o_ptr += i;
277 out_bytes -= i;
278 }
279 if (out_bytes == 0) return MSPACK_ERR_OK;
280
281 /* restore local state */
282 RESTORE_BITS;
283 window = qtm->window;
284 window_posn = qtm->window_posn;
285 frame_todo = qtm->frame_todo;
286 H = qtm->H;
287 L = qtm->L;
288 C = qtm->C;
289
290 /* while we do not have enough decoded bytes in reserve: */
291 while ((qtm->o_end - qtm->o_ptr) < out_bytes) {
292 /* read header if necessary. Initialises H, L and C */
293 if (!qtm->header_read) {
294 H = 0xFFFF; L = 0; READ_BITS(C, 16);
295 qtm->header_read = 1;
296 }
297
298 /* decode more, up to the number of bytes needed, the frame boundary,
299 * or the window boundary, whichever comes first */
300 frame_end = window_posn + (out_bytes - (qtm->o_end - qtm->o_ptr));
301 if ((window_posn + frame_todo) < frame_end) {
302 frame_end = window_posn + frame_todo;
303 }
304 if (frame_end > qtm->window_size) {
305 frame_end = qtm->window_size;
306 }
307
308 while (window_posn < frame_end) {
309 GET_SYMBOL(qtm->model7, selector);
310 if (selector < 4) {
311 /* literal byte */
312 struct qtmd_model *mdl = (selector == 0) ? &qtm->model0 :
313 ((selector == 1) ? &qtm->model1 :
314 ((selector == 2) ? &qtm->model2 :
315 &qtm->model3));
316 GET_SYMBOL((*mdl), sym);
317 window[window_posn++] = sym;
318 frame_todo--;
319 }
320 else {
321 /* match repeated string */
322 switch (selector) {
323 case 4: /* selector 4 = fixed length match (3 bytes) */
324 GET_SYMBOL(qtm->model4, sym);
325 READ_MANY_BITS(extra, extra_bits[sym]);
326 match_offset = position_base[sym] + extra + 1;
327 match_length = 3;
328 break;
329
330 case 5: /* selector 5 = fixed length match (4 bytes) */
331 GET_SYMBOL(qtm->model5, sym);
332 READ_MANY_BITS(extra, extra_bits[sym]);
333 match_offset = position_base[sym] + extra + 1;
334 match_length = 4;
335 break;
336
337 case 6: /* selector 6 = variable length match */
338 GET_SYMBOL(qtm->model6len, sym);
339 READ_MANY_BITS(extra, length_extra[sym]);
340 match_length = length_base[sym] + extra + 5;
341
342 GET_SYMBOL(qtm->model6, sym);
343 READ_MANY_BITS(extra, extra_bits[sym]);
344 match_offset = position_base[sym] + extra + 1;
345 break;
346
347 default:
348 /* should be impossible, model7 can only return 0-6 */
349 D(("got %d from selector", selector))
350 return qtm->error = MSPACK_ERR_DECRUNCH;
351 }
352
353 rundest = &window[window_posn];
354 frame_todo -= match_length;
355
356 /* does match destination wrap the window? This situation is possible
357 * where the window size is less than the 32k frame size, but matches
358 * must not go beyond a frame boundary */
359 if ((window_posn + match_length) > qtm->window_size) {
360 /* copy first part of match, before window end */
361 i = qtm->window_size - window_posn;
362 j = window_posn - match_offset;
363 while (i--) *rundest++ = window[j++ & (qtm->window_size - 1)];
364
365 /* flush currently stored data */
366 i = (&window[qtm->window_size] - qtm->o_ptr);
367
368 /* this should not happen, but if it does then this code
369 * can't handle the situation (can't flush up to the end of
370 * the window, but can't break out either because we haven't
371 * finished writing the match). bail out in this case */
372 if (i > out_bytes) {
373 D(("during window-wrap match; %d bytes to flush but only need %d",
374 i, (int) out_bytes))
375 return qtm->error = MSPACK_ERR_DECRUNCH;
376 }
377 if (qtm->sys->write(qtm->output, qtm->o_ptr, i) != i) {
378 return qtm->error = MSPACK_ERR_WRITE;
379 }
380 out_bytes -= i;
381 qtm->o_ptr = &window[0];
382 qtm->o_end = &window[0];
383
384 /* copy second part of match, after window wrap */
385 rundest = &window[0];
386 i = match_length - (qtm->window_size - window_posn);
387 while (i--) *rundest++ = window[j++ & (qtm->window_size - 1)];
388 window_posn = window_posn + match_length - qtm->window_size;
389
390 break; /* because "window_posn < frame_end" has now failed */
391 }
392 else {
393 /* normal match - output won't wrap window or frame end */
394 i = match_length;
395
396 /* does match _offset_ wrap the window? */
397 if (match_offset > window_posn) {
398 /* j = length from match offset to end of window */
399 j = match_offset - window_posn;
400 if (j > (int) qtm->window_size) {
401 D(("match offset beyond window boundaries"))
402 return qtm->error = MSPACK_ERR_DECRUNCH;
403 }
404 runsrc = &window[qtm->window_size - j];
405 if (j < i) {
406 /* if match goes over the window edge, do two copy runs */
407 i -= j; while (j-- > 0) *rundest++ = *runsrc++;
408 runsrc = window;
409 }
410 while (i-- > 0) *rundest++ = *runsrc++;
411 }
412 else {
413 runsrc = rundest - match_offset;
414 while (i-- > 0) *rundest++ = *runsrc++;
415 }
416 window_posn += match_length;
417 }
418 } /* if (window_posn+match_length > frame_end) */
419 } /* while (window_posn < frame_end) */
420
421 qtm->o_end = &window[window_posn];
422
423 /* if we subtracted too much from frame_todo, it will
424 * wrap around past zero and go above its max value */
425 if (frame_todo > QTM_FRAME_SIZE) {
426 D(("overshot frame alignment"))
427 return qtm->error = MSPACK_ERR_DECRUNCH;
428 }
429
430 /* another frame completed? */
431 if (frame_todo == 0) {
432 /* re-align input */
433 if (bits_left & 7) REMOVE_BITS(bits_left & 7);
434
435 /* special Quantum hack -- cabd.c injects a trailer byte to allow the
436 * decompressor to realign itself. CAB Quantum blocks, unlike LZX
437 * blocks, can have anything from 0 to 4 trailing null bytes. */
438 do { READ_BITS(i, 8); } while (i != 0xFF);
439
440 qtm->header_read = 0;
441
442 frame_todo = QTM_FRAME_SIZE;
443 }
444
445 /* window wrap? */
446 if (window_posn == qtm->window_size) {
447 /* flush all currently stored data */
448 i = (qtm->o_end - qtm->o_ptr);
449 /* break out if we have more than enough to finish this request */
450 if (i >= out_bytes) break;
451 if (qtm->sys->write(qtm->output, qtm->o_ptr, i) != i) {
452 return qtm->error = MSPACK_ERR_WRITE;
453 }
454 out_bytes -= i;
455 qtm->o_ptr = &window[0];
456 qtm->o_end = &window[0];
457 window_posn = 0;
458 }
459
460 } /* while (more bytes needed) */
461
462 if (out_bytes) {
463 i = (int) out_bytes;
464 if (qtm->sys->write(qtm->output, qtm->o_ptr, i) != i) {
465 return qtm->error = MSPACK_ERR_WRITE;
466 }
467 qtm->o_ptr += i;
468 }
469
470 /* store local state */
471
472 STORE_BITS;
473 qtm->window_posn = window_posn;
474 qtm->frame_todo = frame_todo;
475 qtm->H = H;
476 qtm->L = L;
477 qtm->C = C;
478
479 return MSPACK_ERR_OK;
480}
481
482void qtmd_free(struct qtmd_stream *qtm) {
483 struct mspack_system *sys;
484 if (qtm) {
485 sys = qtm->sys;
486 sys->free(qtm->window);
487 sys->free(qtm->inbuf);
488 sys->free(qtm);
489 }
490}
diff --git a/utils/rbutilqt/mspack/readbits.h b/utils/rbutilqt/mspack/readbits.h
new file mode 100644
index 0000000000..9b237a3693
--- /dev/null
+++ b/utils/rbutilqt/mspack/readbits.h
@@ -0,0 +1,207 @@
1/* This file is part of libmspack.
2 * (C) 2003-2010 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10#ifndef MSPACK_READBITS_H
11#define MSPACK_READBITS_H 1
12
13/* this header defines macros that read data streams by
14 * the individual bits
15 *
16 * INIT_BITS initialises bitstream state in state structure
17 * STORE_BITS stores bitstream state in state structure
18 * RESTORE_BITS restores bitstream state from state structure
19 * ENSURE_BITS(n) ensure there are at least N bits in the bit buffer
20 * READ_BITS(var,n) takes N bits from the buffer and puts them in var
21 * PEEK_BITS(n) extracts without removing N bits from the bit buffer
22 * REMOVE_BITS(n) removes N bits from the bit buffer
23 *
24 * READ_BITS simply calls ENSURE_BITS, PEEK_BITS and REMOVE_BITS,
25 * which means it's limited to reading the number of bits you can
26 * ensure at any one time. It also fails if asked to read zero bits.
27 * If you need to read zero bits, or more bits than can be ensured in
28 * one go, use READ_MANY_BITS instead.
29 *
30 * These macros have variable names baked into them, so to use them
31 * you have to define some macros:
32 * - BITS_TYPE: the type name of your state structure
33 * - BITS_VAR: the variable that points to your state structure
34 * - define BITS_ORDER_MSB if bits are read from the MSB, or
35 * define BITS_ORDER_LSB if bits are read from the LSB
36 * - READ_BYTES: some code that reads more data into the bit buffer,
37 * it should use READ_IF_NEEDED (calls read_input if the byte buffer
38 * is empty), then INJECT_BITS(data,n) to put data from the byte
39 * buffer into the bit buffer.
40 *
41 * You also need to define some variables and structure members:
42 * - unsigned char *i_ptr; // current position in the byte buffer
43 * - unsigned char *i_end; // end of the byte buffer
44 * - unsigned int bit_buffer; // the bit buffer itself
45 * - unsigned int bits_left; // number of bits remaining
46 *
47 * If you use read_input() and READ_IF_NEEDED, they also expect these
48 * structure members:
49 * - struct mspack_system *sys; // to access sys->read()
50 * - unsigned int error; // to record/return read errors
51 * - unsigned char input_end; // to mark reaching the EOF
52 * - unsigned char *inbuf; // the input byte buffer
53 * - unsigned int inbuf_size; // the size of the input byte buffer
54 *
55 * Your READ_BYTES implementation should read data from *i_ptr and
56 * put them in the bit buffer. READ_IF_NEEDED will call read_input()
57 * if i_ptr reaches i_end, and will fill up inbuf and set i_ptr to
58 * the start of inbuf and i_end to the end of inbuf.
59 *
60 * If you're reading in MSB order, the routines work by using the area
61 * beyond the MSB and the LSB of the bit buffer as a free source of
62 * zeroes when shifting. This avoids having to mask any bits. So we
63 * have to know the bit width of the bit buffer variable. We use
64 * <limits.h> and CHAR_BIT to find the size of the bit buffer in bits.
65 *
66 * If you are reading in LSB order, bits need to be masked. Normally
67 * this is done by computing the mask: N bits are masked by the value
68 * (1<<N)-1). However, you can define BITS_LSB_TABLE to use a lookup
69 * table instead of computing this. This adds two new macros,
70 * PEEK_BITS_T and READ_BITS_T which work the same way as PEEK_BITS
71 * and READ_BITS, except they use this lookup table. This is useful if
72 * you need to look up a number of bits that are only known at
73 * runtime, so the bit mask can't be turned into a constant by the
74 * compiler.
75
76 * The bit buffer datatype should be at least 32 bits wide: it must be
77 * possible to ENSURE_BITS(17), so it must be possible to add 16 new bits
78 * to the bit buffer when the bit buffer already has 1 to 15 bits left.
79 */
80
81#ifndef BITS_VAR
82# error "define BITS_VAR as the state structure poiner variable name"
83#endif
84#ifndef BITS_TYPE
85# error "define BITS_TYPE as the state structure type"
86#endif
87#if defined(BITS_ORDER_MSB) && defined(BITS_ORDER_LSB)
88# error "you must define either BITS_ORDER_MSB or BITS_ORDER_LSB"
89#else
90# if !(defined(BITS_ORDER_MSB) || defined(BITS_ORDER_LSB))
91# error "you must define BITS_ORDER_MSB or BITS_ORDER_LSB"
92# endif
93#endif
94
95#if HAVE_LIMITS_H
96# include <limits.h>
97#endif
98#ifndef CHAR_BIT
99# define CHAR_BIT (8)
100#endif
101#define BITBUF_WIDTH (sizeof(bit_buffer) * CHAR_BIT)
102
103#define INIT_BITS do { \
104 BITS_VAR->i_ptr = &BITS_VAR->inbuf[0]; \
105 BITS_VAR->i_end = &BITS_VAR->inbuf[0]; \
106 BITS_VAR->bit_buffer = 0; \
107 BITS_VAR->bits_left = 0; \
108 BITS_VAR->input_end = 0; \
109} while (0)
110
111#define STORE_BITS do { \
112 BITS_VAR->i_ptr = i_ptr; \
113 BITS_VAR->i_end = i_end; \
114 BITS_VAR->bit_buffer = bit_buffer; \
115 BITS_VAR->bits_left = bits_left; \
116} while (0)
117
118#define RESTORE_BITS do { \
119 i_ptr = BITS_VAR->i_ptr; \
120 i_end = BITS_VAR->i_end; \
121 bit_buffer = BITS_VAR->bit_buffer; \
122 bits_left = BITS_VAR->bits_left; \
123} while (0)
124
125#define ENSURE_BITS(nbits) do { \
126 while (bits_left < (nbits)) READ_BYTES; \
127} while (0)
128
129#define READ_BITS(val, nbits) do { \
130 ENSURE_BITS(nbits); \
131 (val) = PEEK_BITS(nbits); \
132 REMOVE_BITS(nbits); \
133} while (0)
134
135#define READ_MANY_BITS(val, bits) do { \
136 unsigned char needed = (bits), bitrun; \
137 (val) = 0; \
138 while (needed > 0) { \
139 if (bits_left <= (BITBUF_WIDTH - 16)) READ_BYTES; \
140 bitrun = (bits_left < needed) ? bits_left : needed; \
141 (val) = ((val) << bitrun) | PEEK_BITS(bitrun); \
142 REMOVE_BITS(bitrun); \
143 needed -= bitrun; \
144 } \
145} while (0)
146
147#ifdef BITS_ORDER_MSB
148# define PEEK_BITS(nbits) (bit_buffer >> (BITBUF_WIDTH - (nbits)))
149# define REMOVE_BITS(nbits) ((bit_buffer <<= (nbits)), (bits_left -= (nbits)))
150# define INJECT_BITS(bitdata,nbits) ((bit_buffer |= \
151 (bitdata) << (BITBUF_WIDTH - (nbits) - bits_left)), (bits_left += (nbits)))
152#else /* BITS_ORDER_LSB */
153# define PEEK_BITS(nbits) (bit_buffer & ((1 << (nbits))-1))
154# define REMOVE_BITS(nbits) ((bit_buffer >>= (nbits)), (bits_left -= (nbits)))
155# define INJECT_BITS(bitdata,nbits) ((bit_buffer |= \
156 (bitdata) << bits_left), (bits_left += (nbits)))
157#endif
158
159#ifdef BITS_LSB_TABLE
160/* lsb_bit_mask[n] = (1 << n) - 1 */
161static const unsigned short lsb_bit_mask[17] = {
162 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
163 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
164};
165# define PEEK_BITS_T(nbits) (bit_buffer & lsb_bit_mask[(nbits)])
166# define READ_BITS_T(val, nbits) do { \
167 ENSURE_BITS(nbits); \
168 (val) = PEEK_BITS_T(nbits); \
169 REMOVE_BITS(nbits); \
170} while (0)
171#endif
172
173#ifndef BITS_NO_READ_INPUT
174# define READ_IF_NEEDED do { \
175 if (i_ptr >= i_end) { \
176 if (read_input(BITS_VAR)) \
177 return BITS_VAR->error; \
178 i_ptr = BITS_VAR->i_ptr; \
179 i_end = BITS_VAR->i_end; \
180 } \
181} while (0)
182
183static int read_input(BITS_TYPE *p) {
184 int read = p->sys->read(p->input, &p->inbuf[0], (int)p->inbuf_size);
185 if (read < 0) return p->error = MSPACK_ERR_READ;
186
187 /* we might overrun the input stream by asking for bits we don't use,
188 * so fake 2 more bytes at the end of input */
189 if (read == 0) {
190 if (p->input_end) {
191 D(("out of input bytes"))
192 return p->error = MSPACK_ERR_READ;
193 }
194 else {
195 read = 2;
196 p->inbuf[0] = p->inbuf[1] = 0;
197 p->input_end = 1;
198 }
199 }
200
201 /* update i_ptr and i_end */
202 p->i_ptr = &p->inbuf[0];
203 p->i_end = &p->inbuf[read];
204 return MSPACK_ERR_OK;
205}
206#endif
207#endif
diff --git a/utils/rbutilqt/mspack/readhuff.h b/utils/rbutilqt/mspack/readhuff.h
new file mode 100644
index 0000000000..4d94225789
--- /dev/null
+++ b/utils/rbutilqt/mspack/readhuff.h
@@ -0,0 +1,172 @@
1/* This file is part of libmspack.
2 * (C) 2003-2014 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10#ifndef MSPACK_READHUFF_H
11#define MSPACK_READHUFF_H 1
12
13/* This implements a fast Huffman tree decoding system. */
14
15#if !(defined(BITS_ORDER_MSB) || defined(BITS_ORDER_LSB))
16# error "readhuff.h is used in conjunction with readbits.h, include that first"
17#endif
18#if !(defined(TABLEBITS) && defined(MAXSYMBOLS))
19# error "define TABLEBITS(tbl) and MAXSYMBOLS(tbl) before using readhuff.h"
20#endif
21#if !(defined(HUFF_TABLE) && defined(HUFF_LEN))
22# error "define HUFF_TABLE(tbl) and HUFF_LEN(tbl) before using readhuff.h"
23#endif
24#ifndef HUFF_ERROR
25# error "define HUFF_ERROR before using readhuff.h"
26#endif
27#ifndef HUFF_MAXBITS
28# define HUFF_MAXBITS 16
29#endif
30
31/* Decodes the next huffman symbol from the input bitstream into var.
32 * Do not use this macro on a table unless build_decode_table() succeeded.
33 */
34#define READ_HUFFSYM(tbl, var) do { \
35 ENSURE_BITS(HUFF_MAXBITS); \
36 sym = HUFF_TABLE(tbl, PEEK_BITS(TABLEBITS(tbl))); \
37 if (sym >= MAXSYMBOLS(tbl)) HUFF_TRAVERSE(tbl); \
38 (var) = sym; \
39 i = HUFF_LEN(tbl, sym); \
40 REMOVE_BITS(i); \
41} while (0)
42
43#ifdef BITS_ORDER_LSB
44# define HUFF_TRAVERSE(tbl) do { \
45 i = TABLEBITS(tbl) - 1; \
46 do { \
47 if (i++ > HUFF_MAXBITS) HUFF_ERROR; \
48 sym = HUFF_TABLE(tbl, \
49 (sym << 1) | ((bit_buffer >> i) & 1)); \
50 } while (sym >= MAXSYMBOLS(tbl)); \
51} while (0)
52#else
53#define HUFF_TRAVERSE(tbl) do { \
54 i = 1 << (BITBUF_WIDTH - TABLEBITS(tbl)); \
55 do { \
56 if ((i >>= 1) == 0) HUFF_ERROR; \
57 sym = HUFF_TABLE(tbl, \
58 (sym << 1) | ((bit_buffer & i) ? 1 : 0)); \
59 } while (sym >= MAXSYMBOLS(tbl)); \
60} while (0)
61#endif
62
63/* make_decode_table(nsyms, nbits, length[], table[])
64 *
65 * This function was originally coded by David Tritscher.
66 * It builds a fast huffman decoding table from
67 * a canonical huffman code lengths table.
68 *
69 * nsyms = total number of symbols in this huffman tree.
70 * nbits = any symbols with a code length of nbits or less can be decoded
71 * in one lookup of the table.
72 * length = A table to get code lengths from [0 to nsyms-1]
73 * table = The table to fill up with decoded symbols and pointers.
74 * Should be ((1<<nbits) + (nsyms*2)) in length.
75 *
76 * Returns 0 for OK or 1 for error
77 */
78static int make_decode_table(unsigned int nsyms, unsigned int nbits,
79 unsigned char *length, unsigned short *table)
80{
81 register unsigned short sym, next_symbol;
82 register unsigned int leaf, fill;
83#ifdef BITS_ORDER_LSB
84 register unsigned int reverse;
85#endif
86 register unsigned char bit_num;
87 unsigned int pos = 0; /* the current position in the decode table */
88 unsigned int table_mask = 1 << nbits;
89 unsigned int bit_mask = table_mask >> 1; /* don't do 0 length codes */
90
91 /* fill entries for codes short enough for a direct mapping */
92 for (bit_num = 1; bit_num <= nbits; bit_num++) {
93 for (sym = 0; sym < nsyms; sym++) {
94 if (length[sym] != bit_num) continue;
95#ifdef BITS_ORDER_MSB
96 leaf = pos;
97#else
98 /* reverse the significant bits */
99 fill = length[sym]; reverse = pos >> (nbits - fill); leaf = 0;
100 do {leaf <<= 1; leaf |= reverse & 1; reverse >>= 1;} while (--fill);
101#endif
102
103 if((pos += bit_mask) > table_mask) return 1; /* table overrun */
104
105 /* fill all possible lookups of this symbol with the symbol itself */
106#ifdef BITS_ORDER_MSB
107 for (fill = bit_mask; fill-- > 0;) table[leaf++] = sym;
108#else
109 fill = bit_mask; next_symbol = 1 << bit_num;
110 do { table[leaf] = sym; leaf += next_symbol; } while (--fill);
111#endif
112 }
113 bit_mask >>= 1;
114 }
115
116 /* exit with success if table is now complete */
117 if (pos == table_mask) return 0;
118
119 /* mark all remaining table entries as unused */
120 for (sym = pos; sym < table_mask; sym++) {
121#ifdef BITS_ORDER_MSB
122 table[sym] = 0xFFFF;
123#else
124 reverse = sym; leaf = 0; fill = nbits;
125 do { leaf <<= 1; leaf |= reverse & 1; reverse >>= 1; } while (--fill);
126 table[leaf] = 0xFFFF;
127#endif
128 }
129
130 /* next_symbol = base of allocation for long codes */
131 next_symbol = ((table_mask >> 1) < nsyms) ? nsyms : (table_mask >> 1);
132
133 /* give ourselves room for codes to grow by up to 16 more bits.
134 * codes now start at bit nbits+16 and end at (nbits+16-codelength) */
135 pos <<= 16;
136 table_mask <<= 16;
137 bit_mask = 1 << 15;
138
139 for (bit_num = nbits+1; bit_num <= HUFF_MAXBITS; bit_num++) {
140 for (sym = 0; sym < nsyms; sym++) {
141 if (length[sym] != bit_num) continue;
142 if (pos >= table_mask) return 1; /* table overflow */
143
144#ifdef BITS_ORDER_MSB
145 leaf = pos >> 16;
146#else
147 /* leaf = the first nbits of the code, reversed */
148 reverse = pos >> 16; leaf = 0; fill = nbits;
149 do {leaf <<= 1; leaf |= reverse & 1; reverse >>= 1;} while (--fill);
150#endif
151 for (fill = 0; fill < (bit_num - nbits); fill++) {
152 /* if this path hasn't been taken yet, 'allocate' two entries */
153 if (table[leaf] == 0xFFFF) {
154 table[(next_symbol << 1) ] = 0xFFFF;
155 table[(next_symbol << 1) + 1 ] = 0xFFFF;
156 table[leaf] = next_symbol++;
157 }
158
159 /* follow the path and select either left or right for next bit */
160 leaf = table[leaf] << 1;
161 if ((pos >> (15-fill)) & 1) leaf++;
162 }
163 table[leaf] = sym;
164 pos += bit_mask;
165 }
166 bit_mask >>= 1;
167 }
168
169 /* full table? */
170 return (pos == table_mask) ? 0 : 1;
171}
172#endif
diff --git a/utils/rbutilqt/mspack/sha.h b/utils/rbutilqt/mspack/sha.h
new file mode 100644
index 0000000000..360521519b
--- /dev/null
+++ b/utils/rbutilqt/mspack/sha.h
@@ -0,0 +1,15 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10#ifndef MSPACK_LZSS_H
11#define MSPACK_LZSS_H 1
12
13/* SHA-1 message digest definitions */
14
15#endif
diff --git a/utils/rbutilqt/mspack/system-mspack.c b/utils/rbutilqt/mspack/system-mspack.c
new file mode 100644
index 0000000000..9d4886a8db
--- /dev/null
+++ b/utils/rbutilqt/mspack/system-mspack.c
@@ -0,0 +1,240 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10#ifdef HAVE_CONFIG_H
11# include "config.h"
12#endif
13
14#include "system-mspack.h"
15
16#ifndef LARGEFILE_SUPPORT
17const char *largefile_msg = "library not compiled to support large files.";
18#endif
19
20
21int mspack_version(int entity) {
22 switch (entity) {
23 /* CHM decoder version 1 -> 2 changes:
24 * - added mschmd_sec_mscompressed::spaninfo
25 * - added mschmd_header::first_pmgl
26 * - added mschmd_header::last_pmgl
27 * - added mschmd_header::chunk_cache;
28 */
29 case MSPACK_VER_MSCHMD:
30 return 2;
31 case MSPACK_VER_LIBRARY:
32 case MSPACK_VER_SYSTEM:
33 case MSPACK_VER_MSCABD:
34 case MSPACK_VER_MSSZDDD:
35 case MSPACK_VER_MSKWAJD:
36 return 1;
37 case MSPACK_VER_MSCABC:
38 case MSPACK_VER_MSCHMC:
39 case MSPACK_VER_MSLITD:
40 case MSPACK_VER_MSLITC:
41 case MSPACK_VER_MSHLPD:
42 case MSPACK_VER_MSHLPC:
43 case MSPACK_VER_MSSZDDC:
44 case MSPACK_VER_MSKWAJC:
45 return 0;
46 }
47 return -1;
48}
49
50int mspack_sys_selftest_internal(int offt_size) {
51 return (sizeof(off_t) == offt_size) ? MSPACK_ERR_OK : MSPACK_ERR_SEEK;
52}
53
54/* validates a system structure */
55int mspack_valid_system(struct mspack_system *sys) {
56 return (sys != NULL) && (sys->open != NULL) && (sys->close != NULL) &&
57 (sys->read != NULL) && (sys->write != NULL) && (sys->seek != NULL) &&
58 (sys->tell != NULL) && (sys->message != NULL) && (sys->alloc != NULL) &&
59 (sys->free != NULL) && (sys->copy != NULL) && (sys->null_ptr == NULL);
60}
61
62/* returns the length of a file opened for reading */
63int mspack_sys_filelen(struct mspack_system *system,
64 struct mspack_file *file, off_t *length)
65{
66 off_t current;
67
68 if (!system || !file || !length) return MSPACK_ERR_OPEN;
69
70 /* get current offset */
71 current = system->tell(file);
72
73 /* seek to end of file */
74 if (system->seek(file, (off_t) 0, MSPACK_SYS_SEEK_END)) {
75 return MSPACK_ERR_SEEK;
76 }
77
78 /* get offset of end of file */
79 *length = system->tell(file);
80
81 /* seek back to original offset */
82 if (system->seek(file, current, MSPACK_SYS_SEEK_START)) {
83 return MSPACK_ERR_SEEK;
84 }
85
86 return MSPACK_ERR_OK;
87}
88
89
90
91/* definition of mspack_default_system -- if the library is compiled with
92 * MSPACK_NO_DEFAULT_SYSTEM, no default system will be provided. Otherwise,
93 * an appropriate default system (e.g. the standard C library, or some native
94 * API calls)
95 */
96
97#ifdef MSPACK_NO_DEFAULT_SYSTEM
98struct mspack_system *mspack_default_system = NULL;
99#else
100
101/* implementation of mspack_default_system for standard C library */
102
103#include <stdio.h>
104#include <stdlib.h>
105#include <string.h>
106#include <stdarg.h>
107
108struct mspack_file_p {
109 FILE *fh;
110 const char *name;
111};
112
113static struct mspack_file *msp_open(struct mspack_system *self,
114 const char *filename, int mode)
115{
116 struct mspack_file_p *fh;
117 const char *fmode;
118 (void)self;
119
120 switch (mode) {
121 case MSPACK_SYS_OPEN_READ: fmode = "rb"; break;
122 case MSPACK_SYS_OPEN_WRITE: fmode = "wb"; break;
123 case MSPACK_SYS_OPEN_UPDATE: fmode = "r+b"; break;
124 case MSPACK_SYS_OPEN_APPEND: fmode = "ab"; break;
125 default: return NULL;
126 }
127
128 if ((fh = (struct mspack_file_p *) malloc(sizeof(struct mspack_file_p)))) {
129 fh->name = filename;
130 if ((fh->fh = fopen(filename, fmode))) return (struct mspack_file *) fh;
131 free(fh);
132 }
133 return NULL;
134}
135
136static void msp_close(struct mspack_file *file) {
137 struct mspack_file_p *self = (struct mspack_file_p *) file;
138 if (self) {
139 fclose(self->fh);
140 free(self);
141 }
142}
143
144static int msp_read(struct mspack_file *file, void *buffer, int bytes) {
145 struct mspack_file_p *self = (struct mspack_file_p *) file;
146 if (self && buffer && bytes >= 0) {
147 size_t count = fread(buffer, 1, (size_t) bytes, self->fh);
148 if (!ferror(self->fh)) return (int) count;
149 }
150 return -1;
151}
152
153static int msp_write(struct mspack_file *file, void *buffer, int bytes) {
154 struct mspack_file_p *self = (struct mspack_file_p *) file;
155 if (self && buffer && bytes >= 0) {
156 size_t count = fwrite(buffer, 1, (size_t) bytes, self->fh);
157 if (!ferror(self->fh)) return (int) count;
158 }
159 return -1;
160}
161
162static int msp_seek(struct mspack_file *file, off_t offset, int mode) {
163 struct mspack_file_p *self = (struct mspack_file_p *) file;
164 if (self) {
165 switch (mode) {
166 case MSPACK_SYS_SEEK_START: mode = SEEK_SET; break;
167 case MSPACK_SYS_SEEK_CUR: mode = SEEK_CUR; break;
168 case MSPACK_SYS_SEEK_END: mode = SEEK_END; break;
169 default: return -1;
170 }
171#ifdef HAVE_FSEEKO
172 return fseeko(self->fh, offset, mode);
173#else
174 return fseek(self->fh, offset, mode);
175#endif
176 }
177 return -1;
178}
179
180static off_t msp_tell(struct mspack_file *file) {
181 struct mspack_file_p *self = (struct mspack_file_p *) file;
182#ifdef HAVE_FSEEKO
183 return (self) ? (off_t) ftello(self->fh) : 0;
184#else
185 return (self) ? (off_t) ftell(self->fh) : 0;
186#endif
187}
188
189static void msp_msg(struct mspack_file *file, const char *format, ...) {
190 va_list ap;
191 if (file) fprintf(stderr, "%s: ", ((struct mspack_file_p *) file)->name);
192 va_start(ap, format);
193 vfprintf(stderr, format, ap);
194 va_end(ap);
195 fputc((int) '\n', stderr);
196 fflush(stderr);
197}
198
199static void *msp_alloc(struct mspack_system *self, size_t bytes) {
200#ifdef DEBUG
201 /* make uninitialised data obvious */
202 char *buf = malloc(bytes + 8);
203 (void)self;
204 if (buf) memset(buf, 0xDC, bytes);
205 *((size_t *)buf) = bytes;
206 return &buf[8];
207#else
208 (void)self;
209 return malloc(bytes);
210#endif
211}
212
213static void msp_free(void *buffer) {
214#ifdef DEBUG
215 char *buf = buffer;
216 size_t bytes;
217 if (buf) {
218 buf -= 8;
219 bytes = *((size_t *)buf);
220 /* make freed data obvious */
221 memset(buf, 0xED, bytes);
222 free(buf);
223 }
224#else
225 free(buffer);
226#endif
227}
228
229static void msp_copy(void *src, void *dest, size_t bytes) {
230 memcpy(dest, src, bytes);
231}
232
233static struct mspack_system msp_system = {
234 &msp_open, &msp_close, &msp_read, &msp_write, &msp_seek,
235 &msp_tell, &msp_msg, &msp_alloc, &msp_free, &msp_copy, NULL
236};
237
238struct mspack_system *mspack_default_system = &msp_system;
239
240#endif
diff --git a/utils/rbutilqt/mspack/system-mspack.h b/utils/rbutilqt/mspack/system-mspack.h
new file mode 100644
index 0000000000..a0e6cf3ca8
--- /dev/null
+++ b/utils/rbutilqt/mspack/system-mspack.h
@@ -0,0 +1,129 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10#ifndef MSPACK_SYSTEM_H
11#define MSPACK_SYSTEM_H 1
12
13#ifdef __cplusplus
14extern "C" {
15#endif
16
17/* ensure config.h is read before mspack.h */
18#ifdef HAVE_CONFIG_H
19# include "config.h"
20#endif
21
22#include "mspack.h"
23
24/* fix for problem with GCC 4 and glibc (thanks to Ville Skytta)
25 * http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=150429
26 */
27#ifdef read
28# undef read
29#endif
30
31#ifdef DEBUG
32# include <stdio.h>
33/* Old GCCs don't have __func__, but __FUNCTION__:
34 * http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html
35 */
36# if __STDC_VERSION__ < 199901L
37# if __GNUC__ >= 2
38# define __func__ __FUNCTION__
39# else
40# define __func__ "<unknown>"
41# endif
42# endif
43# define D(x) do { printf("%s:%d (%s) ",__FILE__, __LINE__, __func__); \
44 printf x ; fputc('\n', stdout); fflush(stdout);} while (0);
45#else
46# define D(x)
47#endif
48
49/* CAB supports searching through files over 4GB in size, and the CHM file
50 * format actively uses 64-bit offsets. These can only be fully supported
51 * if the system the code runs on supports large files. If not, the library
52 * will work as normal using only 32-bit arithmetic, but if an offset
53 * greater than 2GB is detected, an error message indicating the library
54 * can't support the file should be printed.
55 */
56#ifdef HAVE_LIMITS_H
57# include <limits.h>
58#endif
59
60#if ((defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS >= 64) || \
61 (defined(FILESIZEBITS) && FILESIZEBITS >= 64) || \
62 (defined(SIZEOF_OFF_T) && SIZEOF_OFF_T >= 8) || \
63 defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE))
64# define LARGEFILE_SUPPORT 1
65# define LD "lld"
66# define LU "llu"
67#else
68extern const char *largefile_msg;
69# define LD "ld"
70# define LU "lu"
71#endif
72
73/* endian-neutral reading of little-endian data */
74#define __egi32(a,n) ( ((((unsigned char *) a)[n+3]) << 24) | \
75 ((((unsigned char *) a)[n+2]) << 16) | \
76 ((((unsigned char *) a)[n+1]) << 8) | \
77 ((((unsigned char *) a)[n+0])))
78#define EndGetI64(a) ((((unsigned long long int) __egi32(a,4)) << 32) | \
79 ((unsigned int) __egi32(a,0)))
80#define EndGetI32(a) __egi32(a,0)
81#define EndGetI16(a) ((((a)[1])<<8)|((a)[0]))
82
83/* endian-neutral reading of big-endian data */
84#define EndGetM32(a) (((((unsigned char *) a)[0]) << 24) | \
85 ((((unsigned char *) a)[1]) << 16) | \
86 ((((unsigned char *) a)[2]) << 8) | \
87 ((((unsigned char *) a)[3])))
88#define EndGetM16(a) ((((a)[0])<<8)|((a)[1]))
89
90extern struct mspack_system *mspack_default_system;
91
92/* returns the length of a file opened for reading */
93extern int mspack_sys_filelen(struct mspack_system *system,
94 struct mspack_file *file, off_t *length);
95
96/* validates a system structure */
97extern int mspack_valid_system(struct mspack_system *sys);
98
99#if HAVE_STRINGS_H
100# include <strings.h>
101#endif
102
103#if HAVE_STRING_H
104# include <string.h>
105#endif
106
107#if HAVE_MEMCMP
108# define mspack_memcmp memcmp
109#else
110/* inline memcmp() */
111#ifdef _MSC_VER /* MSVC requires use of __inline instead of inline */
112#define INLINE __inline
113#else
114#define INLINE inline
115#endif
116static INLINE int mspack_memcmp(const void *s1, const void *s2, size_t n) {
117 unsigned char *c1 = (unsigned char *) s1;
118 unsigned char *c2 = (unsigned char *) s2;
119 if (n == 0) return 0;
120 while (--n && (*c1 == *c2)) c1++, c2++;
121 return *c1 - *c2;
122}
123#endif
124
125#ifdef __cplusplus
126}
127#endif
128
129#endif
diff --git a/utils/rbutilqt/mspack/szdd.h b/utils/rbutilqt/mspack/szdd.h
new file mode 100644
index 0000000000..b9936b42d1
--- /dev/null
+++ b/utils/rbutilqt/mspack/szdd.h
@@ -0,0 +1,39 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10#ifndef MSPACK_SZDD_H
11#define MSPACK_SZDD_H 1
12
13#include "lzss.h"
14
15/* input buffer size during decompression - not worth parameterising IMHO */
16#define SZDD_INPUT_SIZE (2048)
17
18/* SZDD compression definitions */
19
20struct msszdd_compressor_p {
21 struct msszdd_compressor base;
22 struct mspack_system *system;
23 int error;
24};
25
26/* SZDD decompression definitions */
27
28struct msszdd_decompressor_p {
29 struct msszdd_decompressor base;
30 struct mspack_system *system;
31 int error;
32};
33
34struct msszddd_header_p {
35 struct msszddd_header base;
36 struct mspack_file *fh;
37};
38
39#endif
diff --git a/utils/rbutilqt/mspack/szddc.c b/utils/rbutilqt/mspack/szddc.c
new file mode 100644
index 0000000000..6ad6501217
--- /dev/null
+++ b/utils/rbutilqt/mspack/szddc.c
@@ -0,0 +1,24 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10/* SZDD compression implementation */
11
12#include "system-mspack.h"
13#include "szdd.h"
14
15struct msszdd_compressor *
16 mspack_create_szdd_compressor(struct mspack_system *sys)
17{
18 /* todo */
19 return NULL;
20}
21
22void mspack_destroy_szdd_compressor(struct msszdd_compressor *self) {
23 /* todo */
24}
diff --git a/utils/rbutilqt/mspack/szddd.c b/utils/rbutilqt/mspack/szddd.c
new file mode 100644
index 0000000000..1d6d05f844
--- /dev/null
+++ b/utils/rbutilqt/mspack/szddd.c
@@ -0,0 +1,247 @@
1/* This file is part of libmspack.
2 * (C) 2003-2010 Stuart Caie.
3 *
4 * SZDD is a format used in the MS-DOS commands COMPRESS.EXE and
5 * EXPAND.EXE. The compression method is attributed to Steven Zeck,
6 * however it's pretty much identical to LZSS.
7 *
8 * libmspack is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
10 *
11 * For further details, see the file COPYING.LIB distributed with libmspack
12 */
13
14/* SZDD decompression implementation */
15
16#include "system-mspack.h"
17#include "szdd.h"
18
19/* prototypes */
20static struct msszddd_header *szddd_open(
21 struct msszdd_decompressor *base, const char *filename);
22static void szddd_close(
23 struct msszdd_decompressor *base, struct msszddd_header *hdr);
24static int szddd_read_headers(
25 struct mspack_system *sys, struct mspack_file *fh,
26 struct msszddd_header *hdr);
27static int szddd_extract(
28 struct msszdd_decompressor *base, struct msszddd_header *hdr,
29 const char *filename);
30static int szddd_decompress(
31 struct msszdd_decompressor *base, const char *input, const char *output);
32static int szddd_error(
33 struct msszdd_decompressor *base);
34
35/***************************************
36 * MSPACK_CREATE_SZDD_DECOMPRESSOR
37 ***************************************
38 * constructor
39 */
40struct msszdd_decompressor *
41 mspack_create_szdd_decompressor(struct mspack_system *sys)
42{
43 struct msszdd_decompressor_p *self = NULL;
44
45 if (!sys) sys = mspack_default_system;
46 if (!mspack_valid_system(sys)) return NULL;
47
48 if ((self = (struct msszdd_decompressor_p *) sys->alloc(sys, sizeof(struct msszdd_decompressor_p)))) {
49 self->base.open = &szddd_open;
50 self->base.close = &szddd_close;
51 self->base.extract = &szddd_extract;
52 self->base.decompress = &szddd_decompress;
53 self->base.last_error = &szddd_error;
54 self->system = sys;
55 self->error = MSPACK_ERR_OK;
56 }
57 return (struct msszdd_decompressor *) self;
58}
59
60/***************************************
61 * MSPACK_DESTROY_SZDD_DECOMPRESSOR
62 ***************************************
63 * destructor
64 */
65void mspack_destroy_szdd_decompressor(struct msszdd_decompressor *base)
66{
67 struct msszdd_decompressor_p *self = (struct msszdd_decompressor_p *) base;
68 if (self) {
69 struct mspack_system *sys = self->system;
70 sys->free(self);
71 }
72}
73
74/***************************************
75 * SZDDD_OPEN
76 ***************************************
77 * opens an SZDD file without decompressing, reads header
78 */
79static struct msszddd_header *szddd_open(struct msszdd_decompressor *base,
80 const char *filename)
81{
82 struct msszdd_decompressor_p *self = (struct msszdd_decompressor_p *) base;
83 struct msszddd_header *hdr;
84 struct mspack_system *sys;
85 struct mspack_file *fh;
86
87 if (!self) return NULL;
88 sys = self->system;
89
90 fh = sys->open(sys, filename, MSPACK_SYS_OPEN_READ);
91 hdr = (struct msszddd_header *) sys->alloc(sys, sizeof(struct msszddd_header_p));
92 if (fh && hdr) {
93 ((struct msszddd_header_p *) hdr)->fh = fh;
94 self->error = szddd_read_headers(sys, fh, hdr);
95 }
96 else {
97 if (!fh) self->error = MSPACK_ERR_OPEN;
98 if (!hdr) self->error = MSPACK_ERR_NOMEMORY;
99 }
100
101 if (self->error) {
102 if (fh) sys->close(fh);
103 sys->free(hdr);
104 hdr = NULL;
105 }
106
107 return hdr;
108}
109
110/***************************************
111 * SZDDD_CLOSE
112 ***************************************
113 * closes an SZDD file
114 */
115static void szddd_close(struct msszdd_decompressor *base,
116 struct msszddd_header *hdr)
117{
118 struct msszdd_decompressor_p *self = (struct msszdd_decompressor_p *) base;
119 struct msszddd_header_p *hdr_p = (struct msszddd_header_p *) hdr;
120
121 if (!self || !self->system) return;
122
123 /* close the file handle associated */
124 self->system->close(hdr_p->fh);
125
126 /* free the memory associated */
127 self->system->free(hdr);
128
129 self->error = MSPACK_ERR_OK;
130}
131
132/***************************************
133 * SZDDD_READ_HEADERS
134 ***************************************
135 * reads the headers of an SZDD format file
136 */
137static unsigned char szdd_signature_expand[8] = {
138 0x53, 0x5A, 0x44, 0x44, 0x88, 0xF0, 0x27, 0x33
139};
140static unsigned char szdd_signature_qbasic[8] = {
141 0x53, 0x5A, 0x20, 0x88, 0xF0, 0x27, 0x33, 0xD1
142};
143
144static int szddd_read_headers(struct mspack_system *sys,
145 struct mspack_file *fh,
146 struct msszddd_header *hdr)
147{
148 unsigned char buf[8];
149
150 /* read and check signature */
151 if (sys->read(fh, buf, 8) != 8) return MSPACK_ERR_READ;
152
153 if ((memcmp(buf, szdd_signature_expand, 8) == 0)) {
154 /* common SZDD */
155 hdr->format = MSSZDD_FMT_NORMAL;
156
157 /* read the rest of the header */
158 if (sys->read(fh, buf, 6) != 6) return MSPACK_ERR_READ;
159 if (buf[0] != 0x41) return MSPACK_ERR_DATAFORMAT;
160 hdr->missing_char = buf[1];
161 hdr->length = EndGetI32(&buf[2]);
162 }
163 else if ((memcmp(buf, szdd_signature_qbasic, 8) == 0)) {
164 /* special QBasic SZDD */
165 hdr->format = MSSZDD_FMT_QBASIC;
166 if (sys->read(fh, buf, 4) != 4) return MSPACK_ERR_READ;
167 hdr->missing_char = '\0';
168 hdr->length = EndGetI32(buf);
169 }
170 else {
171 return MSPACK_ERR_SIGNATURE;
172 }
173 return MSPACK_ERR_OK;
174}
175
176/***************************************
177 * SZDDD_EXTRACT
178 ***************************************
179 * decompresses an SZDD file
180 */
181static int szddd_extract(struct msszdd_decompressor *base,
182 struct msszddd_header *hdr, const char *filename)
183{
184 struct msszdd_decompressor_p *self = (struct msszdd_decompressor_p *) base;
185 struct mspack_file *fh, *outfh;
186 struct mspack_system *sys;
187 off_t data_offset;
188
189 if (!self) return MSPACK_ERR_ARGS;
190 if (!hdr) return self->error = MSPACK_ERR_ARGS;
191 sys = self->system;
192
193 fh = ((struct msszddd_header_p *) hdr)->fh;
194
195 /* seek to the compressed data */
196 data_offset = (hdr->format == MSSZDD_FMT_NORMAL) ? 14 : 12;
197 if (sys->seek(fh, data_offset, MSPACK_SYS_SEEK_START)) {
198 return self->error = MSPACK_ERR_SEEK;
199 }
200
201 /* open file for output */
202 if (!(outfh = sys->open(sys, filename, MSPACK_SYS_OPEN_WRITE))) {
203 return self->error = MSPACK_ERR_OPEN;
204 }
205
206 /* decompress the data */
207 self->error = lzss_decompress(sys, fh, outfh, SZDD_INPUT_SIZE,
208 hdr->format == MSSZDD_FMT_NORMAL
209 ? LZSS_MODE_EXPAND
210 : LZSS_MODE_QBASIC);
211
212 /* close output file */
213 sys->close(outfh);
214
215 return self->error;
216}
217
218/***************************************
219 * SZDDD_DECOMPRESS
220 ***************************************
221 * unpacks directly from input to output
222 */
223static int szddd_decompress(struct msszdd_decompressor *base,
224 const char *input, const char *output)
225{
226 struct msszdd_decompressor_p *self = (struct msszdd_decompressor_p *) base;
227 struct msszddd_header *hdr;
228 int error;
229
230 if (!self) return MSPACK_ERR_ARGS;
231
232 if (!(hdr = szddd_open(base, input))) return self->error;
233 error = szddd_extract(base, hdr, output);
234 szddd_close(base, hdr);
235 return self->error = error;
236}
237
238/***************************************
239 * SZDDD_ERROR
240 ***************************************
241 * returns the last error that occurred
242 */
243static int szddd_error(struct msszdd_decompressor *base)
244{
245 struct msszdd_decompressor_p *self = (struct msszdd_decompressor_p *) base;
246 return (self) ? self->error : MSPACK_ERR_ARGS;
247}
diff --git a/utils/rbutilqt/msvc/Makefile b/utils/rbutilqt/msvc/Makefile
new file mode 100644
index 0000000000..014e7c87a2
--- /dev/null
+++ b/utils/rbutilqt/msvc/Makefile
@@ -0,0 +1,61 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6#
7
8ifndef V
9SILENT = @
10endif
11# The rbspeex Makefile has problems with msys' path mangling as well as running
12# MSVC's lib tool. Use TOP instead of pwd. This means the resulting files will
13# always be placed in this folder.
14# On Linux use the current folder instead.
15TOP := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
16
17LIBS = ipodpatcher sansapatcher chinachippatcher \
18 mkamsboot mkimxboot mkmpioboot mktccboot \
19 ucl rbspeex
20
21# on Windows uname is not available. However, the environment variable OS holds
22# Windows_NT so check that instead.
23ifneq ($(OS),Windows_NT)
24PWD=$(shell pwd)
25RM=rm -rf
26all: dll
27else
28PWD=$(abspath $(TOP))
29RM=del /q /f
30all: lib
31endif
32
33CC=gcc
34dll: $(addsuffix .dll,$(LIBS))
35
36ucl.dll:
37 $(SILENT)$(MAKE) -C ../../../tools/ucl/src \
38 TARGET_DIR=$(PWD)/ OBJDIR=$(PWD)/build-dll/$(basename $@) \
39 CROSS=$(CROSS) CC=$(CC) APPVERSION=dll dll
40rbspeex.dll:
41 $(SILENT)$(MAKE) -C ../../../tools/rbspeex \
42 TARGET_DIR=$(PWD)/ BUILD_DIR=$(PWD)/build-dll/$(basename $@) \
43 CROSS=$(CROSS) CC=$(CC) STATIC=1 APPVERSION=dll dll
44
45%.dll:
46 $(SILENT)$(MAKE) -C ../../$(basename $@) \
47 TARGET_DIR=$(PWD)/ BUILD_DIR=$(PWD)/build-dll/$(basename $@) \
48 CROSS=$(CROSS) CC=$(CC) APPVERSION=dll dll
49
50lib: $(addsuffix .lib,$(LIBS))
51
52%.lib: %.dll
53 @echo LIB $@
54 @lib /machine:x86 /nologo /def:$(basename $<).def
55
56clean:
57 $(RM) $(addsuffix .dll,$(LIBS))
58 $(RM) $(addsuffix .def,$(LIBS))
59 $(RM) $(addsuffix .exp,$(LIBS))
60 $(RM) $(addsuffix .lib,$(LIBS))
61 $(RM) build-dll
diff --git a/utils/rbutilqt/msvc/README b/utils/rbutilqt/msvc/README
new file mode 100644
index 0000000000..eedec271a1
--- /dev/null
+++ b/utils/rbutilqt/msvc/README
@@ -0,0 +1,106 @@
1Rockbox Utility with Visual Studio
2==================================
3
4This document describes how to build Rockbox Utility using Visual Studio.
5
6*Note*: building with Visual Studio is only useful for debugging / development.
7Since several parts used by Rockbox Utility can't be compiled using Visual
8Studio at all using DLLs is required. For distributing we want a statically
9linked binary, which does not work this way. Building with MinGW is much easier
10in general, since using VS requires the use of MinGW as well.
11
12All of the steps described below are to be performed in the folder this file is
13located in on a command prompt (cmd.exe on Windows). All paths stated are the
14default paths on an english Windows XP setup. You might need to adjust them to
15your system.
16
17Steps
18-----
19Building with VS requires several steps:
201. Prepare your build environment
212. Build DLLs using MinGW for the parts that cannot be compiled with VS and
22 create LIB files from the DLLs. This requires using tools from VS.
233. Create a VS project file
244. Build the remaining code using VS.
25
26Preparing the build environment
27-------------------------------
28The DLLs can be cross compiled on Linux. Everything else has to be done on
29Windows. If you decide to cross compile, you need to install:
30- Linux
31 - MinGW toolchain
32- Windows
33 - MinGW with (at least) the mingw32-make package.
34 - Visual Studio 2008 (other versions might work but are not tested. Express
35 version is sufficient).
36 - Windows Platform SDK (in case you're using the Express version of VS,
37 otherwise this is included in VS)
38 - Qt SDK for VS.
39
40If you decide to not cross compile the DLLs you need to install additionally to
41the programs listed above on Windows:
42- MinGW with the following packages (and their dependencies):
43 - mingw32-gcc
44 - mingw32-make
45 - msys-coreutils
46 - msys-sed
47 - msys-bash
48 - msys-grep
49
50On Windows, open a command prompt and set up your path:
51
52 set PATH=c:\MinGW\bin;c:\MinGW\msys\1.0\bin;%PATH%
53 c:\Program Files\Microsoft Visual Studio 9\Common7\Tools\vsvars.bat
54
55
56Building DLLs and LIBs
57----------------------
58On Linux, run
59
60 make CROSS=i686-pc-mingw32-
61
62Adjust the CROSS variable to the prefix of your cross compiler. This will
63create the DLL files only. Copy the resulting DLL and DEF files to the Windows
64machine, then proceed with the Windows instructions below. The Makefile will
65not remake the DLLs if they are already present.
66
67On Windows, run
68
69 mingw32-make
70
71This will build the DLL files (if missing) and create LIB files from them.
72
73
74Create translations
75-------------------
76Create the translations .qm files. This is only necessary if qmake has been
77called without -config dbg (in which case translations will be left out and not
78compiled into the binary)
79
80 c:\QtSDK\Desktop\Qt\4.7.4\msvc2008\bin\lrelease.exe ..\rbutilqt.pro
81
82
83Create a VS project file
84------------------------
85To create a project file for VS, run
86
87 c:\QtSDK\Desktop\Qt\4.7.4\msvc2008\bin\qmake.exe -tp vc ..
88
89This creates a file RockboxUtility.vcproj.
90
91
92Build using VS
93--------------
94Open the generated project file and build as usual with VS.
95
96
97LICENSE INFORMATION
98===================
99This folder contains additional files necessary for building.
100
101- stdbool.h: taken form clang 2.8
102- stdint.h, inttypes.h: taken from the msinttypes project
103 (http://code.google.com/p/msinttypes) r26.
104
105See the source files for detailed license information.
106
diff --git a/utils/rbutilqt/msvc/inttypes.h b/utils/rbutilqt/msvc/inttypes.h
new file mode 100644
index 0000000000..4b3828a216
--- /dev/null
+++ b/utils/rbutilqt/msvc/inttypes.h
@@ -0,0 +1,305 @@
1// ISO C9x compliant inttypes.h for Microsoft Visual Studio
2// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
3//
4// Copyright (c) 2006 Alexander Chemeris
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are met:
8//
9// 1. Redistributions of source code must retain the above copyright notice,
10// this list of conditions and the following disclaimer.
11//
12// 2. Redistributions in binary form must reproduce the above copyright
13// notice, this list of conditions and the following disclaimer in the
14// documentation and/or other materials provided with the distribution.
15//
16// 3. The name of the author may be used to endorse or promote products
17// derived from this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
20// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
22// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30///////////////////////////////////////////////////////////////////////////////
31
32#ifndef _MSC_VER // [
33#error "Use this header only with Microsoft Visual C++ compilers!"
34#endif // _MSC_VER ]
35
36#ifndef _MSC_INTTYPES_H_ // [
37#define _MSC_INTTYPES_H_
38
39#if _MSC_VER > 1000
40#pragma once
41#endif
42
43#include "stdint.h"
44
45// 7.8 Format conversion of integer types
46
47typedef struct {
48 intmax_t quot;
49 intmax_t rem;
50} imaxdiv_t;
51
52// 7.8.1 Macros for format specifiers
53
54#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
55
56// The fprintf macros for signed integers are:
57#define PRId8 "d"
58#define PRIi8 "i"
59#define PRIdLEAST8 "d"
60#define PRIiLEAST8 "i"
61#define PRIdFAST8 "d"
62#define PRIiFAST8 "i"
63
64#define PRId16 "hd"
65#define PRIi16 "hi"
66#define PRIdLEAST16 "hd"
67#define PRIiLEAST16 "hi"
68#define PRIdFAST16 "hd"
69#define PRIiFAST16 "hi"
70
71#define PRId32 "I32d"
72#define PRIi32 "I32i"
73#define PRIdLEAST32 "I32d"
74#define PRIiLEAST32 "I32i"
75#define PRIdFAST32 "I32d"
76#define PRIiFAST32 "I32i"
77
78#define PRId64 "I64d"
79#define PRIi64 "I64i"
80#define PRIdLEAST64 "I64d"
81#define PRIiLEAST64 "I64i"
82#define PRIdFAST64 "I64d"
83#define PRIiFAST64 "I64i"
84
85#define PRIdMAX "I64d"
86#define PRIiMAX "I64i"
87
88#define PRIdPTR "Id"
89#define PRIiPTR "Ii"
90
91// The fprintf macros for unsigned integers are:
92#define PRIo8 "o"
93#define PRIu8 "u"
94#define PRIx8 "x"
95#define PRIX8 "X"
96#define PRIoLEAST8 "o"
97#define PRIuLEAST8 "u"
98#define PRIxLEAST8 "x"
99#define PRIXLEAST8 "X"
100#define PRIoFAST8 "o"
101#define PRIuFAST8 "u"
102#define PRIxFAST8 "x"
103#define PRIXFAST8 "X"
104
105#define PRIo16 "ho"
106#define PRIu16 "hu"
107#define PRIx16 "hx"
108#define PRIX16 "hX"
109#define PRIoLEAST16 "ho"
110#define PRIuLEAST16 "hu"
111#define PRIxLEAST16 "hx"
112#define PRIXLEAST16 "hX"
113#define PRIoFAST16 "ho"
114#define PRIuFAST16 "hu"
115#define PRIxFAST16 "hx"
116#define PRIXFAST16 "hX"
117
118#define PRIo32 "I32o"
119#define PRIu32 "I32u"
120#define PRIx32 "I32x"
121#define PRIX32 "I32X"
122#define PRIoLEAST32 "I32o"
123#define PRIuLEAST32 "I32u"
124#define PRIxLEAST32 "I32x"
125#define PRIXLEAST32 "I32X"
126#define PRIoFAST32 "I32o"
127#define PRIuFAST32 "I32u"
128#define PRIxFAST32 "I32x"
129#define PRIXFAST32 "I32X"
130
131#define PRIo64 "I64o"
132#define PRIu64 "I64u"
133#define PRIx64 "I64x"
134#define PRIX64 "I64X"
135#define PRIoLEAST64 "I64o"
136#define PRIuLEAST64 "I64u"
137#define PRIxLEAST64 "I64x"
138#define PRIXLEAST64 "I64X"
139#define PRIoFAST64 "I64o"
140#define PRIuFAST64 "I64u"
141#define PRIxFAST64 "I64x"
142#define PRIXFAST64 "I64X"
143
144#define PRIoMAX "I64o"
145#define PRIuMAX "I64u"
146#define PRIxMAX "I64x"
147#define PRIXMAX "I64X"
148
149#define PRIoPTR "Io"
150#define PRIuPTR "Iu"
151#define PRIxPTR "Ix"
152#define PRIXPTR "IX"
153
154// The fscanf macros for signed integers are:
155#define SCNd8 "d"
156#define SCNi8 "i"
157#define SCNdLEAST8 "d"
158#define SCNiLEAST8 "i"
159#define SCNdFAST8 "d"
160#define SCNiFAST8 "i"
161
162#define SCNd16 "hd"
163#define SCNi16 "hi"
164#define SCNdLEAST16 "hd"
165#define SCNiLEAST16 "hi"
166#define SCNdFAST16 "hd"
167#define SCNiFAST16 "hi"
168
169#define SCNd32 "ld"
170#define SCNi32 "li"
171#define SCNdLEAST32 "ld"
172#define SCNiLEAST32 "li"
173#define SCNdFAST32 "ld"
174#define SCNiFAST32 "li"
175
176#define SCNd64 "I64d"
177#define SCNi64 "I64i"
178#define SCNdLEAST64 "I64d"
179#define SCNiLEAST64 "I64i"
180#define SCNdFAST64 "I64d"
181#define SCNiFAST64 "I64i"
182
183#define SCNdMAX "I64d"
184#define SCNiMAX "I64i"
185
186#ifdef _WIN64 // [
187# define SCNdPTR "I64d"
188# define SCNiPTR "I64i"
189#else // _WIN64 ][
190# define SCNdPTR "ld"
191# define SCNiPTR "li"
192#endif // _WIN64 ]
193
194// The fscanf macros for unsigned integers are:
195#define SCNo8 "o"
196#define SCNu8 "u"
197#define SCNx8 "x"
198#define SCNX8 "X"
199#define SCNoLEAST8 "o"
200#define SCNuLEAST8 "u"
201#define SCNxLEAST8 "x"
202#define SCNXLEAST8 "X"
203#define SCNoFAST8 "o"
204#define SCNuFAST8 "u"
205#define SCNxFAST8 "x"
206#define SCNXFAST8 "X"
207
208#define SCNo16 "ho"
209#define SCNu16 "hu"
210#define SCNx16 "hx"
211#define SCNX16 "hX"
212#define SCNoLEAST16 "ho"
213#define SCNuLEAST16 "hu"
214#define SCNxLEAST16 "hx"
215#define SCNXLEAST16 "hX"
216#define SCNoFAST16 "ho"
217#define SCNuFAST16 "hu"
218#define SCNxFAST16 "hx"
219#define SCNXFAST16 "hX"
220
221#define SCNo32 "lo"
222#define SCNu32 "lu"
223#define SCNx32 "lx"
224#define SCNX32 "lX"
225#define SCNoLEAST32 "lo"
226#define SCNuLEAST32 "lu"
227#define SCNxLEAST32 "lx"
228#define SCNXLEAST32 "lX"
229#define SCNoFAST32 "lo"
230#define SCNuFAST32 "lu"
231#define SCNxFAST32 "lx"
232#define SCNXFAST32 "lX"
233
234#define SCNo64 "I64o"
235#define SCNu64 "I64u"
236#define SCNx64 "I64x"
237#define SCNX64 "I64X"
238#define SCNoLEAST64 "I64o"
239#define SCNuLEAST64 "I64u"
240#define SCNxLEAST64 "I64x"
241#define SCNXLEAST64 "I64X"
242#define SCNoFAST64 "I64o"
243#define SCNuFAST64 "I64u"
244#define SCNxFAST64 "I64x"
245#define SCNXFAST64 "I64X"
246
247#define SCNoMAX "I64o"
248#define SCNuMAX "I64u"
249#define SCNxMAX "I64x"
250#define SCNXMAX "I64X"
251
252#ifdef _WIN64 // [
253# define SCNoPTR "I64o"
254# define SCNuPTR "I64u"
255# define SCNxPTR "I64x"
256# define SCNXPTR "I64X"
257#else // _WIN64 ][
258# define SCNoPTR "lo"
259# define SCNuPTR "lu"
260# define SCNxPTR "lx"
261# define SCNXPTR "lX"
262#endif // _WIN64 ]
263
264#endif // __STDC_FORMAT_MACROS ]
265
266// 7.8.2 Functions for greatest-width integer types
267
268// 7.8.2.1 The imaxabs function
269#define imaxabs _abs64
270
271// 7.8.2.2 The imaxdiv function
272
273// This is modified version of div() function from Microsoft's div.c found
274// in %MSVC.NET%\crt\src\div.c
275#ifdef STATIC_IMAXDIV // [
276static
277#else // STATIC_IMAXDIV ][
278_inline
279#endif // STATIC_IMAXDIV ]
280imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
281{
282 imaxdiv_t result;
283
284 result.quot = numer / denom;
285 result.rem = numer % denom;
286
287 if (numer < 0 && result.rem > 0) {
288 // did division wrong; must fix up
289 ++result.quot;
290 result.rem -= denom;
291 }
292
293 return result;
294}
295
296// 7.8.2.3 The strtoimax and strtoumax functions
297#define strtoimax _strtoi64
298#define strtoumax _strtoui64
299
300// 7.8.2.4 The wcstoimax and wcstoumax functions
301#define wcstoimax _wcstoi64
302#define wcstoumax _wcstoui64
303
304
305#endif // _MSC_INTTYPES_H_ ]
diff --git a/utils/rbutilqt/msvc/stdbool.h b/utils/rbutilqt/msvc/stdbool.h
new file mode 100644
index 0000000000..e44a1f9a97
--- /dev/null
+++ b/utils/rbutilqt/msvc/stdbool.h
@@ -0,0 +1,38 @@
1/*===---- stdbool.h - Standard header for booleans -------------------------===
2 *
3 * Copyright (c) 2008 Eli Friedman
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 *
23 *===-----------------------------------------------------------------------===
24 */
25
26#ifndef __STDBOOL_H
27#define __STDBOOL_H
28
29/* Don't define bool, true, and false in C++ */
30#ifndef __cplusplus
31#define bool _Bool
32#define true 1
33#define false 0
34#endif
35
36#define __bool_true_false_are_defined 1
37
38#endif /* __STDBOOL_H */
diff --git a/utils/rbutilqt/msvc/stdint.h b/utils/rbutilqt/msvc/stdint.h
new file mode 100644
index 0000000000..d02608a597
--- /dev/null
+++ b/utils/rbutilqt/msvc/stdint.h
@@ -0,0 +1,247 @@
1// ISO C9x compliant stdint.h for Microsoft Visual Studio
2// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
3//
4// Copyright (c) 2006-2008 Alexander Chemeris
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are met:
8//
9// 1. Redistributions of source code must retain the above copyright notice,
10// this list of conditions and the following disclaimer.
11//
12// 2. Redistributions in binary form must reproduce the above copyright
13// notice, this list of conditions and the following disclaimer in the
14// documentation and/or other materials provided with the distribution.
15//
16// 3. The name of the author may be used to endorse or promote products
17// derived from this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
20// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
22// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30///////////////////////////////////////////////////////////////////////////////
31
32#ifndef _MSC_VER // [
33#error "Use this header only with Microsoft Visual C++ compilers!"
34#endif // _MSC_VER ]
35
36#ifndef _MSC_STDINT_H_ // [
37#define _MSC_STDINT_H_
38
39#if _MSC_VER > 1000
40#pragma once
41#endif
42
43#include <limits.h>
44
45// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
46// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
47// or compiler give many errors like this:
48// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
49#ifdef __cplusplus
50extern "C" {
51#endif
52# include <wchar.h>
53#ifdef __cplusplus
54}
55#endif
56
57// Define _W64 macros to mark types changing their size, like intptr_t.
58#ifndef _W64
59# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
60# define _W64 __w64
61# else
62# define _W64
63# endif
64#endif
65
66
67// 7.18.1 Integer types
68
69// 7.18.1.1 Exact-width integer types
70
71// Visual Studio 6 and Embedded Visual C++ 4 doesn't
72// realize that, e.g. char has the same size as __int8
73// so we give up on __intX for them.
74#if (_MSC_VER < 1300)
75 typedef signed char int8_t;
76 typedef signed short int16_t;
77 typedef signed int int32_t;
78 typedef unsigned char uint8_t;
79 typedef unsigned short uint16_t;
80 typedef unsigned int uint32_t;
81#else
82 typedef signed __int8 int8_t;
83 typedef signed __int16 int16_t;
84 typedef signed __int32 int32_t;
85 typedef unsigned __int8 uint8_t;
86 typedef unsigned __int16 uint16_t;
87 typedef unsigned __int32 uint32_t;
88#endif
89typedef signed __int64 int64_t;
90typedef unsigned __int64 uint64_t;
91
92
93// 7.18.1.2 Minimum-width integer types
94typedef int8_t int_least8_t;
95typedef int16_t int_least16_t;
96typedef int32_t int_least32_t;
97typedef int64_t int_least64_t;
98typedef uint8_t uint_least8_t;
99typedef uint16_t uint_least16_t;
100typedef uint32_t uint_least32_t;
101typedef uint64_t uint_least64_t;
102
103// 7.18.1.3 Fastest minimum-width integer types
104typedef int8_t int_fast8_t;
105typedef int16_t int_fast16_t;
106typedef int32_t int_fast32_t;
107typedef int64_t int_fast64_t;
108typedef uint8_t uint_fast8_t;
109typedef uint16_t uint_fast16_t;
110typedef uint32_t uint_fast32_t;
111typedef uint64_t uint_fast64_t;
112
113// 7.18.1.4 Integer types capable of holding object pointers
114#ifdef _WIN64 // [
115 typedef signed __int64 intptr_t;
116 typedef unsigned __int64 uintptr_t;
117#else // _WIN64 ][
118 typedef _W64 signed int intptr_t;
119 typedef _W64 unsigned int uintptr_t;
120#endif // _WIN64 ]
121
122// 7.18.1.5 Greatest-width integer types
123typedef int64_t intmax_t;
124typedef uint64_t uintmax_t;
125
126
127// 7.18.2 Limits of specified-width integer types
128
129#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
130
131// 7.18.2.1 Limits of exact-width integer types
132#define INT8_MIN ((int8_t)_I8_MIN)
133#define INT8_MAX _I8_MAX
134#define INT16_MIN ((int16_t)_I16_MIN)
135#define INT16_MAX _I16_MAX
136#define INT32_MIN ((int32_t)_I32_MIN)
137#define INT32_MAX _I32_MAX
138#define INT64_MIN ((int64_t)_I64_MIN)
139#define INT64_MAX _I64_MAX
140#define UINT8_MAX _UI8_MAX
141#define UINT16_MAX _UI16_MAX
142#define UINT32_MAX _UI32_MAX
143#define UINT64_MAX _UI64_MAX
144
145// 7.18.2.2 Limits of minimum-width integer types
146#define INT_LEAST8_MIN INT8_MIN
147#define INT_LEAST8_MAX INT8_MAX
148#define INT_LEAST16_MIN INT16_MIN
149#define INT_LEAST16_MAX INT16_MAX
150#define INT_LEAST32_MIN INT32_MIN
151#define INT_LEAST32_MAX INT32_MAX
152#define INT_LEAST64_MIN INT64_MIN
153#define INT_LEAST64_MAX INT64_MAX
154#define UINT_LEAST8_MAX UINT8_MAX
155#define UINT_LEAST16_MAX UINT16_MAX
156#define UINT_LEAST32_MAX UINT32_MAX
157#define UINT_LEAST64_MAX UINT64_MAX
158
159// 7.18.2.3 Limits of fastest minimum-width integer types
160#define INT_FAST8_MIN INT8_MIN
161#define INT_FAST8_MAX INT8_MAX
162#define INT_FAST16_MIN INT16_MIN
163#define INT_FAST16_MAX INT16_MAX
164#define INT_FAST32_MIN INT32_MIN
165#define INT_FAST32_MAX INT32_MAX
166#define INT_FAST64_MIN INT64_MIN
167#define INT_FAST64_MAX INT64_MAX
168#define UINT_FAST8_MAX UINT8_MAX
169#define UINT_FAST16_MAX UINT16_MAX
170#define UINT_FAST32_MAX UINT32_MAX
171#define UINT_FAST64_MAX UINT64_MAX
172
173// 7.18.2.4 Limits of integer types capable of holding object pointers
174#ifdef _WIN64 // [
175# define INTPTR_MIN INT64_MIN
176# define INTPTR_MAX INT64_MAX
177# define UINTPTR_MAX UINT64_MAX
178#else // _WIN64 ][
179# define INTPTR_MIN INT32_MIN
180# define INTPTR_MAX INT32_MAX
181# define UINTPTR_MAX UINT32_MAX
182#endif // _WIN64 ]
183
184// 7.18.2.5 Limits of greatest-width integer types
185#define INTMAX_MIN INT64_MIN
186#define INTMAX_MAX INT64_MAX
187#define UINTMAX_MAX UINT64_MAX
188
189// 7.18.3 Limits of other integer types
190
191#ifdef _WIN64 // [
192# define PTRDIFF_MIN _I64_MIN
193# define PTRDIFF_MAX _I64_MAX
194#else // _WIN64 ][
195# define PTRDIFF_MIN _I32_MIN
196# define PTRDIFF_MAX _I32_MAX
197#endif // _WIN64 ]
198
199#define SIG_ATOMIC_MIN INT_MIN
200#define SIG_ATOMIC_MAX INT_MAX
201
202#ifndef SIZE_MAX // [
203# ifdef _WIN64 // [
204# define SIZE_MAX _UI64_MAX
205# else // _WIN64 ][
206# define SIZE_MAX _UI32_MAX
207# endif // _WIN64 ]
208#endif // SIZE_MAX ]
209
210// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
211#ifndef WCHAR_MIN // [
212# define WCHAR_MIN 0
213#endif // WCHAR_MIN ]
214#ifndef WCHAR_MAX // [
215# define WCHAR_MAX _UI16_MAX
216#endif // WCHAR_MAX ]
217
218#define WINT_MIN 0
219#define WINT_MAX _UI16_MAX
220
221#endif // __STDC_LIMIT_MACROS ]
222
223
224// 7.18.4 Limits of other integer types
225
226#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
227
228// 7.18.4.1 Macros for minimum-width integer constants
229
230#define INT8_C(val) val##i8
231#define INT16_C(val) val##i16
232#define INT32_C(val) val##i32
233#define INT64_C(val) val##i64
234
235#define UINT8_C(val) val##ui8
236#define UINT16_C(val) val##ui16
237#define UINT32_C(val) val##ui32
238#define UINT64_C(val) val##ui64
239
240// 7.18.4.2 Macros for greatest-width integer constants
241#define INTMAX_C INT64_C
242#define UINTMAX_C UINT64_C
243
244#endif // __STDC_CONSTANT_MACROS ]
245
246
247#endif // _MSC_STDINT_H_ ]
diff --git a/utils/rbutilqt/preview.cpp b/utils/rbutilqt/preview.cpp
new file mode 100644
index 0000000000..5006a03a09
--- /dev/null
+++ b/utils/rbutilqt/preview.cpp
@@ -0,0 +1,122 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QDialog>
20#include <QMouseEvent>
21
22#include "preview.h"
23
24PreviewDlg::PreviewDlg(QWidget *parent) : QDialog(parent)
25{
26 ui.setupUi(this);
27 this->setModal(true);
28 this->setMouseTracking(true);
29 this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
30
31}
32
33void PreviewDlg::setText(QString text)
34{
35 ui.themePreview->setText(text);
36}
37
38void PreviewDlg::setPixmap(QPixmap p)
39{
40 ui.themePreview->setFixedSize(p.size());
41 this->resize(QSize(10,10));
42 ui.themePreview->setPixmap(p);
43}
44
45void PreviewDlg::mouseMoveEvent(QMouseEvent * event)
46{
47 (void) event;
48 this->close();
49}
50
51void PreviewDlg::leaveEvent(QEvent * event)
52{
53 (void) event;
54 this->close();
55}
56
57
58void PreviewDlg::changeEvent(QEvent *e)
59{
60 if(e->type() == QEvent::LanguageChange) {
61 ui.retranslateUi(this);
62 } else {
63 QWidget::changeEvent(e);
64 }
65}
66
67PreviewLabel::PreviewLabel(QWidget * parent, Qt::WindowFlags f)
68 :QLabel(parent,f)
69{
70 this->setMouseTracking(true);
71
72 preview = new PreviewDlg(parent);
73
74 hovertimer.setInterval(1500); // wait for 1.5 seconds before showing the Fullsize Preview
75 hovertimer.setSingleShot(true);
76 connect(&hovertimer,SIGNAL(timeout ()),this,SLOT(timeout()));
77}
78
79void PreviewLabel::mouseMoveEvent(QMouseEvent * event)
80{
81 hovertimer.start();
82 mousepos = event->globalPos();
83}
84void PreviewLabel::enterEvent(QEvent * event)
85{
86 (void) event;
87 hovertimer.start();
88}
89void PreviewLabel::leaveEvent(QEvent * event)
90{
91 (void) event;
92 hovertimer.stop();
93}
94
95void PreviewLabel::timeout()
96{
97 preview->move(mousepos.x() - (preview->width() / 2),
98 mousepos.y() - (preview->height() / 2));
99 preview->setVisible(true);
100}
101
102void PreviewLabel::setPixmap(QPixmap p)
103{
104 // set the image for the Fullsize Preview
105 preview->setPixmap(p);
106
107 //scale the image for use in the label
108 QSize img;
109 img.setHeight(this->height());
110 img.setWidth(this->width());
111 QPixmap q;
112 q = p.scaled(img, Qt::KeepAspectRatio, Qt::SmoothTransformation);
113 this->setScaledContents(false);
114 QLabel::setPixmap(q);
115}
116
117void PreviewLabel::setText(QString text)
118{
119 QLabel::setText(text);
120 preview->setText(text);
121}
122
diff --git a/utils/rbutilqt/preview.h b/utils/rbutilqt/preview.h
new file mode 100644
index 0000000000..7462413f0a
--- /dev/null
+++ b/utils/rbutilqt/preview.h
@@ -0,0 +1,74 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#ifndef PREVIEW_H
22#define PREVIEW_H
23
24#include <QDialog>
25#include <QLabel>
26#include <QTimer>
27
28#include "ui_previewfrm.h"
29
30
31class PreviewDlg : public QDialog
32{
33 Q_OBJECT
34
35public:
36 PreviewDlg(QWidget *parent = nullptr);
37 void setPixmap(QPixmap p);
38 void setText(QString text);
39
40private slots:
41 void changeEvent(QEvent *event);
42 void mouseMoveEvent(QMouseEvent * event);
43 void leaveEvent(QEvent * event);
44
45private:
46 Ui::PreviewFrm ui;
47
48
49};
50
51
52class PreviewLabel : public QLabel
53{
54 Q_OBJECT
55
56public:
57 PreviewLabel(QWidget * parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
58
59 void setPixmap(QPixmap p);
60 void setText(QString text);
61private slots:
62 void mouseMoveEvent(QMouseEvent * event);
63 void enterEvent(QEvent * event);
64 void leaveEvent(QEvent * event);
65 void timeout();
66
67private:
68 QTimer hovertimer;
69 QPoint mousepos;
70 PreviewDlg* preview;
71};
72
73
74#endif
diff --git a/utils/rbutilqt/previewfrm.ui b/utils/rbutilqt/previewfrm.ui
new file mode 100644
index 0000000000..359887bfed
--- /dev/null
+++ b/utils/rbutilqt/previewfrm.ui
@@ -0,0 +1,90 @@
1<ui version="4.0" >
2 <class>PreviewFrm</class>
3 <widget class="QDialog" name="PreviewFrm" >
4 <property name="enabled" >
5 <bool>true</bool>
6 </property>
7 <property name="geometry" >
8 <rect>
9 <x>0</x>
10 <y>0</y>
11 <width>266</width>
12 <height>214</height>
13 </rect>
14 </property>
15 <property name="windowTitle" >
16 <string>Preview</string>
17 </property>
18 <layout class="QHBoxLayout" >
19 <property name="spacing" >
20 <number>0</number>
21 </property>
22 <property name="leftMargin" >
23 <number>1</number>
24 </property>
25 <property name="topMargin" >
26 <number>1</number>
27 </property>
28 <property name="rightMargin" >
29 <number>1</number>
30 </property>
31 <property name="bottomMargin" >
32 <number>1</number>
33 </property>
34 <item>
35 <widget class="QGroupBox" name="groupBox" >
36 <property name="acceptDrops" >
37 <bool>false</bool>
38 </property>
39 <property name="autoFillBackground" >
40 <bool>false</bool>
41 </property>
42 <property name="title" >
43 <string/>
44 </property>
45 <layout class="QHBoxLayout" >
46 <property name="spacing" >
47 <number>0</number>
48 </property>
49 <property name="leftMargin" >
50 <number>1</number>
51 </property>
52 <property name="topMargin" >
53 <number>1</number>
54 </property>
55 <property name="rightMargin" >
56 <number>1</number>
57 </property>
58 <property name="bottomMargin" >
59 <number>1</number>
60 </property>
61 <item>
62 <widget class="QLabel" name="themePreview" >
63 <property name="enabled" >
64 <bool>true</bool>
65 </property>
66 <property name="sizePolicy" >
67 <sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
68 <horstretch>0</horstretch>
69 <verstretch>0</verstretch>
70 </sizepolicy>
71 </property>
72 <property name="text" >
73 <string/>
74 </property>
75 <property name="scaledContents" >
76 <bool>false</bool>
77 </property>
78 <property name="alignment" >
79 <set>Qt::AlignCenter</set>
80 </property>
81 </widget>
82 </item>
83 </layout>
84 </widget>
85 </item>
86 </layout>
87 </widget>
88 <resources/>
89 <connections/>
90</ui>
diff --git a/utils/rbutilqt/progressloggerfrm.ui b/utils/rbutilqt/progressloggerfrm.ui
new file mode 100644
index 0000000000..0fa6b79269
--- /dev/null
+++ b/utils/rbutilqt/progressloggerfrm.ui
@@ -0,0 +1,101 @@
1<ui version="4.0" >
2 <class>ProgressLoggerFrm</class>
3 <widget class="QDialog" name="ProgressLoggerFrm" >
4 <property name="geometry" >
5 <rect>
6 <x>0</x>
7 <y>0</y>
8 <!-- Larger progress window - quick workaround to avoid user confusion
9 during iPod Classic 6G bootloader installation. Due to progress
10 scroll, many users (including me) are confused and do not realize
11 an important action message.
12 -->
13 <width>360</width>
14 <height>560</height>
15 </rect>
16 </property>
17 <property name="windowTitle" >
18 <string>Progress</string>
19 </property>
20 <layout class="QGridLayout" name="gridLayout" >
21 <item row="0" column="0" >
22 <widget class="QLabel" name="labelHeader" >
23 <property name="text" >
24 <string>Progress</string>
25 </property>
26 <property name="wordWrap" >
27 <bool>true</bool>
28 </property>
29 </widget>
30 </item>
31 <item row="1" column="0" colspan="3" >
32 <widget class="QListWidget" name="listProgress" >
33 <property name="focusPolicy" >
34 <enum>Qt::TabFocus</enum>
35 </property>
36 <property name="accessibleName" >
37 <string>progresswindow</string>
38 </property>
39 <property name="tabKeyNavigation" >
40 <bool>true</bool>
41 </property>
42 <property name="selectionBehavior" >
43 <enum>QAbstractItemView::SelectRows</enum>
44 </property>
45 <property name="wordWrap" >
46 <bool>true</bool>
47 </property>
48 </widget>
49 </item>
50 <item row="2" column="0" colspan="3" >
51 <widget class="QProgressBar" name="progressBar" >
52 <property name="value" >
53 <number>0</number>
54 </property>
55 </widget>
56 </item>
57 <item row="3" column="0" >
58 <widget class="QPushButton" name="saveLog" >
59 <property name="enabled" >
60 <bool>true</bool>
61 </property>
62 <property name="text" >
63 <string>Save Log</string>
64 </property>
65 <property name="icon" >
66 <iconset resource="rbutilqt.qrc" >
67 <normaloff>:/icons/document-save.svg</normaloff>:/icons/document-save.svg</iconset>
68 </property>
69 </widget>
70 </item>
71 <item row="3" column="1" >
72 <spacer>
73 <property name="orientation" >
74 <enum>Qt::Horizontal</enum>
75 </property>
76 <property name="sizeHint" stdset="0" >
77 <size>
78 <width>40</width>
79 <height>20</height>
80 </size>
81 </property>
82 </spacer>
83 </item>
84 <item row="3" column="2" >
85 <widget class="QPushButton" name="buttonAbort" >
86 <property name="text" >
87 <string>&amp;Abort</string>
88 </property>
89 <property name="icon" >
90 <iconset resource="rbutilqt.qrc" >
91 <normaloff>:/icons/process-stop.svg</normaloff>:/icons/process-stop.svg</iconset>
92 </property>
93 </widget>
94 </item>
95 </layout>
96 </widget>
97 <resources>
98 <include location="rbutilqt.qrc" />
99 </resources>
100 <connections/>
101</ui>
diff --git a/utils/rbutilqt/progressloggergui.cpp b/utils/rbutilqt/progressloggergui.cpp
new file mode 100644
index 0000000000..37e0908ae0
--- /dev/null
+++ b/utils/rbutilqt/progressloggergui.cpp
@@ -0,0 +1,186 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QFileDialog>
20#include "progressloggergui.h"
21
22#include "sysinfo.h"
23#include "systrace.h"
24
25ProgressLoggerGui::ProgressLoggerGui(QWidget* parent): ProgressloggerInterface(parent)
26{
27 downloadProgress = new QDialog(parent);
28 downloadProgress->setModal(true);
29 dp.setupUi(downloadProgress);
30 dp.listProgress->setAlternatingRowColors(true);
31 dp.saveLog->hide();
32 connect(dp.saveLog,SIGNAL(clicked()),this,SLOT(saveErrorLog()));
33 setRunning();
34}
35
36void ProgressLoggerGui::addItem(const QString &text, int flag)
37{
38 QListWidgetItem* item = new QListWidgetItem(text);
39
40 switch(flag)
41 {
42 case LOGNOICON:
43 break;
44 case LOGOK:
45 item->setIcon(QIcon(":/icons/go-next.svg"));
46 break;
47 case LOGINFO:
48 item->setIcon(QIcon(":/icons/dialog-information.svg"));
49 break;
50 case LOGWARNING:
51 item->setIcon(QIcon(":/icons/dialog-warning.svg"));
52 break;
53 case LOGERROR:
54 item->setIcon(QIcon(":/icons/dialog-error.svg"));
55 dp.saveLog->show();
56 break;
57 }
58
59 dp.listProgress->addItem(item);
60 dp.listProgress->scrollToItem(item);
61}
62
63void ProgressLoggerGui::setProgress(int value, int max)
64{
65 // set maximum first to avoid setting a value outside of the max range.
66 // If the current value is outside of the valid range QProgressBar
67 // calls reset() internally.
68 setProgressMax(max);
69 setProgressValue(value);
70}
71
72
73void ProgressLoggerGui::setProgressValue(int value)
74{
75 dp.progressBar->setValue(value);
76}
77
78void ProgressLoggerGui::setProgressMax(int max)
79{
80 dp.progressBar->setMaximum(max);
81}
82
83int ProgressLoggerGui::getProgressMax()
84{
85 return dp.progressBar->maximum();
86}
87
88void ProgressLoggerGui::setProgressVisible(bool b)
89{
90 dp.progressBar->setVisible(b);
91}
92
93
94/** Set logger into "running" state -- the reporting process is still running.
95 * Display "Abort" and emit the aborted() signal on button press.
96 */
97void ProgressLoggerGui::setRunning()
98{
99 dp.buttonAbort->setText(tr("&Abort"));
100 dp.buttonAbort->setIcon(QIcon(QString::fromUtf8(":/icons/process-stop.svg")));
101
102 // make sure to not close the window on button press.
103 disconnect(dp.buttonAbort, SIGNAL(clicked()), downloadProgress, SLOT(close()));
104 // emit aborted() once button is pressed but not closed().
105 disconnect(dp.buttonAbort, SIGNAL(clicked()), this, SIGNAL(closed()));
106 connect(dp.buttonAbort, SIGNAL(clicked()), this, SIGNAL(aborted()));
107
108}
109
110
111/** Set logger into "finished" state -- the reporting process is finished.
112 * Display "Ok". Don't emit aborted() as there is nothing running left.
113 * Close logger on button press and emit closed().
114 */
115void ProgressLoggerGui::setFinished()
116{
117 dp.buttonAbort->setText(tr("&Ok"));
118 dp.buttonAbort->setIcon(QIcon(QString::fromUtf8(":/icons/go-next.svg")));
119
120 // close the window on button press.
121 connect(dp.buttonAbort, SIGNAL(clicked()), downloadProgress, SLOT(close()));
122 // emit closed() once button is pressed but not aborted().
123 disconnect(dp.buttonAbort, SIGNAL(clicked()), this, SIGNAL(aborted()));
124 connect(dp.buttonAbort, SIGNAL(clicked()), this, SIGNAL(closed()));
125}
126
127
128void ProgressLoggerGui::close()
129{
130 downloadProgress->close();
131}
132
133void ProgressLoggerGui::show()
134{
135 downloadProgress->show();
136}
137
138void ProgressLoggerGui::saveErrorLog()
139{
140 QString filename = QFileDialog::getSaveFileName(downloadProgress,
141 tr("Save system trace log"), QDir::homePath(), "*.log");
142 if(filename.isEmpty())
143 return;
144
145 QFile file(filename);
146 if(!file.open(QIODevice::WriteOnly))
147 return;
148
149 //Logger texts
150 QString loggerTexts = "\n*********************************************\n"
151 "*************** Logger *******************\n"
152 "*********************************************\n";
153
154 file.write(loggerTexts.toUtf8(), loggerTexts.size());
155
156
157 int i=0;
158 loggerTexts = "";
159 while(dp.listProgress->item(i) != nullptr)
160 {
161 loggerTexts.append(dp.listProgress->item(i)->text());
162 loggerTexts.append("\n");
163 i++;
164 }
165 file.write(loggerTexts.toUtf8(), loggerTexts.size());
166
167 //systeminfo
168 QString info = "\n*********************************************\n"
169 "************ SYSTEMINFO *******************\n"
170 "*********************************************\n";
171
172 file.write(info.toUtf8(), info.size());
173 info = Sysinfo::getInfo(Sysinfo::InfoText);
174 file.write(info.toUtf8(), info.size());
175
176 // trace
177 QString trace = "\n*********************************************\n"
178 "*********** TRACE **************************\n"
179 "*********************************************\n";
180 file.write(trace.toUtf8(), trace.size());
181 trace = SysTrace::getTrace();
182 file.write(trace.toUtf8(), trace.size());
183
184 file.close();
185}
186
diff --git a/utils/rbutilqt/progressloggergui.h b/utils/rbutilqt/progressloggergui.h
new file mode 100644
index 0000000000..ce9a8c9fa7
--- /dev/null
+++ b/utils/rbutilqt/progressloggergui.h
@@ -0,0 +1,60 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20#ifndef PROGRESSLOGGERGUI_H
21#define PROGRESSLOGGERGUI_H
22
23#include <QWidget>
24
25#include "progressloggerinterface.h"
26#include "ui_progressloggerfrm.h"
27
28class ProgressLoggerGui :public ProgressloggerInterface
29{
30 Q_OBJECT
31public:
32 ProgressLoggerGui(QWidget * parent);
33
34 virtual void setProgressValue(int value);
35 virtual void setProgressMax(int max);
36 virtual int getProgressMax();
37 virtual void setProgressVisible(bool);
38
39signals:
40 void aborted();
41 void closed();
42
43public slots:
44 virtual void addItem(const QString &text, int flag); //! add a string to the list
45 virtual void setProgress(int, int); //! set progress bar
46
47 virtual void close();
48 virtual void show();
49 virtual void setRunning();
50 virtual void setFinished();
51
52 void saveErrorLog();
53private:
54 Ui::ProgressLoggerFrm dp;
55 QDialog *downloadProgress;
56
57};
58
59#endif
60
diff --git a/utils/rbutilqt/quazip/LICENSE.LGPL b/utils/rbutilqt/quazip/LICENSE.LGPL
new file mode 100644
index 0000000000..2cba2ac74c
--- /dev/null
+++ b/utils/rbutilqt/quazip/LICENSE.LGPL
@@ -0,0 +1,458 @@
1 GNU LESSER GENERAL PUBLIC LICENSE
2 Version 2.1, February 1999
3
4 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
6 Everyone is permitted to copy and distribute verbatim copies
7 of this license document, but changing it is not allowed.
8
9[This is the first released version of the Lesser GPL. It also counts
10 as the successor of the GNU Library Public License, version 2, hence
11 the version number 2.1.]
12
13 Preamble
14
15 The licenses for most software are designed to take away your
16freedom to share and change it. By contrast, the GNU General Public
17Licenses are intended to guarantee your freedom to share and change
18free software--to make sure the software is free for all its users.
19
20 This license, the Lesser General Public License, applies to some
21specially designated software packages--typically libraries--of the
22Free Software Foundation and other authors who decide to use it. You
23can use it too, but we suggest you first think carefully about whether
24this license or the ordinary General Public License is the better
25strategy to use in any particular case, based on the explanations below.
26
27 When we speak of free software, we are referring to freedom of use,
28not price. Our General Public Licenses are designed to make sure that
29you have the freedom to distribute copies of free software (and charge
30for this service if you wish); that you receive source code or can get
31it if you want it; that you can change the software and use pieces of
32it in new free programs; and that you are informed that you can do
33these things.
34
35 To protect your rights, we need to make restrictions that forbid
36distributors to deny you these rights or to ask you to surrender these
37rights. These restrictions translate to certain responsibilities for
38you if you distribute copies of the library or if you modify it.
39
40 For example, if you distribute copies of the library, whether gratis
41or for a fee, you must give the recipients all the rights that we gave
42you. You must make sure that they, too, receive or can get the source
43code. If you link other code with the library, you must provide
44complete object files to the recipients, so that they can relink them
45with the library after making changes to the library and recompiling
46it. And you must show them these terms so they know their rights.
47
48 We protect your rights with a two-step method: (1) we copyright the
49library, and (2) we offer you this license, which gives you legal
50permission to copy, distribute and/or modify the library.
51
52 To protect each distributor, we want to make it very clear that
53there is no warranty for the free library. Also, if the library is
54modified by someone else and passed on, the recipients should know
55that what they have is not the original version, so that the original
56author's reputation will not be affected by problems that might be
57introduced by others.
58
59 Finally, software patents pose a constant threat to the existence of
60any free program. We wish to make sure that a company cannot
61effectively restrict the users of a free program by obtaining a
62restrictive license from a patent holder. Therefore, we insist that
63any patent license obtained for a version of the library must be
64consistent with the full freedom of use specified in this license.
65
66 Most GNU software, including some libraries, is covered by the
67ordinary GNU General Public License. This license, the GNU Lesser
68General Public License, applies to certain designated libraries, and
69is quite different from the ordinary General Public License. We use
70this license for certain libraries in order to permit linking those
71libraries into non-free programs.
72
73 When a program is linked with a library, whether statically or using
74a shared library, the combination of the two is legally speaking a
75combined work, a derivative of the original library. The ordinary
76General Public License therefore permits such linking only if the
77entire combination fits its criteria of freedom. The Lesser General
78Public License permits more lax criteria for linking other code with
79the library.
80
81 We call this license the "Lesser" General Public License because it
82does Less to protect the user's freedom than the ordinary General
83Public License. It also provides other free software developers Less
84of an advantage over competing non-free programs. These disadvantages
85are the reason we use the ordinary General Public License for many
86libraries. However, the Lesser license provides advantages in certain
87special circumstances.
88
89 For example, on rare occasions, there may be a special need to
90encourage the widest possible use of a certain library, so that it becomes
91a de-facto standard. To achieve this, non-free programs must be
92allowed to use the library. A more frequent case is that a free
93library does the same job as widely used non-free libraries. In this
94case, there is little to gain by limiting the free library to free
95software only, so we use the Lesser General Public License.
96
97 In other cases, permission to use a particular library in non-free
98programs enables a greater number of people to use a large body of
99free software. For example, permission to use the GNU C Library in
100non-free programs enables many more people to use the whole GNU
101operating system, as well as its variant, the GNU/Linux operating
102system.
103
104 Although the Lesser General Public License is Less protective of the
105users' freedom, it does ensure that the user of a program that is
106linked with the Library has the freedom and the wherewithal to run
107that program using a modified version of the Library.
108
109 The precise terms and conditions for copying, distribution and
110modification follow. Pay close attention to the difference between a
111"work based on the library" and a "work that uses the library". The
112former contains code derived from the library, whereas the latter must
113be combined with the library in order to run.
114
115 GNU LESSER GENERAL PUBLIC LICENSE
116 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
117
118 0. This License Agreement applies to any software library or other
119program which contains a notice placed by the copyright holder or
120other authorized party saying it may be distributed under the terms of
121this Lesser General Public License (also called "this License").
122Each licensee is addressed as "you".
123
124 A "library" means a collection of software functions and/or data
125prepared so as to be conveniently linked with application programs
126(which use some of those functions and data) to form executables.
127
128 The "Library", below, refers to any such software library or work
129which has been distributed under these terms. A "work based on the
130Library" means either the Library or any derivative work under
131copyright law: that is to say, a work containing the Library or a
132portion of it, either verbatim or with modifications and/or translated
133straightforwardly into another language. (Hereinafter, translation is
134included without limitation in the term "modification".)
135
136 "Source code" for a work means the preferred form of the work for
137making modifications to it. For a library, complete source code means
138all the source code for all modules it contains, plus any associated
139interface definition files, plus the scripts used to control compilation
140and installation of the library.
141
142 Activities other than copying, distribution and modification are not
143covered by this License; they are outside its scope. The act of
144running a program using the Library is not restricted, and output from
145such a program is covered only if its contents constitute a work based
146on the Library (independent of the use of the Library in a tool for
147writing it). Whether that is true depends on what the Library does
148and what the program that uses the Library does.
149
150 1. You may copy and distribute verbatim copies of the Library's
151complete source code as you receive it, in any medium, provided that
152you conspicuously and appropriately publish on each copy an
153appropriate copyright notice and disclaimer of warranty; keep intact
154all the notices that refer to this License and to the absence of any
155warranty; and distribute a copy of this License along with the
156Library.
157
158 You may charge a fee for the physical act of transferring a copy,
159and you may at your option offer warranty protection in exchange for a
160fee.
161
162 2. You may modify your copy or copies of the Library or any portion
163of it, thus forming a work based on the Library, and copy and
164distribute such modifications or work under the terms of Section 1
165above, provided that you also meet all of these conditions:
166
167 a) The modified work must itself be a software library.
168
169 b) You must cause the files modified to carry prominent notices
170 stating that you changed the files and the date of any change.
171
172 c) You must cause the whole of the work to be licensed at no
173 charge to all third parties under the terms of this License.
174
175 d) If a facility in the modified Library refers to a function or a
176 table of data to be supplied by an application program that uses
177 the facility, other than as an argument passed when the facility
178 is invoked, then you must make a good faith effort to ensure that,
179 in the event an application does not supply such function or
180 table, the facility still operates, and performs whatever part of
181 its purpose remains meaningful.
182
183 (For example, a function in a library to compute square roots has
184 a purpose that is entirely well-defined independent of the
185 application. Therefore, Subsection 2d requires that any
186 application-supplied function or table used by this function must
187 be optional: if the application does not supply it, the square
188 root function must still compute square roots.)
189
190These requirements apply to the modified work as a whole. If
191identifiable sections of that work are not derived from the Library,
192and can be reasonably considered independent and separate works in
193themselves, then this License, and its terms, do not apply to those
194sections when you distribute them as separate works. But when you
195distribute the same sections as part of a whole which is a work based
196on the Library, the distribution of the whole must be on the terms of
197this License, whose permissions for other licensees extend to the
198entire whole, and thus to each and every part regardless of who wrote
199it.
200
201Thus, it is not the intent of this section to claim rights or contest
202your rights to work written entirely by you; rather, the intent is to
203exercise the right to control the distribution of derivative or
204collective works based on the Library.
205
206In addition, mere aggregation of another work not based on the Library
207with the Library (or with a work based on the Library) on a volume of
208a storage or distribution medium does not bring the other work under
209the scope of this License.
210
211 3. You may opt to apply the terms of the ordinary GNU General Public
212License instead of this License to a given copy of the Library. To do
213this, you must alter all the notices that refer to this License, so
214that they refer to the ordinary GNU General Public License, version 2,
215instead of to this License. (If a newer version than version 2 of the
216ordinary GNU General Public License has appeared, then you can specify
217that version instead if you wish.) Do not make any other change in
218these notices.
219
220 Once this change is made in a given copy, it is irreversible for
221that copy, so the ordinary GNU General Public License applies to all
222subsequent copies and derivative works made from that copy.
223
224 This option is useful when you wish to copy part of the code of
225the Library into a program that is not a library.
226
227 4. You may copy and distribute the Library (or a portion or
228derivative of it, under Section 2) in object code or executable form
229under the terms of Sections 1 and 2 above provided that you accompany
230it with the complete corresponding machine-readable source code, which
231must be distributed under the terms of Sections 1 and 2 above on a
232medium customarily used for software interchange.
233
234 If distribution of object code is made by offering access to copy
235from a designated place, then offering equivalent access to copy the
236source code from the same place satisfies the requirement to
237distribute the source code, even though third parties are not
238compelled to copy the source along with the object code.
239
240 5. A program that contains no derivative of any portion of the
241Library, but is designed to work with the Library by being compiled or
242linked with it, is called a "work that uses the Library". Such a
243work, in isolation, is not a derivative work of the Library, and
244therefore falls outside the scope of this License.
245
246 However, linking a "work that uses the Library" with the Library
247creates an executable that is a derivative of the Library (because it
248contains portions of the Library), rather than a "work that uses the
249library". The executable is therefore covered by this License.
250Section 6 states terms for distribution of such executables.
251
252 When a "work that uses the Library" uses material from a header file
253that is part of the Library, the object code for the work may be a
254derivative work of the Library even though the source code is not.
255Whether this is true is especially significant if the work can be
256linked without the Library, or if the work is itself a library. The
257threshold for this to be true is not precisely defined by law.
258
259 If such an object file uses only numerical parameters, data
260structure layouts and accessors, and small macros and small inline
261functions (ten lines or less in length), then the use of the object
262file is unrestricted, regardless of whether it is legally a derivative
263work. (Executables containing this object code plus portions of the
264Library will still fall under Section 6.)
265
266 Otherwise, if the work is a derivative of the Library, you may
267distribute the object code for the work under the terms of Section 6.
268Any executables containing that work also fall under Section 6,
269whether or not they are linked directly with the Library itself.
270
271 6. As an exception to the Sections above, you may also combine or
272link a "work that uses the Library" with the Library to produce a
273work containing portions of the Library, and distribute that work
274under terms of your choice, provided that the terms permit
275modification of the work for the customer's own use and reverse
276engineering for debugging such modifications.
277
278 You must give prominent notice with each copy of the work that the
279Library is used in it and that the Library and its use are covered by
280this License. You must supply a copy of this License. If the work
281during execution displays copyright notices, you must include the
282copyright notice for the Library among them, as well as a reference
283directing the user to the copy of this License. Also, you must do one
284of these things:
285
286 a) Accompany the work with the complete corresponding
287 machine-readable source code for the Library including whatever
288 changes were used in the work (which must be distributed under
289 Sections 1 and 2 above); and, if the work is an executable linked
290 with the Library, with the complete machine-readable "work that
291 uses the Library", as object code and/or source code, so that the
292 user can modify the Library and then relink to produce a modified
293 executable containing the modified Library. (It is understood
294 that the user who changes the contents of definitions files in the
295 Library will not necessarily be able to recompile the application
296 to use the modified definitions.)
297
298 b) Use a suitable shared library mechanism for linking with the
299 Library. A suitable mechanism is one that (1) uses at run time a
300 copy of the library already present on the user's computer system,
301 rather than copying library functions into the executable, and (2)
302 will operate properly with a modified version of the library, if
303 the user installs one, as long as the modified version is
304 interface-compatible with the version that the work was made with.
305
306 c) Accompany the work with a written offer, valid for at
307 least three years, to give the same user the materials
308 specified in Subsection 6a, above, for a charge no more
309 than the cost of performing this distribution.
310
311 d) If distribution of the work is made by offering access to copy
312 from a designated place, offer equivalent access to copy the above
313 specified materials from the same place.
314
315 e) Verify that the user has already received a copy of these
316 materials or that you have already sent this user a copy.
317
318 For an executable, the required form of the "work that uses the
319Library" must include any data and utility programs needed for
320reproducing the executable from it. However, as a special exception,
321the materials to be distributed need not include anything that is
322normally distributed (in either source or binary form) with the major
323components (compiler, kernel, and so on) of the operating system on
324which the executable runs, unless that component itself accompanies
325the executable.
326
327 It may happen that this requirement contradicts the license
328restrictions of other proprietary libraries that do not normally
329accompany the operating system. Such a contradiction means you cannot
330use both them and the Library together in an executable that you
331distribute.
332
333 7. You may place library facilities that are a work based on the
334Library side-by-side in a single library together with other library
335facilities not covered by this License, and distribute such a combined
336library, provided that the separate distribution of the work based on
337the Library and of the other library facilities is otherwise
338permitted, and provided that you do these two things:
339
340 a) Accompany the combined library with a copy of the same work
341 based on the Library, uncombined with any other library
342 facilities. This must be distributed under the terms of the
343 Sections above.
344
345 b) Give prominent notice with the combined library of the fact
346 that part of it is a work based on the Library, and explaining
347 where to find the accompanying uncombined form of the same work.
348
349 8. You may not copy, modify, sublicense, link with, or distribute
350the Library except as expressly provided under this License. Any
351attempt otherwise to copy, modify, sublicense, link with, or
352distribute the Library is void, and will automatically terminate your
353rights under this License. However, parties who have received copies,
354or rights, from you under this License will not have their licenses
355terminated so long as such parties remain in full compliance.
356
357 9. You are not required to accept this License, since you have not
358signed it. However, nothing else grants you permission to modify or
359distribute the Library or its derivative works. These actions are
360prohibited by law if you do not accept this License. Therefore, by
361modifying or distributing the Library (or any work based on the
362Library), you indicate your acceptance of this License to do so, and
363all its terms and conditions for copying, distributing or modifying
364the Library or works based on it.
365
366 10. Each time you redistribute the Library (or any work based on the
367Library), the recipient automatically receives a license from the
368original licensor to copy, distribute, link with or modify the Library
369subject to these terms and conditions. You may not impose any further
370restrictions on the recipients' exercise of the rights granted herein.
371You are not responsible for enforcing compliance by third parties with
372this License.
373
374 11. If, as a consequence of a court judgment or allegation of patent
375infringement or for any other reason (not limited to patent issues),
376conditions are imposed on you (whether by court order, agreement or
377otherwise) that contradict the conditions of this License, they do not
378excuse you from the conditions of this License. If you cannot
379distribute so as to satisfy simultaneously your obligations under this
380License and any other pertinent obligations, then as a consequence you
381may not distribute the Library at all. For example, if a patent
382license would not permit royalty-free redistribution of the Library by
383all those who receive copies directly or indirectly through you, then
384the only way you could satisfy both it and this License would be to
385refrain entirely from distribution of the Library.
386
387If any portion of this section is held invalid or unenforceable under any
388particular circumstance, the balance of the section is intended to apply,
389and the section as a whole is intended to apply in other circumstances.
390
391It is not the purpose of this section to induce you to infringe any
392patents or other property right claims or to contest validity of any
393such claims; this section has the sole purpose of protecting the
394integrity of the free software distribution system which is
395implemented by public license practices. Many people have made
396generous contributions to the wide range of software distributed
397through that system in reliance on consistent application of that
398system; it is up to the author/donor to decide if he or she is willing
399to distribute software through any other system and a licensee cannot
400impose that choice.
401
402This section is intended to make thoroughly clear what is believed to
403be a consequence of the rest of this License.
404
405 12. If the distribution and/or use of the Library is restricted in
406certain countries either by patents or by copyrighted interfaces, the
407original copyright holder who places the Library under this License may add
408an explicit geographical distribution limitation excluding those countries,
409so that distribution is permitted only in or among countries not thus
410excluded. In such case, this License incorporates the limitation as if
411written in the body of this License.
412
413 13. The Free Software Foundation may publish revised and/or new
414versions of the Lesser General Public License from time to time.
415Such new versions will be similar in spirit to the present version,
416but may differ in detail to address new problems or concerns.
417
418Each version is given a distinguishing version number. If the Library
419specifies a version number of this License which applies to it and
420"any later version", you have the option of following the terms and
421conditions either of that version or of any later version published by
422the Free Software Foundation. If the Library does not specify a
423license version number, you may choose any version ever published by
424the Free Software Foundation.
425
426 14. If you wish to incorporate parts of the Library into other free
427programs whose distribution conditions are incompatible with these,
428write to the author to ask for permission. For software which is
429copyrighted by the Free Software Foundation, write to the Free
430Software Foundation; we sometimes make exceptions for this. Our
431decision will be guided by the two goals of preserving the free status
432of all derivatives of our free software and of promoting the sharing
433and reuse of software generally.
434
435 NO WARRANTY
436
437 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
438WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
439EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
440OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
441KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
442IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
444LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
445THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
446
447 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
448WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
449AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
450FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
451CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
452LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
453RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
454FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
455SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
456DAMAGES.
457
458 END OF TERMS AND CONDITIONS
diff --git a/utils/rbutilqt/quazip/README.ROCKBOX b/utils/rbutilqt/quazip/README.ROCKBOX
new file mode 100644
index 0000000000..a168b2a079
--- /dev/null
+++ b/utils/rbutilqt/quazip/README.ROCKBOX
@@ -0,0 +1,9 @@
1This folder contains the quazip project for ZIP file compression/decompression.
2These files are distributed under the LGPL v2.1 or later. Only source files
3actually used in Rockbox Utility are included, further sources have been left
4out. Check the quazip source distribution for those.
5
6The source files have been last synced with the projects release 0.9.1 at
7https://github.com/stachenov/quazip/ on June 8, 2020.
8
9
diff --git a/utils/rbutilqt/quazip/ioapi.h b/utils/rbutilqt/quazip/ioapi.h
new file mode 100644
index 0000000000..75d0aa6933
--- /dev/null
+++ b/utils/rbutilqt/quazip/ioapi.h
@@ -0,0 +1,207 @@
1/* ioapi.h -- IO base function header for compress/uncompress .zip
2 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
3
4 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
5
6 Modifications for Zip64 support
7 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
8
9 Modified by Sergey A. Tachenov to allow QIODevice API usage.
10
11 For more info read MiniZip_info.txt
12
13 Changes
14
15 Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
16 Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
17 More if/def section may be needed to support other platforms
18 Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
19 (but you should use iowin32.c for windows instead)
20
21*/
22
23#ifndef _ZLIBIOAPI64_H
24#define _ZLIBIOAPI64_H
25
26#if (!defined(_WIN32)) && (!defined(WIN32))
27
28 // Linux needs this to support file operation on files larger then 4+GB
29 // But might need better if/def to select just the platforms that needs them.
30
31 #ifndef __USE_FILE_OFFSET64
32 #define __USE_FILE_OFFSET64
33 #endif
34 #ifndef __USE_LARGEFILE64
35 #define __USE_LARGEFILE64
36 #endif
37 #ifndef _LARGEFILE64_SOURCE
38 #define _LARGEFILE64_SOURCE
39 #endif
40 #ifndef _FILE_OFFSET_BIT
41 #define _FILE_OFFSET_BIT 64
42 #endif
43#endif
44
45#include <stdio.h>
46#include <stdlib.h>
47#include <zlib.h>
48
49#if defined(USE_FILE32API)
50#define fopen64 fopen
51#define ftello64 ftell
52#define fseeko64 fseek
53#else
54#ifdef _MSC_VER
55 #define fopen64 fopen
56 #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
57 #define ftello64 _ftelli64
58 #define fseeko64 _fseeki64
59 #else // old MSC
60 #define ftello64 ftell
61 #define fseeko64 fseek
62 #endif
63#endif
64#endif
65
66/*
67#ifndef ZPOS64_T
68 #ifdef _WIN32
69 #define ZPOS64_T fpos_t
70 #else
71 #include <stdint.h>
72 #define ZPOS64_T uint64_t
73 #endif
74#endif
75*/
76
77#ifdef HAVE_MINIZIP64_CONF_H
78#include "mz64conf.h"
79#endif
80
81/* a type choosen by DEFINE */
82#ifdef HAVE_64BIT_INT_CUSTOM
83typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T;
84#else
85#ifdef HAS_STDINT_H
86#include "stdint.h"
87typedef uint64_t ZPOS64_T;
88#else
89
90
91#if defined(_MSC_VER) || defined(__BORLANDC__)
92typedef unsigned __int64 ZPOS64_T;
93#else
94typedef unsigned long long int ZPOS64_T;
95#endif
96#endif
97#endif
98
99
100
101#ifdef __cplusplus
102extern "C" {
103#endif
104
105#ifndef OF
106#define OF _Z_OF
107#endif
108
109#define ZLIB_FILEFUNC_SEEK_CUR (1)
110#define ZLIB_FILEFUNC_SEEK_END (2)
111#define ZLIB_FILEFUNC_SEEK_SET (0)
112
113#define ZLIB_FILEFUNC_MODE_READ (1)
114#define ZLIB_FILEFUNC_MODE_WRITE (2)
115#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
116
117#define ZLIB_FILEFUNC_MODE_EXISTING (4)
118#define ZLIB_FILEFUNC_MODE_CREATE (8)
119
120
121#ifndef ZCALLBACK
122 #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
123 #define ZCALLBACK CALLBACK
124 #else
125 #define ZCALLBACK
126 #endif
127#endif
128
129
130
131
132typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, voidpf file, int mode));
133typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
134typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
135typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
136typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
137
138typedef uLong (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
139typedef int (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
140
141
142/* here is the "old" 32 bits structure structure */
143typedef struct zlib_filefunc_def_s
144{
145 open_file_func zopen_file;
146 read_file_func zread_file;
147 write_file_func zwrite_file;
148 tell_file_func ztell_file;
149 seek_file_func zseek_file;
150 close_file_func zclose_file;
151 testerror_file_func zerror_file;
152 voidpf opaque;
153} zlib_filefunc_def;
154
155typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream));
156typedef int (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
157typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, voidpf file, int mode));
158
159typedef struct zlib_filefunc64_def_s
160{
161 open64_file_func zopen64_file;
162 read_file_func zread_file;
163 write_file_func zwrite_file;
164 tell64_file_func ztell64_file;
165 seek64_file_func zseek64_file;
166 close_file_func zclose_file;
167 testerror_file_func zerror_file;
168 voidpf opaque;
169 close_file_func zfakeclose_file; // for no-auto-close flag
170} zlib_filefunc64_def;
171
172void fill_qiodevice64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
173void fill_qiodevice_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
174
175/* now internal definition, only for zip.c and unzip.h */
176typedef struct zlib_filefunc64_32_def_s
177{
178 zlib_filefunc64_def zfile_func64;
179 open_file_func zopen32_file;
180 tell_file_func ztell32_file;
181 seek_file_func zseek32_file;
182} zlib_filefunc64_32_def;
183
184
185#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
186#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
187//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))
188//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))
189#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream))
190#define ZFAKECLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zfakeclose_file)) ((filefunc).zfile_func64.opaque,filestream))
191#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream))
192
193voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf file,int mode));
194int call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
195ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
196
197void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
198
199#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode)))
200#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream)))
201#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
202
203#ifdef __cplusplus
204}
205#endif
206
207#endif
diff --git a/utils/rbutilqt/quazip/minizip_crypt.h b/utils/rbutilqt/quazip/minizip_crypt.h
new file mode 100644
index 0000000000..2e833f7f3c
--- /dev/null
+++ b/utils/rbutilqt/quazip/minizip_crypt.h
@@ -0,0 +1,135 @@
1/* crypt.h -- base code for crypt/uncrypt ZIPfile
2
3
4 Version 1.01e, February 12th, 2005
5
6 Copyright (C) 1998-2005 Gilles Vollant
7
8 This code is a modified version of crypting code in Infozip distribution
9
10 The encryption/decryption parts of this source code (as opposed to the
11 non-echoing password parts) were originally written in Europe. The
12 whole source package can be freely distributed, including from the USA.
13 (Prior to January 2000, re-export from the US was a violation of US law.)
14
15 This encryption code is a direct transcription of the algorithm from
16 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
17 file (appnote.txt) is distributed with the PKZIP program (even in the
18 version without encryption capabilities).
19
20 If you don't need crypting in your application, just define symbols
21 NOCRYPT and NOUNCRYPT.
22
23 This code support the "Traditional PKWARE Encryption".
24
25 The new AES encryption added on Zip format by Winzip (see the page
26 http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
27 Encryption is not supported.
28*/
29
30#include "quazip_global.h"
31
32#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
33
34/***********************************************************************
35 * Return the next byte in the pseudo-random sequence
36 */
37static int decrypt_byte(unsigned long* pkeys, const z_crc_t FAR * pcrc_32_tab QUAZIP_UNUSED)
38{
39 //(void) pcrc_32_tab; /* avoid "unused parameter" warning */
40 unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
41 * unpredictable manner on 16-bit systems; not a problem
42 * with any known compiler so far, though */
43
44 temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
45 return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
46}
47
48/***********************************************************************
49 * Update the encryption keys with the next byte of plain text
50 */
51static int update_keys(unsigned long* pkeys,const z_crc_t FAR * pcrc_32_tab,int c)
52{
53 (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
54 (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
55 (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
56 {
57 register int keyshift = (int)((*(pkeys+1)) >> 24);
58 (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
59 }
60 return c;
61}
62
63
64/***********************************************************************
65 * Initialize the encryption keys and the random header according to
66 * the given password.
67 */
68static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t FAR * pcrc_32_tab)
69{
70 *(pkeys+0) = 305419896L;
71 *(pkeys+1) = 591751049L;
72 *(pkeys+2) = 878082192L;
73 while (*passwd != '\0') {
74 update_keys(pkeys,pcrc_32_tab,(int)*passwd);
75 passwd++;
76 }
77}
78
79#define zdecode(pkeys,pcrc_32_tab,c) \
80 (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
81
82#define zencode(pkeys,pcrc_32_tab,c,t) \
83 (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
84
85#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
86
87#define RAND_HEAD_LEN 12
88 /* "last resort" source for second part of crypt seed pattern */
89# ifndef ZCR_SEED2
90# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
91# endif
92
93static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
94 const char *passwd; /* password string */
95 unsigned char *buf; /* where to write header */
96 int bufSize;
97 unsigned long* pkeys;
98 const z_crc_t FAR * pcrc_32_tab;
99 unsigned long crcForCrypting;
100{
101 int n; /* index in random header */
102 int t; /* temporary */
103 int c; /* random byte */
104 unsigned char header[RAND_HEAD_LEN-2]; /* random header */
105 static unsigned calls = 0; /* ensure different random header each time */
106
107 if (bufSize<RAND_HEAD_LEN)
108 return 0;
109
110 /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
111 * output of rand() to get less predictability, since rand() is
112 * often poorly implemented.
113 */
114 if (++calls == 1)
115 {
116 srand((unsigned)(time(NULL) ^ ZCR_SEED2));
117 }
118 init_keys(passwd, pkeys, pcrc_32_tab);
119 for (n = 0; n < RAND_HEAD_LEN-2; n++)
120 {
121 c = (rand() >> 7) & 0xff;
122 header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
123 }
124 /* Encrypt random header (last two bytes is high word of crc) */
125 init_keys(passwd, pkeys, pcrc_32_tab);
126 for (n = 0; n < RAND_HEAD_LEN-2; n++)
127 {
128 buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
129 }
130 buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
131 buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
132 return n;
133}
134
135#endif
diff --git a/utils/rbutilqt/quazip/qioapi.cpp b/utils/rbutilqt/quazip/qioapi.cpp
new file mode 100644
index 0000000000..3932ebeef0
--- /dev/null
+++ b/utils/rbutilqt/quazip/qioapi.cpp
@@ -0,0 +1,363 @@
1/* ioapi.c -- IO base function header for compress/uncompress .zip
2 files using zlib + zip or unzip API
3
4 Version 1.01e, February 12th, 2005
5
6 Copyright (C) 1998-2005 Gilles Vollant
7
8 Modified by Sergey A. Tachenov to integrate with Qt.
9*/
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <zlib.h>
15
16#include "ioapi.h"
17#include "quazip_global.h"
18#include <QtCore/QIODevice>
19#if (QT_VERSION >= 0x050100)
20#define QUAZIP_QSAVEFILE_BUG_WORKAROUND
21#endif
22#ifdef QUAZIP_QSAVEFILE_BUG_WORKAROUND
23#include <QtCore/QSaveFile>
24#endif
25
26/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
27
28#ifndef SEEK_CUR
29#define SEEK_CUR 1
30#endif
31
32#ifndef SEEK_END
33#define SEEK_END 2
34#endif
35
36#ifndef SEEK_SET
37#define SEEK_SET 0
38#endif
39
40voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,voidpf file,int mode)
41{
42 if (pfilefunc->zfile_func64.zopen64_file != NULL)
43 return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,file,mode);
44 else
45 {
46 return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,file,mode);
47 }
48}
49
50int call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
51{
52 if (pfilefunc->zfile_func64.zseek64_file != NULL)
53 return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
54 else
55 {
56 uLong offsetTruncated = (uLong)offset;
57 if (offsetTruncated != offset)
58 return -1;
59 else
60 return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
61 }
62}
63
64ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
65{
66 if (pfilefunc->zfile_func64.zseek64_file != NULL)
67 return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
68 else
69 {
70 uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
71 if ((tell_uLong) == ((uLong)-1))
72 return (ZPOS64_T)-1;
73 else
74 return tell_uLong;
75 }
76}
77
78/// @cond internal
79struct QIODevice_descriptor {
80 // Position only used for writing to sequential devices.
81 qint64 pos;
82 inline QIODevice_descriptor():
83 pos(0)
84 {}
85};
86/// @endcond
87
88voidpf ZCALLBACK qiodevice_open_file_func (
89 voidpf opaque,
90 voidpf file,
91 int mode)
92{
93 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
94 QIODevice *iodevice = reinterpret_cast<QIODevice*>(file);
95 QIODevice::OpenMode desiredMode;
96 if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
97 desiredMode = QIODevice::ReadOnly;
98 else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
99 desiredMode = QIODevice::ReadWrite;
100 else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
101 desiredMode = QIODevice::WriteOnly;
102 if (iodevice->isOpen()) {
103 if ((iodevice->openMode() & desiredMode) == desiredMode) {
104 if (desiredMode != QIODevice::WriteOnly
105 && iodevice->isSequential()) {
106 // We can use sequential devices only for writing.
107 delete d;
108 return NULL;
109 } else {
110 if ((desiredMode & QIODevice::WriteOnly) != 0) {
111 // open for writing, need to seek existing device
112 if (!iodevice->isSequential()) {
113 iodevice->seek(0);
114 } else {
115 d->pos = iodevice->pos();
116 }
117 }
118 }
119 return iodevice;
120 } else {
121 delete d;
122 return NULL;
123 }
124 }
125 iodevice->open(desiredMode);
126 if (iodevice->isOpen()) {
127 if (desiredMode != QIODevice::WriteOnly && iodevice->isSequential()) {
128 // We can use sequential devices only for writing.
129 iodevice->close();
130 delete d;
131 return NULL;
132 } else {
133 return iodevice;
134 }
135 } else {
136 delete d;
137 return NULL;
138 }
139}
140
141
142uLong ZCALLBACK qiodevice_read_file_func (
143 voidpf opaque,
144 voidpf stream,
145 void* buf,
146 uLong size)
147{
148 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
149 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
150 qint64 ret64 = iodevice->read((char*)buf,size);
151 uLong ret;
152 ret = (uLong) ret64;
153 if (ret64 != -1) {
154 d->pos += ret64;
155 }
156 return ret;
157}
158
159
160uLong ZCALLBACK qiodevice_write_file_func (
161 voidpf opaque,
162 voidpf stream,
163 const void* buf,
164 uLong size)
165{
166 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
167 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
168 uLong ret;
169 qint64 ret64 = iodevice->write((char*)buf,size);
170 if (ret64 != -1) {
171 d->pos += ret64;
172 }
173 ret = (uLong) ret64;
174 return ret;
175}
176
177uLong ZCALLBACK qiodevice_tell_file_func (
178 voidpf opaque,
179 voidpf stream)
180{
181 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
182 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
183 uLong ret;
184 qint64 ret64;
185 if (iodevice->isSequential()) {
186 ret64 = d->pos;
187 } else {
188 ret64 = iodevice->pos();
189 }
190 ret = static_cast<uLong>(ret64);
191 return ret;
192}
193
194ZPOS64_T ZCALLBACK qiodevice64_tell_file_func (
195 voidpf opaque,
196 voidpf stream)
197{
198 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
199 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
200 qint64 ret;
201 if (iodevice->isSequential()) {
202 ret = d->pos;
203 } else {
204 ret = iodevice->pos();
205 }
206 return static_cast<ZPOS64_T>(ret);
207}
208
209int ZCALLBACK qiodevice_seek_file_func (
210 voidpf /*opaque UNUSED*/,
211 voidpf stream,
212 uLong offset,
213 int origin)
214{
215 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
216 if (iodevice->isSequential()) {
217 if (origin == ZLIB_FILEFUNC_SEEK_END
218 && offset == 0) {
219 // sequential devices are always at end (needed in mdAppend)
220 return 0;
221 } else {
222 qWarning("qiodevice_seek_file_func() called for sequential device");
223 return -1;
224 }
225 }
226 uLong qiodevice_seek_result=0;
227 int ret;
228 switch (origin)
229 {
230 case ZLIB_FILEFUNC_SEEK_CUR :
231 qiodevice_seek_result = ((QIODevice*)stream)->pos() + offset;
232 break;
233 case ZLIB_FILEFUNC_SEEK_END :
234 qiodevice_seek_result = ((QIODevice*)stream)->size() - offset;
235 break;
236 case ZLIB_FILEFUNC_SEEK_SET :
237 qiodevice_seek_result = offset;
238 break;
239 default:
240 return -1;
241 }
242 ret = !iodevice->seek(qiodevice_seek_result);
243 return ret;
244}
245
246int ZCALLBACK qiodevice64_seek_file_func (
247 voidpf /*opaque UNUSED*/,
248 voidpf stream,
249 ZPOS64_T offset,
250 int origin)
251{
252 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
253 if (iodevice->isSequential()) {
254 if (origin == ZLIB_FILEFUNC_SEEK_END
255 && offset == 0) {
256 // sequential devices are always at end (needed in mdAppend)
257 return 0;
258 } else {
259 qWarning("qiodevice_seek_file_func() called for sequential device");
260 return -1;
261 }
262 }
263 qint64 qiodevice_seek_result=0;
264 int ret;
265 switch (origin)
266 {
267 case ZLIB_FILEFUNC_SEEK_CUR :
268 qiodevice_seek_result = ((QIODevice*)stream)->pos() + offset;
269 break;
270 case ZLIB_FILEFUNC_SEEK_END :
271 qiodevice_seek_result = ((QIODevice*)stream)->size() - offset;
272 break;
273 case ZLIB_FILEFUNC_SEEK_SET :
274 qiodevice_seek_result = offset;
275 break;
276 default:
277 return -1;
278 }
279 ret = !iodevice->seek(qiodevice_seek_result);
280 return ret;
281}
282
283int ZCALLBACK qiodevice_close_file_func (
284 voidpf opaque,
285 voidpf stream)
286{
287 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
288 delete d;
289 QIODevice *device = reinterpret_cast<QIODevice*>(stream);
290#ifdef QUAZIP_QSAVEFILE_BUG_WORKAROUND
291 // QSaveFile terribly breaks the is-a idiom:
292 // it IS a QIODevice, but it is NOT compatible with it: close() is private
293 QSaveFile *file = qobject_cast<QSaveFile*>(device);
294 if (file != NULL) {
295 // We have to call the ugly commit() instead:
296 return file->commit() ? 0 : -1;
297 }
298#endif
299 device->close();
300 return 0;
301}
302
303int ZCALLBACK qiodevice_fakeclose_file_func (
304 voidpf opaque,
305 voidpf /*stream*/)
306{
307 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
308 delete d;
309 return 0;
310}
311
312int ZCALLBACK qiodevice_error_file_func (
313 voidpf /*opaque UNUSED*/,
314 voidpf /*stream UNUSED*/)
315{
316 // can't check for error due to the QIODevice API limitation
317 return 0;
318}
319
320void fill_qiodevice_filefunc (
321 zlib_filefunc_def* pzlib_filefunc_def)
322{
323 pzlib_filefunc_def->zopen_file = qiodevice_open_file_func;
324 pzlib_filefunc_def->zread_file = qiodevice_read_file_func;
325 pzlib_filefunc_def->zwrite_file = qiodevice_write_file_func;
326 pzlib_filefunc_def->ztell_file = qiodevice_tell_file_func;
327 pzlib_filefunc_def->zseek_file = qiodevice_seek_file_func;
328 pzlib_filefunc_def->zclose_file = qiodevice_close_file_func;
329 pzlib_filefunc_def->zerror_file = qiodevice_error_file_func;
330 pzlib_filefunc_def->opaque = new QIODevice_descriptor;
331}
332
333void fill_qiodevice64_filefunc (
334 zlib_filefunc64_def* pzlib_filefunc_def)
335{
336 // Open functions are the same for Qt.
337 pzlib_filefunc_def->zopen64_file = qiodevice_open_file_func;
338 pzlib_filefunc_def->zread_file = qiodevice_read_file_func;
339 pzlib_filefunc_def->zwrite_file = qiodevice_write_file_func;
340 pzlib_filefunc_def->ztell64_file = qiodevice64_tell_file_func;
341 pzlib_filefunc_def->zseek64_file = qiodevice64_seek_file_func;
342 pzlib_filefunc_def->zclose_file = qiodevice_close_file_func;
343 pzlib_filefunc_def->zerror_file = qiodevice_error_file_func;
344 pzlib_filefunc_def->opaque = new QIODevice_descriptor;
345 pzlib_filefunc_def->zfakeclose_file = qiodevice_fakeclose_file_func;
346}
347
348void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
349{
350 p_filefunc64_32->zfile_func64.zopen64_file = NULL;
351 p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
352 p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
353 p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
354 p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
355 p_filefunc64_32->zfile_func64.ztell64_file = NULL;
356 p_filefunc64_32->zfile_func64.zseek64_file = NULL;
357 p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
358 p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
359 p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
360 p_filefunc64_32->zfile_func64.zfakeclose_file = NULL;
361 p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
362 p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
363}
diff --git a/utils/rbutilqt/quazip/quazip.cpp b/utils/rbutilqt/quazip/quazip.cpp
new file mode 100644
index 0000000000..61c2ea87eb
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazip.cpp
@@ -0,0 +1,846 @@
1/*
2Copyright (C) 2005-2014 Sergey A. Tachenov
3
4This file is part of QuaZIP.
5
6QuaZIP is free software: you can redistribute it and/or modify
7it under the terms of the GNU Lesser General Public License as published by
8the Free Software Foundation, either version 2.1 of the License, or
9(at your option) any later version.
10
11QuaZIP is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU Lesser General Public License for more details.
15
16You should have received a copy of the GNU Lesser General Public License
17along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
18
19See COPYING file for the full LGPL text.
20
21Original ZIP package is copyrighted by Gilles Vollant, see
22quazip/(un)zip.h files for details, basically it's zlib license.
23 **/
24
25#include <QtCore/QFile>
26#include <QtCore/QFlags>
27#include <QtCore/QHash>
28
29#include "quazip.h"
30
31#define QUAZIP_OS_UNIX 3u
32
33/// All the internal stuff for the QuaZip class.
34/**
35 \internal
36
37 This class keeps all the private stuff for the QuaZip class so it can
38 be changed without breaking binary compatibility, according to the
39 Pimpl idiom.
40 */
41class QuaZipPrivate {
42 friend class QuaZip;
43 private:
44 Q_DISABLE_COPY(QuaZipPrivate)
45 /// The pointer to the corresponding QuaZip instance.
46 QuaZip *q;
47 /// The codec for file names (used when UTF-8 is not enabled).
48 QTextCodec *fileNameCodec;
49 /// The codec for comments (used when UTF-8 is not enabled).
50 QTextCodec *commentCodec;
51 /// The archive file name.
52 QString zipName;
53 /// The device to access the archive.
54 QIODevice *ioDevice;
55 /// The global comment.
56 QString comment;
57 /// The open mode.
58 QuaZip::Mode mode;
59 union {
60 /// The internal handle for UNZIP modes.
61 unzFile unzFile_f;
62 /// The internal handle for ZIP modes.
63 zipFile zipFile_f;
64 };
65 /// Whether a current file is set.
66 bool hasCurrentFile_f;
67 /// The last error.
68 int zipError;
69 /// Whether \ref QuaZip::setDataDescriptorWritingEnabled() "the data descriptor writing mode" is enabled.
70 bool dataDescriptorWritingEnabled;
71 /// The zip64 mode.
72 bool zip64;
73 /// The auto-close flag.
74 bool autoClose;
75 /// The UTF-8 flag.
76 bool utf8;
77 /// The OS code.
78 uint osCode;
79 inline QTextCodec *getDefaultFileNameCodec()
80 {
81 if (defaultFileNameCodec == NULL) {
82 return QTextCodec::codecForLocale();
83 } else {
84 return defaultFileNameCodec;
85 }
86 }
87 /// The constructor for the corresponding QuaZip constructor.
88 inline QuaZipPrivate(QuaZip *q):
89 q(q),
90 fileNameCodec(getDefaultFileNameCodec()),
91 commentCodec(QTextCodec::codecForLocale()),
92 ioDevice(NULL),
93 mode(QuaZip::mdNotOpen),
94 hasCurrentFile_f(false),
95 zipError(UNZ_OK),
96 dataDescriptorWritingEnabled(true),
97 zip64(false),
98 autoClose(true),
99 utf8(false),
100 osCode(defaultOsCode)
101 {
102 unzFile_f = NULL;
103 zipFile_f = NULL;
104 lastMappedDirectoryEntry.num_of_file = 0;
105 lastMappedDirectoryEntry.pos_in_zip_directory = 0;
106 }
107 /// The constructor for the corresponding QuaZip constructor.
108 inline QuaZipPrivate(QuaZip *q, const QString &zipName):
109 q(q),
110 fileNameCodec(getDefaultFileNameCodec()),
111 commentCodec(QTextCodec::codecForLocale()),
112 zipName(zipName),
113 ioDevice(NULL),
114 mode(QuaZip::mdNotOpen),
115 hasCurrentFile_f(false),
116 zipError(UNZ_OK),
117 dataDescriptorWritingEnabled(true),
118 zip64(false),
119 autoClose(true),
120 utf8(false),
121 osCode(defaultOsCode)
122 {
123 unzFile_f = NULL;
124 zipFile_f = NULL;
125 lastMappedDirectoryEntry.num_of_file = 0;
126 lastMappedDirectoryEntry.pos_in_zip_directory = 0;
127 }
128 /// The constructor for the corresponding QuaZip constructor.
129 inline QuaZipPrivate(QuaZip *q, QIODevice *ioDevice):
130 q(q),
131 fileNameCodec(getDefaultFileNameCodec()),
132 commentCodec(QTextCodec::codecForLocale()),
133 ioDevice(ioDevice),
134 mode(QuaZip::mdNotOpen),
135 hasCurrentFile_f(false),
136 zipError(UNZ_OK),
137 dataDescriptorWritingEnabled(true),
138 zip64(false),
139 autoClose(true),
140 utf8(false),
141 osCode(defaultOsCode)
142 {
143 unzFile_f = NULL;
144 zipFile_f = NULL;
145 lastMappedDirectoryEntry.num_of_file = 0;
146 lastMappedDirectoryEntry.pos_in_zip_directory = 0;
147 }
148 /// Returns either a list of file names or a list of QuaZipFileInfo.
149 template<typename TFileInfo>
150 bool getFileInfoList(QList<TFileInfo> *result) const;
151
152 /// Stores map of filenames and file locations for unzipping
153 inline void clearDirectoryMap();
154 inline void addCurrentFileToDirectoryMap(const QString &fileName);
155 bool goToFirstUnmappedFile();
156 QHash<QString, unz64_file_pos> directoryCaseSensitive;
157 QHash<QString, unz64_file_pos> directoryCaseInsensitive;
158 unz64_file_pos lastMappedDirectoryEntry;
159 static QTextCodec *defaultFileNameCodec;
160 static uint defaultOsCode;
161};
162
163QTextCodec *QuaZipPrivate::defaultFileNameCodec = NULL;
164uint QuaZipPrivate::defaultOsCode = QUAZIP_OS_UNIX;
165
166void QuaZipPrivate::clearDirectoryMap()
167{
168 directoryCaseInsensitive.clear();
169 directoryCaseSensitive.clear();
170 lastMappedDirectoryEntry.num_of_file = 0;
171 lastMappedDirectoryEntry.pos_in_zip_directory = 0;
172}
173
174void QuaZipPrivate::addCurrentFileToDirectoryMap(const QString &fileName)
175{
176 if (!hasCurrentFile_f || fileName.isEmpty()) {
177 return;
178 }
179 // Adds current file to filename map as fileName
180 unz64_file_pos fileDirectoryPos;
181 unzGetFilePos64(unzFile_f, &fileDirectoryPos);
182 directoryCaseSensitive.insert(fileName, fileDirectoryPos);
183 // Only add lowercase to directory map if not already there
184 // ensures only map the first one seen
185 QString lower = fileName.toLower();
186 if (!directoryCaseInsensitive.contains(lower))
187 directoryCaseInsensitive.insert(lower, fileDirectoryPos);
188 // Mark last one
189 if (fileDirectoryPos.pos_in_zip_directory > lastMappedDirectoryEntry.pos_in_zip_directory)
190 lastMappedDirectoryEntry = fileDirectoryPos;
191}
192
193bool QuaZipPrivate::goToFirstUnmappedFile()
194{
195 zipError = UNZ_OK;
196 if (mode != QuaZip::mdUnzip) {
197 qWarning("QuaZipPrivate::goToNextUnmappedFile(): ZIP is not open in mdUnzip mode");
198 return false;
199 }
200 // If not mapped anything, go to beginning
201 if (lastMappedDirectoryEntry.pos_in_zip_directory == 0) {
202 unzGoToFirstFile(unzFile_f);
203 } else {
204 // Goto the last one mapped, plus one
205 unzGoToFilePos64(unzFile_f, &lastMappedDirectoryEntry);
206 unzGoToNextFile(unzFile_f);
207 }
208 hasCurrentFile_f=zipError==UNZ_OK;
209 if(zipError==UNZ_END_OF_LIST_OF_FILE)
210 zipError=UNZ_OK;
211 return hasCurrentFile_f;
212}
213
214QuaZip::QuaZip():
215 p(new QuaZipPrivate(this))
216{
217}
218
219QuaZip::QuaZip(const QString& zipName):
220 p(new QuaZipPrivate(this, zipName))
221{
222}
223
224QuaZip::QuaZip(QIODevice *ioDevice):
225 p(new QuaZipPrivate(this, ioDevice))
226{
227}
228
229QuaZip::~QuaZip()
230{
231 if(isOpen())
232 close();
233 delete p;
234}
235
236bool QuaZip::open(Mode mode, zlib_filefunc_def* ioApi)
237{
238 p->zipError=UNZ_OK;
239 if(isOpen()) {
240 qWarning("QuaZip::open(): ZIP already opened");
241 return false;
242 }
243 QIODevice *ioDevice = p->ioDevice;
244 if (ioDevice == NULL) {
245 if (p->zipName.isEmpty()) {
246 qWarning("QuaZip::open(): set either ZIP file name or IO device first");
247 return false;
248 } else {
249 ioDevice = new QFile(p->zipName);
250 }
251 }
252 unsigned flags = 0;
253 switch(mode) {
254 case mdUnzip:
255 if (ioApi == NULL) {
256 if (p->autoClose)
257 flags |= UNZ_AUTO_CLOSE;
258 p->unzFile_f=unzOpenInternal(ioDevice, NULL, 1, flags);
259 } else {
260 // QuaZIP pre-zip64 compatibility mode
261 p->unzFile_f=unzOpen2(ioDevice, ioApi);
262 if (p->unzFile_f != NULL) {
263 if (p->autoClose) {
264 unzSetFlags(p->unzFile_f, UNZ_AUTO_CLOSE);
265 } else {
266 unzClearFlags(p->unzFile_f, UNZ_AUTO_CLOSE);
267 }
268 }
269 }
270 if(p->unzFile_f!=NULL) {
271 if (ioDevice->isSequential()) {
272 unzClose(p->unzFile_f);
273 if (!p->zipName.isEmpty())
274 delete ioDevice;
275 qWarning("QuaZip::open(): "
276 "only mdCreate can be used with "
277 "sequential devices");
278 return false;
279 }
280 p->mode=mode;
281 p->ioDevice = ioDevice;
282 return true;
283 } else {
284 p->zipError=UNZ_OPENERROR;
285 if (!p->zipName.isEmpty())
286 delete ioDevice;
287 return false;
288 }
289 case mdCreate:
290 case mdAppend:
291 case mdAdd:
292 if (ioApi == NULL) {
293 if (p->autoClose)
294 flags |= ZIP_AUTO_CLOSE;
295 if (p->dataDescriptorWritingEnabled)
296 flags |= ZIP_WRITE_DATA_DESCRIPTOR;
297 if (p->utf8)
298 flags |= ZIP_ENCODING_UTF8;
299 p->zipFile_f=zipOpen3(ioDevice,
300 mode==mdCreate?APPEND_STATUS_CREATE:
301 mode==mdAppend?APPEND_STATUS_CREATEAFTER:
302 APPEND_STATUS_ADDINZIP,
303 NULL, NULL, flags);
304 } else {
305 // QuaZIP pre-zip64 compatibility mode
306 p->zipFile_f=zipOpen2(ioDevice,
307 mode==mdCreate?APPEND_STATUS_CREATE:
308 mode==mdAppend?APPEND_STATUS_CREATEAFTER:
309 APPEND_STATUS_ADDINZIP,
310 NULL,
311 ioApi);
312 if (p->zipFile_f != NULL) {
313 zipSetFlags(p->zipFile_f, flags);
314 }
315 }
316 if(p->zipFile_f!=NULL) {
317 if (ioDevice->isSequential()) {
318 if (mode != mdCreate) {
319 zipClose(p->zipFile_f, NULL);
320 qWarning("QuaZip::open(): "
321 "only mdCreate can be used with "
322 "sequential devices");
323 if (!p->zipName.isEmpty())
324 delete ioDevice;
325 return false;
326 }
327 zipSetFlags(p->zipFile_f, ZIP_SEQUENTIAL);
328 }
329 p->mode=mode;
330 p->ioDevice = ioDevice;
331 return true;
332 } else {
333 p->zipError=UNZ_OPENERROR;
334 if (!p->zipName.isEmpty())
335 delete ioDevice;
336 return false;
337 }
338 default:
339 qWarning("QuaZip::open(): unknown mode: %d", (int)mode);
340 if (!p->zipName.isEmpty())
341 delete ioDevice;
342 return false;
343 break;
344 }
345}
346
347void QuaZip::close()
348{
349 p->zipError=UNZ_OK;
350 switch(p->mode) {
351 case mdNotOpen:
352 qWarning("QuaZip::close(): ZIP is not open");
353 return;
354 case mdUnzip:
355 p->zipError=unzClose(p->unzFile_f);
356 break;
357 case mdCreate:
358 case mdAppend:
359 case mdAdd:
360 p->zipError=zipClose(p->zipFile_f, p->comment.isNull() ? NULL : isUtf8Enabled()
361 ? p->comment.toUtf8().constData()
362 : p->commentCodec->fromUnicode(p->comment).constData());
363 break;
364 default:
365 qWarning("QuaZip::close(): unknown mode: %d", (int)p->mode);
366 return;
367 }
368 // opened by name, need to delete the internal IO device
369 if (!p->zipName.isEmpty()) {
370 delete p->ioDevice;
371 p->ioDevice = NULL;
372 }
373 p->clearDirectoryMap();
374 if(p->zipError==UNZ_OK)
375 p->mode=mdNotOpen;
376}
377
378void QuaZip::setZipName(const QString& zipName)
379{
380 if(isOpen()) {
381 qWarning("QuaZip::setZipName(): ZIP is already open!");
382 return;
383 }
384 p->zipName=zipName;
385 p->ioDevice = NULL;
386}
387
388void QuaZip::setIoDevice(QIODevice *ioDevice)
389{
390 if(isOpen()) {
391 qWarning("QuaZip::setIoDevice(): ZIP is already open!");
392 return;
393 }
394 p->ioDevice = ioDevice;
395 p->zipName = QString();
396}
397
398int QuaZip::getEntriesCount()const
399{
400 QuaZip *fakeThis=(QuaZip*)this; // non-const
401 fakeThis->p->zipError=UNZ_OK;
402 if(p->mode!=mdUnzip) {
403 qWarning("QuaZip::getEntriesCount(): ZIP is not open in mdUnzip mode");
404 return -1;
405 }
406 unz_global_info64 globalInfo;
407 if((fakeThis->p->zipError=unzGetGlobalInfo64(p->unzFile_f, &globalInfo))!=UNZ_OK)
408 return p->zipError;
409 return (int)globalInfo.number_entry;
410}
411
412QString QuaZip::getComment()const
413{
414 QuaZip *fakeThis=(QuaZip*)this; // non-const
415 fakeThis->p->zipError=UNZ_OK;
416 if(p->mode!=mdUnzip) {
417 qWarning("QuaZip::getComment(): ZIP is not open in mdUnzip mode");
418 return QString();
419 }
420 unz_global_info64 globalInfo;
421 QByteArray comment;
422 if((fakeThis->p->zipError=unzGetGlobalInfo64(p->unzFile_f, &globalInfo))!=UNZ_OK)
423 return QString();
424 comment.resize(globalInfo.size_comment);
425 if((fakeThis->p->zipError=unzGetGlobalComment(p->unzFile_f, comment.data(), comment.size())) < 0)
426 return QString();
427 fakeThis->p->zipError = UNZ_OK;
428 unsigned flags = 0;
429 return (unzGetFileFlags(p->unzFile_f, &flags) == UNZ_OK) && (flags & UNZ_ENCODING_UTF8)
430 ? QString::fromUtf8(comment) : p->commentCodec->toUnicode(comment);
431}
432
433bool QuaZip::setCurrentFile(const QString& fileName, CaseSensitivity cs)
434{
435 p->zipError=UNZ_OK;
436 if(p->mode!=mdUnzip) {
437 qWarning("QuaZip::setCurrentFile(): ZIP is not open in mdUnzip mode");
438 return false;
439 }
440 if(fileName.isEmpty()) {
441 p->hasCurrentFile_f=false;
442 return true;
443 }
444 // Unicode-aware reimplementation of the unzLocateFile function
445 if(p->unzFile_f==NULL) {
446 p->zipError=UNZ_PARAMERROR;
447 return false;
448 }
449 if(fileName.length()>MAX_FILE_NAME_LENGTH) {
450 p->zipError=UNZ_PARAMERROR;
451 return false;
452 }
453 // Find the file by name
454 bool sens = convertCaseSensitivity(cs) == Qt::CaseSensitive;
455 QString lower, current;
456 if(!sens) lower=fileName.toLower();
457 p->hasCurrentFile_f=false;
458
459 // Check the appropriate Map
460 unz64_file_pos fileDirPos;
461 fileDirPos.pos_in_zip_directory = 0;
462 if (sens) {
463 if (p->directoryCaseSensitive.contains(fileName))
464 fileDirPos = p->directoryCaseSensitive.value(fileName);
465 } else {
466 if (p->directoryCaseInsensitive.contains(lower))
467 fileDirPos = p->directoryCaseInsensitive.value(lower);
468 }
469
470 if (fileDirPos.pos_in_zip_directory != 0) {
471 p->zipError = unzGoToFilePos64(p->unzFile_f, &fileDirPos);
472 p->hasCurrentFile_f = p->zipError == UNZ_OK;
473 }
474
475 if (p->hasCurrentFile_f)
476 return p->hasCurrentFile_f;
477
478 // Not mapped yet, start from where we have got to so far
479 for(bool more=p->goToFirstUnmappedFile(); more; more=goToNextFile()) {
480 current=getCurrentFileName();
481 if(current.isEmpty()) return false;
482 if(sens) {
483 if(current==fileName) break;
484 } else {
485 if(current.toLower()==lower) break;
486 }
487 }
488 return p->hasCurrentFile_f;
489}
490
491bool QuaZip::goToFirstFile()
492{
493 p->zipError=UNZ_OK;
494 if(p->mode!=mdUnzip) {
495 qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode");
496 return false;
497 }
498 p->zipError=unzGoToFirstFile(p->unzFile_f);
499 p->hasCurrentFile_f=p->zipError==UNZ_OK;
500 return p->hasCurrentFile_f;
501}
502
503bool QuaZip::goToNextFile()
504{
505 p->zipError=UNZ_OK;
506 if(p->mode!=mdUnzip) {
507 qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode");
508 return false;
509 }
510 p->zipError=unzGoToNextFile(p->unzFile_f);
511 p->hasCurrentFile_f=p->zipError==UNZ_OK;
512 if(p->zipError==UNZ_END_OF_LIST_OF_FILE)
513 p->zipError=UNZ_OK;
514 return p->hasCurrentFile_f;
515}
516
517bool QuaZip::getCurrentFileInfo(QuaZipFileInfo *info)const
518{
519 QuaZipFileInfo64 info64;
520 if (info == NULL) { // Very unlikely because of the overloads
521 return false;
522 }
523 if (getCurrentFileInfo(&info64)) {
524 info64.toQuaZipFileInfo(*info);
525 return true;
526 } else {
527 return false;
528 }
529}
530
531bool QuaZip::getCurrentFileInfo(QuaZipFileInfo64 *info)const
532{
533 QuaZip *fakeThis=(QuaZip*)this; // non-const
534 fakeThis->p->zipError=UNZ_OK;
535 if(p->mode!=mdUnzip) {
536 qWarning("QuaZip::getCurrentFileInfo(): ZIP is not open in mdUnzip mode");
537 return false;
538 }
539 unz_file_info64 info_z;
540 QByteArray fileName;
541 QByteArray extra;
542 QByteArray comment;
543 if(info==NULL) return false;
544 if(!isOpen()||!hasCurrentFile()) return false;
545 if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, &info_z, NULL, 0, NULL, 0, NULL, 0))!=UNZ_OK)
546 return false;
547 fileName.resize(info_z.size_filename);
548 extra.resize(info_z.size_file_extra);
549 comment.resize(info_z.size_file_comment);
550 if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, NULL,
551 fileName.data(), fileName.size(),
552 extra.data(), extra.size(),
553 comment.data(), comment.size()))!=UNZ_OK)
554 return false;
555 info->versionCreated=info_z.version;
556 info->versionNeeded=info_z.version_needed;
557 info->flags=info_z.flag;
558 info->method=info_z.compression_method;
559 info->crc=info_z.crc;
560 info->compressedSize=info_z.compressed_size;
561 info->uncompressedSize=info_z.uncompressed_size;
562 info->diskNumberStart=info_z.disk_num_start;
563 info->internalAttr=info_z.internal_fa;
564 info->externalAttr=info_z.external_fa;
565 info->name=(info->flags & UNZ_ENCODING_UTF8) ? QString::fromUtf8(fileName) : p->fileNameCodec->toUnicode(fileName);
566 info->comment=(info->flags & UNZ_ENCODING_UTF8) ? QString::fromUtf8(comment) : p->commentCodec->toUnicode(comment);
567 info->extra=extra;
568 info->dateTime=QDateTime(
569 QDate(info_z.tmu_date.tm_year, info_z.tmu_date.tm_mon+1, info_z.tmu_date.tm_mday),
570 QTime(info_z.tmu_date.tm_hour, info_z.tmu_date.tm_min, info_z.tmu_date.tm_sec));
571 // Add to directory map
572 p->addCurrentFileToDirectoryMap(info->name);
573 return true;
574}
575
576QString QuaZip::getCurrentFileName()const
577{
578 QuaZip *fakeThis=(QuaZip*)this; // non-const
579 fakeThis->p->zipError=UNZ_OK;
580 if(p->mode!=mdUnzip) {
581 qWarning("QuaZip::getCurrentFileName(): ZIP is not open in mdUnzip mode");
582 return QString();
583 }
584 if(!isOpen()||!hasCurrentFile()) return QString();
585 QByteArray fileName(MAX_FILE_NAME_LENGTH, 0);
586 unz_file_info64 file_info;
587 if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, &file_info, fileName.data(), fileName.size(),
588 NULL, 0, NULL, 0))!=UNZ_OK)
589 return QString();
590 fileName.resize(file_info.size_filename);
591 QString result = (file_info.flag & UNZ_ENCODING_UTF8)
592 ? QString::fromUtf8(fileName) : p->fileNameCodec->toUnicode(fileName);
593 if (result.isEmpty())
594 return result;
595 // Add to directory map
596 p->addCurrentFileToDirectoryMap(result);
597 return result;
598}
599
600void QuaZip::setFileNameCodec(QTextCodec *fileNameCodec)
601{
602 p->fileNameCodec=fileNameCodec;
603}
604
605void QuaZip::setFileNameCodec(const char *fileNameCodecName)
606{
607 p->fileNameCodec=QTextCodec::codecForName(fileNameCodecName);
608}
609
610void QuaZip::setOsCode(uint osCode)
611{
612 p->osCode = osCode;
613}
614
615uint QuaZip::getOsCode() const
616{
617 return p->osCode;
618}
619
620QTextCodec *QuaZip::getFileNameCodec()const
621{
622 return p->fileNameCodec;
623}
624
625void QuaZip::setCommentCodec(QTextCodec *commentCodec)
626{
627 p->commentCodec=commentCodec;
628}
629
630void QuaZip::setCommentCodec(const char *commentCodecName)
631{
632 p->commentCodec=QTextCodec::codecForName(commentCodecName);
633}
634
635QTextCodec *QuaZip::getCommentCodec()const
636{
637 return p->commentCodec;
638}
639
640QString QuaZip::getZipName() const
641{
642 return p->zipName;
643}
644
645QIODevice *QuaZip::getIoDevice() const
646{
647 if (!p->zipName.isEmpty()) // opened by name, using an internal QIODevice
648 return NULL;
649 return p->ioDevice;
650}
651
652QuaZip::Mode QuaZip::getMode()const
653{
654 return p->mode;
655}
656
657bool QuaZip::isOpen()const
658{
659 return p->mode!=mdNotOpen;
660}
661
662int QuaZip::getZipError() const
663{
664 return p->zipError;
665}
666
667void QuaZip::setComment(const QString& comment)
668{
669 p->comment=comment;
670}
671
672bool QuaZip::hasCurrentFile()const
673{
674 return p->hasCurrentFile_f;
675}
676
677unzFile QuaZip::getUnzFile()
678{
679 return p->unzFile_f;
680}
681
682zipFile QuaZip::getZipFile()
683{
684 return p->zipFile_f;
685}
686
687void QuaZip::setDataDescriptorWritingEnabled(bool enabled)
688{
689 p->dataDescriptorWritingEnabled = enabled;
690}
691
692bool QuaZip::isDataDescriptorWritingEnabled() const
693{
694 return p->dataDescriptorWritingEnabled;
695}
696
697template<typename TFileInfo>
698TFileInfo QuaZip_getFileInfo(QuaZip *zip, bool *ok);
699
700template<>
701QuaZipFileInfo QuaZip_getFileInfo(QuaZip *zip, bool *ok)
702{
703 QuaZipFileInfo info;
704 *ok = zip->getCurrentFileInfo(&info);
705 return info;
706}
707
708template<>
709QuaZipFileInfo64 QuaZip_getFileInfo(QuaZip *zip, bool *ok)
710{
711 QuaZipFileInfo64 info;
712 *ok = zip->getCurrentFileInfo(&info);
713 return info;
714}
715
716template<>
717QString QuaZip_getFileInfo(QuaZip *zip, bool *ok)
718{
719 QString name = zip->getCurrentFileName();
720 *ok = !name.isEmpty();
721 return name;
722}
723
724template<typename TFileInfo>
725bool QuaZipPrivate::getFileInfoList(QList<TFileInfo> *result) const
726{
727 QuaZipPrivate *fakeThis=const_cast<QuaZipPrivate*>(this);
728 fakeThis->zipError=UNZ_OK;
729 if (mode!=QuaZip::mdUnzip) {
730 qWarning("QuaZip::getFileNameList/getFileInfoList(): "
731 "ZIP is not open in mdUnzip mode");
732 return false;
733 }
734 QString currentFile;
735 if (q->hasCurrentFile()) {
736 currentFile = q->getCurrentFileName();
737 }
738 if (q->goToFirstFile()) {
739 do {
740 bool ok;
741 result->append(QuaZip_getFileInfo<TFileInfo>(q, &ok));
742 if (!ok)
743 return false;
744 } while (q->goToNextFile());
745 }
746 if (zipError != UNZ_OK)
747 return false;
748 if (currentFile.isEmpty()) {
749 if (!q->goToFirstFile())
750 return false;
751 } else {
752 if (!q->setCurrentFile(currentFile))
753 return false;
754 }
755 return true;
756}
757
758QStringList QuaZip::getFileNameList() const
759{
760 QStringList list;
761 if (p->getFileInfoList(&list))
762 return list;
763 else
764 return QStringList();
765}
766
767QList<QuaZipFileInfo> QuaZip::getFileInfoList() const
768{
769 QList<QuaZipFileInfo> list;
770 if (p->getFileInfoList(&list))
771 return list;
772 else
773 return QList<QuaZipFileInfo>();
774}
775
776QList<QuaZipFileInfo64> QuaZip::getFileInfoList64() const
777{
778 QList<QuaZipFileInfo64> list;
779 if (p->getFileInfoList(&list))
780 return list;
781 else
782 return QList<QuaZipFileInfo64>();
783}
784
785Qt::CaseSensitivity QuaZip::convertCaseSensitivity(QuaZip::CaseSensitivity cs)
786{
787 if (cs == csDefault) {
788#ifdef Q_OS_WIN
789 return Qt::CaseInsensitive;
790#else
791 return Qt::CaseSensitive;
792#endif
793 } else {
794 return cs == csSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
795 }
796}
797
798void QuaZip::setDefaultFileNameCodec(QTextCodec *codec)
799{
800 QuaZipPrivate::defaultFileNameCodec = codec;
801}
802
803void QuaZip::setDefaultFileNameCodec(const char *codecName)
804{
805 setDefaultFileNameCodec(QTextCodec::codecForName(codecName));
806}
807
808void QuaZip::setDefaultOsCode(uint osCode)
809{
810 QuaZipPrivate::defaultOsCode = osCode;
811}
812
813uint QuaZip::getDefaultOsCode()
814{
815 return QuaZipPrivate::defaultOsCode;
816}
817
818void QuaZip::setZip64Enabled(bool zip64)
819{
820 p->zip64 = zip64;
821}
822
823bool QuaZip::isZip64Enabled() const
824{
825 return p->zip64;
826}
827
828void QuaZip::setUtf8Enabled(bool utf8)
829{
830 p->utf8 = utf8;
831}
832
833bool QuaZip::isUtf8Enabled() const
834{
835 return p->utf8;
836}
837
838bool QuaZip::isAutoClose() const
839{
840 return p->autoClose;
841}
842
843void QuaZip::setAutoClose(bool autoClose) const
844{
845 p->autoClose = autoClose;
846}
diff --git a/utils/rbutilqt/quazip/quazip.h b/utils/rbutilqt/quazip/quazip.h
new file mode 100644
index 0000000000..8ff0756254
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazip.h
@@ -0,0 +1,611 @@
1#ifndef QUA_ZIP_H
2#define QUA_ZIP_H
3
4/*
5Copyright (C) 2005-2014 Sergey A. Tachenov
6
7This file is part of QuaZIP.
8
9QuaZIP is free software: you can redistribute it and/or modify
10it under the terms of the GNU Lesser General Public License as published by
11the Free Software Foundation, either version 2.1 of the License, or
12(at your option) any later version.
13
14QuaZIP is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License
20along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
21
22See COPYING file for the full LGPL text.
23
24Original ZIP package is copyrighted by Gilles Vollant, see
25quazip/(un)zip.h files for details, basically it's zlib license.
26 **/
27
28#include <QtCore/QString>
29#include <QtCore/QStringList>
30#include <QTextCodec>
31
32#include "zip.h"
33#include "unzip.h"
34
35#include "quazip_global.h"
36#include "quazipfileinfo.h"
37
38// just in case it will be defined in the later versions of the ZIP/UNZIP
39#ifndef UNZ_OPENERROR
40// define additional error code
41#define UNZ_OPENERROR -1000
42#endif
43
44class QuaZipPrivate;
45
46/// ZIP archive.
47/** \class QuaZip quazip.h <quazip/quazip.h>
48 * This class implements basic interface to the ZIP archive. It can be
49 * used to read table contents of the ZIP archive and retreiving
50 * information about the files inside it.
51 *
52 * You can also use this class to open files inside archive by passing
53 * pointer to the instance of this class to the constructor of the
54 * QuaZipFile class. But see QuaZipFile::QuaZipFile(QuaZip*, QObject*)
55 * for the possible pitfalls.
56 *
57 * This class is indended to provide interface to the ZIP subpackage of
58 * the ZIP/UNZIP package as well as to the UNZIP subpackage. But
59 * currently it supports only UNZIP.
60 *
61 * The use of this class is simple - just create instance using
62 * constructor, then set ZIP archive file name using setFile() function
63 * (if you did not passed the name to the constructor), then open() and
64 * then use different functions to work with it! Well, if you are
65 * paranoid, you may also wish to call close before destructing the
66 * instance, to check for errors on close.
67 *
68 * You may also use getUnzFile() and getZipFile() functions to get the
69 * ZIP archive handle and use it with ZIP/UNZIP package API directly.
70 *
71 * This class supports localized file names inside ZIP archive, but you
72 * have to set up proper codec with setCodec() function. By default,
73 * locale codec will be used, which is probably ok for UNIX systems, but
74 * will almost certainly fail with ZIP archives created in Windows. This
75 * is because Windows ZIP programs have strange habit of using DOS
76 * encoding for file names in ZIP archives. For example, ZIP archive
77 * with cyrillic names created in Windows will have file names in \c
78 * IBM866 encoding instead of \c WINDOWS-1251. I think that calling one
79 * function is not much trouble, but for true platform independency it
80 * would be nice to have some mechanism for file name encoding auto
81 * detection using locale information. Does anyone know a good way to do
82 * it?
83 **/
84class QUAZIP_EXPORT QuaZip {
85 friend class QuaZipPrivate;
86 public:
87 /// Useful constants.
88 enum Constants {
89 MAX_FILE_NAME_LENGTH=256 /**< Maximum file name length. Taken from
90 \c UNZ_MAXFILENAMEINZIP constant in
91 unzip.c. */
92 };
93 /// Open mode of the ZIP file.
94 enum Mode {
95 mdNotOpen, ///< ZIP file is not open. This is the initial mode.
96 mdUnzip, ///< ZIP file is open for reading files inside it.
97 mdCreate, ///< ZIP file was created with open() call.
98 mdAppend, /**< ZIP file was opened in append mode. This refers to
99 * \c APPEND_STATUS_CREATEAFTER mode in ZIP/UNZIP package
100 * and means that zip is appended to some existing file
101 * what is useful when that file contains
102 * self-extractor code. This is obviously \em not what
103 * you whant to use to add files to the existing ZIP
104 * archive.
105 **/
106 mdAdd ///< ZIP file was opened for adding files in the archive.
107 };
108 /// Case sensitivity for the file names.
109 /** This is what you specify when accessing files in the archive.
110 * Works perfectly fine with any characters thanks to Qt's great
111 * unicode support. This is different from ZIP/UNZIP API, where
112 * only US-ASCII characters was supported.
113 **/
114 enum CaseSensitivity {
115 csDefault=0, ///< Default for platform. Case sensitive for UNIX, not for Windows.
116 csSensitive=1, ///< Case sensitive.
117 csInsensitive=2 ///< Case insensitive.
118 };
119 /// Returns the actual case sensitivity for the specified QuaZIP one.
120 /**
121 \param cs The value to convert.
122 \returns If CaseSensitivity::csDefault, then returns the default
123 file name case sensitivity for the platform. Otherwise, just
124 returns the appropriate value from the Qt::CaseSensitivity enum.
125 */
126 static Qt::CaseSensitivity convertCaseSensitivity(
127 CaseSensitivity cs);
128 private:
129 QuaZipPrivate *p;
130 // not (and will not be) implemented
131 QuaZip(const QuaZip& that);
132 // not (and will not be) implemented
133 QuaZip& operator=(const QuaZip& that);
134 public:
135 /// Constructs QuaZip object.
136 /** Call setName() before opening constructed object. */
137 QuaZip();
138 /// Constructs QuaZip object associated with ZIP file \a zipName.
139 QuaZip(const QString& zipName);
140 /// Constructs QuaZip object associated with ZIP file represented by \a ioDevice.
141 /** The IO device must be seekable, otherwise an error will occur when opening. */
142 QuaZip(QIODevice *ioDevice);
143 /// Destroys QuaZip object.
144 /** Calls close() if necessary. */
145 ~QuaZip();
146 /// Opens ZIP file.
147 /**
148 * Argument \a mode specifies open mode of the ZIP archive. See Mode
149 * for details. Note that there is zipOpen2() function in the
150 * ZIP/UNZIP API which accepts \a globalcomment argument, but it
151 * does not use it anywhere, so this open() function does not have this
152 * argument. See setComment() if you need to set global comment.
153 *
154 * If the ZIP file is accessed via explicitly set QIODevice, then
155 * this device is opened in the necessary mode. If the device was
156 * already opened by some other means, then QuaZIP checks if the
157 * open mode is compatible to the mode needed for the requested operation.
158 * If necessary, seeking is performed to position the device properly.
159 *
160 * \return \c true if successful, \c false otherwise.
161 *
162 * \note ZIP/UNZIP API open calls do not return error code - they
163 * just return \c NULL indicating an error. But to make things
164 * easier, quazip.h header defines additional error code \c
165 * UNZ_ERROROPEN and getZipError() will return it if the open call
166 * of the ZIP/UNZIP API returns \c NULL.
167 *
168 * Argument \a ioApi specifies IO function set for ZIP/UNZIP
169 * package to use. See unzip.h, zip.h and ioapi.h for details. Note
170 * that IO API for QuaZip is different from the original package.
171 * The file path argument was changed to be of type \c voidpf, and
172 * QuaZip passes a QIODevice pointer there. This QIODevice is either
173 * set explicitly via setIoDevice() or the QuaZip(QIODevice*)
174 * constructor, or it is created internally when opening the archive
175 * by its file name. The default API (qioapi.cpp) just delegates
176 * everything to the QIODevice API. Not only this allows to use a
177 * QIODevice instead of file name, but also has a nice side effect
178 * of raising the file size limit from 2G to 4G (in non-zip64 archives).
179 *
180 * \note If the zip64 support is needed, the ioApi argument \em must be NULL
181 * because due to the backwards compatibility issues it can be used to
182 * provide a 32-bit API only.
183 *
184 * \note If the \ref QuaZip::setAutoClose() "no-auto-close" feature is used,
185 * then the \a ioApi argument \em should be NULL because the old API
186 * doesn't support the 'fake close' operation, causing slight memory leaks
187 * and other possible troubles (like closing the output device in case
188 * when an error occurs during opening).
189 *
190 * In short: just forget about the \a ioApi argument and you'll be
191 * fine.
192 **/
193 bool open(Mode mode, zlib_filefunc_def *ioApi =NULL);
194 /// Closes ZIP file.
195 /** Call getZipError() to determine if the close was successful.
196 *
197 * If the file was opened by name, then the underlying QIODevice is closed
198 * and deleted.
199 *
200 * If the underlying QIODevice was set explicitly using setIoDevice() or
201 * the appropriate constructor, then it is closed if the auto-close flag
202 * is set (which it is by default). Call setAutoClose() to clear the
203 * auto-close flag if this behavior is undesirable.
204 *
205 * Since Qt 5.1, the QSaveFile was introduced. It breaks the QIODevice API
206 * by making close() private and crashing the application if it is called
207 * from the base class where it is public. It is an excellent example
208 * of poor design that illustrates why you should never ever break
209 * an is-a relationship between the base class and a subclass. QuaZIP
210 * works around this bug by checking if the QIODevice is an instance
211 * of QSaveFile, using qobject_cast<>, and if it is, calls
212 * QSaveFile::commit() instead of close(). It is a really ugly hack,
213 * but at least it makes your programs work instead of crashing. Note that
214 * if the auto-close flag is cleared, then this is a non-issue, and
215 * commit() isn't called.
216 */
217 void close();
218 /// Sets the codec used to encode/decode file names inside archive.
219 /** This is necessary to access files in the ZIP archive created
220 * under Windows with non-latin characters in file names. For
221 * example, file names with cyrillic letters will be in \c IBM866
222 * encoding.
223 **/
224 void setFileNameCodec(QTextCodec *fileNameCodec);
225 /// Sets the codec used to encode/decode file names inside archive.
226 /** \overload
227 * Equivalent to calling setFileNameCodec(QTextCodec::codecForName(codecName));
228 **/
229 void setFileNameCodec(const char *fileNameCodecName);
230 /// Sets the OS code (highest 8 bits of the “version made by” field) for new files.
231 /** There is currently no way to specify this for each file individually,
232 except by calling this function before opening each file. If this function is not called,
233 then the default OS code will be used. The default code is set by calling
234 setDefaultOsCode(). The default value at the moment of QuaZip creation will be used. */
235 void setOsCode(uint osCode);
236 /// Returns the OS code for new files.
237 uint getOsCode() const;
238 /// Returns the codec used to encode/decode comments inside archive.
239 QTextCodec* getFileNameCodec() const;
240 /// Sets the codec used to encode/decode comments inside archive.
241 /** This codec defaults to locale codec, which is probably ok.
242 **/
243 void setCommentCodec(QTextCodec *commentCodec);
244 /// Sets the codec used to encode/decode comments inside archive.
245 /** \overload
246 * Equivalent to calling setCommentCodec(QTextCodec::codecForName(codecName));
247 **/
248 void setCommentCodec(const char *commentCodecName);
249 /// Returns the codec used to encode/decode comments inside archive.
250 QTextCodec* getCommentCodec() const;
251 /// Returns the name of the ZIP file.
252 /** Returns null string if no ZIP file name has been set, for
253 * example when the QuaZip instance is set up to use a QIODevice
254 * instead.
255 * \sa setZipName(), setIoDevice(), getIoDevice()
256 **/
257 QString getZipName() const;
258 /// Sets the name of the ZIP file.
259 /** Does nothing if the ZIP file is open.
260 *
261 * Does not reset error code returned by getZipError().
262 * \sa setIoDevice(), getIoDevice(), getZipName()
263 **/
264 void setZipName(const QString& zipName);
265 /// Returns the device representing this ZIP file.
266 /** Returns null string if no device has been set explicitly, for
267 * example when opening a ZIP file by name.
268 * \sa setIoDevice(), getZipName(), setZipName()
269 **/
270 QIODevice *getIoDevice() const;
271 /// Sets the device representing the ZIP file.
272 /** Does nothing if the ZIP file is open.
273 *
274 * Does not reset error code returned by getZipError().
275 * \sa getIoDevice(), getZipName(), setZipName()
276 **/
277 void setIoDevice(QIODevice *ioDevice);
278 /// Returns the mode in which ZIP file was opened.
279 Mode getMode() const;
280 /// Returns \c true if ZIP file is open, \c false otherwise.
281 bool isOpen() const;
282 /// Returns the error code of the last operation.
283 /** Returns \c UNZ_OK if the last operation was successful.
284 *
285 * Error code resets to \c UNZ_OK every time you call any function
286 * that accesses something inside ZIP archive, even if it is \c
287 * const (like getEntriesCount()). open() and close() calls reset
288 * error code too. See documentation for the specific functions for
289 * details on error detection.
290 **/
291 int getZipError() const;
292 /// Returns number of the entries in the ZIP central directory.
293 /** Returns negative error code in the case of error. The same error
294 * code will be returned by subsequent getZipError() call.
295 **/
296 int getEntriesCount() const;
297 /// Returns global comment in the ZIP file.
298 QString getComment() const;
299 /// Sets the global comment in the ZIP file.
300 /** The comment will be written to the archive on close operation.
301 * QuaZip makes a distinction between a null QByteArray() comment
302 * and an empty &quot;&quot; comment in the QuaZip::mdAdd mode.
303 * A null comment is the default and it means &quot;don't change
304 * the comment&quot;. An empty comment removes the original comment.
305 *
306 * \sa open()
307 **/
308 void setComment(const QString& comment);
309 /// Sets the current file to the first file in the archive.
310 /** Returns \c true on success, \c false otherwise. Call
311 * getZipError() to get the error code.
312 **/
313 bool goToFirstFile();
314 /// Sets the current file to the next file in the archive.
315 /** Returns \c true on success, \c false otherwise. Call
316 * getZipError() to determine if there was an error.
317 *
318 * Should be used only in QuaZip::mdUnzip mode.
319 *
320 * \note If the end of file was reached, getZipError() will return
321 * \c UNZ_OK instead of \c UNZ_END_OF_LIST_OF_FILE. This is to make
322 * things like this easier:
323 * \code
324 * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) {
325 * // do something
326 * }
327 * if(zip.getZipError()==UNZ_OK) {
328 * // ok, there was no error
329 * }
330 * \endcode
331 **/
332 bool goToNextFile();
333 /// Sets current file by its name.
334 /** Returns \c true if successful, \c false otherwise. Argument \a
335 * cs specifies case sensitivity of the file name. Call
336 * getZipError() in the case of a failure to get error code.
337 *
338 * This is not a wrapper to unzLocateFile() function. That is
339 * because I had to implement locale-specific case-insensitive
340 * comparison.
341 *
342 * Here are the differences from the original implementation:
343 *
344 * - If the file was not found, error code is \c UNZ_OK, not \c
345 * UNZ_END_OF_LIST_OF_FILE (see also goToNextFile()).
346 * - If this function fails, it unsets the current file rather than
347 * resetting it back to what it was before the call.
348 *
349 * If \a fileName is null string then this function unsets the
350 * current file and return \c true. Note that you should close the
351 * file first if it is open! See
352 * QuaZipFile::QuaZipFile(QuaZip*,QObject*) for the details.
353 *
354 * Should be used only in QuaZip::mdUnzip mode.
355 *
356 * \sa setFileNameCodec(), CaseSensitivity
357 **/
358 bool setCurrentFile(const QString& fileName, CaseSensitivity cs =csDefault);
359 /// Returns \c true if the current file has been set.
360 bool hasCurrentFile() const;
361 /// Retrieves information about the current file.
362 /** Fills the structure pointed by \a info. Returns \c true on
363 * success, \c false otherwise. In the latter case structure pointed
364 * by \a info remains untouched. If there was an error,
365 * getZipError() returns error code.
366 *
367 * Should be used only in QuaZip::mdUnzip mode.
368 *
369 * Does nothing and returns \c false in any of the following cases.
370 * - ZIP is not open;
371 * - ZIP does not have current file.
372 *
373 * In both cases getZipError() returns \c UNZ_OK since there
374 * is no ZIP/UNZIP API call.
375 *
376 * This overload doesn't support zip64, but will work OK on zip64 archives
377 * except that if one of the sizes (compressed or uncompressed) is greater
378 * than 0xFFFFFFFFu, it will be set to exactly 0xFFFFFFFFu.
379 *
380 * \sa getCurrentFileInfo(QuaZipFileInfo64* info)const
381 * \sa QuaZipFileInfo64::toQuaZipFileInfo(QuaZipFileInfo&)const
382 **/
383 bool getCurrentFileInfo(QuaZipFileInfo* info)const;
384 /// Retrieves information about the current file.
385 /** \overload
386 *
387 * This function supports zip64. If the archive doesn't use zip64, it is
388 * completely equivalent to getCurrentFileInfo(QuaZipFileInfo* info)
389 * except for the argument type.
390 *
391 * \sa
392 **/
393 bool getCurrentFileInfo(QuaZipFileInfo64* info)const;
394 /// Returns the current file name.
395 /** Equivalent to calling getCurrentFileInfo() and then getting \c
396 * name field of the QuaZipFileInfo structure, but faster and more
397 * convenient.
398 *
399 * Should be used only in QuaZip::mdUnzip mode.
400 **/
401 QString getCurrentFileName()const;
402 /// Returns \c unzFile handle.
403 /** You can use this handle to directly call UNZIP part of the
404 * ZIP/UNZIP package functions (see unzip.h).
405 *
406 * \warning When using the handle returned by this function, please
407 * keep in mind that QuaZip class is unable to detect any changes
408 * you make in the ZIP file state (e. g. changing current file, or
409 * closing the handle). So please do not do anything with this
410 * handle that is possible to do with the functions of this class.
411 * Or at least return the handle in the original state before
412 * calling some another function of this class (including implicit
413 * destructor calls and calls from the QuaZipFile objects that refer
414 * to this QuaZip instance!). So if you have changed the current
415 * file in the ZIP archive - then change it back or you may
416 * experience some strange behavior or even crashes.
417 **/
418 unzFile getUnzFile();
419 /// Returns \c zipFile handle.
420 /** You can use this handle to directly call ZIP part of the
421 * ZIP/UNZIP package functions (see zip.h). Warnings about the
422 * getUnzFile() function also apply to this function.
423 **/
424 zipFile getZipFile();
425 /// Changes the data descriptor writing mode.
426 /**
427 According to the ZIP format specification, a file inside archive
428 may have a data descriptor immediately following the file
429 data. This is reflected by a special flag in the local file header
430 and in the central directory. By default, QuaZIP sets this flag
431 and writes the data descriptor unless both method and level were
432 set to 0, in which case it operates in 1.0-compatible mode and
433 never writes data descriptors.
434
435 By setting this flag to false, it is possible to disable data
436 descriptor writing, thus increasing compatibility with archive
437 readers that don't understand this feature of the ZIP file format.
438
439 Setting this flag affects all the QuaZipFile instances that are
440 opened after this flag is set.
441
442 The data descriptor writing mode is enabled by default.
443
444 Note that if the ZIP archive is written into a QIODevice for which
445 QIODevice::isSequential() returns \c true, then the data descriptor
446 is mandatory and will be written even if this flag is set to false.
447
448 \param enabled If \c true, enable local descriptor writing,
449 disable it otherwise.
450
451 \sa QuaZipFile::isDataDescriptorWritingEnabled()
452 */
453 void setDataDescriptorWritingEnabled(bool enabled);
454 /// Returns the data descriptor default writing mode.
455 /**
456 \sa setDataDescriptorWritingEnabled()
457 */
458 bool isDataDescriptorWritingEnabled() const;
459 /// Returns a list of files inside the archive.
460 /**
461 \return A list of file names or an empty list if there
462 was an error or if the archive is empty (call getZipError() to
463 figure out which).
464 \sa getFileInfoList()
465 */
466 QStringList getFileNameList() const;
467 /// Returns information list about all files inside the archive.
468 /**
469 \return A list of QuaZipFileInfo objects or an empty list if there
470 was an error or if the archive is empty (call getZipError() to
471 figure out which).
472
473 This function doesn't support zip64, but will still work with zip64
474 archives, converting results using QuaZipFileInfo64::toQuaZipFileInfo().
475 If all file sizes are below 4 GB, it will work just fine.
476
477 \sa getFileNameList()
478 \sa getFileInfoList64()
479 */
480 QList<QuaZipFileInfo> getFileInfoList() const;
481 /// Returns information list about all files inside the archive.
482 /**
483 \overload
484
485 This function supports zip64.
486
487 \sa getFileNameList()
488 \sa getFileInfoList()
489 */
490 QList<QuaZipFileInfo64> getFileInfoList64() const;
491 /// Enables the zip64 mode.
492 /**
493 * @param zip64 If \c true, the zip64 mode is enabled, disabled otherwise.
494 *
495 * Once this is enabled, all new files (until the mode is disabled again)
496 * will be created in the zip64 mode, thus enabling the ability to write
497 * files larger than 4 GB. By default, the zip64 mode is off due to
498 * compatibility reasons.
499 *
500 * Note that this does not affect the ability to read zip64 archives in any
501 * way.
502 *
503 * \sa isZip64Enabled()
504 */
505 void setZip64Enabled(bool zip64);
506 /// Returns whether the zip64 mode is enabled.
507 /**
508 * @return \c true if and only if the zip64 mode is enabled.
509 *
510 * \sa setZip64Enabled()
511 */
512 bool isZip64Enabled() const;
513 /// Enables the use of UTF-8 encoding for file names and comments text.
514 /**
515 * @param utf8 If \c true, the UTF-8 mode is enabled, disabled otherwise.
516 *
517 * Once this is enabled, the names of all new files and comments text (until
518 * the mode is disabled again) will be encoded in UTF-8 encoding, and the
519 * version to extract will be set to 6.3 (63) in ZIP header. By default,
520 * the UTF-8 mode is off due to compatibility reasons.
521 *
522 * Note that when extracting ZIP archives, the UTF-8 mode is determined from
523 * ZIP file header, not from this flag.
524 *
525 * \sa isUtf8Enabled()
526 */
527 void setUtf8Enabled(bool utf8);
528 /// Returns whether the UTF-8 encoding mode is enabled.
529 /**
530 * @return \c true if and only if the UTF-8 mode is enabled.
531 *
532 * \sa setUtf8Enabled()
533 */
534 bool isUtf8Enabled() const;
535 /// Returns the auto-close flag.
536 /**
537 @sa setAutoClose()
538 */
539 bool isAutoClose() const;
540 /// Sets or unsets the auto-close flag.
541 /**
542 By default, QuaZIP opens the underlying QIODevice when open() is called,
543 and closes it when close() is called. In some cases, when the device
544 is set explicitly using setIoDevice(), it may be desirable to
545 leave the device open. If the auto-close flag is unset using this method,
546 then the device isn't closed automatically if it was set explicitly.
547
548 If it is needed to clear this flag, it is recommended to do so before
549 opening the archive because otherwise QuaZIP may close the device
550 during the open() call if an error is encountered after the device
551 is opened.
552
553 If the device was not set explicitly, but rather the setZipName() or
554 the appropriate constructor was used to set the ZIP file name instead,
555 then the auto-close flag has no effect, and the internal device
556 is closed nevertheless because there is no other way to close it.
557
558 @sa isAutoClose()
559 @sa setIoDevice()
560 */
561 void setAutoClose(bool autoClose) const;
562 /// Sets the default file name codec to use.
563 /**
564 * The default codec is used by the constructors, so calling this function
565 * won't affect the QuaZip instances already created at that moment.
566 *
567 * The codec specified here can be overriden by calling setFileNameCodec().
568 * If neither function is called, QTextCodec::codecForLocale() will be used
569 * to decode or encode file names. Use this function with caution if
570 * the application uses other libraries that depend on QuaZIP. Those
571 * libraries can either call this function by themselves, thus overriding
572 * your setting or can rely on the default encoding, thus failing
573 * mysteriously if you change it. For these reasons, it isn't recommended
574 * to use this function if you are developing a library, not an application.
575 * Instead, ask your library users to call it in case they need specific
576 * encoding.
577 *
578 * In most cases, using setFileNameCodec() instead is the right choice.
579 * However, if you depend on third-party code that uses QuaZIP, then the
580 * reasons stated above can actually become a reason to use this function
581 * in case the third-party code in question fails because it doesn't
582 * understand the encoding you need and doesn't provide a way to specify it.
583 * This applies to the JlCompress class as well, as it was contributed and
584 * doesn't support explicit encoding parameters.
585 *
586 * In short: use setFileNameCodec() when you can, resort to
587 * setDefaultFileNameCodec() when you don't have access to the QuaZip
588 * instance.
589 *
590 * @param codec The codec to use by default. If NULL, resets to default.
591 */
592 static void setDefaultFileNameCodec(QTextCodec *codec);
593 /**
594 * @overload
595 * Equivalent to calling
596 * setDefaultFileNameCodec(QTextCodec::codecForName(codecName)).
597 */
598 static void setDefaultFileNameCodec(const char *codecName);
599 /// Sets default OS code.
600 /**
601 * @sa setOsCode()
602 */
603 static void setDefaultOsCode(uint osCode);
604 /// Returns default OS code.
605 /**
606 * @sa getOsCode()
607 */
608 static uint getDefaultOsCode();
609};
610
611#endif
diff --git a/utils/rbutilqt/quazip/quazip.pri b/utils/rbutilqt/quazip/quazip.pri
new file mode 100644
index 0000000000..3a82bd0275
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazip.pri
@@ -0,0 +1,25 @@
1
2SOURCES += \
3 $$PWD/quazip.cpp \
4 $$PWD/quazipfile.cpp \
5 $$PWD/quazipnewinfo.cpp \
6 $$PWD/quazipfileinfo.cpp \
7 $$PWD/qioapi.cpp \
8 $$PWD/unzip.c \
9 $$PWD/zip.c \
10
11HEADERS += \
12 $$PWD/minizip_crypt.h \
13 $$PWD/ioapi.h \
14 $$PWD/quazipfile.h \
15 $$PWD/quazipfileinfo.h \
16 $$PWD/quazipnewinfo.h \
17 $$PWD/quazip.h \
18 $$PWD/quazipnewinfo.h \
19 $$PWD/quazip_global.h \
20 $$PWD/unzip.h \
21 $$PWD/zip.h \
22
23DEFINES += \
24 QUAZIP_STATIC
25
diff --git a/utils/rbutilqt/quazip/quazip_global.h b/utils/rbutilqt/quazip/quazip_global.h
new file mode 100644
index 0000000000..de581bd7c4
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazip_global.h
@@ -0,0 +1,63 @@
1#ifndef QUAZIP_GLOBAL_H
2#define QUAZIP_GLOBAL_H
3
4/*
5Copyright (C) 2005-2014 Sergey A. Tachenov
6
7This file is part of QuaZIP.
8
9QuaZIP is free software: you can redistribute it and/or modify
10it under the terms of the GNU Lesser General Public License as published by
11the Free Software Foundation, either version 2.1 of the License, or
12(at your option) any later version.
13
14QuaZIP is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License
20along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
21
22See COPYING file for the full LGPL text.
23
24Original ZIP package is copyrighted by Gilles Vollant and contributors,
25see quazip/(un)zip.h files for details. Basically it's the zlib license.
26*/
27
28#include <QtCore/qglobal.h>
29
30/**
31 This is automatically defined when building a static library, but when
32 including QuaZip sources directly into a project, QUAZIP_STATIC should
33 be defined explicitly to avoid possible troubles with unnecessary
34 importing/exporting.
35 */
36#ifdef QUAZIP_STATIC
37#define QUAZIP_EXPORT
38#else
39/**
40 * When building a DLL with MSVC, QUAZIP_BUILD must be defined.
41 * qglobal.h takes care of defining Q_DECL_* correctly for msvc/gcc.
42 */
43#if defined(QUAZIP_BUILD)
44 #define QUAZIP_EXPORT Q_DECL_EXPORT
45#else
46 #define QUAZIP_EXPORT Q_DECL_IMPORT
47#endif
48#endif // QUAZIP_STATIC
49
50#ifdef __GNUC__
51#define QUAZIP_UNUSED __attribute__((__unused__))
52#else
53#define QUAZIP_UNUSED
54#endif
55
56#define QUAZIP_EXTRA_NTFS_MAGIC 0x000Au
57#define QUAZIP_EXTRA_NTFS_TIME_MAGIC 0x0001u
58#define QUAZIP_EXTRA_EXT_TIME_MAGIC 0x5455u
59#define QUAZIP_EXTRA_EXT_MOD_TIME_FLAG 1
60#define QUAZIP_EXTRA_EXT_AC_TIME_FLAG 2
61#define QUAZIP_EXTRA_EXT_CR_TIME_FLAG 4
62
63#endif // QUAZIP_GLOBAL_H
diff --git a/utils/rbutilqt/quazip/quazipfile.cpp b/utils/rbutilqt/quazip/quazipfile.cpp
new file mode 100644
index 0000000000..b984de7279
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazipfile.cpp
@@ -0,0 +1,570 @@
1/*
2Copyright (C) 2005-2014 Sergey A. Tachenov
3
4This file is part of QuaZIP.
5
6QuaZIP is free software: you can redistribute it and/or modify
7it under the terms of the GNU Lesser General Public License as published by
8the Free Software Foundation, either version 2.1 of the License, or
9(at your option) any later version.
10
11QuaZIP is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU Lesser General Public License for more details.
15
16You should have received a copy of the GNU Lesser General Public License
17along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
18
19See COPYING file for the full LGPL text.
20
21Original ZIP package is copyrighted by Gilles Vollant, see
22quazip/(un)zip.h files for details, basically it's zlib license.
23 **/
24
25#include "quazipfile.h"
26
27#include "quazipfileinfo.h"
28
29using namespace std;
30
31#define QUAZIP_VERSION_MADE_BY 0x1Eu
32
33/// The implementation class for QuaZip.
34/**
35\internal
36
37This class contains all the private stuff for the QuaZipFile class, thus
38allowing to preserve binary compatibility between releases, the
39technique known as the Pimpl (private implementation) idiom.
40*/
41class QuaZipFilePrivate {
42 friend class QuaZipFile;
43 private:
44 Q_DISABLE_COPY(QuaZipFilePrivate)
45 /// The pointer to the associated QuaZipFile instance.
46 QuaZipFile *q;
47 /// The QuaZip object to work with.
48 QuaZip *zip;
49 /// The file name.
50 QString fileName;
51 /// Case sensitivity mode.
52 QuaZip::CaseSensitivity caseSensitivity;
53 /// Whether this file is opened in the raw mode.
54 bool raw;
55 /// Write position to keep track of.
56 /**
57 QIODevice::pos() is broken for non-seekable devices, so we need
58 our own position.
59 */
60 qint64 writePos;
61 /// Uncompressed size to write along with a raw file.
62 quint64 uncompressedSize;
63 /// CRC to write along with a raw file.
64 quint32 crc;
65 /// Whether \ref zip points to an internal QuaZip instance.
66 /**
67 This is true if the archive was opened by name, rather than by
68 supplying an existing QuaZip instance.
69 */
70 bool internal;
71 /// The last error.
72 int zipError;
73 /// Resets \ref zipError.
74 inline void resetZipError() const {setZipError(UNZ_OK);}
75 /// Sets the zip error.
76 /**
77 This function is marked as const although it changes one field.
78 This allows to call it from const functions that don't change
79 anything by themselves.
80 */
81 void setZipError(int zipError) const;
82 /// The constructor for the corresponding QuaZipFile constructor.
83 inline QuaZipFilePrivate(QuaZipFile *q):
84 q(q),
85 zip(NULL),
86 caseSensitivity(QuaZip::csDefault),
87 raw(false),
88 writePos(0),
89 uncompressedSize(0),
90 crc(0),
91 internal(true),
92 zipError(UNZ_OK) {}
93 /// The constructor for the corresponding QuaZipFile constructor.
94 inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName):
95 q(q),
96 caseSensitivity(QuaZip::csDefault),
97 raw(false),
98 writePos(0),
99 uncompressedSize(0),
100 crc(0),
101 internal(true),
102 zipError(UNZ_OK)
103 {
104 zip=new QuaZip(zipName);
105 }
106 /// The constructor for the corresponding QuaZipFile constructor.
107 inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName, const QString &fileName,
108 QuaZip::CaseSensitivity cs):
109 q(q),
110 raw(false),
111 writePos(0),
112 uncompressedSize(0),
113 crc(0),
114 internal(true),
115 zipError(UNZ_OK)
116 {
117 zip=new QuaZip(zipName);
118 this->fileName=fileName;
119 if (this->fileName.startsWith(QLatin1String("/")))
120 this->fileName = this->fileName.mid(1);
121 this->caseSensitivity=cs;
122 }
123 /// The constructor for the QuaZipFile constructor accepting a file name.
124 inline QuaZipFilePrivate(QuaZipFile *q, QuaZip *zip):
125 q(q),
126 zip(zip),
127 raw(false),
128 writePos(0),
129 uncompressedSize(0),
130 crc(0),
131 internal(false),
132 zipError(UNZ_OK) {}
133 /// The destructor.
134 inline ~QuaZipFilePrivate()
135 {
136 if (internal)
137 delete zip;
138 }
139};
140
141QuaZipFile::QuaZipFile():
142 p(new QuaZipFilePrivate(this))
143{
144}
145
146QuaZipFile::QuaZipFile(QObject *parent):
147 QIODevice(parent),
148 p(new QuaZipFilePrivate(this))
149{
150}
151
152QuaZipFile::QuaZipFile(const QString& zipName, QObject *parent):
153 QIODevice(parent),
154 p(new QuaZipFilePrivate(this, zipName))
155{
156}
157
158QuaZipFile::QuaZipFile(const QString& zipName, const QString& fileName,
159 QuaZip::CaseSensitivity cs, QObject *parent):
160 QIODevice(parent),
161 p(new QuaZipFilePrivate(this, zipName, fileName, cs))
162{
163}
164
165QuaZipFile::QuaZipFile(QuaZip *zip, QObject *parent):
166 QIODevice(parent),
167 p(new QuaZipFilePrivate(this, zip))
168{
169}
170
171QuaZipFile::~QuaZipFile()
172{
173 if (isOpen())
174 close();
175 delete p;
176}
177
178QString QuaZipFile::getZipName() const
179{
180 return p->zip==NULL ? QString() : p->zip->getZipName();
181}
182
183QuaZip *QuaZipFile::getZip() const
184{
185 return p->internal ? NULL : p->zip;
186}
187
188QString QuaZipFile::getActualFileName()const
189{
190 p->setZipError(UNZ_OK);
191 if (p->zip == NULL || (openMode() & WriteOnly))
192 return QString();
193 QString name=p->zip->getCurrentFileName();
194 if(name.isNull())
195 p->setZipError(p->zip->getZipError());
196 return name;
197}
198
199void QuaZipFile::setZipName(const QString& zipName)
200{
201 if(isOpen()) {
202 qWarning("QuaZipFile::setZipName(): file is already open - can not set ZIP name");
203 return;
204 }
205 if(p->zip!=NULL && p->internal)
206 delete p->zip;
207 p->zip=new QuaZip(zipName);
208 p->internal=true;
209}
210
211void QuaZipFile::setZip(QuaZip *zip)
212{
213 if(isOpen()) {
214 qWarning("QuaZipFile::setZip(): file is already open - can not set ZIP");
215 return;
216 }
217 if(p->zip!=NULL && p->internal)
218 delete p->zip;
219 p->zip=zip;
220 p->fileName=QString();
221 p->internal=false;
222}
223
224void QuaZipFile::setFileName(const QString& fileName, QuaZip::CaseSensitivity cs)
225{
226 if(p->zip==NULL) {
227 qWarning("QuaZipFile::setFileName(): call setZipName() first");
228 return;
229 }
230 if(!p->internal) {
231 qWarning("QuaZipFile::setFileName(): should not be used when not using internal QuaZip");
232 return;
233 }
234 if(isOpen()) {
235 qWarning("QuaZipFile::setFileName(): can not set file name for already opened file");
236 return;
237 }
238 p->fileName=fileName;
239 if (p->fileName.startsWith(QLatin1String("/")))
240 p->fileName = p->fileName.mid(1);
241 p->caseSensitivity=cs;
242}
243
244void QuaZipFilePrivate::setZipError(int zipError) const
245{
246 QuaZipFilePrivate *fakeThis = const_cast<QuaZipFilePrivate*>(this); // non-const
247 fakeThis->zipError=zipError;
248 if(zipError==UNZ_OK)
249 q->setErrorString(QString());
250 else
251 q->setErrorString(QuaZipFile::tr("ZIP/UNZIP API error %1").arg(zipError));
252}
253
254bool QuaZipFile::open(OpenMode mode)
255{
256 return open(mode, NULL);
257}
258
259bool QuaZipFile::open(OpenMode mode, int *method, int *level, bool raw, const char *password)
260{
261 p->resetZipError();
262 if(isOpen()) {
263 qWarning("QuaZipFile::open(): already opened");
264 return false;
265 }
266 if(mode&Unbuffered) {
267 qWarning("QuaZipFile::open(): Unbuffered mode is not supported");
268 return false;
269 }
270 if((mode&ReadOnly)&&!(mode&WriteOnly)) {
271 if(p->internal) {
272 if(!p->zip->open(QuaZip::mdUnzip)) {
273 p->setZipError(p->zip->getZipError());
274 return false;
275 }
276 if(!p->zip->setCurrentFile(p->fileName, p->caseSensitivity)) {
277 p->setZipError(p->zip->getZipError());
278 p->zip->close();
279 return false;
280 }
281 } else {
282 if(p->zip==NULL) {
283 qWarning("QuaZipFile::open(): zip is NULL");
284 return false;
285 }
286 if(p->zip->getMode()!=QuaZip::mdUnzip) {
287 qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d",
288 (int)mode, (int)p->zip->getMode());
289 return false;
290 }
291 if(!p->zip->hasCurrentFile()) {
292 qWarning("QuaZipFile::open(): zip does not have current file");
293 return false;
294 }
295 }
296 p->setZipError(unzOpenCurrentFile3(p->zip->getUnzFile(), method, level, (int)raw, password));
297 if(p->zipError==UNZ_OK) {
298 setOpenMode(mode);
299 p->raw=raw;
300 return true;
301 } else
302 return false;
303 }
304 qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode);
305 return false;
306}
307
308bool QuaZipFile::open(OpenMode mode, const QuaZipNewInfo& info,
309 const char *password, quint32 crc,
310 int method, int level, bool raw,
311 int windowBits, int memLevel, int strategy)
312{
313 zip_fileinfo info_z;
314 p->resetZipError();
315 if(isOpen()) {
316 qWarning("QuaZipFile::open(): already opened");
317 return false;
318 }
319 if((mode&WriteOnly)&&!(mode&ReadOnly)) {
320 if(p->internal) {
321 qWarning("QuaZipFile::open(): write mode is incompatible with internal QuaZip approach");
322 return false;
323 }
324 if(p->zip==NULL) {
325 qWarning("QuaZipFile::open(): zip is NULL");
326 return false;
327 }
328 if(p->zip->getMode()!=QuaZip::mdCreate&&p->zip->getMode()!=QuaZip::mdAppend&&p->zip->getMode()!=QuaZip::mdAdd) {
329 qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d",
330 (int)mode, (int)p->zip->getMode());
331 return false;
332 }
333 info_z.tmz_date.tm_year=info.dateTime.date().year();
334 info_z.tmz_date.tm_mon=info.dateTime.date().month() - 1;
335 info_z.tmz_date.tm_mday=info.dateTime.date().day();
336 info_z.tmz_date.tm_hour=info.dateTime.time().hour();
337 info_z.tmz_date.tm_min=info.dateTime.time().minute();
338 info_z.tmz_date.tm_sec=info.dateTime.time().second();
339 info_z.dosDate = 0;
340 info_z.internal_fa=(uLong)info.internalAttr;
341 info_z.external_fa=(uLong)info.externalAttr;
342 if (p->zip->isDataDescriptorWritingEnabled())
343 zipSetFlags(p->zip->getZipFile(), ZIP_WRITE_DATA_DESCRIPTOR);
344 else
345 zipClearFlags(p->zip->getZipFile(), ZIP_WRITE_DATA_DESCRIPTOR);
346 p->setZipError(zipOpenNewFileInZip4_64(p->zip->getZipFile(),
347 p->zip->isUtf8Enabled()
348 ? info.name.toUtf8().constData()
349 : p->zip->getFileNameCodec()->fromUnicode(info.name).constData(),
350 &info_z,
351 info.extraLocal.constData(), info.extraLocal.length(),
352 info.extraGlobal.constData(), info.extraGlobal.length(),
353 p->zip->isUtf8Enabled()
354 ? info.comment.toUtf8().constData()
355 : p->zip->getCommentCodec()->fromUnicode(info.comment).constData(),
356 method, level, (int)raw,
357 windowBits, memLevel, strategy,
358 password, (uLong)crc,
359 (p->zip->getOsCode() << 8) | QUAZIP_VERSION_MADE_BY,
360 0,
361 p->zip->isZip64Enabled()));
362 if(p->zipError==UNZ_OK) {
363 p->writePos=0;
364 setOpenMode(mode);
365 p->raw=raw;
366 if(raw) {
367 p->crc=crc;
368 p->uncompressedSize=info.uncompressedSize;
369 }
370 return true;
371 } else
372 return false;
373 }
374 qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode);
375 return false;
376}
377
378bool QuaZipFile::isSequential()const
379{
380 return true;
381}
382
383qint64 QuaZipFile::pos()const
384{
385 if(p->zip==NULL) {
386 qWarning("QuaZipFile::pos(): call setZipName() or setZip() first");
387 return -1;
388 }
389 if(!isOpen()) {
390 qWarning("QuaZipFile::pos(): file is not open");
391 return -1;
392 }
393 if(openMode()&ReadOnly)
394 // QIODevice::pos() is broken for sequential devices,
395 // but thankfully bytesAvailable() returns the number of
396 // bytes buffered, so we know how far ahead we are.
397 return unztell64(p->zip->getUnzFile()) - QIODevice::bytesAvailable();
398 else
399 return p->writePos;
400}
401
402bool QuaZipFile::atEnd()const
403{
404 if(p->zip==NULL) {
405 qWarning("QuaZipFile::atEnd(): call setZipName() or setZip() first");
406 return false;
407 }
408 if(!isOpen()) {
409 qWarning("QuaZipFile::atEnd(): file is not open");
410 return false;
411 }
412 if(openMode()&ReadOnly)
413 // the same problem as with pos()
414 return QIODevice::bytesAvailable() == 0
415 && unzeof(p->zip->getUnzFile())==1;
416 else
417 return true;
418}
419
420qint64 QuaZipFile::size()const
421{
422 if(!isOpen()) {
423 qWarning("QuaZipFile::atEnd(): file is not open");
424 return -1;
425 }
426 if(openMode()&ReadOnly)
427 return p->raw?csize():usize();
428 else
429 return p->writePos;
430}
431
432qint64 QuaZipFile::csize()const
433{
434 unz_file_info64 info_z;
435 p->setZipError(UNZ_OK);
436 if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1;
437 p->setZipError(unzGetCurrentFileInfo64(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0));
438 if(p->zipError!=UNZ_OK)
439 return -1;
440 return info_z.compressed_size;
441}
442
443qint64 QuaZipFile::usize()const
444{
445 unz_file_info64 info_z;
446 p->setZipError(UNZ_OK);
447 if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1;
448 p->setZipError(unzGetCurrentFileInfo64(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0));
449 if(p->zipError!=UNZ_OK)
450 return -1;
451 return info_z.uncompressed_size;
452}
453
454bool QuaZipFile::getFileInfo(QuaZipFileInfo *info)
455{
456 QuaZipFileInfo64 info64;
457 if (getFileInfo(&info64)) {
458 info64.toQuaZipFileInfo(*info);
459 return true;
460 } else {
461 return false;
462 }
463}
464
465bool QuaZipFile::getFileInfo(QuaZipFileInfo64 *info)
466{
467 if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return false;
468 p->zip->getCurrentFileInfo(info);
469 p->setZipError(p->zip->getZipError());
470 return p->zipError==UNZ_OK;
471}
472
473void QuaZipFile::close()
474{
475 p->resetZipError();
476 if(p->zip==NULL||!p->zip->isOpen()) return;
477 if(!isOpen()) {
478 qWarning("QuaZipFile::close(): file isn't open");
479 return;
480 }
481 if(openMode()&ReadOnly)
482 p->setZipError(unzCloseCurrentFile(p->zip->getUnzFile()));
483 else if(openMode()&WriteOnly)
484 if(isRaw()) p->setZipError(zipCloseFileInZipRaw64(p->zip->getZipFile(), p->uncompressedSize, p->crc));
485 else p->setZipError(zipCloseFileInZip(p->zip->getZipFile()));
486 else {
487 qWarning("Wrong open mode: %d", (int)openMode());
488 return;
489 }
490 if(p->zipError==UNZ_OK) setOpenMode(QIODevice::NotOpen);
491 else return;
492 if(p->internal) {
493 p->zip->close();
494 p->setZipError(p->zip->getZipError());
495 }
496}
497
498qint64 QuaZipFile::readData(char *data, qint64 maxSize)
499{
500 p->setZipError(UNZ_OK);
501 qint64 bytesRead=unzReadCurrentFile(p->zip->getUnzFile(), data, (unsigned)maxSize);
502 if (bytesRead < 0) {
503 p->setZipError((int) bytesRead);
504 return -1;
505 }
506 return bytesRead;
507}
508
509qint64 QuaZipFile::writeData(const char* data, qint64 maxSize)
510{
511 p->setZipError(ZIP_OK);
512 p->setZipError(zipWriteInFileInZip(p->zip->getZipFile(), data, (uint)maxSize));
513 if(p->zipError!=ZIP_OK) return -1;
514 else {
515 p->writePos+=maxSize;
516 return maxSize;
517 }
518}
519
520QString QuaZipFile::getFileName() const
521{
522 return p->fileName;
523}
524
525QuaZip::CaseSensitivity QuaZipFile::getCaseSensitivity() const
526{
527 return p->caseSensitivity;
528}
529
530bool QuaZipFile::isRaw() const
531{
532 return p->raw;
533}
534
535int QuaZipFile::getZipError() const
536{
537 return p->zipError;
538}
539
540qint64 QuaZipFile::bytesAvailable() const
541{
542 return size() - pos();
543}
544
545QByteArray QuaZipFile::getLocalExtraField()
546{
547 int size = unzGetLocalExtrafield(p->zip->getUnzFile(), NULL, 0);
548 QByteArray extra(size, '\0');
549 int err = unzGetLocalExtrafield(p->zip->getUnzFile(), extra.data(), static_cast<uint>(extra.size()));
550 if (err < 0) {
551 p->setZipError(err);
552 return QByteArray();
553 }
554 return extra;
555}
556
557QDateTime QuaZipFile::getExtModTime()
558{
559 return QuaZipFileInfo64::getExtTime(getLocalExtraField(), QUAZIP_EXTRA_EXT_MOD_TIME_FLAG);
560}
561
562QDateTime QuaZipFile::getExtAcTime()
563{
564 return QuaZipFileInfo64::getExtTime(getLocalExtraField(), QUAZIP_EXTRA_EXT_AC_TIME_FLAG);
565}
566
567QDateTime QuaZipFile::getExtCrTime()
568{
569 return QuaZipFileInfo64::getExtTime(getLocalExtraField(), QUAZIP_EXTRA_EXT_CR_TIME_FLAG);
570}
diff --git a/utils/rbutilqt/quazip/quazipfile.h b/utils/rbutilqt/quazip/quazipfile.h
new file mode 100644
index 0000000000..0fd6829f36
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazipfile.h
@@ -0,0 +1,508 @@
1#ifndef QUA_ZIPFILE_H
2#define QUA_ZIPFILE_H
3
4/*
5Copyright (C) 2005-2014 Sergey A. Tachenov
6
7This file is part of QuaZIP.
8
9QuaZIP is free software: you can redistribute it and/or modify
10it under the terms of the GNU Lesser General Public License as published by
11the Free Software Foundation, either version 2.1 of the License, or
12(at your option) any later version.
13
14QuaZIP is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License
20along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
21
22See COPYING file for the full LGPL text.
23
24Original ZIP package is copyrighted by Gilles Vollant, see
25quazip/(un)zip.h files for details, basically it's zlib license.
26 **/
27
28#include <QtCore/QIODevice>
29
30#include "quazip_global.h"
31#include "quazip.h"
32#include "quazipnewinfo.h"
33
34class QuaZipFilePrivate;
35
36/// A file inside ZIP archive.
37/** \class QuaZipFile quazipfile.h <quazip/quazipfile.h>
38 * This is the most interesting class. Not only it provides C++
39 * interface to the ZIP/UNZIP package, but also integrates it with Qt by
40 * subclassing QIODevice. This makes possible to access files inside ZIP
41 * archive using QTextStream or QDataStream, for example. Actually, this
42 * is the main purpose of the whole QuaZIP library.
43 *
44 * You can either use existing QuaZip instance to create instance of
45 * this class or pass ZIP archive file name to this class, in which case
46 * it will create internal QuaZip object. See constructors' descriptions
47 * for details. Writing is only possible with the existing instance.
48 *
49 * Note that due to the underlying library's limitation it is not
50 * possible to use multiple QuaZipFile instances to open several files
51 * in the same archive at the same time. If you need to write to
52 * multiple files in parallel, then you should write to temporary files
53 * first, then pack them all at once when you have finished writing. If
54 * you need to read multiple files inside the same archive in parallel,
55 * you should extract them all into a temporary directory first.
56 *
57 * \section quazipfile-sequential Sequential or random-access?
58 *
59 * At the first thought, QuaZipFile has fixed size, the start and the
60 * end and should be therefore considered random-access device. But
61 * there is one major obstacle to making it random-access: ZIP/UNZIP API
62 * does not support seek() operation and the only way to implement it is
63 * through reopening the file and re-reading to the required position,
64 * but this is prohibitively slow.
65 *
66 * Therefore, QuaZipFile is considered to be a sequential device. This
67 * has advantage of availability of the ungetChar() operation (QIODevice
68 * does not implement it properly for non-sequential devices unless they
69 * support seek()). Disadvantage is a somewhat strange behaviour of the
70 * size() and pos() functions. This should be kept in mind while using
71 * this class.
72 *
73 **/
74class QUAZIP_EXPORT QuaZipFile: public QIODevice {
75 friend class QuaZipFilePrivate;
76 Q_OBJECT
77 private:
78 QuaZipFilePrivate *p;
79 // these are not supported nor implemented
80 QuaZipFile(const QuaZipFile& that);
81 QuaZipFile& operator=(const QuaZipFile& that);
82 protected:
83 /// Implementation of the QIODevice::readData().
84 qint64 readData(char *data, qint64 maxSize);
85 /// Implementation of the QIODevice::writeData().
86 qint64 writeData(const char *data, qint64 maxSize);
87 public:
88 /// Constructs a QuaZipFile instance.
89 /** You should use setZipName() and setFileName() or setZip() before
90 * trying to call open() on the constructed object.
91 **/
92 QuaZipFile();
93 /// Constructs a QuaZipFile instance.
94 /** \a parent argument specifies this object's parent object.
95 *
96 * You should use setZipName() and setFileName() or setZip() before
97 * trying to call open() on the constructed object.
98 **/
99 QuaZipFile(QObject *parent);
100 /// Constructs a QuaZipFile instance.
101 /** \a parent argument specifies this object's parent object and \a
102 * zipName specifies ZIP archive file name.
103 *
104 * You should use setFileName() before trying to call open() on the
105 * constructed object.
106 *
107 * QuaZipFile constructed by this constructor can be used for read
108 * only access. Use QuaZipFile(QuaZip*,QObject*) for writing.
109 **/
110 QuaZipFile(const QString& zipName, QObject *parent =NULL);
111 /// Constructs a QuaZipFile instance.
112 /** \a parent argument specifies this object's parent object, \a
113 * zipName specifies ZIP archive file name and \a fileName and \a cs
114 * specify a name of the file to open inside archive.
115 *
116 * QuaZipFile constructed by this constructor can be used for read
117 * only access. Use QuaZipFile(QuaZip*,QObject*) for writing.
118 *
119 * \sa QuaZip::setCurrentFile()
120 **/
121 QuaZipFile(const QString& zipName, const QString& fileName,
122 QuaZip::CaseSensitivity cs =QuaZip::csDefault, QObject *parent =NULL);
123 /// Constructs a QuaZipFile instance.
124 /** \a parent argument specifies this object's parent object.
125 *
126 * \a zip is the pointer to the existing QuaZip object. This
127 * QuaZipFile object then can be used to read current file in the
128 * \a zip or to write to the file inside it.
129 *
130 * \warning Using this constructor for reading current file can be
131 * tricky. Let's take the following example:
132 * \code
133 * QuaZip zip("archive.zip");
134 * zip.open(QuaZip::mdUnzip);
135 * zip.setCurrentFile("file-in-archive");
136 * QuaZipFile file(&zip);
137 * file.open(QIODevice::ReadOnly);
138 * // ok, now we can read from the file
139 * file.read(somewhere, some);
140 * zip.setCurrentFile("another-file-in-archive"); // oops...
141 * QuaZipFile anotherFile(&zip);
142 * anotherFile.open(QIODevice::ReadOnly);
143 * anotherFile.read(somewhere, some); // this is still ok...
144 * file.read(somewhere, some); // and this is NOT
145 * \endcode
146 * So, what exactly happens here? When we change current file in the
147 * \c zip archive, \c file that references it becomes invalid
148 * (actually, as far as I understand ZIP/UNZIP sources, it becomes
149 * closed, but QuaZipFile has no means to detect it).
150 *
151 * Summary: do not close \c zip object or change its current file as
152 * long as QuaZipFile is open. Even better - use another constructors
153 * which create internal QuaZip instances, one per object, and
154 * therefore do not cause unnecessary trouble. This constructor may
155 * be useful, though, if you already have a QuaZip instance and do
156 * not want to access several files at once. Good example:
157 * \code
158 * QuaZip zip("archive.zip");
159 * zip.open(QuaZip::mdUnzip);
160 * // first, we need some information about archive itself
161 * QByteArray comment=zip.getComment();
162 * // and now we are going to access files inside it
163 * QuaZipFile file(&zip);
164 * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) {
165 * file.open(QIODevice::ReadOnly);
166 * // do something cool with file here
167 * file.close(); // do not forget to close!
168 * }
169 * zip.close();
170 * \endcode
171 **/
172 QuaZipFile(QuaZip *zip, QObject *parent =NULL);
173 /// Destroys a QuaZipFile instance.
174 /** Closes file if open, destructs internal QuaZip object (if it
175 * exists and \em is internal, of course).
176 **/
177 virtual ~QuaZipFile();
178 /// Returns the ZIP archive file name.
179 /** If this object was created by passing QuaZip pointer to the
180 * constructor, this function will return that QuaZip's file name
181 * (or null string if that object does not have file name yet).
182 *
183 * Otherwise, returns associated ZIP archive file name or null
184 * string if there are no name set yet.
185 *
186 * \sa setZipName() getFileName()
187 **/
188 QString getZipName()const;
189 /// Returns a pointer to the associated QuaZip object.
190 /** Returns \c NULL if there is no associated QuaZip or it is
191 * internal (so you will not mess with it).
192 **/
193 QuaZip* getZip()const;
194 /// Returns file name.
195 /** This function returns file name you passed to this object either
196 * by using
197 * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*)
198 * or by calling setFileName(). Real name of the file may differ in
199 * case if you used case-insensitivity.
200 *
201 * Returns null string if there is no file name set yet. This is the
202 * case when this QuaZipFile operates on the existing QuaZip object
203 * (constructor QuaZipFile(QuaZip*,QObject*) or setZip() was used).
204 *
205 * \sa getActualFileName
206 **/
207 QString getFileName() const;
208 /// Returns case sensitivity of the file name.
209 /** This function returns case sensitivity argument you passed to
210 * this object either by using
211 * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*)
212 * or by calling setFileName().
213 *
214 * Returns unpredictable value if getFileName() returns null string
215 * (this is the case when you did not used setFileName() or
216 * constructor above).
217 *
218 * \sa getFileName
219 **/
220 QuaZip::CaseSensitivity getCaseSensitivity() const;
221 /// Returns the actual file name in the archive.
222 /** This is \em not a ZIP archive file name, but a name of file inside
223 * archive. It is not necessary the same name that you have passed
224 * to the
225 * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*),
226 * setFileName() or QuaZip::setCurrentFile() - this is the real file
227 * name inside archive, so it may differ in case if the file name
228 * search was case-insensitive.
229 *
230 * Equivalent to calling getCurrentFileName() on the associated
231 * QuaZip object. Returns null string if there is no associated
232 * QuaZip object or if it does not have a current file yet. And this
233 * is the case if you called setFileName() but did not open the
234 * file yet. So this is perfectly fine:
235 * \code
236 * QuaZipFile file("somezip.zip");
237 * file.setFileName("somefile");
238 * QString name=file.getName(); // name=="somefile"
239 * QString actual=file.getActualFileName(); // actual is null string
240 * file.open(QIODevice::ReadOnly);
241 * QString actual=file.getActualFileName(); // actual can be "SoMeFiLe" on Windows
242 * \endcode
243 *
244 * \sa getZipName(), getFileName(), QuaZip::CaseSensitivity
245 **/
246 QString getActualFileName()const;
247 /// Sets the ZIP archive file name.
248 /** Automatically creates internal QuaZip object and destroys
249 * previously created internal QuaZip object, if any.
250 *
251 * Will do nothing if this file is already open. You must close() it
252 * first.
253 **/
254 void setZipName(const QString& zipName);
255 /// Returns \c true if the file was opened in raw mode.
256 /** If the file is not open, the returned value is undefined.
257 *
258 * \sa open(OpenMode,int*,int*,bool,const char*)
259 **/
260 bool isRaw() const;
261 /// Binds to the existing QuaZip instance.
262 /** This function destroys internal QuaZip object, if any, and makes
263 * this QuaZipFile to use current file in the \a zip object for any
264 * further operations. See QuaZipFile(QuaZip*,QObject*) for the
265 * possible pitfalls.
266 *
267 * Will do nothing if the file is currently open. You must close()
268 * it first.
269 **/
270 void setZip(QuaZip *zip);
271 /// Sets the file name.
272 /** Will do nothing if at least one of the following conditions is
273 * met:
274 * - ZIP name has not been set yet (getZipName() returns null
275 * string).
276 * - This QuaZipFile is associated with external QuaZip. In this
277 * case you should call that QuaZip's setCurrentFile() function
278 * instead!
279 * - File is already open so setting the name is meaningless.
280 *
281 * \sa QuaZip::setCurrentFile
282 **/
283 void setFileName(const QString& fileName, QuaZip::CaseSensitivity cs =QuaZip::csDefault);
284 /// Opens a file for reading.
285 /** Returns \c true on success, \c false otherwise.
286 * Call getZipError() to get error code.
287 *
288 * \note Since ZIP/UNZIP API provides buffered reading only,
289 * QuaZipFile does not support unbuffered reading. So do not pass
290 * QIODevice::Unbuffered flag in \a mode, or open will fail.
291 **/
292 virtual bool open(OpenMode mode);
293 /// Opens a file for reading.
294 /** \overload
295 * Argument \a password specifies a password to decrypt the file. If
296 * it is NULL then this function behaves just like open(OpenMode).
297 **/
298 inline bool open(OpenMode mode, const char *password)
299 {return open(mode, NULL, NULL, false, password);}
300 /// Opens a file for reading.
301 /** \overload
302 * Argument \a password specifies a password to decrypt the file.
303 *
304 * An integers pointed by \a method and \a level will receive codes
305 * of the compression method and level used. See unzip.h.
306 *
307 * If raw is \c true then no decompression is performed.
308 *
309 * \a method should not be \c NULL. \a level can be \c NULL if you
310 * don't want to know the compression level.
311 **/
312 bool open(OpenMode mode, int *method, int *level, bool raw, const char *password =NULL);
313 /// Opens a file for writing.
314 /** \a info argument specifies information about file. It should at
315 * least specify a correct file name. Also, it is a good idea to
316 * specify correct timestamp (by default, current time will be
317 * used). See QuaZipNewInfo.
318 *
319 * The \a password argument specifies the password for crypting. Pass NULL
320 * if you don't need any crypting. The \a crc argument was supposed
321 * to be used for crypting too, but then it turned out that it's
322 * false information, so you need to set it to 0 unless you want to
323 * use the raw mode (see below).
324 *
325 * Arguments \a method and \a level specify compression method and
326 * level. The only method supported is Z_DEFLATED, but you may also
327 * specify 0 for no compression. If all of the files in the archive
328 * use both method 0 and either level 0 is explicitly specified or
329 * data descriptor writing is disabled with
330 * QuaZip::setDataDescriptorWritingEnabled(), then the
331 * resulting archive is supposed to be compatible with the 1.0 ZIP
332 * format version, should you need that. Except for this, \a level
333 * has no other effects with method 0.
334 *
335 * If \a raw is \c true, no compression is performed. In this case,
336 * \a crc and uncompressedSize field of the \a info are required.
337 *
338 * Arguments \a windowBits, \a memLevel, \a strategy provide zlib
339 * algorithms tuning. See deflateInit2() in zlib.
340 **/
341 bool open(OpenMode mode, const QuaZipNewInfo& info,
342 const char *password =NULL, quint32 crc =0,
343 int method =Z_DEFLATED, int level =Z_DEFAULT_COMPRESSION, bool raw =false,
344 int windowBits =-MAX_WBITS, int memLevel =DEF_MEM_LEVEL, int strategy =Z_DEFAULT_STRATEGY);
345 /// Returns \c true, but \ref quazipfile-sequential "beware"!
346 virtual bool isSequential()const;
347 /// Returns current position in the file.
348 /** Implementation of the QIODevice::pos(). When reading, this
349 * function is a wrapper to the ZIP/UNZIP unztell(), therefore it is
350 * unable to keep track of the ungetChar() calls (which is
351 * non-virtual and therefore is dangerous to reimplement). So if you
352 * are using ungetChar() feature of the QIODevice, this function
353 * reports incorrect value until you get back characters which you
354 * ungot.
355 *
356 * When writing, pos() returns number of bytes already written
357 * (uncompressed unless you use raw mode).
358 *
359 * \note Although
360 * \ref quazipfile-sequential "QuaZipFile is a sequential device"
361 * and therefore pos() should always return zero, it does not,
362 * because it would be misguiding. Keep this in mind.
363 *
364 * This function returns -1 if the file or archive is not open.
365 *
366 * Error code returned by getZipError() is not affected by this
367 * function call.
368 **/
369 virtual qint64 pos()const;
370 /// Returns \c true if the end of file was reached.
371 /** This function returns \c false in the case of error. This means
372 * that you called this function on either not open file, or a file
373 * in the not open archive or even on a QuaZipFile instance that
374 * does not even have QuaZip instance associated. Do not do that
375 * because there is no means to determine whether \c false is
376 * returned because of error or because end of file was reached.
377 * Well, on the other side you may interpret \c false return value
378 * as "there is no file open to check for end of file and there is
379 * no end of file therefore".
380 *
381 * When writing, this function always returns \c true (because you
382 * are always writing to the end of file).
383 *
384 * Error code returned by getZipError() is not affected by this
385 * function call.
386 **/
387 virtual bool atEnd()const;
388 /// Returns file size.
389 /** This function returns csize() if the file is open for reading in
390 * raw mode, usize() if it is open for reading in normal mode and
391 * pos() if it is open for writing.
392 *
393 * Returns -1 on error, call getZipError() to get error code.
394 *
395 * \note This function returns file size despite that
396 * \ref quazipfile-sequential "QuaZipFile is considered to be sequential device",
397 * for which size() should return bytesAvailable() instead. But its
398 * name would be very misguiding otherwise, so just keep in mind
399 * this inconsistence.
400 **/
401 virtual qint64 size()const;
402 /// Returns compressed file size.
403 /** Equivalent to calling getFileInfo() and then getting
404 * compressedSize field, but more convenient and faster.
405 *
406 * File must be open for reading before calling this function.
407 *
408 * Returns -1 on error, call getZipError() to get error code.
409 **/
410 qint64 csize()const;
411 /// Returns uncompressed file size.
412 /** Equivalent to calling getFileInfo() and then getting
413 * uncompressedSize field, but more convenient and faster. See
414 * getFileInfo() for a warning.
415 *
416 * File must be open for reading before calling this function.
417 *
418 * Returns -1 on error, call getZipError() to get error code.
419 **/
420 qint64 usize()const;
421 /// Gets information about current file.
422 /** This function does the same thing as calling
423 * QuaZip::getCurrentFileInfo() on the associated QuaZip object,
424 * but you can not call getCurrentFileInfo() if the associated
425 * QuaZip is internal (because you do not have access to it), while
426 * you still can call this function in that case.
427 *
428 * File must be open for reading before calling this function.
429 *
430 * \return \c false in the case of an error.
431 *
432 * This function doesn't support zip64, but will still work fine on zip64
433 * archives if file sizes are below 4 GB, otherwise the values will be set
434 * as if converted using QuaZipFileInfo64::toQuaZipFileInfo().
435 *
436 * \sa getFileInfo(QuaZipFileInfo64*)
437 **/
438 bool getFileInfo(QuaZipFileInfo *info);
439 /// Gets information about current file with zip64 support.
440 /**
441 * @overload
442 *
443 * \sa getFileInfo(QuaZipFileInfo*)
444 */
445 bool getFileInfo(QuaZipFileInfo64 *info);
446 /// Closes the file.
447 /** Call getZipError() to determine if the close was successful.
448 **/
449 virtual void close();
450 /// Returns the error code returned by the last ZIP/UNZIP API call.
451 int getZipError() const;
452 /// Returns the number of bytes available for reading.
453 virtual qint64 bytesAvailable() const;
454 /// Returns the local extra field
455 /**
456 There are two (optional) local extra fields associated with a file.
457 One is located in the central header and is available along
458 with the rest of the file information in @ref QuaZipFileInfo64::extra.
459 Another is located before the file itself,
460 and is returned by this function. The file must be open first.
461
462 @return the local extra field, or an empty array if there is none
463 (or file is not open)
464 */
465 QByteArray getLocalExtraField();
466 /// Returns the extended modification timestamp
467 /**
468 * The getExt*Time() functions only work if there is an extended timestamp
469 * extra field (ID 0x5455) present. Otherwise, they all return invalid null
470 * timestamps.
471 *
472 * Modification time, but not other times, can also be accessed through
473 * @ref QuaZipFileInfo64 without the need to open the file first.
474 *
475 * @sa dateTime
476 * @sa QuaZipFileInfo64::getExtModTime()
477 * @sa getExtAcTime()
478 * @sa getExtCrTime()
479 * @return The extended modification time, UTC
480 */
481 QDateTime getExtModTime();
482 /// Returns the extended access timestamp
483 /**
484 * The getExt*Time() functions only work if there is an extended timestamp
485 * extra field (ID 0x5455) present. Otherwise, they all return invalid null
486 * timestamps.
487 * @sa dateTime
488 * @sa QuaZipFileInfo64::getExtModTime()
489 * @sa getExtModTime()
490 * @sa getExtCrTime()
491 * @return The extended access time, UTC
492 */
493 QDateTime getExtAcTime();
494 /// Returns the extended creation timestamp
495 /**
496 * The getExt*Time() functions only work if there is an extended timestamp
497 * extra field (ID 0x5455) present. Otherwise, they all return invalid null
498 * timestamps.
499 * @sa dateTime
500 * @sa QuaZipFileInfo64::getExtModTime()
501 * @sa getExtModTime()
502 * @sa getExtAcTime()
503 * @return The extended creation time, UTC
504 */
505 QDateTime getExtCrTime();
506};
507
508#endif
diff --git a/utils/rbutilqt/quazip/quazipfileinfo.cpp b/utils/rbutilqt/quazip/quazipfileinfo.cpp
new file mode 100644
index 0000000000..d5798ea771
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazipfileinfo.cpp
@@ -0,0 +1,196 @@
1/*
2Copyright (C) 2005-2014 Sergey A. Tachenov
3
4This file is part of QuaZIP.
5
6QuaZIP is free software: you can redistribute it and/or modify
7it under the terms of the GNU Lesser General Public License as published by
8the Free Software Foundation, either version 2.1 of the License, or
9(at your option) any later version.
10
11QuaZIP is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU Lesser General Public License for more details.
15
16You should have received a copy of the GNU Lesser General Public License
17along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
18
19See COPYING file for the full LGPL text.
20
21Original ZIP package is copyrighted by Gilles Vollant and contributors,
22see quazip/(un)zip.h files for details. Basically it's the zlib license.
23*/
24
25#include "quazipfileinfo.h"
26
27#include <QtCore/QDataStream>
28
29static QFile::Permissions permissionsFromExternalAttr(quint32 externalAttr) {
30 quint32 uPerm = (externalAttr & 0xFFFF0000u) >> 16;
31 QFile::Permissions perm = QFile::Permissions();
32 if ((uPerm & 0400) != 0)
33 perm |= QFile::ReadOwner;
34 if ((uPerm & 0200) != 0)
35 perm |= QFile::WriteOwner;
36 if ((uPerm & 0100) != 0)
37 perm |= QFile::ExeOwner;
38 if ((uPerm & 0040) != 0)
39 perm |= QFile::ReadGroup;
40 if ((uPerm & 0020) != 0)
41 perm |= QFile::WriteGroup;
42 if ((uPerm & 0010) != 0)
43 perm |= QFile::ExeGroup;
44 if ((uPerm & 0004) != 0)
45 perm |= QFile::ReadOther;
46 if ((uPerm & 0002) != 0)
47 perm |= QFile::WriteOther;
48 if ((uPerm & 0001) != 0)
49 perm |= QFile::ExeOther;
50 return perm;
51
52}
53
54QFile::Permissions QuaZipFileInfo::getPermissions() const
55{
56 return permissionsFromExternalAttr(externalAttr);
57}
58
59QFile::Permissions QuaZipFileInfo64::getPermissions() const
60{
61 return permissionsFromExternalAttr(externalAttr);
62}
63
64bool QuaZipFileInfo64::toQuaZipFileInfo(QuaZipFileInfo &info) const
65{
66 bool noOverflow = true;
67 info.name = name;
68 info.versionCreated = versionCreated;
69 info.versionNeeded = versionNeeded;
70 info.flags = flags;
71 info.method = method;
72 info.dateTime = dateTime;
73 info.crc = crc;
74 if (compressedSize > 0xFFFFFFFFu) {
75 info.compressedSize = 0xFFFFFFFFu;
76 noOverflow = false;
77 } else {
78 info.compressedSize = compressedSize;
79 }
80 if (uncompressedSize > 0xFFFFFFFFu) {
81 info.uncompressedSize = 0xFFFFFFFFu;
82 noOverflow = false;
83 } else {
84 info.uncompressedSize = uncompressedSize;
85 }
86 info.diskNumberStart = diskNumberStart;
87 info.internalAttr = internalAttr;
88 info.externalAttr = externalAttr;
89 info.comment = comment;
90 info.extra = extra;
91 return noOverflow;
92}
93
94static QDateTime getNTFSTime(const QByteArray &extra, int position,
95 int *fineTicks)
96{
97 QDateTime dateTime;
98 QuaExtraFieldHash extraHash = QuaZipFileInfo64::parseExtraField(extra);
99 QList<QByteArray> ntfsExtraFields = extraHash[QUAZIP_EXTRA_NTFS_MAGIC];
100 if (ntfsExtraFields.isEmpty())
101 return dateTime;
102 QByteArray ntfsExtraField = ntfsExtraFields.at(0);
103 if (ntfsExtraField.length() <= 4)
104 return dateTime;
105 QByteArray ntfsAttributes = ntfsExtraField.mid(4);
106 QuaExtraFieldHash ntfsHash = QuaZipFileInfo64::parseExtraField(ntfsAttributes);
107 QList<QByteArray> ntfsTimeAttributes = ntfsHash[QUAZIP_EXTRA_NTFS_TIME_MAGIC];
108 if (ntfsTimeAttributes.isEmpty())
109 return dateTime;
110 QByteArray ntfsTimes = ntfsTimeAttributes.at(0);
111 if (ntfsTimes.size() < 24)
112 return dateTime;
113 QDataStream timeReader(ntfsTimes);
114 timeReader.setByteOrder(QDataStream::LittleEndian);
115 timeReader.device()->seek(position);
116 quint64 time;
117 timeReader >> time;
118 QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
119 dateTime = base.addMSecs(time / 10000);
120 if (fineTicks != NULL) {
121 *fineTicks = static_cast<int>(time % 10000);
122 }
123 return dateTime;
124}
125
126QDateTime QuaZipFileInfo64::getNTFSmTime(int *fineTicks) const
127{
128 return getNTFSTime(extra, 0, fineTicks);
129}
130
131QDateTime QuaZipFileInfo64::getNTFSaTime(int *fineTicks) const
132{
133 return getNTFSTime(extra, 8, fineTicks);
134}
135
136QDateTime QuaZipFileInfo64::getNTFScTime(int *fineTicks) const
137{
138 return getNTFSTime(extra, 16, fineTicks);
139}
140
141QDateTime QuaZipFileInfo64::getExtTime(const QByteArray &extra, int flag)
142{
143 QDateTime dateTime;
144 QuaExtraFieldHash extraHash = QuaZipFileInfo64::parseExtraField(extra);
145 QList<QByteArray> extTimeFields = extraHash[QUAZIP_EXTRA_EXT_TIME_MAGIC];
146 if (extTimeFields.isEmpty())
147 return dateTime;
148 QByteArray extTimeField = extTimeFields.at(0);
149 if (extTimeField.length() < 1)
150 return dateTime;
151 QDataStream input(extTimeField);
152 input.setByteOrder(QDataStream::LittleEndian);
153 quint8 flags;
154 input >> flags;
155 int flagsRemaining = flags;
156 while (!input.atEnd()) {
157 int nextFlag = flagsRemaining & -flagsRemaining;
158 flagsRemaining &= flagsRemaining - 1;
159 qint32 time;
160 input >> time;
161 if (nextFlag == flag) {
162 QDateTime base(QDate(1970, 1, 1), QTime(0, 0), Qt::UTC);
163 dateTime = base.addSecs(time);
164 return dateTime;
165 }
166 }
167 return dateTime;
168}
169
170QDateTime QuaZipFileInfo64::getExtModTime() const
171{
172 return getExtTime(extra, 1);
173}
174
175QuaExtraFieldHash QuaZipFileInfo64::parseExtraField(const QByteArray &extraField)
176{
177 QDataStream input(extraField);
178 input.setByteOrder(QDataStream::LittleEndian);
179 QHash<quint16, QList<QByteArray> > result;
180 while (!input.atEnd()) {
181 quint16 id, size;
182 input >> id;
183 if (input.status() == QDataStream::ReadPastEnd)
184 return result;
185 input >> size;
186 if (input.status() == QDataStream::ReadPastEnd)
187 return result;
188 QByteArray data;
189 data.resize(size);
190 int read = input.readRawData(data.data(), data.size());
191 if (read < data.size())
192 return result;
193 result[id] << data;
194 }
195 return result;
196}
diff --git a/utils/rbutilqt/quazip/quazipfileinfo.h b/utils/rbutilqt/quazip/quazipfileinfo.h
new file mode 100644
index 0000000000..43665b4ac2
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazipfileinfo.h
@@ -0,0 +1,226 @@
1#ifndef QUA_ZIPFILEINFO_H
2#define QUA_ZIPFILEINFO_H
3
4/*
5Copyright (C) 2005-2014 Sergey A. Tachenov
6
7This file is part of QuaZIP.
8
9QuaZIP is free software: you can redistribute it and/or modify
10it under the terms of the GNU Lesser General Public License as published by
11the Free Software Foundation, either version 2.1 of the License, or
12(at your option) any later version.
13
14QuaZIP is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License
20along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
21
22See COPYING file for the full LGPL text.
23
24Original ZIP package is copyrighted by Gilles Vollant and contributors,
25see quazip/(un)zip.h files for details. Basically it's the zlib license.
26*/
27
28#include <QtCore/QByteArray>
29#include <QtCore/QDateTime>
30#include <QtCore/QFile>
31#include <QtCore/QHash>
32
33#include "quazip_global.h"
34
35/// The typedef to store extra field parse results
36typedef QHash<quint16, QList<QByteArray> > QuaExtraFieldHash;
37
38/// Information about a file inside archive.
39/**
40 * \deprecated Use QuaZipFileInfo64 instead. Not only it supports large files,
41 * but also more convenience methods as well.
42 *
43 * Call QuaZip::getCurrentFileInfo() or QuaZipFile::getFileInfo() to
44 * fill this structure. */
45struct QUAZIP_EXPORT QuaZipFileInfo {
46 /// File name.
47 QString name;
48 /// Version created by.
49 quint16 versionCreated;
50 /// Version needed to extract.
51 quint16 versionNeeded;
52 /// General purpose flags.
53 quint16 flags;
54 /// Compression method.
55 quint16 method;
56 /// Last modification date and time.
57 QDateTime dateTime;
58 /// CRC.
59 quint32 crc;
60 /// Compressed file size.
61 quint32 compressedSize;
62 /// Uncompressed file size.
63 quint32 uncompressedSize;
64 /// Disk number start.
65 quint16 diskNumberStart;
66 /// Internal file attributes.
67 quint16 internalAttr;
68 /// External file attributes.
69 quint32 externalAttr;
70 /// Comment.
71 QString comment;
72 /// Extra field.
73 QByteArray extra;
74 /// Get the file permissions.
75 /**
76 Returns the high 16 bits of external attributes converted to
77 QFile::Permissions.
78 */
79 QFile::Permissions getPermissions() const;
80};
81
82/// Information about a file inside archive (with zip64 support).
83/** Call QuaZip::getCurrentFileInfo() or QuaZipFile::getFileInfo() to
84 * fill this structure. */
85struct QUAZIP_EXPORT QuaZipFileInfo64 {
86 /// File name.
87 QString name;
88 /// Version created by.
89 quint16 versionCreated;
90 /// Version needed to extract.
91 quint16 versionNeeded;
92 /// General purpose flags.
93 quint16 flags;
94 /// Compression method.
95 quint16 method;
96 /// Last modification date and time.
97 /**
98 * This is the time stored in the standard ZIP header. This format only allows
99 * to store time with 2-second precision, so the seconds will always be even
100 * and the milliseconds will always be zero. If you need more precise
101 * date and time, you can try to call the getNTFSmTime() function or
102 * its siblings, provided that the archive itself contains these NTFS times.
103 */
104 QDateTime dateTime;
105 /// CRC.
106 quint32 crc;
107 /// Compressed file size.
108 quint64 compressedSize;
109 /// Uncompressed file size.
110 quint64 uncompressedSize;
111 /// Disk number start.
112 quint16 diskNumberStart;
113 /// Internal file attributes.
114 quint16 internalAttr;
115 /// External file attributes.
116 quint32 externalAttr;
117 /// Comment.
118 QString comment;
119 /// Extra field.
120 QByteArray extra;
121 /// Get the file permissions.
122 /**
123 Returns the high 16 bits of external attributes converted to
124 QFile::Permissions.
125 */
126 QFile::Permissions getPermissions() const;
127 /// Converts to QuaZipFileInfo
128 /**
129 If any of the fields are greater than 0xFFFFFFFFu, they are set to
130 0xFFFFFFFFu exactly, not just truncated. This function should be mainly used
131 for compatibility with the old code expecting QuaZipFileInfo, in the cases
132 when it's impossible or otherwise unadvisable (due to ABI compatibility
133 reasons, for example) to modify that old code to use QuaZipFileInfo64.
134
135 \return \c true if all fields converted correctly, \c false if an overflow
136 occured.
137 */
138 bool toQuaZipFileInfo(QuaZipFileInfo &info) const;
139 /// Returns the NTFS modification time
140 /**
141 * The getNTFS*Time() functions only work if there is an NTFS extra field
142 * present. Otherwise, they all return invalid null timestamps.
143 * @param fineTicks If not NULL, the fractional part of milliseconds returned
144 * there, measured in 100-nanosecond ticks. Will be set to
145 * zero if there is no NTFS extra field.
146 * @sa dateTime
147 * @sa getNTFSaTime()
148 * @sa getNTFScTime()
149 * @return The NTFS modification time, UTC
150 */
151 QDateTime getNTFSmTime(int *fineTicks = NULL) const;
152 /// Returns the NTFS access time
153 /**
154 * The getNTFS*Time() functions only work if there is an NTFS extra field
155 * present. Otherwise, they all return invalid null timestamps.
156 * @param fineTicks If not NULL, the fractional part of milliseconds returned
157 * there, measured in 100-nanosecond ticks. Will be set to
158 * zero if there is no NTFS extra field.
159 * @sa dateTime
160 * @sa getNTFSmTime()
161 * @sa getNTFScTime()
162 * @return The NTFS access time, UTC
163 */
164 QDateTime getNTFSaTime(int *fineTicks = NULL) const;
165 /// Returns the NTFS creation time
166 /**
167 * The getNTFS*Time() functions only work if there is an NTFS extra field
168 * present. Otherwise, they all return invalid null timestamps.
169 * @param fineTicks If not NULL, the fractional part of milliseconds returned
170 * there, measured in 100-nanosecond ticks. Will be set to
171 * zero if there is no NTFS extra field.
172 * @sa dateTime
173 * @sa getNTFSmTime()
174 * @sa getNTFSaTime()
175 * @return The NTFS creation time, UTC
176 */
177 QDateTime getNTFScTime(int *fineTicks = NULL) const;
178 /// Returns the extended modification timestamp
179 /**
180 * The getExt*Time() functions only work if there is an extended timestamp
181 * extra field (ID 0x5455) present. Otherwise, they all return invalid null
182 * timestamps.
183 *
184 * QuaZipFileInfo64 only contains the modification time because it's extracted
185 * from @ref extra, which contains the global extra field, and access and
186 * creation time are in the local header which can be accessed through
187 * @ref QuaZipFile.
188 *
189 * @sa dateTime
190 * @sa QuaZipFile::getExtModTime()
191 * @sa QuaZipFile::getExtAcTime()
192 * @sa QuaZipFile::getExtCrTime()
193 * @return The extended modification time, UTC
194 */
195 QDateTime getExtModTime() const;
196 /// Checks whether the file is encrypted.
197 bool isEncrypted() const {return (flags & 1) != 0;}
198 /// Parses extra field
199 /**
200 * The returned hash table contains a list of data blocks for every header ID
201 * in the provided extra field. The number of data blocks in a hash table value
202 * equals to the number of occurrences of the appropriate header id. In most cases,
203 * a block with a specific header ID only occurs once, and therefore the returned
204 * hash table will contain a list consisting of a single element for that header ID.
205 *
206 * @param extraField extra field to parse
207 * @return header id to list of data block hash
208 */
209 static QuaExtraFieldHash parseExtraField(const QByteArray &extraField);
210 /// Extracts extended time from the extra field
211 /**
212 * Utility function used by various getExt*Time() functions, but can be used directly
213 * if the extra field is obtained elsewhere (from a third party library, for example).
214 *
215 * @param extra the extra field for a file
216 * @param flag 1 - modification time, 2 - access time, 4 - creation time
217 * @return the extracted time or null QDateTime if not present
218 * @sa getExtModTime()
219 * @sa QuaZipFile::getExtModTime()
220 * @sa QuaZipFile::getExtAcTime()
221 * @sa QuaZipFile::getExtCrTime()
222 */
223 static QDateTime getExtTime(const QByteArray &extra, int flag);
224};
225
226#endif
diff --git a/utils/rbutilqt/quazip/quazipnewinfo.cpp b/utils/rbutilqt/quazip/quazipnewinfo.cpp
new file mode 100644
index 0000000000..98630e086a
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazipnewinfo.cpp
@@ -0,0 +1,290 @@
1/*
2Copyright (C) 2005-2014 Sergey A. Tachenov
3
4This file is part of QuaZIP.
5
6QuaZIP is free software: you can redistribute it and/or modify
7it under the terms of the GNU Lesser General Public License as published by
8the Free Software Foundation, either version 2.1 of the License, or
9(at your option) any later version.
10
11QuaZIP is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU Lesser General Public License for more details.
15
16You should have received a copy of the GNU Lesser General Public License
17along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
18
19See COPYING file for the full LGPL text.
20
21Original ZIP package is copyrighted by Gilles Vollant and contributors,
22see quazip/(un)zip.h files for details. Basically it's the zlib license.
23*/
24
25#include <QtCore/QFileInfo>
26
27#include "quazipnewinfo.h"
28
29#include <string.h>
30
31static void QuaZipNewInfo_setPermissions(QuaZipNewInfo *info,
32 QFile::Permissions perm, bool isDir, bool isSymLink = false)
33{
34 quint32 uPerm = isDir ? 0040000 : 0100000;
35
36 if ( isSymLink ) {
37#ifdef Q_OS_WIN
38 uPerm = 0200000;
39#else
40 uPerm = 0120000;
41#endif
42 }
43
44 if ((perm & QFile::ReadOwner) != 0)
45 uPerm |= 0400;
46 if ((perm & QFile::WriteOwner) != 0)
47 uPerm |= 0200;
48 if ((perm & QFile::ExeOwner) != 0)
49 uPerm |= 0100;
50 if ((perm & QFile::ReadGroup) != 0)
51 uPerm |= 0040;
52 if ((perm & QFile::WriteGroup) != 0)
53 uPerm |= 0020;
54 if ((perm & QFile::ExeGroup) != 0)
55 uPerm |= 0010;
56 if ((perm & QFile::ReadOther) != 0)
57 uPerm |= 0004;
58 if ((perm & QFile::WriteOther) != 0)
59 uPerm |= 0002;
60 if ((perm & QFile::ExeOther) != 0)
61 uPerm |= 0001;
62 info->externalAttr = (info->externalAttr & ~0xFFFF0000u) | (uPerm << 16);
63}
64
65template<typename FileInfo>
66void QuaZipNewInfo_init(QuaZipNewInfo &self, const FileInfo &existing)
67{
68 self.name = existing.name;
69 self.dateTime = existing.dateTime;
70 self.internalAttr = existing.internalAttr;
71 self.externalAttr = existing.externalAttr;
72 self.comment = existing.comment;
73 self.extraLocal = existing.extra;
74 self.extraGlobal = existing.extra;
75 self.uncompressedSize = existing.uncompressedSize;
76}
77
78QuaZipNewInfo::QuaZipNewInfo(const QuaZipFileInfo &existing)
79{
80 QuaZipNewInfo_init(*this, existing);
81}
82
83QuaZipNewInfo::QuaZipNewInfo(const QuaZipFileInfo64 &existing)
84{
85 QuaZipNewInfo_init(*this, existing);
86}
87
88QuaZipNewInfo::QuaZipNewInfo(const QString& name):
89 name(name), dateTime(QDateTime::currentDateTime()), internalAttr(0), externalAttr(0),
90 uncompressedSize(0)
91{
92}
93
94QuaZipNewInfo::QuaZipNewInfo(const QString& name, const QString& file):
95 name(name), internalAttr(0), externalAttr(0), uncompressedSize(0)
96{
97 QFileInfo info(file);
98 QDateTime lm = info.lastModified();
99 if (!info.exists()) {
100 dateTime = QDateTime::currentDateTime();
101 } else {
102 dateTime = lm;
103 QuaZipNewInfo_setPermissions(this, info.permissions(), info.isDir(), info.isSymLink());
104 }
105}
106
107void QuaZipNewInfo::setFileDateTime(const QString& file)
108{
109 QFileInfo info(file);
110 QDateTime lm = info.lastModified();
111 if (info.exists())
112 dateTime = lm;
113}
114
115void QuaZipNewInfo::setFilePermissions(const QString &file)
116{
117 QFileInfo info = QFileInfo(file);
118 QFile::Permissions perm = info.permissions();
119 QuaZipNewInfo_setPermissions(this, perm, info.isDir(), info.isSymLink());
120}
121
122void QuaZipNewInfo::setPermissions(QFile::Permissions permissions)
123{
124 QuaZipNewInfo_setPermissions(this, permissions, name.endsWith(QLatin1String("/")));
125}
126
127void QuaZipNewInfo::setFileNTFSTimes(const QString &fileName)
128{
129 QFileInfo fi(fileName);
130 if (!fi.exists()) {
131 qWarning("QuaZipNewInfo::setFileNTFSTimes(): '%s' doesn't exist",
132 fileName.toUtf8().constData());
133 return;
134 }
135 setFileNTFSmTime(fi.lastModified());
136 setFileNTFSaTime(fi.lastRead());
137#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
138 setFileNTFScTime(fi.birthTime());
139#else
140 setFileNTFScTime(fi.created());
141#endif
142}
143
144static void setNTFSTime(QByteArray &extra, const QDateTime &time, int position,
145 int fineTicks) {
146 int ntfsPos = -1, timesPos = -1;
147 unsigned ntfsLength = 0, ntfsTimesLength = 0;
148 for (int i = 0; i <= extra.size() - 4; ) {
149 unsigned type = static_cast<unsigned>(static_cast<unsigned char>(
150 extra.at(i)))
151 | (static_cast<unsigned>(static_cast<unsigned char>(
152 extra.at(i + 1))) << 8);
153 i += 2;
154 unsigned length = static_cast<unsigned>(static_cast<unsigned char>(
155 extra.at(i)))
156 | (static_cast<unsigned>(static_cast<unsigned char>(
157 extra.at(i + 1))) << 8);
158 i += 2;
159 if (type == QUAZIP_EXTRA_NTFS_MAGIC) {
160 ntfsPos = i - 4; // the beginning of the NTFS record
161 ntfsLength = length;
162 if (length <= 4) {
163 break; // no times in the NTFS record
164 }
165 i += 4; // reserved
166 while (i <= extra.size() - 4) {
167 unsigned tag = static_cast<unsigned>(
168 static_cast<unsigned char>(extra.at(i)))
169 | (static_cast<unsigned>(
170 static_cast<unsigned char>(extra.at(i + 1)))
171 << 8);
172 i += 2;
173 unsigned tagsize = static_cast<unsigned>(
174 static_cast<unsigned char>(extra.at(i)))
175 | (static_cast<unsigned>(
176 static_cast<unsigned char>(extra.at(i + 1)))
177 << 8);
178 i += 2;
179 if (tag == QUAZIP_EXTRA_NTFS_TIME_MAGIC) {
180 timesPos = i - 4; // the beginning of the NTFS times tag
181 ntfsTimesLength = tagsize;
182 break;
183 } else {
184 i += tagsize;
185 }
186 }
187 break; // I ain't going to search for yet another NTFS record!
188 } else {
189 i += length;
190 }
191 }
192 if (ntfsPos == -1) {
193 // No NTFS record, need to create one.
194 ntfsPos = extra.size();
195 ntfsLength = 32;
196 extra.resize(extra.size() + 4 + ntfsLength);
197 // the NTFS record header
198 extra[ntfsPos] = static_cast<char>(QUAZIP_EXTRA_NTFS_MAGIC);
199 extra[ntfsPos + 1] = static_cast<char>(QUAZIP_EXTRA_NTFS_MAGIC >> 8);
200 extra[ntfsPos + 2] = 32; // the 2-byte size in LittleEndian
201 extra[ntfsPos + 3] = 0;
202 // zero the record
203 memset(extra.data() + ntfsPos + 4, 0, 32);
204 timesPos = ntfsPos + 8;
205 // now set the tag data
206 extra[timesPos] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC);
207 extra[timesPos + 1] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC
208 >> 8);
209 // the size:
210 extra[timesPos + 2] = 24;
211 extra[timesPos + 3] = 0;
212 ntfsTimesLength = 24;
213 }
214 if (timesPos == -1) {
215 // No time tag in the NTFS record, need to add one.
216 timesPos = ntfsPos + 4 + ntfsLength;
217 extra.resize(extra.size() + 28);
218 // Now we need to move the rest of the field
219 // (possibly zero bytes, but memmove() is OK with that).
220 // 0 ......... ntfsPos .. ntfsPos + 4 ... timesPos
221 // <some data> <header> <NTFS record> <need-to-move data> <end>
222 memmove(extra.data() + timesPos + 28, extra.data() + timesPos,
223 extra.size() - 28 - timesPos);
224 ntfsLength += 28;
225 // now set the tag data
226 extra[timesPos] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC);
227 extra[timesPos + 1] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC
228 >> 8);
229 // the size:
230 extra[timesPos + 2] = 24;
231 extra[timesPos + 3] = 0;
232 // zero the record
233 memset(extra.data() + timesPos + 4, 0, 24);
234 ntfsTimesLength = 24;
235 }
236 if (ntfsTimesLength < 24) {
237 // Broken times field. OK, this is really unlikely, but just in case...
238 size_t timesEnd = timesPos + 4 + ntfsTimesLength;
239 extra.resize(extra.size() + (24 - ntfsTimesLength));
240 // Move it!
241 // 0 ......... timesPos .... timesPos + 4 .. timesEnd
242 // <some data> <time header> <broken times> <need-to-move data> <end>
243 memmove(extra.data() + timesEnd + (24 - ntfsTimesLength),
244 extra.data() + timesEnd,
245 extra.size() - (24 - ntfsTimesLength) - timesEnd);
246 // Now we have to increase the NTFS record and time tag lengths.
247 ntfsLength += (24 - ntfsTimesLength);
248 ntfsTimesLength = 24;
249 extra[ntfsPos + 2] = static_cast<char>(ntfsLength);
250 extra[ntfsPos + 3] = static_cast<char>(ntfsLength >> 8);
251 extra[timesPos + 2] = static_cast<char>(ntfsTimesLength);
252 extra[timesPos + 3] = static_cast<char>(ntfsTimesLength >> 8);
253 }
254 QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
255#if (QT_VERSION >= 0x040700)
256 quint64 ticks = base.msecsTo(time) * 10000 + fineTicks;
257#else
258 QDateTime utc = time.toUTC();
259 quint64 ticks = (static_cast<qint64>(base.date().daysTo(utc.date()))
260 * Q_INT64_C(86400000)
261 + static_cast<qint64>(base.time().msecsTo(utc.time())))
262 * Q_INT64_C(10000) + fineTicks;
263#endif
264 extra[timesPos + 4 + position] = static_cast<char>(ticks);
265 extra[timesPos + 5 + position] = static_cast<char>(ticks >> 8);
266 extra[timesPos + 6 + position] = static_cast<char>(ticks >> 16);
267 extra[timesPos + 7 + position] = static_cast<char>(ticks >> 24);
268 extra[timesPos + 8 + position] = static_cast<char>(ticks >> 32);
269 extra[timesPos + 9 + position] = static_cast<char>(ticks >> 40);
270 extra[timesPos + 10 + position] = static_cast<char>(ticks >> 48);
271 extra[timesPos + 11 + position] = static_cast<char>(ticks >> 56);
272}
273
274void QuaZipNewInfo::setFileNTFSmTime(const QDateTime &mTime, int fineTicks)
275{
276 setNTFSTime(extraLocal, mTime, 0, fineTicks);
277 setNTFSTime(extraGlobal, mTime, 0, fineTicks);
278}
279
280void QuaZipNewInfo::setFileNTFSaTime(const QDateTime &aTime, int fineTicks)
281{
282 setNTFSTime(extraLocal, aTime, 8, fineTicks);
283 setNTFSTime(extraGlobal, aTime, 8, fineTicks);
284}
285
286void QuaZipNewInfo::setFileNTFScTime(const QDateTime &cTime, int fineTicks)
287{
288 setNTFSTime(extraLocal, cTime, 16, fineTicks);
289 setNTFSTime(extraGlobal, cTime, 16, fineTicks);
290}
diff --git a/utils/rbutilqt/quazip/quazipnewinfo.h b/utils/rbutilqt/quazip/quazipnewinfo.h
new file mode 100644
index 0000000000..43a1e6fd08
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazipnewinfo.h
@@ -0,0 +1,208 @@
1#ifndef QUA_ZIPNEWINFO_H
2#define QUA_ZIPNEWINFO_H
3
4/*
5Copyright (C) 2005-2014 Sergey A. Tachenov
6
7This file is part of QuaZIP.
8
9QuaZIP is free software: you can redistribute it and/or modify
10it under the terms of the GNU Lesser General Public License as published by
11the Free Software Foundation, either version 2.1 of the License, or
12(at your option) any later version.
13
14QuaZIP is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License
20along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
21
22See COPYING file for the full LGPL text.
23
24Original ZIP package is copyrighted by Gilles Vollant, see
25quazip/(un)zip.h files for details, basically it's zlib license.
26 **/
27
28#include <QtCore/QDateTime>
29#include <QtCore/QFile>
30#include <QtCore/QString>
31
32#include "quazip_global.h"
33
34#include "quazipfileinfo.h"
35
36/// Information about a file to be created.
37/** This structure holds information about a file to be created inside
38 * ZIP archive. At least name should be set to something correct before
39 * passing this structure to
40 * QuaZipFile::open(OpenMode,const QuaZipNewInfo&,int,int,bool).
41 *
42 * Zip64 support of this structure is slightly limited: in the raw mode (when
43 * a pre-compressed file is written into a ZIP file as-is), it is necessary
44 * to specify the uncompressed file size and the appropriate field is 32 bit.
45 * Since the raw mode is used extremely rare, there is no real need to have
46 * a separate QuaZipNewInfo64 structure like QuaZipFileInfo64. It may be added
47 * in the future though, if there is a demand for the raw mode with zip64
48 * archives.
49 **/
50struct QUAZIP_EXPORT QuaZipNewInfo {
51 /// File name.
52 /** This field holds file name inside archive, including path relative
53 * to archive root.
54 **/
55 QString name;
56 /// File timestamp.
57 /** This is the last file modification date and time. Will be stored
58 * in the archive central directory. It is a good practice to set it
59 * to the source file timestamp instead of archive creating time. Use
60 * setFileDateTime() or QuaZipNewInfo(const QString&, const QString&).
61 **/
62 QDateTime dateTime;
63 /// File internal attributes.
64 quint16 internalAttr;
65 /// File external attributes.
66 /**
67 The highest 16 bits contain Unix file permissions and type (dir or
68 file). The constructor QuaZipNewInfo(const QString&, const QString&)
69 takes permissions from the provided file.
70 */
71 quint32 externalAttr;
72 /// File comment.
73 /** Will be encoded in UTF-8 encoding.
74 **/
75 QString comment;
76 /// File local extra field.
77 QByteArray extraLocal;
78 /// File global extra field.
79 QByteArray extraGlobal;
80 /// Uncompressed file size.
81 /** This is only needed if you are using raw file zipping mode, i. e.
82 * adding precompressed file in the zip archive.
83 **/
84 ulong uncompressedSize;
85 /// Constructs QuaZipNewInfo instance.
86 /** Initializes name with \a name, dateTime with current date and
87 * time. Attributes are initialized with zeros, comment and extra
88 * field with null values.
89 **/
90 QuaZipNewInfo(const QString& name);
91 /// Constructs QuaZipNewInfo instance.
92 /** Initializes name with \a name. Timestamp and permissions are taken
93 * from the specified file. If the \a file does not exists or its timestamp
94 * is inaccessible (e. g. you do not have read permission for the
95 * directory file in), uses current time and zero permissions. Other attributes are
96 * initialized with zeros, comment and extra field with null values.
97 *
98 * \sa setFileDateTime()
99 **/
100 QuaZipNewInfo(const QString& name, const QString& file);
101 /// Initializes the new instance from existing file info.
102 /** Mainly used when copying files between archives.
103 *
104 * Both extra fields are initialized to existing.extra.
105 * @brief QuaZipNewInfo
106 * @param existing
107 */
108 QuaZipNewInfo(const QuaZipFileInfo &existing);
109 /// Initializes the new instance from existing file info.
110 /** Mainly used when copying files between archives.
111 *
112 * Both extra fields are initialized to existing.extra.
113 * @brief QuaZipNewInfo
114 * @param existing
115 */
116 QuaZipNewInfo(const QuaZipFileInfo64 &existing);
117 /// Sets the file timestamp from the existing file.
118 /** Use this function to set the file timestamp from the existing
119 * file. Use it like this:
120 * \code
121 * QuaZipFile zipFile(&zip);
122 * QFile file("file-to-add");
123 * file.open(QIODevice::ReadOnly);
124 * QuaZipNewInfo info("file-name-in-archive");
125 * info.setFileDateTime("file-to-add"); // take the timestamp from file
126 * zipFile.open(QIODevice::WriteOnly, info);
127 * \endcode
128 *
129 * This function does not change dateTime if some error occured (e. g.
130 * file is inaccessible).
131 **/
132 void setFileDateTime(const QString& file);
133 /// Sets the file permissions from the existing file.
134 /**
135 Takes permissions from the file and sets the high 16 bits of
136 external attributes. Uses QFileInfo to get permissions on all
137 platforms.
138 */
139 void setFilePermissions(const QString &file);
140 /// Sets the file permissions.
141 /**
142 Modifies the highest 16 bits of external attributes. The type part
143 is set to dir if the name ends with a slash, and to regular file
144 otherwise.
145 */
146 void setPermissions(QFile::Permissions permissions);
147 /// Sets the NTFS times from an existing file.
148 /**
149 * If the file doesn't exist, a warning is printed to the stderr and nothing
150 * is done. Otherwise, all three times, as reported by
151 * QFileInfo::lastModified(), QFileInfo::lastRead() and
152 * QFileInfo::birthTime() (>=Qt5.10) or QFileInfo::created(), are written to
153 * the NTFS extra field record.
154 *
155 * The NTFS record is written to
156 * both the local and the global extra fields, updating the existing record
157 * if there is one, or creating a new one and appending it to the end
158 * of each extra field.
159 *
160 * The microseconds will be zero, as they aren't reported by QFileInfo.
161 * @param fileName
162 */
163 void setFileNTFSTimes(const QString &fileName);
164 /// Sets the NTFS modification time.
165 /**
166 * The time is written into the NTFS record in
167 * both the local and the global extra fields, updating the existing record
168 * if there is one, or creating a new one and appending it to the end
169 * of each extra field. When updating an existing record, all other fields
170 * are left intact.
171 * @param mTime The new modification time.
172 * @param fineTicks The fractional part of milliseconds, in 100-nanosecond
173 * ticks (i. e. 9999 ticks = 999.9 microsecond). Values greater than
174 * 9999 will add milliseconds or even seconds, but this can be
175 * confusing and therefore is discouraged.
176 */
177 void setFileNTFSmTime(const QDateTime &mTime, int fineTicks = 0);
178 /// Sets the NTFS access time.
179 /**
180 * The time is written into the NTFS record in
181 * both the local and the global extra fields, updating the existing record
182 * if there is one, or creating a new one and appending it to the end
183 * of each extra field. When updating an existing record, all other fields
184 * are left intact.
185 * @param aTime The new access time.
186 * @param fineTicks The fractional part of milliseconds, in 100-nanosecond
187 * ticks (i. e. 9999 ticks = 999.9 microsecond). Values greater than
188 * 9999 will add milliseconds or even seconds, but this can be
189 * confusing and therefore is discouraged.
190 */
191 void setFileNTFSaTime(const QDateTime &aTime, int fineTicks = 0);
192 /// Sets the NTFS creation time.
193 /**
194 * The time is written into the NTFS record in
195 * both the local and the global extra fields, updating the existing record
196 * if there is one, or creating a new one and appending it to the end
197 * of each extra field. When updating an existing record, all other fields
198 * are left intact.
199 * @param cTime The new creation time.
200 * @param fineTicks The fractional part of milliseconds, in 100-nanosecond
201 * ticks (i. e. 9999 ticks = 999.9 microsecond). Values greater than
202 * 9999 will add milliseconds or even seconds, but this can be
203 * confusing and therefore is discouraged.
204 */
205 void setFileNTFScTime(const QDateTime &cTime, int fineTicks = 0);
206};
207
208#endif
diff --git a/utils/rbutilqt/quazip/unzip.c b/utils/rbutilqt/quazip/unzip.c
new file mode 100644
index 0000000000..6aaeba6930
--- /dev/null
+++ b/utils/rbutilqt/quazip/unzip.c
@@ -0,0 +1,2163 @@
1/* unzip.c -- IO for uncompress .zip files using zlib
2 Version 1.1, February 14h, 2010
3 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
4
5 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
6
7 Modifications of Unzip for Zip64
8 Copyright (C) 2007-2008 Even Rouault
9
10 Modifications for Zip64 support on both zip and unzip
11 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
12
13 Modifications for QIODevice support and other QuaZIP fixes
14 Copyright (C) 2005-2014 Sergey A. Tachenov
15
16 For more info read MiniZip_info.txt
17
18 Modifications for static code analysis report
19 Copyright (C) 2016 Intel Deutschland GmbH
20
21 ------------------------------------------------------------------------------------
22 Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
23 compatibility with older software. The following is from the original crypt.c.
24 Code woven in by Terry Thorsen 1/2003.
25
26 Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
27
28 See the accompanying file LICENSE, version 2000-Apr-09 or later
29 (the contents of which are also included in zip.h) for terms of use.
30 If, for some reason, all these files are missing, the Info-ZIP license
31 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
32
33 crypt.c (full version) by Info-ZIP. Last revised: [see minizip_crypt.h]
34
35 The encryption/decryption parts of this source code (as opposed to the
36 non-echoing password parts) were originally written in Europe. The
37 whole source package can be freely distributed, including from the USA.
38 (Prior to January 2000, re-export from the US was a violation of US law.)
39
40 This encryption code is a direct transcription of the algorithm from
41 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
42 file (appnote.txt) is distributed with the PKZIP program (even in the
43 version without encryption capabilities).
44
45 ------------------------------------------------------------------------------------
46
47 Changes in unzip.c
48
49 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
50 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
51 2007-2008 - Even Rouault - Remove old C style function prototypes
52 2007-2008 - Even Rouault - Add unzip support for ZIP64
53
54 Copyright (C) 2007-2008 Even Rouault
55
56
57 Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
58 Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
59 should only read the compressed/uncompressed size from the Zip64 format if
60 the size from normal header was 0xFFFFFFFF
61 Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
62 Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
63 Patch created by Daniel Borca
64
65 Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
66
67 Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
68
69*/
70
71
72#include <stdio.h>
73#include <stdlib.h>
74#include <string.h>
75
76#include <zlib.h>
77#if (ZLIB_VERNUM < 0x1270)
78typedef uLongf z_crc_t;
79#endif
80#include "unzip.h"
81
82#ifdef STDC
83# include <stddef.h>
84# include <string.h>
85# include <stdlib.h>
86#endif
87#ifdef NO_ERRNO_H
88 extern int errno;
89#else
90# include <errno.h>
91#endif
92
93
94#ifndef local
95# define local static
96#endif
97/* compile with -Dlocal if your debugger can't find static symbols */
98
99
100#ifndef CASESENSITIVITYDEFAULT_NO
101# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
102# define CASESENSITIVITYDEFAULT_NO
103# endif
104#endif
105
106
107#ifndef UNZ_BUFSIZE
108#define UNZ_BUFSIZE (16384)
109#endif
110
111#ifndef UNZ_MAXFILENAMEINZIP
112#define UNZ_MAXFILENAMEINZIP (256)
113#endif
114
115#ifndef ALLOC
116# define ALLOC(size) (malloc(size))
117#endif
118#ifndef TRYFREE
119# define TRYFREE(p) {if (p) free(p);}
120#endif
121
122#define SIZECENTRALDIRITEM (0x2e)
123#define SIZEZIPLOCALHEADER (0x1e)
124
125
126const char unz_copyright[] =
127 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
128
129/* unz_file_info_interntal contain internal info about a file in zipfile*/
130typedef struct unz_file_info64_internal_s
131{
132 ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
133} unz_file_info64_internal;
134
135
136/* file_in_zip_read_info_s contain internal information about a file in zipfile,
137 when reading and decompress it */
138typedef struct
139{
140 char *read_buffer; /* internal buffer for compressed data */
141 z_stream stream; /* zLib stream structure for inflate */
142
143#ifdef HAVE_BZIP2
144 bz_stream bstream; /* bzLib stream structure for bziped */
145#endif
146
147 ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
148 uLong stream_initialised; /* flag set if stream structure is initialised*/
149
150 ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
151 uInt size_local_extrafield;/* size of the local extra field */
152 ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/
153 ZPOS64_T total_out_64;
154
155 uLong crc32; /* crc32 of all data uncompressed */
156 uLong crc32_wait; /* crc32 we must obtain after decompress all */
157 ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
158 ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
159 zlib_filefunc64_32_def z_filefunc;
160 voidpf filestream; /* io structore of the zipfile */
161 uLong compression_method; /* compression method (0==store) */
162 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
163 int raw;
164} file_in_zip64_read_info_s;
165
166
167/* unz64_s contain internal information about the zipfile
168*/
169typedef struct
170{
171 zlib_filefunc64_32_def z_filefunc;
172 int is64bitOpenFunction;
173 voidpf filestream; /* io structore of the zipfile */
174 unz_global_info64 gi; /* public global information */
175 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
176 ZPOS64_T num_file; /* number of the current file in the zipfile*/
177 ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/
178 ZPOS64_T current_file_ok; /* flag about the usability of the current file*/
179 ZPOS64_T central_pos; /* position of the beginning of the central dir*/
180
181 ZPOS64_T size_central_dir; /* size of the central directory */
182 ZPOS64_T offset_central_dir; /* offset of start of central directory with
183 respect to the starting disk number */
184
185 unz_file_info64 cur_file_info; /* public info about the current file in zip*/
186 unz_file_info64_internal cur_file_info_internal; /* private info about it*/
187 file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
188 file if we are decompressing it */
189 int encrypted;
190
191 int isZip64;
192 unsigned flags;
193
194# ifndef NOUNCRYPT
195 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
196 const z_crc_t FAR * pcrc_32_tab;
197# endif
198} unz64_s;
199
200
201#ifndef NOUNCRYPT
202#include "minizip_crypt.h"
203#endif
204
205/* ===========================================================================
206 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
207 for end of file.
208 IN assertion: the stream s has been sucessfully opened for reading.
209*/
210
211
212local int unz64local_getByte OF((
213 const zlib_filefunc64_32_def* pzlib_filefunc_def,
214 voidpf filestream,
215 int *pi));
216
217local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
218{
219 unsigned char c;
220 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
221 if (err==1)
222 {
223 *pi = (int)c;
224 return UNZ_OK;
225 }
226 else
227 {
228 if (ZERROR64(*pzlib_filefunc_def,filestream))
229 return UNZ_ERRNO;
230 else
231 return UNZ_EOF;
232 }
233}
234
235
236/* ===========================================================================
237 Reads a long in LSB order from the given gz_stream. Sets
238*/
239local int unz64local_getShort OF((
240 const zlib_filefunc64_32_def* pzlib_filefunc_def,
241 voidpf filestream,
242 uLong *pX));
243
244local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
245 voidpf filestream,
246 uLong *pX)
247{
248 uLong x ;
249 int i = 0;
250 int err;
251
252 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
253 x = (uLong)i;
254
255 if (err==UNZ_OK)
256 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
257 x |= ((uLong)i)<<8;
258
259 if (err==UNZ_OK)
260 *pX = x;
261 else
262 *pX = 0;
263 return err;
264}
265
266local int unz64local_getLong OF((
267 const zlib_filefunc64_32_def* pzlib_filefunc_def,
268 voidpf filestream,
269 uLong *pX));
270
271local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
272 voidpf filestream,
273 uLong *pX)
274{
275 uLong x ;
276 int i = 0;
277 int err;
278
279 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
280 x = (uLong)i;
281
282 if (err==UNZ_OK)
283 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
284 x |= ((uLong)i)<<8;
285
286 if (err==UNZ_OK)
287 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
288 x |= ((uLong)i)<<16;
289
290 if (err==UNZ_OK)
291 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
292 x += ((uLong)i)<<24;
293
294 if (err==UNZ_OK)
295 *pX = x;
296 else
297 *pX = 0;
298 return err;
299}
300
301local int unz64local_getLong64 OF((
302 const zlib_filefunc64_32_def* pzlib_filefunc_def,
303 voidpf filestream,
304 ZPOS64_T *pX));
305
306
307local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
308 voidpf filestream,
309 ZPOS64_T *pX)
310{
311 ZPOS64_T x ;
312 int i = 0;
313 int err;
314
315 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
316 x = (ZPOS64_T)i;
317
318 if (err==UNZ_OK)
319 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
320 x |= ((ZPOS64_T)i)<<8;
321
322 if (err==UNZ_OK)
323 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
324 x |= ((ZPOS64_T)i)<<16;
325
326 if (err==UNZ_OK)
327 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
328 x |= ((ZPOS64_T)i)<<24;
329
330 if (err==UNZ_OK)
331 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
332 x |= ((ZPOS64_T)i)<<32;
333
334 if (err==UNZ_OK)
335 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
336 x |= ((ZPOS64_T)i)<<40;
337
338 if (err==UNZ_OK)
339 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
340 x |= ((ZPOS64_T)i)<<48;
341
342 if (err==UNZ_OK)
343 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
344 x |= ((ZPOS64_T)i)<<56;
345
346 if (err==UNZ_OK)
347 *pX = x;
348 else
349 *pX = 0;
350 return err;
351}
352
353/* My own strcmpi / strcasecmp */
354local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
355{
356 for (;;)
357 {
358 char c1=*(fileName1++);
359 char c2=*(fileName2++);
360 if ((c1>='a') && (c1<='z'))
361 c1 -= 0x20;
362 if ((c2>='a') && (c2<='z'))
363 c2 -= 0x20;
364 if (c1=='\0')
365 return ((c2=='\0') ? 0 : -1);
366 if (c2=='\0')
367 return 1;
368 if (c1<c2)
369 return -1;
370 if (c1>c2)
371 return 1;
372 }
373}
374
375
376#ifdef CASESENSITIVITYDEFAULT_NO
377#define CASESENSITIVITYDEFAULTVALUE 2
378#else
379#define CASESENSITIVITYDEFAULTVALUE 1
380#endif
381
382#ifndef STRCMPCASENOSENTIVEFUNCTION
383#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
384#endif
385
386/*
387 Compare two filename (fileName1,fileName2).
388 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
389 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
390 or strcasecmp)
391 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
392 (like 1 on Unix, 2 on Windows)
393
394*/
395extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
396 const char* fileName2,
397 int iCaseSensitivity)
398
399{
400 if (iCaseSensitivity==0)
401 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
402
403 if (iCaseSensitivity==1)
404 return strcmp(fileName1,fileName2);
405
406 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
407}
408
409#ifndef BUFREADCOMMENT
410#define BUFREADCOMMENT (0x400)
411#endif
412
413/*
414 Locate the Central directory of a zipfile (at the end, just before
415 the global comment)
416*/
417local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
418local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
419{
420 unsigned char* buf;
421 ZPOS64_T uSizeFile;
422 ZPOS64_T uBackRead;
423 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
424 ZPOS64_T uPosFound=0;
425
426 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
427 return 0;
428
429
430 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
431
432 if (uMaxBack>uSizeFile)
433 uMaxBack = uSizeFile;
434
435 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
436 if (buf==NULL)
437 return 0;
438
439 uBackRead = 4;
440 while (uBackRead<uMaxBack)
441 {
442 uLong uReadSize;
443 ZPOS64_T uReadPos ;
444 int i;
445 if (uBackRead+BUFREADCOMMENT>uMaxBack)
446 uBackRead = uMaxBack;
447 else
448 uBackRead+=BUFREADCOMMENT;
449 uReadPos = uSizeFile-uBackRead ;
450
451 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
452 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
453 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
454 break;
455
456 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
457 break;
458
459 for (i=(int)uReadSize-3; (i--)>0;)
460 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
461 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
462 {
463 uPosFound = uReadPos+i;
464 break;
465 }
466
467 if (uPosFound!=0)
468 break;
469 }
470 TRYFREE(buf);
471 return uPosFound;
472}
473
474
475/*
476 Locate the Central directory 64 of a zipfile (at the end, just before
477 the global comment)
478*/
479local ZPOS64_T unz64local_SearchCentralDir64 OF((
480 const zlib_filefunc64_32_def* pzlib_filefunc_def,
481 voidpf filestream));
482
483local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
484 voidpf filestream)
485{
486 unsigned char* buf;
487 ZPOS64_T uSizeFile;
488 ZPOS64_T uBackRead;
489 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
490 ZPOS64_T uPosFound=0;
491 uLong uL;
492 ZPOS64_T relativeOffset;
493
494 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
495 return 0;
496
497
498 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
499
500 if (uMaxBack>uSizeFile)
501 uMaxBack = uSizeFile;
502
503 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
504 if (buf==NULL)
505 return 0;
506
507 uBackRead = 4;
508 while (uBackRead<uMaxBack)
509 {
510 uLong uReadSize;
511 ZPOS64_T uReadPos;
512 int i;
513 if (uBackRead+BUFREADCOMMENT>uMaxBack)
514 uBackRead = uMaxBack;
515 else
516 uBackRead+=BUFREADCOMMENT;
517 uReadPos = uSizeFile-uBackRead ;
518
519 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
520 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
521 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
522 break;
523
524 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
525 break;
526
527 for (i=(int)uReadSize-3; (i--)>0;)
528 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
529 ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
530 {
531 uPosFound = uReadPos+i;
532 break;
533 }
534
535 if (uPosFound!=0)
536 break;
537 }
538 TRYFREE(buf);
539 if (uPosFound == 0)
540 return 0;
541
542 /* Zip64 end of central directory locator */
543 if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
544 return 0;
545
546 /* the signature, already checked */
547 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
548 return 0;
549
550 /* number of the disk with the start of the zip64 end of central directory */
551 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
552 return 0;
553 if (uL != 0)
554 return 0;
555
556 /* relative offset of the zip64 end of central directory record */
557 if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
558 return 0;
559
560 /* total number of disks */
561 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
562 return 0;
563 if (uL != 1)
564 return 0;
565
566 /* Goto end of central directory record */
567 if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
568 return 0;
569
570 /* the signature */
571 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
572 return 0;
573
574 if (uL != 0x06064b50)
575 return 0;
576
577 return relativeOffset;
578}
579
580/*
581 Open a Zip file. path contain the full pathname (by example,
582 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
583 "zlib/zlib114.zip".
584 If the zipfile cannot be opened (file doesn't exist or in not valid), the
585 return value is NULL.
586 Else, the return value is a unzFile Handle, usable with other function
587 of this unzip package.
588*/
589extern unzFile unzOpenInternal (voidpf file,
590 zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
591 int is64bitOpenFunction, unsigned flags)
592{
593 unz64_s us;
594 unz64_s *s;
595 ZPOS64_T central_pos;
596 uLong uL;
597
598 uLong number_disk; /* number of the current dist, used for
599 spaning ZIP, unsupported, always 0*/
600 uLong number_disk_with_CD; /* number the the disk with central dir, used
601 for spaning ZIP, unsupported, always 0*/
602 ZPOS64_T number_entry_CD; /* total number of entries in
603 the central dir
604 (same than number_entry on nospan) */
605
606 int err=UNZ_OK;
607
608 if (unz_copyright[0]!=' ')
609 return NULL;
610
611 us.flags = flags;
612 us.z_filefunc.zseek32_file = NULL;
613 us.z_filefunc.ztell32_file = NULL;
614 if (pzlib_filefunc64_32_def==NULL)
615 fill_qiodevice64_filefunc(&us.z_filefunc.zfile_func64);
616 else
617 us.z_filefunc = *pzlib_filefunc64_32_def;
618 us.is64bitOpenFunction = is64bitOpenFunction;
619
620
621
622 us.filestream = ZOPEN64(us.z_filefunc,
623 file,
624 ZLIB_FILEFUNC_MODE_READ |
625 ZLIB_FILEFUNC_MODE_EXISTING);
626 if (us.filestream==NULL)
627 return NULL;
628
629 central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
630 if (central_pos)
631 {
632 uLong uS;
633 ZPOS64_T uL64;
634
635 us.isZip64 = 1;
636
637 if (ZSEEK64(us.z_filefunc, us.filestream,
638 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
639 err=UNZ_ERRNO;
640
641 /* the signature, already checked */
642 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
643 err=UNZ_ERRNO;
644
645 /* size of zip64 end of central directory record */
646 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
647 err=UNZ_ERRNO;
648
649 /* version made by */
650 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
651 err=UNZ_ERRNO;
652
653 /* version needed to extract */
654 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
655 err=UNZ_ERRNO;
656
657 /* number of this disk */
658 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
659 err=UNZ_ERRNO;
660
661 /* number of the disk with the start of the central directory */
662 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
663 err=UNZ_ERRNO;
664
665 /* total number of entries in the central directory on this disk */
666 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
667 err=UNZ_ERRNO;
668
669 /* total number of entries in the central directory */
670 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
671 err=UNZ_ERRNO;
672
673 if ((number_entry_CD!=us.gi.number_entry) ||
674 (number_disk_with_CD!=0) ||
675 (number_disk!=0))
676 err=UNZ_BADZIPFILE;
677
678 /* size of the central directory */
679 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
680 err=UNZ_ERRNO;
681
682 /* offset of start of central directory with respect to the
683 starting disk number */
684 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
685 err=UNZ_ERRNO;
686
687 us.gi.size_comment = 0;
688 }
689 else
690 {
691 central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
692 if (central_pos==0)
693 err=UNZ_ERRNO;
694
695 us.isZip64 = 0;
696
697 if (ZSEEK64(us.z_filefunc, us.filestream,
698 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
699 err=UNZ_ERRNO;
700
701 /* the signature, already checked */
702 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
703 err=UNZ_ERRNO;
704
705 /* number of this disk */
706 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
707 err=UNZ_ERRNO;
708
709 /* number of the disk with the start of the central directory */
710 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
711 err=UNZ_ERRNO;
712
713 /* total number of entries in the central dir on this disk */
714 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
715 err=UNZ_ERRNO;
716 us.gi.number_entry = uL;
717
718 /* total number of entries in the central dir */
719 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
720 err=UNZ_ERRNO;
721 number_entry_CD = uL;
722
723 if ((number_entry_CD!=us.gi.number_entry) ||
724 (number_disk_with_CD!=0) ||
725 (number_disk!=0))
726 err=UNZ_BADZIPFILE;
727
728 /* size of the central directory */
729 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
730 err=UNZ_ERRNO;
731 us.size_central_dir = uL;
732
733 /* offset of start of central directory with respect to the
734 starting disk number */
735 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
736 err=UNZ_ERRNO;
737 us.offset_central_dir = uL;
738
739 /* zipfile comment length */
740 if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
741 err=UNZ_ERRNO;
742 }
743
744 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
745 (err==UNZ_OK))
746 err=UNZ_BADZIPFILE;
747
748 if (err!=UNZ_OK)
749 {
750 if ((us.flags & UNZ_AUTO_CLOSE) != 0)
751 ZCLOSE64(us.z_filefunc, us.filestream);
752 else
753 ZFAKECLOSE64(us.z_filefunc, us.filestream);
754 return NULL;
755 }
756
757 us.byte_before_the_zipfile = central_pos -
758 (us.offset_central_dir+us.size_central_dir);
759 us.central_pos = central_pos;
760 us.pfile_in_zip_read = NULL;
761 us.encrypted = 0;
762
763
764 s=(unz64_s*)ALLOC(sizeof(unz64_s));
765 if( s != NULL)
766 {
767 *s=us;
768 unzGoToFirstFile((unzFile)s);
769 }
770 return (unzFile)s;
771}
772
773
774extern unzFile ZEXPORT unzOpen2 (voidpf file,
775 zlib_filefunc_def* pzlib_filefunc32_def)
776{
777 if (pzlib_filefunc32_def != NULL)
778 {
779 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
780 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
781 return unzOpenInternal(file, &zlib_filefunc64_32_def_fill, 0, UNZ_DEFAULT_FLAGS);
782 }
783 else
784 return unzOpenInternal(file, NULL, 0, UNZ_DEFAULT_FLAGS);
785}
786
787extern unzFile ZEXPORT unzOpen2_64 (voidpf file,
788 zlib_filefunc64_def* pzlib_filefunc_def)
789{
790 if (pzlib_filefunc_def != NULL)
791 {
792 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
793 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
794 zlib_filefunc64_32_def_fill.ztell32_file = NULL;
795 zlib_filefunc64_32_def_fill.zseek32_file = NULL;
796 return unzOpenInternal(file, &zlib_filefunc64_32_def_fill, 1, UNZ_DEFAULT_FLAGS);
797 }
798 else
799 return unzOpenInternal(file, NULL, 1, UNZ_DEFAULT_FLAGS);
800}
801
802extern unzFile ZEXPORT unzOpen (voidpf file)
803{
804 return unzOpenInternal(file, NULL, 0, UNZ_DEFAULT_FLAGS);
805}
806
807extern unzFile ZEXPORT unzOpen64 (voidpf file)
808{
809 return unzOpenInternal(file, NULL, 1, UNZ_DEFAULT_FLAGS);
810}
811
812/*
813 Close a ZipFile opened with unzipOpen.
814 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
815 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
816 return UNZ_OK if there is no problem. */
817extern int ZEXPORT unzClose (unzFile file)
818{
819 unz64_s* s;
820 if (file==NULL)
821 return UNZ_PARAMERROR;
822 s=(unz64_s*)file;
823
824 if (s->pfile_in_zip_read!=NULL)
825 unzCloseCurrentFile(file);
826
827 if ((s->flags & UNZ_AUTO_CLOSE) != 0)
828 ZCLOSE64(s->z_filefunc, s->filestream);
829 else
830 ZFAKECLOSE64(s->z_filefunc, s->filestream);
831 TRYFREE(s);
832 return UNZ_OK;
833}
834
835
836/*
837 Write info about the ZipFile in the *pglobal_info structure.
838 No preparation of the structure is needed
839 return UNZ_OK if there is no problem. */
840extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
841{
842 unz64_s* s;
843 if (file==NULL)
844 return UNZ_PARAMERROR;
845 s=(unz64_s*)file;
846 *pglobal_info=s->gi;
847 return UNZ_OK;
848}
849
850extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
851{
852 unz64_s* s;
853 if (file==NULL)
854 return UNZ_PARAMERROR;
855 s=(unz64_s*)file;
856 /* to do : check if number_entry is not truncated */
857 pglobal_info32->number_entry = (uLong)s->gi.number_entry;
858 pglobal_info32->size_comment = s->gi.size_comment;
859 return UNZ_OK;
860}
861
862extern int ZEXPORT unzGetFileFlags (unzFile file, unsigned* pflags)
863{
864 unz64_s* s;
865 if (file==NULL)
866 return UNZ_PARAMERROR;
867 s=(unz64_s*)file;
868 *pflags = s->flags;
869 return UNZ_OK;
870}
871
872/*
873 Translate date/time from Dos format to tm_unz (readable more easilty)
874*/
875local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
876{
877 ZPOS64_T uDate;
878 uDate = (ZPOS64_T)(ulDosDate>>16);
879 ptm->tm_mday = (uInt)(uDate&0x1f) ;
880 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
881 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
882
883 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
884 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
885 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
886}
887
888/*
889 Get Info about the current file in the zipfile, with internal only info
890*/
891local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
892 unz_file_info64 *pfile_info,
893 unz_file_info64_internal
894 *pfile_info_internal,
895 char *szFileName,
896 uLong fileNameBufferSize,
897 void *extraField,
898 uLong extraFieldBufferSize,
899 char *szComment,
900 uLong commentBufferSize));
901
902local int unz64local_GetCurrentFileInfoInternal (unzFile file,
903 unz_file_info64 *pfile_info,
904 unz_file_info64_internal
905 *pfile_info_internal,
906 char *szFileName,
907 uLong fileNameBufferSize,
908 void *extraField,
909 uLong extraFieldBufferSize,
910 char *szComment,
911 uLong commentBufferSize)
912{
913 unz64_s* s;
914 unz_file_info64 file_info;
915 unz_file_info64_internal file_info_internal;
916 int err=UNZ_OK;
917 uLong uMagic;
918 ZPOS64_T llSeek=0;
919 uLong uL;
920
921 if (file==NULL)
922 return UNZ_PARAMERROR;
923 s=(unz64_s*)file;
924 if (ZSEEK64(s->z_filefunc, s->filestream,
925 s->pos_in_central_dir+s->byte_before_the_zipfile,
926 ZLIB_FILEFUNC_SEEK_SET)!=0)
927 err=UNZ_ERRNO;
928
929
930 /* we check the magic */
931 if (err==UNZ_OK)
932 {
933 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
934 err=UNZ_ERRNO;
935 else if (uMagic!=0x02014b50)
936 err=UNZ_BADZIPFILE;
937 }
938
939 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
940 err=UNZ_ERRNO;
941
942 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
943 err=UNZ_ERRNO;
944
945 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
946 err=UNZ_ERRNO;
947
948 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
949 err=UNZ_ERRNO;
950
951 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
952 err=UNZ_ERRNO;
953
954 unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
955
956 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
957 err=UNZ_ERRNO;
958
959 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
960 err=UNZ_ERRNO;
961 file_info.compressed_size = uL;
962
963 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
964 err=UNZ_ERRNO;
965 file_info.uncompressed_size = uL;
966
967 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
968 err=UNZ_ERRNO;
969
970 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
971 err=UNZ_ERRNO;
972
973 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
974 err=UNZ_ERRNO;
975
976 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
977 err=UNZ_ERRNO;
978
979 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
980 err=UNZ_ERRNO;
981
982 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
983 err=UNZ_ERRNO;
984
985 /* relative offset of local header */
986 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
987 err=UNZ_ERRNO;
988 file_info_internal.offset_curfile = uL;
989
990 llSeek+=file_info.size_filename;
991 if ((err==UNZ_OK) && (szFileName!=NULL))
992 {
993 uLong uSizeRead ;
994 if (file_info.size_filename<fileNameBufferSize)
995 {
996 *(szFileName+file_info.size_filename)='\0';
997 uSizeRead = file_info.size_filename;
998 }
999 else
1000 uSizeRead = fileNameBufferSize;
1001
1002 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
1003 if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
1004 err=UNZ_ERRNO;
1005 llSeek -= uSizeRead;
1006 }
1007
1008 /* Read extrafield */
1009 if ((err==UNZ_OK) && (extraField!=NULL))
1010 {
1011 ZPOS64_T uSizeRead ;
1012 if (file_info.size_file_extra<extraFieldBufferSize)
1013 uSizeRead = file_info.size_file_extra;
1014 else
1015 uSizeRead = extraFieldBufferSize;
1016
1017 if (llSeek!=0)
1018 {
1019 if (ZSEEK64(s->z_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1020 llSeek=0;
1021 else
1022 err=UNZ_ERRNO;
1023 }
1024
1025 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
1026 if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
1027 err=UNZ_ERRNO;
1028
1029 llSeek += file_info.size_file_extra - (uLong)uSizeRead;
1030 }
1031 else
1032 llSeek += file_info.size_file_extra;
1033
1034
1035 if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
1036 {
1037 uLong acc = 0;
1038
1039 /* since lSeek now points to after the extra field we need to move back */
1040 llSeek -= file_info.size_file_extra;
1041
1042 if (llSeek!=0)
1043 {
1044 if (ZSEEK64(s->z_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1045 llSeek=0;
1046 else
1047 err=UNZ_ERRNO;
1048 }
1049
1050 while(acc < file_info.size_file_extra)
1051 {
1052 uLong headerId;
1053 uLong dataSize;
1054
1055 if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
1056 err=UNZ_ERRNO;
1057
1058 if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
1059 err=UNZ_ERRNO;
1060
1061 /* ZIP64 extra fields */
1062 if (headerId == 0x0001)
1063 {
1064 uLong uL;
1065
1066 if(file_info.uncompressed_size == (ZPOS64_T)0xFFFFFFFFu)
1067 {
1068 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
1069 err=UNZ_ERRNO;
1070 }
1071
1072 if(file_info.compressed_size == (ZPOS64_T)0xFFFFFFFFu)
1073 {
1074 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
1075 err=UNZ_ERRNO;
1076 }
1077
1078 if(file_info_internal.offset_curfile == (ZPOS64_T)0xFFFFFFFFu)
1079 {
1080 /* Relative Header offset */
1081 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
1082 err=UNZ_ERRNO;
1083 }
1084
1085 if(file_info.disk_num_start == 0xFFFFFFFFu)
1086 {
1087 /* Disk Start Number */
1088 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
1089 err=UNZ_ERRNO;
1090 }
1091
1092 }
1093 else
1094 {
1095 if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
1096 err=UNZ_ERRNO;
1097 }
1098
1099 acc += 2 + 2 + dataSize;
1100 }
1101 }
1102
1103 if ((err==UNZ_OK) && (szComment!=NULL))
1104 {
1105 uLong uSizeRead ;
1106 if (file_info.size_file_comment<commentBufferSize)
1107 {
1108 *(szComment+file_info.size_file_comment)='\0';
1109 uSizeRead = file_info.size_file_comment;
1110 }
1111 else
1112 uSizeRead = commentBufferSize;
1113
1114 if (llSeek!=0)
1115 {
1116 if (ZSEEK64(s->z_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1117 llSeek=0;
1118 else
1119 err=UNZ_ERRNO;
1120 }
1121
1122 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
1123 if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
1124 err=UNZ_ERRNO;
1125 llSeek+=file_info.size_file_comment - uSizeRead;
1126 }
1127 else
1128 llSeek+=file_info.size_file_comment;
1129
1130
1131 if ((err==UNZ_OK) && (pfile_info!=NULL))
1132 *pfile_info=file_info;
1133
1134 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
1135 *pfile_info_internal=file_info_internal;
1136
1137 return err;
1138}
1139
1140
1141
1142/*
1143 Write info about the ZipFile in the *pglobal_info structure.
1144 No preparation of the structure is needed
1145 return UNZ_OK if there is no problem.
1146*/
1147extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
1148 unz_file_info64 * pfile_info,
1149 char * szFileName, uLong fileNameBufferSize,
1150 void *extraField, uLong extraFieldBufferSize,
1151 char* szComment, uLong commentBufferSize)
1152{
1153 return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
1154 szFileName,fileNameBufferSize,
1155 extraField,extraFieldBufferSize,
1156 szComment,commentBufferSize);
1157}
1158
1159extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
1160 unz_file_info * pfile_info,
1161 char * szFileName, uLong fileNameBufferSize,
1162 void *extraField, uLong extraFieldBufferSize,
1163 char* szComment, uLong commentBufferSize)
1164{
1165 int err;
1166 unz_file_info64 file_info64;
1167 err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
1168 szFileName,fileNameBufferSize,
1169 extraField,extraFieldBufferSize,
1170 szComment,commentBufferSize);
1171 if (err==UNZ_OK && pfile_info != NULL)
1172 {
1173 pfile_info->version = file_info64.version;
1174 pfile_info->version_needed = file_info64.version_needed;
1175 pfile_info->flag = file_info64.flag;
1176 pfile_info->compression_method = file_info64.compression_method;
1177 pfile_info->dosDate = file_info64.dosDate;
1178 pfile_info->crc = file_info64.crc;
1179
1180 pfile_info->size_filename = file_info64.size_filename;
1181 pfile_info->size_file_extra = file_info64.size_file_extra;
1182 pfile_info->size_file_comment = file_info64.size_file_comment;
1183
1184 pfile_info->disk_num_start = file_info64.disk_num_start;
1185 pfile_info->internal_fa = file_info64.internal_fa;
1186 pfile_info->external_fa = file_info64.external_fa;
1187
1188 pfile_info->tmu_date = file_info64.tmu_date,
1189
1190
1191 pfile_info->compressed_size = (uLong)file_info64.compressed_size;
1192 pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
1193
1194 }
1195 return err;
1196}
1197/*
1198 Set the current file of the zipfile to the first file.
1199 return UNZ_OK if there is no problem
1200*/
1201extern int ZEXPORT unzGoToFirstFile (unzFile file)
1202{
1203 int err=UNZ_OK;
1204 unz64_s* s;
1205 if (file==NULL)
1206 return UNZ_PARAMERROR;
1207 s=(unz64_s*)file;
1208 s->pos_in_central_dir=s->offset_central_dir;
1209 s->num_file=0;
1210 err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1211 &s->cur_file_info_internal,
1212 NULL,0,NULL,0,NULL,0);
1213 s->current_file_ok = (err == UNZ_OK);
1214 if (s->cur_file_info.flag & UNZ_ENCODING_UTF8)
1215 unzSetFlags(file, UNZ_ENCODING_UTF8);
1216 return err;
1217}
1218
1219/*
1220 Set the current file of the zipfile to the next file.
1221 return UNZ_OK if there is no problem
1222 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
1223*/
1224extern int ZEXPORT unzGoToNextFile (unzFile file)
1225{
1226 unz64_s* s;
1227 int err;
1228
1229 if (file==NULL)
1230 return UNZ_PARAMERROR;
1231 s=(unz64_s*)file;
1232 if (!s->current_file_ok)
1233 return UNZ_END_OF_LIST_OF_FILE;
1234 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
1235 if (s->num_file+1==s->gi.number_entry)
1236 return UNZ_END_OF_LIST_OF_FILE;
1237
1238 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
1239 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
1240 s->num_file++;
1241 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1242 &s->cur_file_info_internal,
1243 NULL,0,NULL,0,NULL,0);
1244 s->current_file_ok = (err == UNZ_OK);
1245 return err;
1246}
1247
1248
1249/*
1250 Try locate the file szFileName in the zipfile.
1251 For the iCaseSensitivity signification, see unzipStringFileNameCompare
1252
1253 return value :
1254 UNZ_OK if the file is found. It becomes the current file.
1255 UNZ_END_OF_LIST_OF_FILE if the file is not found
1256*/
1257extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
1258{
1259 unz64_s* s;
1260 int err;
1261
1262 /* We remember the 'current' position in the file so that we can jump
1263 * back there if we fail.
1264 */
1265 unz_file_info64 cur_file_infoSaved;
1266 unz_file_info64_internal cur_file_info_internalSaved;
1267 ZPOS64_T num_fileSaved;
1268 ZPOS64_T pos_in_central_dirSaved;
1269
1270
1271 if (file==NULL)
1272 return UNZ_PARAMERROR;
1273
1274 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
1275 return UNZ_PARAMERROR;
1276
1277 s=(unz64_s*)file;
1278 if (!s->current_file_ok)
1279 return UNZ_END_OF_LIST_OF_FILE;
1280
1281 /* Save the current state */
1282 num_fileSaved = s->num_file;
1283 pos_in_central_dirSaved = s->pos_in_central_dir;
1284 cur_file_infoSaved = s->cur_file_info;
1285 cur_file_info_internalSaved = s->cur_file_info_internal;
1286
1287 err = unzGoToFirstFile(file);
1288
1289 while (err == UNZ_OK)
1290 {
1291 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
1292 err = unzGetCurrentFileInfo64(file,NULL,
1293 szCurrentFileName,sizeof(szCurrentFileName)-1,
1294 NULL,0,NULL,0);
1295 if (err == UNZ_OK)
1296 {
1297 if (unzStringFileNameCompare(szCurrentFileName,
1298 szFileName,iCaseSensitivity)==0)
1299 return UNZ_OK;
1300 err = unzGoToNextFile(file);
1301 }
1302 }
1303
1304 /* We failed, so restore the state of the 'current file' to where we
1305 * were.
1306 */
1307 s->num_file = num_fileSaved ;
1308 s->pos_in_central_dir = pos_in_central_dirSaved ;
1309 s->cur_file_info = cur_file_infoSaved;
1310 s->cur_file_info_internal = cur_file_info_internalSaved;
1311 return err;
1312}
1313
1314
1315/*
1316///////////////////////////////////////////
1317// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
1318// I need random access
1319//
1320// Further optimization could be realized by adding an ability
1321// to cache the directory in memory. The goal being a single
1322// comprehensive file read to put the file I need in a memory.
1323*/
1324
1325/*
1326typedef struct unz_file_pos_s
1327{
1328 ZPOS64_T pos_in_zip_directory; // offset in file
1329 ZPOS64_T num_of_file; // # of file
1330} unz_file_pos;
1331*/
1332
1333extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos)
1334{
1335 unz64_s* s;
1336
1337 if (file==NULL || file_pos==NULL)
1338 return UNZ_PARAMERROR;
1339 s=(unz64_s*)file;
1340 if (!s->current_file_ok)
1341 return UNZ_END_OF_LIST_OF_FILE;
1342
1343 file_pos->pos_in_zip_directory = s->pos_in_central_dir;
1344 file_pos->num_of_file = s->num_file;
1345
1346 return UNZ_OK;
1347}
1348
1349extern int ZEXPORT unzGetFilePos(
1350 unzFile file,
1351 unz_file_pos* file_pos)
1352{
1353 unz64_file_pos file_pos64;
1354 int err = unzGetFilePos64(file,&file_pos64);
1355 if (err==UNZ_OK)
1356 {
1357 file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
1358 file_pos->num_of_file = (uLong)file_pos64.num_of_file;
1359 }
1360 return err;
1361}
1362
1363extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
1364{
1365 unz64_s* s;
1366 int err;
1367
1368 if (file==NULL || file_pos==NULL)
1369 return UNZ_PARAMERROR;
1370 s=(unz64_s*)file;
1371
1372 /* jump to the right spot */
1373 s->pos_in_central_dir = file_pos->pos_in_zip_directory;
1374 s->num_file = file_pos->num_of_file;
1375
1376 /* set the current file */
1377 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1378 &s->cur_file_info_internal,
1379 NULL,0,NULL,0,NULL,0);
1380 /* return results */
1381 s->current_file_ok = (err == UNZ_OK);
1382 return err;
1383}
1384
1385extern int ZEXPORT unzGoToFilePos(
1386 unzFile file,
1387 unz_file_pos* file_pos)
1388{
1389 unz64_file_pos file_pos64;
1390 if (file_pos == NULL)
1391 return UNZ_PARAMERROR;
1392
1393 file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
1394 file_pos64.num_of_file = file_pos->num_of_file;
1395 return unzGoToFilePos64(file,&file_pos64);
1396}
1397
1398/* Unzip Helper Functions - should be here? */
1399/*///////////////////////////////////////// */
1400
1401/*
1402 Read the local header of the current zipfile
1403 Check the coherency of the local header and info in the end of central
1404 directory about this file
1405 store in *piSizeVar the size of extra info in local header
1406 (filename and size of extra field data)
1407*/
1408local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
1409 ZPOS64_T * poffset_local_extrafield,
1410 uInt * psize_local_extrafield)
1411{
1412 uLong uMagic,uData,uFlags;
1413 uLong size_filename;
1414 uLong size_extra_field;
1415 int err=UNZ_OK;
1416
1417 *piSizeVar = 0;
1418 *poffset_local_extrafield = 0;
1419 *psize_local_extrafield = 0;
1420
1421 if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
1422 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
1423 return UNZ_ERRNO;
1424
1425
1426 if (err==UNZ_OK)
1427 {
1428 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
1429 err=UNZ_ERRNO;
1430 else if (uMagic!=0x04034b50)
1431 err=UNZ_BADZIPFILE;
1432 }
1433
1434 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1435 err=UNZ_ERRNO;
1436/*
1437 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
1438 err=UNZ_BADZIPFILE;
1439*/
1440 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
1441 err=UNZ_ERRNO;
1442
1443 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1444 err=UNZ_ERRNO;
1445 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
1446 err=UNZ_BADZIPFILE;
1447
1448 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1449/* #ifdef HAVE_BZIP2 */
1450 (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1451/* #endif */
1452 (s->cur_file_info.compression_method!=Z_DEFLATED))
1453 err=UNZ_BADZIPFILE;
1454
1455 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1456 err=UNZ_ERRNO;
1457
1458 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1459 err=UNZ_ERRNO;
1460 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
1461 err=UNZ_BADZIPFILE;
1462
1463 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1464 err=UNZ_ERRNO;
1465 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
1466 err=UNZ_BADZIPFILE;
1467
1468 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1469 err=UNZ_ERRNO;
1470 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
1471 err=UNZ_BADZIPFILE;
1472
1473 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1474 err=UNZ_ERRNO;
1475 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1476 err=UNZ_BADZIPFILE;
1477
1478 *piSizeVar += (uInt)size_filename;
1479
1480 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1481 err=UNZ_ERRNO;
1482 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1483 SIZEZIPLOCALHEADER + size_filename;
1484 *psize_local_extrafield = (uInt)size_extra_field;
1485
1486 *piSizeVar += (uInt)size_extra_field;
1487
1488 return err;
1489}
1490
1491/*
1492 Open for reading data the current file in the zipfile.
1493 If there is no error and the file is opened, the return value is UNZ_OK.
1494*/
1495extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
1496 int* level, int raw, const char* password)
1497{
1498 int err=UNZ_OK;
1499 uInt iSizeVar;
1500 unz64_s* s;
1501 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1502 ZPOS64_T offset_local_extrafield; /* offset of the local extra field */
1503 uInt size_local_extrafield; /* size of the local extra field */
1504# ifndef NOUNCRYPT
1505 char source[12];
1506# else
1507 if (password != NULL)
1508 return UNZ_PARAMERROR;
1509# endif
1510
1511 if (file==NULL)
1512 return UNZ_PARAMERROR;
1513 s=(unz64_s*)file;
1514 if (!s->current_file_ok)
1515 return UNZ_PARAMERROR;
1516
1517 if (s->pfile_in_zip_read != NULL)
1518 unzCloseCurrentFile(file);
1519
1520 if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1521 return UNZ_BADZIPFILE;
1522
1523 pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
1524 if (pfile_in_zip_read_info==NULL)
1525 return UNZ_INTERNALERROR;
1526
1527 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1528 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1529 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1530 pfile_in_zip_read_info->pos_local_extrafield=0;
1531 pfile_in_zip_read_info->raw=raw;
1532
1533 if (pfile_in_zip_read_info->read_buffer==NULL)
1534 {
1535 TRYFREE(pfile_in_zip_read_info);
1536 return UNZ_INTERNALERROR;
1537 }
1538
1539 pfile_in_zip_read_info->stream_initialised=0;
1540
1541 if (method!=NULL)
1542 *method = (int)s->cur_file_info.compression_method;
1543
1544 if (level!=NULL)
1545 {
1546 *level = 6;
1547 switch (s->cur_file_info.flag & 0x06)
1548 {
1549 case 6 : *level = 1; break;
1550 case 4 : *level = 2; break;
1551 case 2 : *level = 9; break;
1552 }
1553 }
1554
1555 if ((s->cur_file_info.compression_method!=0) &&
1556/* #ifdef HAVE_BZIP2 */
1557 (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1558/* #endif */
1559 (s->cur_file_info.compression_method!=Z_DEFLATED))
1560
1561 err=UNZ_BADZIPFILE;
1562
1563 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1564 pfile_in_zip_read_info->crc32=0;
1565 pfile_in_zip_read_info->total_out_64=0;
1566 pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
1567 pfile_in_zip_read_info->filestream=s->filestream;
1568 pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1569 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1570
1571 pfile_in_zip_read_info->stream.total_out = 0;
1572
1573 if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
1574 {
1575#ifdef HAVE_BZIP2
1576 pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
1577 pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
1578 pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
1579 pfile_in_zip_read_info->bstream.state = (voidpf)0;
1580
1581 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1582 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1583 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1584 pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1585 pfile_in_zip_read_info->stream.avail_in = 0;
1586
1587 err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
1588 if (err == Z_OK)
1589 pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
1590 else
1591 {
1592 TRYFREE(pfile_in_zip_read_info);
1593 return err;
1594 }
1595#else
1596 pfile_in_zip_read_info->raw=1;
1597#endif
1598 }
1599 else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
1600 {
1601 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1602 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1603 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1604 pfile_in_zip_read_info->stream.next_in = 0;
1605 pfile_in_zip_read_info->stream.avail_in = 0;
1606
1607 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1608 if (err == Z_OK)
1609 pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
1610 else
1611 {
1612 TRYFREE(pfile_in_zip_read_info->read_buffer);
1613 TRYFREE(pfile_in_zip_read_info);
1614 return err;
1615 }
1616 /* windowBits is passed < 0 to tell that there is no zlib header.
1617 * Note that in this case inflate *requires* an extra "dummy" byte
1618 * after the compressed stream in order to complete decompression and
1619 * return Z_STREAM_END.
1620 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1621 * size of both compressed and uncompressed data
1622 */
1623 }
1624 pfile_in_zip_read_info->rest_read_compressed =
1625 s->cur_file_info.compressed_size ;
1626 pfile_in_zip_read_info->rest_read_uncompressed =
1627 s->cur_file_info.uncompressed_size ;
1628
1629
1630 pfile_in_zip_read_info->pos_in_zipfile =
1631 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1632 iSizeVar;
1633
1634 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1635
1636 s->pfile_in_zip_read = pfile_in_zip_read_info;
1637 s->encrypted = 0;
1638
1639# ifndef NOUNCRYPT
1640 if (password != NULL)
1641 {
1642 int i;
1643 s->pcrc_32_tab = get_crc_table();
1644 init_keys(password,s->keys,s->pcrc_32_tab);
1645 if (ZSEEK64(s->z_filefunc, s->filestream,
1646 s->pfile_in_zip_read->pos_in_zipfile +
1647 s->pfile_in_zip_read->byte_before_the_zipfile,
1648 SEEK_SET)!=0)
1649 return UNZ_INTERNALERROR;
1650 if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
1651 return UNZ_INTERNALERROR;
1652
1653 for (i = 0; i<12; i++)
1654 zdecode(s->keys,s->pcrc_32_tab,source[i]);
1655
1656 s->pfile_in_zip_read->pos_in_zipfile+=12;
1657 s->encrypted=1;
1658 }
1659# endif
1660
1661
1662 return UNZ_OK;
1663}
1664
1665extern int ZEXPORT unzOpenCurrentFile (unzFile file)
1666{
1667 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1668}
1669
1670extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password)
1671{
1672 return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1673}
1674
1675extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
1676{
1677 return unzOpenCurrentFile3(file, method, level, raw, NULL);
1678}
1679
1680/** Addition for GDAL : START */
1681
1682extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
1683{
1684 unz64_s* s;
1685 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1686 s=(unz64_s*)file;
1687 if (file==NULL)
1688 return 0; /*UNZ_PARAMERROR; */
1689 pfile_in_zip_read_info=s->pfile_in_zip_read;
1690 if (pfile_in_zip_read_info==NULL)
1691 return 0; /*UNZ_PARAMERROR; */
1692 return pfile_in_zip_read_info->pos_in_zipfile +
1693 pfile_in_zip_read_info->byte_before_the_zipfile;
1694}
1695
1696/** Addition for GDAL : END */
1697
1698/*
1699 Read bytes from the current file.
1700 buf contain buffer where data must be copied
1701 len the size of buf.
1702
1703 return the number of byte copied if somes bytes are copied
1704 return 0 if the end of file was reached
1705 return <0 with error code if there is an error
1706 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1707*/
1708extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
1709{
1710 int err=UNZ_OK;
1711 uInt iRead = 0;
1712 unz64_s* s;
1713 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1714 if (file==NULL)
1715 return UNZ_PARAMERROR;
1716 s=(unz64_s*)file;
1717 pfile_in_zip_read_info=s->pfile_in_zip_read;
1718
1719 if (pfile_in_zip_read_info==NULL)
1720 return UNZ_PARAMERROR;
1721
1722
1723 if (pfile_in_zip_read_info->read_buffer == NULL)
1724 return UNZ_END_OF_LIST_OF_FILE;
1725 if (len==0)
1726 return 0;
1727
1728 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1729
1730 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1731
1732 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1733 (!(pfile_in_zip_read_info->raw)))
1734 pfile_in_zip_read_info->stream.avail_out =
1735 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1736
1737 if ((len>pfile_in_zip_read_info->rest_read_compressed+
1738 pfile_in_zip_read_info->stream.avail_in) &&
1739 (pfile_in_zip_read_info->raw))
1740 pfile_in_zip_read_info->stream.avail_out =
1741 (uInt)pfile_in_zip_read_info->rest_read_compressed+
1742 pfile_in_zip_read_info->stream.avail_in;
1743
1744 while (pfile_in_zip_read_info->stream.avail_out>0)
1745 {
1746 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1747 (pfile_in_zip_read_info->rest_read_compressed>0))
1748 {
1749 uInt uReadThis = UNZ_BUFSIZE;
1750 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1751 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1752 if (uReadThis == 0)
1753 return UNZ_EOF;
1754 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
1755 pfile_in_zip_read_info->filestream,
1756 pfile_in_zip_read_info->pos_in_zipfile +
1757 pfile_in_zip_read_info->byte_before_the_zipfile,
1758 ZLIB_FILEFUNC_SEEK_SET)!=0)
1759 return UNZ_ERRNO;
1760 if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
1761 pfile_in_zip_read_info->filestream,
1762 pfile_in_zip_read_info->read_buffer,
1763 uReadThis)!=uReadThis)
1764 return UNZ_ERRNO;
1765
1766
1767# ifndef NOUNCRYPT
1768 if(s->encrypted)
1769 {
1770 uInt i;
1771 for(i=0;i<uReadThis;i++)
1772 pfile_in_zip_read_info->read_buffer[i] =
1773 zdecode(s->keys,s->pcrc_32_tab,
1774 pfile_in_zip_read_info->read_buffer[i]);
1775 }
1776# endif
1777
1778
1779 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1780
1781 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1782
1783 pfile_in_zip_read_info->stream.next_in =
1784 (Bytef*)pfile_in_zip_read_info->read_buffer;
1785 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1786 }
1787
1788 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1789 {
1790 uInt uDoCopy,i ;
1791
1792 if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1793 (pfile_in_zip_read_info->rest_read_compressed == 0))
1794 return (iRead==0) ? UNZ_EOF : iRead;
1795
1796 if (pfile_in_zip_read_info->stream.avail_out <
1797 pfile_in_zip_read_info->stream.avail_in)
1798 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1799 else
1800 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1801
1802 for (i=0;i<uDoCopy;i++)
1803 *(pfile_in_zip_read_info->stream.next_out+i) =
1804 *(pfile_in_zip_read_info->stream.next_in+i);
1805
1806 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
1807
1808 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1809 pfile_in_zip_read_info->stream.next_out,
1810 uDoCopy);
1811 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1812 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1813 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1814 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1815 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1816 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1817 iRead += uDoCopy;
1818 }
1819 else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
1820 {
1821#ifdef HAVE_BZIP2
1822 uLong uTotalOutBefore,uTotalOutAfter;
1823 const Bytef *bufBefore;
1824 uLong uOutThis;
1825
1826 pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in;
1827 pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;
1828 pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;
1829 pfile_in_zip_read_info->bstream.total_in_hi32 = 0;
1830 pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out;
1831 pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;
1832 pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
1833 pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
1834
1835 uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
1836 bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
1837
1838 err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
1839
1840 uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
1841 uOutThis = uTotalOutAfter-uTotalOutBefore;
1842
1843 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1844
1845 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
1846 pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
1847 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1848
1849 pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
1850 pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;
1851 pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;
1852 pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
1853 pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
1854 pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
1855
1856 if (err==BZ_STREAM_END)
1857 return (iRead==0) ? UNZ_EOF : iRead;
1858 if (err!=BZ_OK)
1859 break;
1860#endif
1861 } /* end Z_BZIP2ED */
1862 else
1863 {
1864 uInt uAvailOutBefore,uAvailOutAfter;
1865 const Bytef *bufBefore;
1866 uInt uOutThis;
1867 int flush=Z_SYNC_FLUSH;
1868
1869 uAvailOutBefore = pfile_in_zip_read_info->stream.avail_out;
1870 bufBefore = pfile_in_zip_read_info->stream.next_out;
1871
1872 err=inflate(&pfile_in_zip_read_info->stream,flush);
1873
1874 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1875 err = Z_DATA_ERROR;
1876
1877 uAvailOutAfter = pfile_in_zip_read_info->stream.avail_out;
1878 uOutThis = uAvailOutBefore - uAvailOutAfter;
1879
1880 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1881
1882 pfile_in_zip_read_info->crc32
1883 = crc32(pfile_in_zip_read_info->crc32,bufBefore, uOutThis);
1884
1885 pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
1886
1887 iRead += uAvailOutBefore - uAvailOutAfter;
1888
1889 if (err==Z_STREAM_END)
1890 return (iRead==0) ? UNZ_EOF : iRead;
1891 if (err!=Z_OK)
1892 break;
1893 }
1894 }
1895
1896 if (err==Z_OK)
1897 return iRead;
1898 return err;
1899}
1900
1901
1902/*
1903 Give the current position in uncompressed data
1904*/
1905extern z_off_t ZEXPORT unztell (unzFile file)
1906{
1907 unz64_s* s;
1908 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1909 if (file==NULL)
1910 return UNZ_PARAMERROR;
1911 s=(unz64_s*)file;
1912 pfile_in_zip_read_info=s->pfile_in_zip_read;
1913
1914 if (pfile_in_zip_read_info==NULL)
1915 return UNZ_PARAMERROR;
1916
1917 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1918}
1919
1920extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
1921{
1922
1923 unz64_s* s;
1924 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1925 if (file==NULL)
1926 return (ZPOS64_T)-1;
1927 s=(unz64_s*)file;
1928 pfile_in_zip_read_info=s->pfile_in_zip_read;
1929
1930 if (pfile_in_zip_read_info==NULL)
1931 return (ZPOS64_T)-1;
1932
1933 return pfile_in_zip_read_info->total_out_64;
1934}
1935
1936
1937/*
1938 return 1 if the end of file was reached, 0 elsewhere
1939*/
1940extern int ZEXPORT unzeof (unzFile file)
1941{
1942 unz64_s* s;
1943 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1944 if (file==NULL)
1945 return UNZ_PARAMERROR;
1946 s=(unz64_s*)file;
1947 pfile_in_zip_read_info=s->pfile_in_zip_read;
1948
1949 if (pfile_in_zip_read_info==NULL)
1950 return UNZ_PARAMERROR;
1951
1952 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1953 return 1;
1954 else
1955 return 0;
1956}
1957
1958
1959
1960/*
1961Read extra field from the current file (opened by unzOpenCurrentFile)
1962This is the local-header version of the extra field (sometimes, there is
1963more info in the local-header version than in the central-header)
1964
1965 if buf==NULL, it return the size of the local extra field that can be read
1966
1967 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1968 buf.
1969 the return value is the number of bytes copied in buf, or (if <0)
1970 the error code
1971*/
1972extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
1973{
1974 unz64_s* s;
1975 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1976 uInt read_now;
1977 ZPOS64_T size_to_read;
1978
1979 if (file==NULL)
1980 return UNZ_PARAMERROR;
1981 s=(unz64_s*)file;
1982 pfile_in_zip_read_info=s->pfile_in_zip_read;
1983
1984 if (pfile_in_zip_read_info==NULL)
1985 return UNZ_PARAMERROR;
1986
1987 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1988 pfile_in_zip_read_info->pos_local_extrafield);
1989
1990 if (buf==NULL)
1991 return (int)size_to_read;
1992
1993 if (len>size_to_read)
1994 read_now = (uInt)size_to_read;
1995 else
1996 read_now = (uInt)len ;
1997
1998 if (read_now==0)
1999 return 0;
2000
2001 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
2002 pfile_in_zip_read_info->filestream,
2003 pfile_in_zip_read_info->offset_local_extrafield +
2004 pfile_in_zip_read_info->pos_local_extrafield,
2005 ZLIB_FILEFUNC_SEEK_SET)!=0)
2006 return UNZ_ERRNO;
2007
2008 if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
2009 pfile_in_zip_read_info->filestream,
2010 buf,read_now)!=read_now)
2011 return UNZ_ERRNO;
2012
2013 return (int)read_now;
2014}
2015
2016/*
2017 Close the file in zip opened with unzipOpenCurrentFile
2018 Return UNZ_CRCERROR if all the file was read but the CRC is not good
2019*/
2020extern int ZEXPORT unzCloseCurrentFile (unzFile file)
2021{
2022 int err=UNZ_OK;
2023
2024 unz64_s* s;
2025 file_in_zip64_read_info_s* pfile_in_zip_read_info;
2026 if (file==NULL)
2027 return UNZ_PARAMERROR;
2028 s=(unz64_s*)file;
2029 pfile_in_zip_read_info=s->pfile_in_zip_read;
2030
2031 if (pfile_in_zip_read_info==NULL)
2032 return UNZ_PARAMERROR;
2033
2034
2035 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
2036 (!pfile_in_zip_read_info->raw))
2037 {
2038 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
2039 err=UNZ_CRCERROR;
2040 }
2041
2042
2043 TRYFREE(pfile_in_zip_read_info->read_buffer);
2044 pfile_in_zip_read_info->read_buffer = NULL;
2045 if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
2046 inflateEnd(&pfile_in_zip_read_info->stream);
2047#ifdef HAVE_BZIP2
2048 else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
2049 BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
2050#endif
2051
2052
2053 pfile_in_zip_read_info->stream_initialised = 0;
2054 TRYFREE(pfile_in_zip_read_info);
2055
2056 s->pfile_in_zip_read=NULL;
2057
2058 return err;
2059}
2060
2061
2062/*
2063 Get the global comment string of the ZipFile, in the szComment buffer.
2064 uSizeBuf is the size of the szComment buffer.
2065 return the number of byte copied or an error code <0
2066*/
2067extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
2068{
2069 unz64_s* s;
2070 uLong uReadThis ;
2071 if (file==NULL)
2072 return (int)UNZ_PARAMERROR;
2073 s=(unz64_s*)file;
2074
2075 uReadThis = uSizeBuf;
2076 if (uReadThis>s->gi.size_comment)
2077 uReadThis = s->gi.size_comment;
2078
2079 if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
2080 return UNZ_ERRNO;
2081
2082 if (uReadThis>0)
2083 {
2084 *szComment='\0';
2085 if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
2086 return UNZ_ERRNO;
2087 }
2088
2089 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
2090 *(szComment+s->gi.size_comment)='\0';
2091 return (int)uReadThis;
2092}
2093
2094/* Additions by RX '2004 */
2095extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
2096{
2097 unz64_s* s;
2098
2099 if (file==NULL)
2100 return 0; /*UNZ_PARAMERROR; */
2101 s=(unz64_s*)file;
2102 if (!s->current_file_ok)
2103 return 0;
2104 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
2105 if (s->num_file==s->gi.number_entry)
2106 return 0;
2107 return s->pos_in_central_dir;
2108}
2109
2110extern uLong ZEXPORT unzGetOffset (unzFile file)
2111{
2112 ZPOS64_T offset64;
2113
2114 if (file==NULL)
2115 return 0; /*UNZ_PARAMERROR; */
2116 offset64 = unzGetOffset64(file);
2117 return (uLong)offset64;
2118}
2119
2120extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
2121{
2122 unz64_s* s;
2123 int err;
2124
2125 if (file==NULL)
2126 return UNZ_PARAMERROR;
2127 s=(unz64_s*)file;
2128
2129 s->pos_in_central_dir = pos;
2130 s->num_file = s->gi.number_entry; /* hack */
2131 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
2132 &s->cur_file_info_internal,
2133 NULL,0,NULL,0,NULL,0);
2134 s->current_file_ok = (err == UNZ_OK);
2135 return err;
2136}
2137
2138extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
2139{
2140 return unzSetOffset64(file,pos);
2141}
2142
2143
2144int ZEXPORT unzSetFlags(unzFile file, unsigned flags)
2145{
2146 unz64_s* s;
2147 if (file == NULL)
2148 return UNZ_PARAMERROR;
2149 s = (unz64_s*)file;
2150 s->flags |= flags;
2151 return UNZ_OK;
2152}
2153
2154
2155int ZEXPORT unzClearFlags(unzFile file, unsigned flags)
2156{
2157 unz64_s* s;
2158 if (file == NULL)
2159 return UNZ_PARAMERROR;
2160 s = (unz64_s*)file;
2161 s->flags &= ~flags;
2162 return UNZ_OK;
2163}
diff --git a/utils/rbutilqt/quazip/unzip.h b/utils/rbutilqt/quazip/unzip.h
new file mode 100644
index 0000000000..fdefa2217a
--- /dev/null
+++ b/utils/rbutilqt/quazip/unzip.h
@@ -0,0 +1,461 @@
1/* unzip.h -- IO for uncompress .zip files using zlib
2 Version 1.1, February 14h, 2010
3 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
4
5 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
6
7 Modifications of Unzip for Zip64
8 Copyright (C) 2007-2008 Even Rouault
9
10 Modifications for Zip64 support on both zip and unzip
11 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
12
13 For more info read MiniZip_info.txt
14
15 ---------------------------------------------------------------------------------
16
17 Condition of use and distribution are the same than zlib :
18
19 This software is provided 'as-is', without any express or implied
20 warranty. In no event will the authors be held liable for any damages
21 arising from the use of this software.
22
23 Permission is granted to anyone to use this software for any purpose,
24 including commercial applications, and to alter it and redistribute it
25 freely, subject to the following restrictions:
26
27 1. The origin of this software must not be misrepresented; you must not
28 claim that you wrote the original software. If you use this software
29 in a product, an acknowledgment in the product documentation would be
30 appreciated but is not required.
31 2. Altered source versions must be plainly marked as such, and must not be
32 misrepresented as being the original software.
33 3. This notice may not be removed or altered from any source distribution.
34
35 ---------------------------------------------------------------------------------
36
37 Changes
38
39 See header of unzip64.c
40
41 ---------------------------------------------------------------------------
42
43 As per the requirement above, this file is plainly marked as modified
44 by Sergey A. Tachenov. Most modifications include the I/O API redesign
45 to support QIODevice interface. Some improvements and small fixes were also made.
46*/
47
48#ifndef _unz64_H
49#define _unz64_H
50
51#ifdef __cplusplus
52extern "C" {
53#endif
54
55#ifndef _ZLIB_H
56#include <zlib.h>
57#endif
58
59#ifndef _ZLIBIOAPI_H
60#include "ioapi.h"
61#endif
62
63#ifdef HAVE_BZIP2
64#include "bzlib.h"
65#endif
66
67#define Z_BZIP2ED 12
68
69#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
70/* like the STRICT of WIN32, we define a pointer that cannot be converted
71 from (void*) without cast */
72typedef struct TagunzFile__ { int unused; } unzFile__;
73typedef unzFile__ *unzFile;
74#else
75typedef voidp unzFile;
76#endif
77
78
79#define UNZ_OK (0)
80#define UNZ_END_OF_LIST_OF_FILE (-100)
81#define UNZ_ERRNO (Z_ERRNO)
82#define UNZ_EOF (0)
83#define UNZ_PARAMERROR (-102)
84#define UNZ_BADZIPFILE (-103)
85#define UNZ_INTERNALERROR (-104)
86#define UNZ_CRCERROR (-105)
87
88#define UNZ_AUTO_CLOSE 0x01u
89#define UNZ_DEFAULT_FLAGS UNZ_AUTO_CLOSE
90#define UNZ_ENCODING_UTF8 0x0800u
91
92/* tm_unz contain date/time info */
93typedef struct tm_unz_s
94{
95 uInt tm_sec; /* seconds after the minute - [0,59] */
96 uInt tm_min; /* minutes after the hour - [0,59] */
97 uInt tm_hour; /* hours since midnight - [0,23] */
98 uInt tm_mday; /* day of the month - [1,31] */
99 uInt tm_mon; /* months since January - [0,11] */
100 uInt tm_year; /* years - [1980..2044] */
101} tm_unz;
102
103/* unz_global_info structure contain global data about the ZIPfile
104 These data comes from the end of central dir */
105typedef struct unz_global_info64_s
106{
107 ZPOS64_T number_entry; /* total number of entries in
108 the central dir on this disk */
109 uLong size_comment; /* size of the global comment of the zipfile */
110} unz_global_info64;
111
112typedef struct unz_global_info_s
113{
114 uLong number_entry; /* total number of entries in
115 the central dir on this disk */
116 uLong size_comment; /* size of the global comment of the zipfile */
117} unz_global_info;
118
119/* unz_file_info contain information about a file in the zipfile */
120typedef struct unz_file_info64_s
121{
122 uLong version; /* version made by 2 bytes */
123 uLong version_needed; /* version needed to extract 2 bytes */
124 uLong flag; /* general purpose bit flag 2 bytes */
125 uLong compression_method; /* compression method 2 bytes */
126 uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
127 uLong crc; /* crc-32 4 bytes */
128 ZPOS64_T compressed_size; /* compressed size 8 bytes */
129 ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */
130 uLong size_filename; /* filename length 2 bytes */
131 uLong size_file_extra; /* extra field length 2 bytes */
132 uLong size_file_comment; /* file comment length 2 bytes */
133
134 uLong disk_num_start; /* disk number start 2 bytes */
135 uLong internal_fa; /* internal file attributes 2 bytes */
136 uLong external_fa; /* external file attributes 4 bytes */
137
138 tm_unz tmu_date;
139} unz_file_info64;
140
141typedef struct unz_file_info_s
142{
143 uLong version; /* version made by 2 bytes */
144 uLong version_needed; /* version needed to extract 2 bytes */
145 uLong flag; /* general purpose bit flag 2 bytes */
146 uLong compression_method; /* compression method 2 bytes */
147 uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
148 uLong crc; /* crc-32 4 bytes */
149 uLong compressed_size; /* compressed size 4 bytes */
150 uLong uncompressed_size; /* uncompressed size 4 bytes */
151 uLong size_filename; /* filename length 2 bytes */
152 uLong size_file_extra; /* extra field length 2 bytes */
153 uLong size_file_comment; /* file comment length 2 bytes */
154
155 uLong disk_num_start; /* disk number start 2 bytes */
156 uLong internal_fa; /* internal file attributes 2 bytes */
157 uLong external_fa; /* external file attributes 4 bytes */
158
159 tm_unz tmu_date;
160} unz_file_info;
161
162extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
163 const char* fileName2,
164 int iCaseSensitivity));
165/*
166 Compare two filename (fileName1,fileName2).
167 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
168 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
169 or strcasecmp)
170 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
171 (like 1 on Unix, 2 on Windows)
172*/
173
174
175extern unzFile ZEXPORT unzOpen OF((voidpf file));
176extern unzFile ZEXPORT unzOpen64 OF((voidpf file));
177/*
178 Open a Zip file. path contain the full pathname (by example,
179 on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
180 "zlib/zlib113.zip".
181 If the zipfile cannot be opened (file don't exist or in not valid), the
182 return value is NULL.
183 Else, the return value is a unzFile Handle, usable with other function
184 of this unzip package.
185 the "64" function take a const void* pointer, because the path is just the
186 value passed to the open64_file_func callback.
187 Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path
188 is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char*
189 does not describe the reality
190*/
191
192
193extern unzFile ZEXPORT unzOpen2 OF((voidpf file,
194 zlib_filefunc_def* pzlib_filefunc_def));
195/*
196 Open a Zip file, like unzOpen, but provide a set of file low level API
197 for read/write the zip file (see ioapi.h)
198*/
199
200extern unzFile ZEXPORT unzOpen2_64 OF((voidpf file,
201 zlib_filefunc64_def* pzlib_filefunc_def));
202/*
203 Open a Zip file, like unz64Open, but provide a set of file low level API
204 for read/write the zip file (see ioapi.h)
205*/
206
207
208/*
209 * Exported by Sergey A. Tachenov to implement some QuaZIP features. This
210 * function MAY change signature in order to implement even more features.
211 * You have been warned!
212 * */
213extern unzFile unzOpenInternal (voidpf file,
214 zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
215 int is64bitOpenFunction, unsigned flags);
216
217
218
219extern int ZEXPORT unzClose OF((unzFile file));
220/*
221 Close a ZipFile opened with unzipOpen.
222 If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
223 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
224 return UNZ_OK if there is no problem. */
225
226extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
227 unz_global_info *pglobal_info));
228
229extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file,
230 unz_global_info64 *pglobal_info));
231
232extern int ZEXPORT unzGetFileFlags OF((unzFile file, unsigned* pflags));
233/*
234 Write info about the ZipFile in the *pglobal_info structure.
235 No preparation of the structure is needed
236 return UNZ_OK if there is no problem. */
237
238
239extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
240 char *szComment,
241 uLong uSizeBuf));
242/*
243 Get the global comment string of the ZipFile, in the szComment buffer.
244 uSizeBuf is the size of the szComment buffer.
245 return the number of byte copied or an error code <0
246*/
247
248
249/***************************************************************************/
250/* Unzip package allow you browse the directory of the zipfile */
251
252extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
253/*
254 Set the current file of the zipfile to the first file.
255 return UNZ_OK if there is no problem
256*/
257
258extern int ZEXPORT unzGoToNextFile OF((unzFile file));
259/*
260 Set the current file of the zipfile to the next file.
261 return UNZ_OK if there is no problem
262 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
263*/
264
265extern int ZEXPORT unzLocateFile OF((unzFile file,
266 const char *szFileName,
267 int iCaseSensitivity));
268/*
269 Try locate the file szFileName in the zipfile.
270 For the iCaseSensitivity signification, see unzStringFileNameCompare
271
272 return value :
273 UNZ_OK if the file is found. It becomes the current file.
274 UNZ_END_OF_LIST_OF_FILE if the file is not found
275*/
276
277
278/* ****************************************** */
279/* Ryan supplied functions */
280/* unz_file_info contain information about a file in the zipfile */
281typedef struct unz_file_pos_s
282{
283 uLong pos_in_zip_directory; /* offset in zip file directory */
284 uLong num_of_file; /* # of file */
285} unz_file_pos;
286
287extern int ZEXPORT unzGetFilePos(
288 unzFile file,
289 unz_file_pos* file_pos);
290
291extern int ZEXPORT unzGoToFilePos(
292 unzFile file,
293 unz_file_pos* file_pos);
294
295typedef struct unz64_file_pos_s
296{
297 ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */
298 ZPOS64_T num_of_file; /* # of file */
299} unz64_file_pos;
300
301extern int ZEXPORT unzGetFilePos64(
302 unzFile file,
303 unz64_file_pos* file_pos);
304
305extern int ZEXPORT unzGoToFilePos64(
306 unzFile file,
307 const unz64_file_pos* file_pos);
308
309/* ****************************************** */
310
311extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file,
312 unz_file_info64 *pfile_info,
313 char *szFileName,
314 uLong fileNameBufferSize,
315 void *extraField,
316 uLong extraFieldBufferSize,
317 char *szComment,
318 uLong commentBufferSize));
319
320extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
321 unz_file_info *pfile_info,
322 char *szFileName,
323 uLong fileNameBufferSize,
324 void *extraField,
325 uLong extraFieldBufferSize,
326 char *szComment,
327 uLong commentBufferSize));
328/*
329 Get Info about the current file
330 if pfile_info!=NULL, the *pfile_info structure will contain somes info about
331 the current file
332 if szFileName!=NULL, the filemane string will be copied in szFileName
333 (fileNameBufferSize is the size of the buffer)
334 if extraField!=NULL, the extra field information will be copied in extraField
335 (extraFieldBufferSize is the size of the buffer).
336 This is the Central-header version of the extra field
337 if szComment!=NULL, the comment string of the file will be copied in szComment
338 (commentBufferSize is the size of the buffer)
339*/
340
341
342/** Addition for GDAL : START */
343
344extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));
345
346/** Addition for GDAL : END */
347
348
349/***************************************************************************/
350/* for reading the content of the current zipfile, you can open it, read data
351 from it, and close it (you can close it before reading all the file)
352 */
353
354extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
355/*
356 Open for reading data the current file in the zipfile.
357 If there is no error, the return value is UNZ_OK.
358*/
359
360extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
361 const char* password));
362/*
363 Open for reading data the current file in the zipfile.
364 password is a crypting password
365 If there is no error, the return value is UNZ_OK.
366*/
367
368extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
369 int* method,
370 int* level,
371 int raw));
372/*
373 Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
374 if raw==1
375 *method will receive method of compression, *level will receive level of
376 compression
377 note : you can set level parameter as NULL (if you did not want known level,
378 but you CANNOT set method parameter as NULL
379*/
380
381extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
382 int* method,
383 int* level,
384 int raw,
385 const char* password));
386/*
387 Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
388 if raw==1
389 *method will receive method of compression, *level will receive level of
390 compression
391 note : you can set level parameter as NULL (if you did not want known level,
392 but you CANNOT set method parameter as NULL
393*/
394
395
396extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
397/*
398 Close the file in zip opened with unzOpenCurrentFile
399 Return UNZ_CRCERROR if all the file was read but the CRC is not good
400*/
401
402extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
403 voidp buf,
404 unsigned len));
405/*
406 Read bytes from the current file (opened by unzOpenCurrentFile)
407 buf contain buffer where data must be copied
408 len the size of buf.
409
410 return the number of byte copied if somes bytes are copied
411 return 0 if the end of file was reached
412 return <0 with error code if there is an error
413 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
414*/
415
416extern z_off_t ZEXPORT unztell OF((unzFile file));
417
418extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));
419/*
420 Give the current position in uncompressed data
421*/
422
423extern int ZEXPORT unzeof OF((unzFile file));
424/*
425 return 1 if the end of file was reached, 0 elsewhere
426*/
427
428extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
429 voidp buf,
430 unsigned len));
431/*
432 Read extra field from the current file (opened by unzOpenCurrentFile)
433 This is the local-header version of the extra field (sometimes, there is
434 more info in the local-header version than in the central-header)
435
436 if buf==NULL, it return the size of the local extra field
437
438 if buf!=NULL, len is the size of the buffer, the extra header is copied in
439 buf.
440 the return value is the number of bytes copied in buf, or (if <0)
441 the error code
442*/
443
444/***************************************************************************/
445
446/* Get the current file offset */
447extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file);
448extern uLong ZEXPORT unzGetOffset (unzFile file);
449
450/* Set the current file offset */
451extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos);
452extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
453
454extern int ZEXPORT unzSetFlags(unzFile file, unsigned flags);
455extern int ZEXPORT unzClearFlags(unzFile file, unsigned flags);
456
457#ifdef __cplusplus
458}
459#endif
460
461#endif /* _unz64_H */
diff --git a/utils/rbutilqt/quazip/zip.c b/utils/rbutilqt/quazip/zip.c
new file mode 100644
index 0000000000..0f3deb04c1
--- /dev/null
+++ b/utils/rbutilqt/quazip/zip.c
@@ -0,0 +1,2111 @@
1/* zip.c -- IO on .zip files using zlib
2 Version 1.1, February 14h, 2010
3 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
4
5 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
6
7 Modifications for Zip64 support
8 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
9
10 For more info read MiniZip_info.txt
11
12 Modifications for QIODevice support and other QuaZIP fixes
13 Copyright (C) 2005-2014 Sergey A. Tachenov
14
15 Fixing static code analysis issues
16 Copyright (C) 2016 Intel Deutschland GmbH
17
18 Changes
19 Oct-2009 - Mathias Svensson - Remove old C style function prototypes
20 Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
21 Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
22 Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
23 It is used when recreting zip archive with RAW when deleting items from a zip.
24 ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.
25 Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
26 Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
27
28*/
29
30
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <time.h>
35
36#include <zlib.h>
37#if (ZLIB_VERNUM < 0x1270)
38typedef uLongf z_crc_t;
39#endif
40#include "zip.h"
41
42#ifdef STDC
43# include <stddef.h>
44# include <string.h>
45# include <stdlib.h>
46#endif
47#ifdef NO_ERRNO_H
48 extern int errno;
49#else
50# include <errno.h>
51#endif
52
53
54#ifndef local
55# define local static
56#endif
57/* compile with -Dlocal if your debugger can't find static symbols */
58
59#ifndef VERSIONMADEBY
60# define VERSIONMADEBY (0x031e) /* best for standard pkware crypt */
61#endif
62
63#ifndef Z_BUFSIZE
64#define Z_BUFSIZE (64*1024) /* (16384) */
65#endif
66
67#ifndef Z_MAXFILENAMEINZIP
68#define Z_MAXFILENAMEINZIP (256)
69#endif
70
71#ifndef ALLOC
72# define ALLOC(size) (malloc(size))
73#endif
74#ifndef TRYFREE
75# define TRYFREE(p) {if (p) free(p);}
76#endif
77
78/*
79#define SIZECENTRALDIRITEM (0x2e)
80#define SIZEZIPLOCALHEADER (0x1e)
81*/
82
83/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
84
85
86/* NOT sure that this work on ALL platform */
87#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
88
89#ifndef SEEK_CUR
90#define SEEK_CUR 1
91#endif
92
93#ifndef SEEK_END
94#define SEEK_END 2
95#endif
96
97#ifndef SEEK_SET
98#define SEEK_SET 0
99#endif
100
101#ifndef DEF_MEM_LEVEL
102#if MAX_MEM_LEVEL >= 8
103# define DEF_MEM_LEVEL 8
104#else
105# define DEF_MEM_LEVEL MAX_MEM_LEVEL
106#endif
107#endif
108const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
109
110
111#define SIZEDATA_INDATABLOCK (4096-(4*4))
112
113#define LOCALHEADERMAGIC (0x04034b50)
114#define DESCRIPTORHEADERMAGIC (0x08074b50)
115#define CENTRALHEADERMAGIC (0x02014b50)
116#define ENDHEADERMAGIC (0x06054b50)
117#define ZIP64ENDHEADERMAGIC (0x6064b50)
118#define ZIP64ENDLOCHEADERMAGIC (0x7064b50)
119
120#define FLAG_LOCALHEADER_OFFSET (0x06)
121#define CRC_LOCALHEADER_OFFSET (0x0e)
122
123#define SIZECENTRALHEADER (0x2e) /* 46 */
124
125typedef struct linkedlist_datablock_internal_s
126{
127 struct linkedlist_datablock_internal_s* next_datablock;
128 uLong avail_in_this_block;
129 uLong filled_in_this_block;
130 uLong unused; /* for future use and alignement */
131 unsigned char data[SIZEDATA_INDATABLOCK];
132} linkedlist_datablock_internal;
133
134typedef struct linkedlist_data_s
135{
136 linkedlist_datablock_internal* first_block;
137 linkedlist_datablock_internal* last_block;
138} linkedlist_data;
139
140
141typedef struct
142{
143 z_stream stream; /* zLib stream structure for inflate */
144#ifdef HAVE_BZIP2
145 bz_stream bstream; /* bzLib stream structure for bziped */
146#endif
147
148 int stream_initialised; /* 1 is stream is initialised */
149 uInt pos_in_buffered_data; /* last written byte in buffered_data */
150
151 ZPOS64_T pos_local_header; /* offset of the local header of the file
152 currenty writing */
153 char* central_header; /* central header data for the current file */
154 uLong size_centralExtra;
155 uLong size_centralheader; /* size of the central header for cur file */
156 uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
157 uLong flag; /* flag of the file currently writing */
158
159 int method; /* compression method of file currenty wr.*/
160 int raw; /* 1 for directly writing raw data */
161 Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
162 uLong dosDate;
163 uLong crc32;
164 int encrypt;
165 int zip64; /* Add ZIP64 extened information in the extra field */
166 ZPOS64_T pos_zip64extrainfo;
167 ZPOS64_T totalCompressedData;
168 ZPOS64_T totalUncompressedData;
169#ifndef NOCRYPT
170 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
171 const z_crc_t FAR * pcrc_32_tab;
172 int crypt_header_size;
173#endif
174} curfile64_info;
175
176typedef struct
177{
178 zlib_filefunc64_32_def z_filefunc;
179 voidpf filestream; /* io structore of the zipfile */
180 linkedlist_data central_dir;/* datablock with central dir in construction*/
181 int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
182 curfile64_info ci; /* info on the file curretly writing */
183
184 ZPOS64_T begin_pos; /* position of the beginning of the zipfile */
185 ZPOS64_T add_position_when_writting_offset;
186 ZPOS64_T number_entry;
187
188#ifndef NO_ADDFILEINEXISTINGZIP
189 char *globalcomment;
190#endif
191
192 unsigned flags;
193
194} zip64_internal;
195
196
197#ifndef NOCRYPT
198#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
199#include "minizip_crypt.h"
200#endif
201
202local linkedlist_datablock_internal* allocate_new_datablock()
203{
204 linkedlist_datablock_internal* ldi;
205 ldi = (linkedlist_datablock_internal*)
206 ALLOC(sizeof(linkedlist_datablock_internal));
207 if (ldi!=NULL)
208 {
209 ldi->next_datablock = NULL ;
210 ldi->filled_in_this_block = 0 ;
211 ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
212 }
213 return ldi;
214}
215
216local void free_datablock(linkedlist_datablock_internal* ldi)
217{
218 while (ldi!=NULL)
219 {
220 linkedlist_datablock_internal* ldinext = ldi->next_datablock;
221 TRYFREE(ldi);
222 ldi = ldinext;
223 }
224}
225
226local void init_linkedlist(linkedlist_data* ll)
227{
228 ll->first_block = ll->last_block = NULL;
229}
230
231local void free_linkedlist(linkedlist_data* ll)
232{
233 free_datablock(ll->first_block);
234 ll->first_block = ll->last_block = NULL;
235}
236
237
238local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
239{
240 linkedlist_datablock_internal* ldi;
241 const unsigned char* from_copy;
242
243 if (ll==NULL)
244 return ZIP_INTERNALERROR;
245
246 if (ll->last_block == NULL)
247 {
248 ll->first_block = ll->last_block = allocate_new_datablock();
249 if (ll->first_block == NULL)
250 return ZIP_INTERNALERROR;
251 }
252
253 ldi = ll->last_block;
254 from_copy = (unsigned char*)buf;
255
256 while (len>0)
257 {
258 uInt copy_this;
259 uInt i;
260 unsigned char* to_copy;
261
262 if (ldi->avail_in_this_block==0)
263 {
264 ldi->next_datablock = allocate_new_datablock();
265 if (ldi->next_datablock == NULL)
266 return ZIP_INTERNALERROR;
267 ldi = ldi->next_datablock ;
268 ll->last_block = ldi;
269 }
270
271 if (ldi->avail_in_this_block < len)
272 copy_this = (uInt)ldi->avail_in_this_block;
273 else
274 copy_this = (uInt)len;
275
276 to_copy = &(ldi->data[ldi->filled_in_this_block]);
277
278 for (i=0;i<copy_this;i++)
279 *(to_copy+i)=*(from_copy+i);
280
281 ldi->filled_in_this_block += copy_this;
282 ldi->avail_in_this_block -= copy_this;
283 from_copy += copy_this ;
284 len -= copy_this;
285 }
286 return ZIP_OK;
287}
288
289
290
291/****************************************************************************/
292
293#ifndef NO_ADDFILEINEXISTINGZIP
294/* ===========================================================================
295 Inputs a long in LSB order to the given file
296 nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
297*/
298
299local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
300local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
301{
302 unsigned char buf[8];
303 int n;
304 for (n = 0; n < nbByte; n++)
305 {
306 buf[n] = (unsigned char)(x & 0xff);
307 x >>= 8;
308 }
309 if (x != 0)
310 { /* data overflow - hack for ZIP64 (X Roche) */
311 for (n = 0; n < nbByte; n++)
312 {
313 buf[n] = 0xff;
314 }
315 }
316
317 if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
318 return ZIP_ERRNO;
319 else
320 return ZIP_OK;
321}
322
323local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
324local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
325{
326 unsigned char* buf=(unsigned char*)dest;
327 int n;
328 for (n = 0; n < nbByte; n++) {
329 buf[n] = (unsigned char)(x & 0xff);
330 x >>= 8;
331 }
332
333 if (x != 0)
334 { /* data overflow - hack for ZIP64 */
335 for (n = 0; n < nbByte; n++)
336 {
337 buf[n] = 0xff;
338 }
339 }
340}
341
342/****************************************************************************/
343
344
345local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
346{
347 uLong year = (uLong)ptm->tm_year;
348 if (year>=1980)
349 year-=1980;
350 else if (year>=80)
351 year-=80;
352 return
353 (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
354 ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
355}
356
357
358/****************************************************************************/
359
360local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
361
362local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
363{
364 unsigned char c;
365 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
366 if (err==1)
367 {
368 *pi = (int)c;
369 return ZIP_OK;
370 }
371 else
372 {
373 if (ZERROR64(*pzlib_filefunc_def,filestream))
374 return ZIP_ERRNO;
375 else
376 return ZIP_EOF;
377 }
378}
379
380
381/* ===========================================================================
382 Reads a long in LSB order from the given gz_stream. Sets
383*/
384local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
385
386local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
387{
388 uLong x ;
389 int i = 0;
390 int err;
391
392 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
393 x = (uLong)i;
394
395 if (err==ZIP_OK)
396 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
397 x += ((uLong)i)<<8;
398
399 if (err==ZIP_OK)
400 *pX = x;
401 else
402 *pX = 0;
403 return err;
404}
405
406local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
407
408local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
409{
410 uLong x ;
411 int i = 0;
412 int err;
413
414 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
415 x = (uLong)i;
416
417 if (err==ZIP_OK)
418 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
419 x += ((uLong)i)<<8;
420
421 if (err==ZIP_OK)
422 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
423 x += ((uLong)i)<<16;
424
425 if (err==ZIP_OK)
426 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
427 x += ((uLong)i)<<24;
428
429 if (err==ZIP_OK)
430 *pX = x;
431 else
432 *pX = 0;
433 return err;
434}
435
436local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
437
438
439local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
440{
441 ZPOS64_T x;
442 int i = 0;
443 int err;
444
445 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
446 x = (ZPOS64_T)i;
447
448 if (err==ZIP_OK)
449 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
450 x += ((ZPOS64_T)i)<<8;
451
452 if (err==ZIP_OK)
453 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
454 x += ((ZPOS64_T)i)<<16;
455
456 if (err==ZIP_OK)
457 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
458 x += ((ZPOS64_T)i)<<24;
459
460 if (err==ZIP_OK)
461 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
462 x += ((ZPOS64_T)i)<<32;
463
464 if (err==ZIP_OK)
465 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
466 x += ((ZPOS64_T)i)<<40;
467
468 if (err==ZIP_OK)
469 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
470 x += ((ZPOS64_T)i)<<48;
471
472 if (err==ZIP_OK)
473 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
474 x += ((ZPOS64_T)i)<<56;
475
476 if (err==ZIP_OK)
477 *pX = x;
478 else
479 *pX = 0;
480
481 return err;
482}
483
484#ifndef BUFREADCOMMENT
485#define BUFREADCOMMENT (0x400)
486#endif
487/*
488 Locate the Central directory of a zipfile (at the end, just before
489 the global comment)
490*/
491local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
492
493local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
494{
495 unsigned char* buf;
496 ZPOS64_T uSizeFile;
497 ZPOS64_T uBackRead;
498 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
499 ZPOS64_T uPosFound=0;
500
501 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
502 return 0;
503
504
505 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
506
507 if (uMaxBack>uSizeFile)
508 uMaxBack = uSizeFile;
509
510 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
511 if (buf==NULL)
512 return 0;
513
514 uBackRead = 4;
515 while (uBackRead<uMaxBack)
516 {
517 uLong uReadSize;
518 ZPOS64_T uReadPos ;
519 int i;
520 if (uBackRead+BUFREADCOMMENT>uMaxBack)
521 uBackRead = uMaxBack;
522 else
523 uBackRead+=BUFREADCOMMENT;
524 uReadPos = uSizeFile-uBackRead ;
525
526 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
527 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
528 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
529 break;
530
531 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
532 break;
533
534 for (i=(int)uReadSize-3; (i--)>0;){
535 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
536 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
537 {
538 uPosFound = uReadPos+i;
539 break;
540 }
541 }
542
543 if (uPosFound!=0)
544 break;
545 }
546 TRYFREE(buf);
547 return uPosFound;
548}
549
550/*
551Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
552the global comment)
553*/
554local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
555
556local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
557{
558 unsigned char* buf;
559 ZPOS64_T uSizeFile;
560 ZPOS64_T uBackRead;
561 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
562 ZPOS64_T uPosFound=0;
563 uLong uL;
564 ZPOS64_T relativeOffset;
565
566 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
567 return 0;
568
569 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
570
571 if (uMaxBack>uSizeFile)
572 uMaxBack = uSizeFile;
573
574 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
575 if (buf==NULL)
576 return 0;
577
578 uBackRead = 4;
579 while (uBackRead<uMaxBack)
580 {
581 uLong uReadSize;
582 ZPOS64_T uReadPos;
583 int i;
584 if (uBackRead+BUFREADCOMMENT>uMaxBack)
585 uBackRead = uMaxBack;
586 else
587 uBackRead+=BUFREADCOMMENT;
588 uReadPos = uSizeFile-uBackRead ;
589
590 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
591 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
592 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
593 break;
594
595 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
596 break;
597
598 for (i=(int)uReadSize-3; (i--)>0;)
599 {
600 /* Signature "0x07064b50" Zip64 end of central directory locater */
601 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
602 {
603 uPosFound = uReadPos+i;
604 break;
605 }
606 }
607
608 if (uPosFound!=0)
609 break;
610 }
611
612 TRYFREE(buf);
613 if (uPosFound == 0)
614 return 0;
615
616 /* Zip64 end of central directory locator */
617 if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
618 return 0;
619
620 /* the signature, already checked */
621 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
622 return 0;
623
624 /* number of the disk with the start of the zip64 end of central directory */
625 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
626 return 0;
627 if (uL != 0)
628 return 0;
629
630 /* relative offset of the zip64 end of central directory record */
631 if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
632 return 0;
633
634 /* total number of disks */
635 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
636 return 0;
637 if (uL != 1)
638 return 0;
639
640 /* Goto Zip64 end of central directory record */
641 if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
642 return 0;
643
644 /* the signature */
645 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
646 return 0;
647
648 if (uL != 0x06064b50) /* signature of 'Zip64 end of central directory' */
649 return 0;
650
651 return relativeOffset;
652}
653
654int LoadCentralDirectoryRecord(zip64_internal* pziinit)
655{
656 int err=ZIP_OK;
657 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
658
659 ZPOS64_T size_central_dir; /* size of the central directory */
660 ZPOS64_T offset_central_dir; /* offset of start of central directory */
661 ZPOS64_T central_pos;
662 uLong uL;
663
664 uLong number_disk; /* number of the current dist, used for
665 spaning ZIP, unsupported, always 0*/
666 uLong number_disk_with_CD; /* number the the disk with central dir, used
667 for spaning ZIP, unsupported, always 0*/
668 ZPOS64_T number_entry;
669 ZPOS64_T number_entry_CD; /* total number of entries in
670 the central dir
671 (same than number_entry on nospan) */
672 uLong VersionMadeBy;
673 uLong VersionNeeded;
674 uLong size_comment;
675
676 int hasZIP64Record = 0;
677
678 /* check first if we find a ZIP64 record */
679 central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
680 if(central_pos > 0)
681 {
682 hasZIP64Record = 1;
683 }
684 else if(central_pos == 0)
685 {
686 central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
687 }
688
689/* disable to allow appending to empty ZIP archive
690 if (central_pos==0)
691 err=ZIP_ERRNO;
692*/
693
694 if(hasZIP64Record)
695 {
696 ZPOS64_T sizeEndOfCentralDirectory;
697 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
698 err=ZIP_ERRNO;
699
700 /* the signature, already checked */
701 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
702 err=ZIP_ERRNO;
703
704 /* size of zip64 end of central directory record */
705 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
706 err=ZIP_ERRNO;
707
708 /* version made by */
709 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
710 err=ZIP_ERRNO;
711
712 /* version needed to extract */
713 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
714 err=ZIP_ERRNO;
715
716 /* number of this disk */
717 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
718 err=ZIP_ERRNO;
719
720 /* number of the disk with the start of the central directory */
721 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
722 err=ZIP_ERRNO;
723
724 /* total number of entries in the central directory on this disk */
725 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
726 err=ZIP_ERRNO;
727
728 /* total number of entries in the central directory */
729 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
730 err=ZIP_ERRNO;
731
732 if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
733 err=ZIP_BADZIPFILE;
734
735 /* size of the central directory */
736 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
737 err=ZIP_ERRNO;
738
739 /* offset of start of central directory with respect to the
740 starting disk number */
741 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
742 err=ZIP_ERRNO;
743
744 /* TODO.. */
745 /* read the comment from the standard central header. */
746 size_comment = 0;
747 }
748 else
749 {
750 /* Read End of central Directory info */
751 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
752 err=ZIP_ERRNO;
753
754 /* the signature, already checked */
755 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
756 err=ZIP_ERRNO;
757
758 /* number of this disk */
759 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
760 err=ZIP_ERRNO;
761
762 /* number of the disk with the start of the central directory */
763 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
764 err=ZIP_ERRNO;
765
766 /* total number of entries in the central dir on this disk */
767 number_entry = 0;
768 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
769 err=ZIP_ERRNO;
770 else
771 number_entry = uL;
772
773 /* total number of entries in the central dir */
774 number_entry_CD = 0;
775 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
776 err=ZIP_ERRNO;
777 else
778 number_entry_CD = uL;
779
780 if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
781 err=ZIP_BADZIPFILE;
782
783 /* size of the central directory */
784 size_central_dir = 0;
785 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
786 err=ZIP_ERRNO;
787 else
788 size_central_dir = uL;
789
790 /* offset of start of central directory with respect to the starting disk number */
791 offset_central_dir = 0;
792 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
793 err=ZIP_ERRNO;
794 else
795 offset_central_dir = uL;
796
797
798 /* zipfile global comment length */
799 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
800 err=ZIP_ERRNO;
801 }
802
803 if ((central_pos<offset_central_dir+size_central_dir) &&
804 (err==ZIP_OK))
805 err=ZIP_BADZIPFILE;
806
807 if (err!=ZIP_OK)
808 {
809 if ((pziinit->flags & ZIP_AUTO_CLOSE) != 0) {
810 ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
811 } else {
812 ZFAKECLOSE64(pziinit->z_filefunc, pziinit->filestream);
813 }
814 return ZIP_ERRNO;
815 }
816
817 if (size_comment>0)
818 {
819 pziinit->globalcomment = (char*)ALLOC(size_comment+1);
820 if (pziinit->globalcomment)
821 {
822 size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
823 pziinit->globalcomment[size_comment]=0;
824 }
825 }
826
827 byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
828 pziinit->add_position_when_writting_offset = byte_before_the_zipfile;
829
830 {
831 ZPOS64_T size_central_dir_to_read = size_central_dir;
832 size_t buf_size = SIZEDATA_INDATABLOCK;
833 void* buf_read = (void*)ALLOC(buf_size);
834 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
835 err=ZIP_ERRNO;
836
837 while ((size_central_dir_to_read>0) && (err==ZIP_OK))
838 {
839 ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
840 if (read_this > size_central_dir_to_read)
841 read_this = size_central_dir_to_read;
842
843 if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
844 err=ZIP_ERRNO;
845
846 if (err==ZIP_OK)
847 err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
848
849 size_central_dir_to_read-=read_this;
850 }
851 TRYFREE(buf_read);
852 }
853 pziinit->begin_pos = byte_before_the_zipfile;
854 pziinit->number_entry = number_entry_CD;
855
856 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
857 err=ZIP_ERRNO;
858
859 return err;
860}
861
862
863#endif /* !NO_ADDFILEINEXISTINGZIP*/
864
865
866/************************************************************/
867extern zipFile ZEXPORT zipOpen3 (voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
868 unsigned flags)
869{
870 zip64_internal ziinit;
871 zip64_internal* zi;
872 int err=ZIP_OK;
873
874 ziinit.flags = flags;
875 ziinit.z_filefunc.zseek32_file = NULL;
876 ziinit.z_filefunc.ztell32_file = NULL;
877 if (pzlib_filefunc64_32_def==NULL)
878 fill_qiodevice64_filefunc(&ziinit.z_filefunc.zfile_func64);
879 else
880 ziinit.z_filefunc = *pzlib_filefunc64_32_def;
881
882 ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
883 file,
884 (append == APPEND_STATUS_CREATE) ?
885 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
886 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
887
888 if (ziinit.filestream == NULL)
889 return NULL;
890
891 if (append == APPEND_STATUS_CREATEAFTER)
892 ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
893
894 ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
895 ziinit.in_opened_file_inzip = 0;
896 ziinit.ci.stream_initialised = 0;
897 ziinit.number_entry = 0;
898 ziinit.add_position_when_writting_offset = 0;
899 init_linkedlist(&(ziinit.central_dir));
900
901
902
903 zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
904 if (zi==NULL)
905 {
906 if ((ziinit.flags & ZIP_AUTO_CLOSE) != 0) {
907 ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
908 } else {
909 ZFAKECLOSE64(ziinit.z_filefunc,ziinit.filestream);
910 }
911 return NULL;
912 }
913
914 /* now we add file in a zipfile */
915# ifndef NO_ADDFILEINEXISTINGZIP
916 ziinit.globalcomment = NULL;
917 if (append == APPEND_STATUS_ADDINZIP)
918 {
919 /* Read and Cache Central Directory Records */
920 err = LoadCentralDirectoryRecord(&ziinit);
921 }
922
923 if (globalcomment)
924 {
925 *globalcomment = ziinit.globalcomment;
926 }
927# endif /* !NO_ADDFILEINEXISTINGZIP*/
928
929 if (err != ZIP_OK)
930 {
931# ifndef NO_ADDFILEINEXISTINGZIP
932 TRYFREE(ziinit.globalcomment);
933# endif /* !NO_ADDFILEINEXISTINGZIP*/
934 TRYFREE(zi);
935 return NULL;
936 }
937 else
938 {
939 *zi = ziinit;
940 return (zipFile)zi;
941 }
942}
943
944extern zipFile ZEXPORT zipOpen2 (voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
945{
946 if (pzlib_filefunc32_def != NULL)
947 {
948 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
949 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
950 return zipOpen3(file, append, globalcomment, &zlib_filefunc64_32_def_fill, ZIP_DEFAULT_FLAGS);
951 }
952 else
953 return zipOpen3(file, append, globalcomment, NULL, ZIP_DEFAULT_FLAGS);
954}
955
956extern zipFile ZEXPORT zipOpen2_64 (voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
957{
958 if (pzlib_filefunc_def != NULL)
959 {
960 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
961 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
962 zlib_filefunc64_32_def_fill.ztell32_file = NULL;
963 zlib_filefunc64_32_def_fill.zseek32_file = NULL;
964 return zipOpen3(file, append, globalcomment, &zlib_filefunc64_32_def_fill, ZIP_DEFAULT_FLAGS);
965 }
966 else
967 return zipOpen3(file, append, globalcomment, NULL, ZIP_DEFAULT_FLAGS);
968}
969
970
971
972extern zipFile ZEXPORT zipOpen (voidpf file, int append)
973{
974 return zipOpen3(file,append,NULL,NULL, ZIP_DEFAULT_FLAGS);
975}
976
977extern zipFile ZEXPORT zipOpen64 (voidpf file, int append)
978{
979 return zipOpen3(file,append,NULL,NULL, ZIP_DEFAULT_FLAGS);
980}
981
982int Write_LocalFileHeader(zip64_internal* zi, const char* filename,
983 uInt size_extrafield_local,
984 const void* extrafield_local,
985 uLong version_to_extract)
986{
987 /* write the local header */
988 int err;
989 uInt size_filename = (uInt)strlen(filename);
990 uInt size_extrafield = size_extrafield_local;
991
992 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
993
994 if (err==ZIP_OK)
995 {
996 if(zi->ci.flag & ZIP_ENCODING_UTF8)
997 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)63,2);/* Version 6.3 is required for Unicode support */
998 else if(zi->ci.zip64)
999 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
1000 else
1001 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)version_to_extract,2);
1002 }
1003
1004 if (err==ZIP_OK)
1005 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
1006
1007 if (err==ZIP_OK)
1008 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
1009
1010 if (err==ZIP_OK)
1011 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
1012
1013 /* CRC / Compressed size / Uncompressed size will be filled in later and rewritten later */
1014 if (err==ZIP_OK)
1015 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
1016 if (err==ZIP_OK)
1017 {
1018 if(zi->ci.zip64)
1019 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
1020 else
1021 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
1022 }
1023 if (err==ZIP_OK)
1024 {
1025 if(zi->ci.zip64)
1026 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
1027 else
1028 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
1029 }
1030
1031 if (err==ZIP_OK)
1032 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
1033
1034 if(zi->ci.zip64)
1035 {
1036 size_extrafield += 20;
1037 }
1038
1039 if (err==ZIP_OK)
1040 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
1041
1042 if ((err==ZIP_OK) && (size_filename > 0))
1043 {
1044 if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
1045 err = ZIP_ERRNO;
1046 }
1047
1048 if ((err==ZIP_OK) && (size_extrafield_local > 0))
1049 {
1050 if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
1051 err = ZIP_ERRNO;
1052 }
1053
1054
1055 if ((err==ZIP_OK) && (zi->ci.zip64))
1056 {
1057 /* write the Zip64 extended info */
1058 short HeaderID = 1;
1059 short DataSize = 16;
1060 ZPOS64_T CompressedSize = 0;
1061 ZPOS64_T UncompressedSize = 0;
1062
1063 /* Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) */
1064 zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
1065
1066 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);
1067 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);
1068
1069 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
1070 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
1071 }
1072
1073 return err;
1074}
1075
1076/*
1077 NOTE.
1078 When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
1079 before calling this function it can be done with zipRemoveExtraInfoBlock
1080
1081 It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
1082 unnecessary allocations.
1083 */
1084extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
1085 const void* extrafield_local, uInt size_extrafield_local,
1086 const void* extrafield_global, uInt size_extrafield_global,
1087 const char* comment, int method, int level, int raw,
1088 int windowBits,int memLevel, int strategy,
1089 const char* password, uLong crcForCrypting,
1090 uLong versionMadeBy, uLong flagBase, int zip64)
1091{
1092 zip64_internal* zi;
1093 uInt size_filename;
1094 uInt size_comment;
1095 uInt i;
1096 int err = ZIP_OK;
1097 uLong version_to_extract;
1098
1099# ifdef NOCRYPT
1100 if (password != NULL)
1101 return ZIP_PARAMERROR;
1102# endif
1103
1104 if (file == NULL)
1105 return ZIP_PARAMERROR;
1106
1107#ifdef HAVE_BZIP2
1108 if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
1109 return ZIP_PARAMERROR;
1110#else
1111 if ((method!=0) && (method!=Z_DEFLATED))
1112 return ZIP_PARAMERROR;
1113#endif
1114
1115 zi = (zip64_internal*)file;
1116
1117 if (zi->in_opened_file_inzip == 1)
1118 {
1119 err = zipCloseFileInZip (file);
1120 if (err != ZIP_OK)
1121 return err;
1122 }
1123
1124 if (method == 0
1125 && (level == 0 || (zi->flags & ZIP_WRITE_DATA_DESCRIPTOR) == 0)
1126 && (zi->flags & ZIP_SEQUENTIAL) == 0)
1127 {
1128 version_to_extract = 10;
1129 }
1130 else
1131 {
1132 version_to_extract = 20;
1133 }
1134
1135 if (filename==NULL)
1136 filename="-";
1137
1138 if (comment==NULL)
1139 size_comment = 0;
1140 else
1141 size_comment = (uInt)strlen(comment);
1142
1143 size_filename = (uInt)strlen(filename);
1144
1145 if (zipfi == NULL)
1146 zi->ci.dosDate = 0;
1147 else
1148 {
1149 if (zipfi->dosDate != 0)
1150 zi->ci.dosDate = zipfi->dosDate;
1151 else
1152 zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
1153 }
1154
1155 zi->ci.flag = flagBase;
1156 if (zi->flags & ZIP_ENCODING_UTF8)
1157 zi->ci.flag |= ZIP_ENCODING_UTF8;
1158 if ((level==8) || (level==9))
1159 zi->ci.flag |= 2;
1160 if (level==2)
1161 zi->ci.flag |= 4;
1162 if (level==1)
1163 zi->ci.flag |= 6;
1164 if (password != NULL)
1165 zi->ci.flag |= 1;
1166 if (version_to_extract >= 20
1167 && ((zi->flags & ZIP_WRITE_DATA_DESCRIPTOR) != 0
1168 || (zi->flags & ZIP_SEQUENTIAL) != 0))
1169 zi->ci.flag |= 8;
1170
1171 zi->ci.crc32 = 0;
1172 zi->ci.method = method;
1173 zi->ci.encrypt = 0;
1174 zi->ci.stream_initialised = 0;
1175 zi->ci.pos_in_buffered_data = 0;
1176 zi->ci.raw = raw;
1177 zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
1178
1179 zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
1180 zi->ci.size_centralExtraFree = 32; /* Extra space we have reserved in case we need to add ZIP64 extra info data */
1181
1182 zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
1183 if(!zi->ci.central_header) {
1184 return (Z_MEM_ERROR);
1185 }
1186
1187 zi->ci.size_centralExtra = size_extrafield_global;
1188 zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
1189 /* version info */
1190 zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
1191 zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)version_to_extract,2);
1192 zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
1193 zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
1194 zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
1195 zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
1196 zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
1197 zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
1198 zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
1199 zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
1200 zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
1201 zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
1202
1203 if (zipfi==NULL)
1204 zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
1205 else
1206 zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
1207
1208 if (zipfi==NULL)
1209 zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
1210 else
1211 zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
1212
1213 if(zi->ci.pos_local_header >= 0xffffffff)
1214 zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
1215 else
1216 zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);
1217
1218 for (i=0;i<size_filename;i++)
1219 *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
1220
1221 for (i=0;i<size_extrafield_global;i++)
1222 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
1223 *(((const char*)extrafield_global)+i);
1224
1225 for (i=0;i<size_comment;i++)
1226 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
1227 size_extrafield_global+i) = *(comment+i);
1228 if (zi->ci.central_header == NULL)
1229 return ZIP_INTERNALERROR;
1230
1231 zi->ci.zip64 = zip64;
1232 zi->ci.totalCompressedData = 0;
1233 zi->ci.totalUncompressedData = 0;
1234 zi->ci.pos_zip64extrainfo = 0;
1235
1236 err = Write_LocalFileHeader(zi, filename, size_extrafield_local,
1237 extrafield_local, version_to_extract);
1238
1239#ifdef HAVE_BZIP2
1240 zi->ci.bstream.avail_in = (uInt)0;
1241 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
1242 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
1243 zi->ci.bstream.total_in_hi32 = 0;
1244 zi->ci.bstream.total_in_lo32 = 0;
1245 zi->ci.bstream.total_out_hi32 = 0;
1246 zi->ci.bstream.total_out_lo32 = 0;
1247#endif
1248
1249 zi->ci.stream.avail_in = (uInt)0;
1250 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
1251 zi->ci.stream.next_out = zi->ci.buffered_data;
1252 zi->ci.stream.total_in = 0;
1253 zi->ci.stream.total_out = 0;
1254 zi->ci.stream.data_type = Z_BINARY;
1255
1256#ifdef HAVE_BZIP2
1257 if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
1258#else
1259 if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1260#endif
1261 {
1262 if(zi->ci.method == Z_DEFLATED)
1263 {
1264 zi->ci.stream.zalloc = (alloc_func)0;
1265 zi->ci.stream.zfree = (free_func)0;
1266 zi->ci.stream.opaque = (voidpf)0;
1267
1268 if (windowBits>0)
1269 windowBits = -windowBits;
1270
1271 err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
1272
1273 if (err==Z_OK)
1274 zi->ci.stream_initialised = Z_DEFLATED;
1275 }
1276 else if(zi->ci.method == Z_BZIP2ED)
1277 {
1278#ifdef HAVE_BZIP2
1279 /* Init BZip stuff here */
1280 zi->ci.bstream.bzalloc = 0;
1281 zi->ci.bstream.bzfree = 0;
1282 zi->ci.bstream.opaque = (voidpf)0;
1283
1284 err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
1285 if(err == BZ_OK)
1286 zi->ci.stream_initialised = Z_BZIP2ED;
1287#endif
1288 }
1289
1290 }
1291
1292# ifndef NOCRYPT
1293 zi->ci.crypt_header_size = 0;
1294 if ((err==Z_OK) && (password != NULL))
1295 {
1296 unsigned char bufHead[RAND_HEAD_LEN];
1297 unsigned int sizeHead;
1298 zi->ci.encrypt = 1;
1299 zi->ci.pcrc_32_tab = get_crc_table();
1300 /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
1301 if (crcForCrypting == 0) {
1302 crcForCrypting = (uLong)zi->ci.dosDate << 16; /* ATTANTION! Without this row, you don't unpack your password protected archive in other app. */
1303 }
1304 sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
1305 zi->ci.crypt_header_size = sizeHead;
1306
1307 if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
1308 err = ZIP_ERRNO;
1309 }
1310# endif
1311
1312 if (err==Z_OK)
1313 zi->in_opened_file_inzip = 1;
1314 return err;
1315}
1316
1317extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
1318 const void* extrafield_local, uInt size_extrafield_local,
1319 const void* extrafield_global, uInt size_extrafield_global,
1320 const char* comment, int method, int level, int raw,
1321 int windowBits,int memLevel, int strategy,
1322 const char* password, uLong crcForCrypting,
1323 uLong versionMadeBy, uLong flagBase)
1324{
1325 return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1326 extrafield_local, size_extrafield_local,
1327 extrafield_global, size_extrafield_global,
1328 comment, method, level, raw,
1329 windowBits, memLevel, strategy,
1330 password, crcForCrypting, versionMadeBy, flagBase, 0);
1331}
1332
1333extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
1334 const void* extrafield_local, uInt size_extrafield_local,
1335 const void* extrafield_global, uInt size_extrafield_global,
1336 const char* comment, int method, int level, int raw,
1337 int windowBits,int memLevel, int strategy,
1338 const char* password, uLong crcForCrypting)
1339{
1340 return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1341 extrafield_local, size_extrafield_local,
1342 extrafield_global, size_extrafield_global,
1343 comment, method, level, raw,
1344 windowBits, memLevel, strategy,
1345 password, crcForCrypting, VERSIONMADEBY, 0, 0);
1346}
1347
1348extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
1349 const void* extrafield_local, uInt size_extrafield_local,
1350 const void* extrafield_global, uInt size_extrafield_global,
1351 const char* comment, int method, int level, int raw,
1352 int windowBits,int memLevel, int strategy,
1353 const char* password, uLong crcForCrypting, int zip64)
1354{
1355 return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1356 extrafield_local, size_extrafield_local,
1357 extrafield_global, size_extrafield_global,
1358 comment, method, level, raw,
1359 windowBits, memLevel, strategy,
1360 password, crcForCrypting, VERSIONMADEBY, 0, zip64);
1361}
1362
1363extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
1364 const void* extrafield_local, uInt size_extrafield_local,
1365 const void* extrafield_global, uInt size_extrafield_global,
1366 const char* comment, int method, int level, int raw)
1367{
1368 return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1369 extrafield_local, size_extrafield_local,
1370 extrafield_global, size_extrafield_global,
1371 comment, method, level, raw,
1372 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
1373 NULL, 0, VERSIONMADEBY, 0, 0);
1374}
1375
1376extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
1377 const void* extrafield_local, uInt size_extrafield_local,
1378 const void* extrafield_global, uInt size_extrafield_global,
1379 const char* comment, int method, int level, int raw, int zip64)
1380{
1381 return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1382 extrafield_local, size_extrafield_local,
1383 extrafield_global, size_extrafield_global,
1384 comment, method, level, raw,
1385 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
1386 NULL, 0, VERSIONMADEBY, 0, zip64);
1387}
1388
1389extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
1390 const void* extrafield_local, uInt size_extrafield_local,
1391 const void*extrafield_global, uInt size_extrafield_global,
1392 const char* comment, int method, int level, int zip64)
1393{
1394 return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1395 extrafield_local, size_extrafield_local,
1396 extrafield_global, size_extrafield_global,
1397 comment, method, level, 0,
1398 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
1399 NULL, 0, VERSIONMADEBY, 0, zip64);
1400}
1401
1402extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
1403 const void* extrafield_local, uInt size_extrafield_local,
1404 const void*extrafield_global, uInt size_extrafield_global,
1405 const char* comment, int method, int level)
1406{
1407 return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1408 extrafield_local, size_extrafield_local,
1409 extrafield_global, size_extrafield_global,
1410 comment, method, level, 0,
1411 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
1412 NULL, 0, VERSIONMADEBY, 0, 0);
1413}
1414
1415local int zip64FlushWriteBuffer(zip64_internal* zi)
1416{
1417 int err=ZIP_OK;
1418
1419 if (zi->ci.encrypt != 0)
1420 {
1421#ifndef NOCRYPT
1422 uInt i;
1423 int t;
1424 for (i=0;i<zi->ci.pos_in_buffered_data;i++)
1425 zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
1426#endif
1427 }
1428
1429 if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
1430 err = ZIP_ERRNO;
1431
1432 zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
1433
1434#ifdef HAVE_BZIP2
1435 if(zi->ci.method == Z_BZIP2ED)
1436 {
1437 zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
1438 zi->ci.bstream.total_in_lo32 = 0;
1439 zi->ci.bstream.total_in_hi32 = 0;
1440 }
1441 else
1442#endif
1443 {
1444 zi->ci.totalUncompressedData += zi->ci.stream.total_in;
1445 zi->ci.stream.total_in = 0;
1446 }
1447
1448
1449 zi->ci.pos_in_buffered_data = 0;
1450
1451 return err;
1452}
1453
1454extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
1455{
1456 zip64_internal* zi;
1457 int err=ZIP_OK;
1458
1459 if (file == NULL)
1460 return ZIP_PARAMERROR;
1461 zi = (zip64_internal*)file;
1462
1463 if (zi->in_opened_file_inzip == 0)
1464 return ZIP_PARAMERROR;
1465
1466 zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
1467
1468#ifdef HAVE_BZIP2
1469 if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
1470 {
1471 zi->ci.bstream.next_in = (void*)buf;
1472 zi->ci.bstream.avail_in = len;
1473 err = BZ_RUN_OK;
1474
1475 while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
1476 {
1477 if (zi->ci.bstream.avail_out == 0)
1478 {
1479 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
1480 err = ZIP_ERRNO;
1481 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
1482 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
1483 }
1484
1485
1486 if(err != BZ_RUN_OK)
1487 break;
1488
1489 if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
1490 {
1491 uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
1492/* uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; */
1493 err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN);
1494
1495 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
1496 }
1497 }
1498
1499 if(err == BZ_RUN_OK)
1500 err = ZIP_OK;
1501 }
1502 else
1503#endif
1504 {
1505 zi->ci.stream.next_in = (Bytef*)buf;
1506 zi->ci.stream.avail_in = len;
1507
1508 while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
1509 {
1510 if (zi->ci.stream.avail_out == 0)
1511 {
1512 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
1513 err = ZIP_ERRNO;
1514 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
1515 zi->ci.stream.next_out = zi->ci.buffered_data;
1516 }
1517
1518
1519 if(err != ZIP_OK)
1520 break;
1521
1522 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1523 {
1524 uInt uAvailOutBefore = zi->ci.stream.avail_out;
1525 err=deflate(&zi->ci.stream, Z_NO_FLUSH);
1526 zi->ci.pos_in_buffered_data += uAvailOutBefore - zi->ci.stream.avail_out;
1527 }
1528 else
1529 {
1530 uInt copy_this,i;
1531 if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
1532 copy_this = zi->ci.stream.avail_in;
1533 else
1534 copy_this = zi->ci.stream.avail_out;
1535
1536 for (i = 0; i < copy_this; i++)
1537 *(((char*)zi->ci.stream.next_out)+i) =
1538 *(((const char*)zi->ci.stream.next_in)+i);
1539 {
1540 zi->ci.stream.avail_in -= copy_this;
1541 zi->ci.stream.avail_out-= copy_this;
1542 zi->ci.stream.next_in+= copy_this;
1543 zi->ci.stream.next_out+= copy_this;
1544 zi->ci.stream.total_in+= copy_this;
1545 zi->ci.stream.total_out+= copy_this;
1546 zi->ci.pos_in_buffered_data += copy_this;
1547 }
1548 }
1549 }/* while(...) */
1550 }
1551
1552 return err;
1553}
1554
1555extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
1556{
1557 return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
1558}
1559
1560extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
1561{
1562 zip64_internal* zi;
1563 ZPOS64_T compressed_size;
1564 uLong invalidValue = 0xffffffff;
1565 short datasize = 0;
1566 int err=ZIP_OK;
1567
1568 if (file == NULL)
1569 return ZIP_PARAMERROR;
1570 zi = (zip64_internal*)file;
1571
1572 if (zi->in_opened_file_inzip == 0)
1573 return ZIP_PARAMERROR;
1574 zi->ci.stream.avail_in = 0;
1575
1576 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1577 {
1578 while (err==ZIP_OK)
1579 {
1580 uLong uAvailOutBefore;
1581 if (zi->ci.stream.avail_out == 0)
1582 {
1583 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
1584 err = ZIP_ERRNO;
1585 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
1586 zi->ci.stream.next_out = zi->ci.buffered_data;
1587 }
1588 uAvailOutBefore = zi->ci.stream.avail_out;
1589 err=deflate(&zi->ci.stream, Z_FINISH);
1590 zi->ci.pos_in_buffered_data += uAvailOutBefore - zi->ci.stream.avail_out;
1591 }
1592 }
1593 else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
1594 {
1595#ifdef HAVE_BZIP2
1596 err = BZ_FINISH_OK;
1597 while (err==BZ_FINISH_OK)
1598 {
1599 uLong uTotalOutBefore;
1600 if (zi->ci.bstream.avail_out == 0)
1601 {
1602 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
1603 err = ZIP_ERRNO;
1604 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
1605 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
1606 }
1607 uTotalOutBefore = zi->ci.bstream.total_out_lo32;
1608 err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH);
1609 if(err == BZ_STREAM_END)
1610 err = Z_STREAM_END;
1611
1612 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
1613 }
1614
1615 if(err == BZ_FINISH_OK)
1616 err = ZIP_OK;
1617#endif
1618 }
1619
1620 if (err==Z_STREAM_END)
1621 err=ZIP_OK; /* this is normal */
1622
1623 if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
1624 {
1625 if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
1626 err = ZIP_ERRNO;
1627 }
1628
1629 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1630 {
1631 int tmp_err = deflateEnd(&zi->ci.stream);
1632 if (err == ZIP_OK)
1633 err = tmp_err;
1634 zi->ci.stream_initialised = 0;
1635 }
1636#ifdef HAVE_BZIP2
1637 else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
1638 {
1639 int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
1640 if (err==ZIP_OK)
1641 err = tmperr;
1642 zi->ci.stream_initialised = 0;
1643 }
1644#endif
1645
1646 if (!zi->ci.raw)
1647 {
1648 crc32 = (uLong)zi->ci.crc32;
1649 uncompressed_size = zi->ci.totalUncompressedData;
1650 }
1651 compressed_size = zi->ci.totalCompressedData;
1652
1653# ifndef NOCRYPT
1654 compressed_size += zi->ci.crypt_header_size;
1655# endif
1656
1657 /* update Current Item crc and sizes, */
1658 if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
1659 {
1660 /*version Made by*/
1661 zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
1662 /*version needed*/
1663 zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)((zi->ci.flag & ZIP_ENCODING_UTF8) ? 63 : 45),2);
1664 }
1665
1666 zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
1667
1668
1669 if(compressed_size >= 0xffffffff)
1670 zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
1671 else
1672 zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
1673
1674 /* set internal file attributes field */
1675 if (zi->ci.stream.data_type == Z_ASCII)
1676 zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
1677
1678 if(uncompressed_size >= 0xffffffff)
1679 zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
1680 else
1681 zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
1682
1683 /* Add ZIP64 extra info field for uncompressed size */
1684 if(uncompressed_size >= 0xffffffff)
1685 datasize += 8;
1686
1687 /* Add ZIP64 extra info field for compressed size */
1688 if(compressed_size >= 0xffffffff)
1689 datasize += 8;
1690
1691 /* Add ZIP64 extra info field for relative offset to local file header of current file */
1692 if(zi->ci.pos_local_header >= 0xffffffff)
1693 datasize += 8;
1694
1695 if(datasize > 0)
1696 {
1697 char* p = NULL;
1698
1699 if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
1700 {
1701 /* we can not write more data to the buffer that we have room for. */
1702 return ZIP_BADZIPFILE;
1703 }
1704
1705 p = zi->ci.central_header + zi->ci.size_centralheader;
1706
1707 /* Add Extra Information Header for 'ZIP64 information' */
1708 zip64local_putValue_inmemory(p, 0x0001, 2); /* HeaderID */
1709 p += 2;
1710 zip64local_putValue_inmemory(p, datasize, 2); /* DataSize */
1711 p += 2;
1712
1713 if(uncompressed_size >= 0xffffffff)
1714 {
1715 zip64local_putValue_inmemory(p, uncompressed_size, 8);
1716 p += 8;
1717 }
1718
1719 if(compressed_size >= 0xffffffff)
1720 {
1721 zip64local_putValue_inmemory(p, compressed_size, 8);
1722 p += 8;
1723 }
1724
1725 if(zi->ci.pos_local_header >= 0xffffffff)
1726 {
1727 zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
1728 p += 8;
1729 }
1730
1731 /* Update how much extra free space we got in the memory buffer */
1732 /* and increase the centralheader size so the new ZIP64 fields are included */
1733 /* ( 4 below is the size of HeaderID and DataSize field ) */
1734 zi->ci.size_centralExtraFree -= datasize + 4;
1735 zi->ci.size_centralheader += datasize + 4;
1736
1737 /* Update the extra info size field */
1738 zi->ci.size_centralExtra += datasize + 4;
1739 zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
1740 }
1741
1742 if (err==ZIP_OK)
1743 err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
1744
1745 TRYFREE(zi->ci.central_header);
1746
1747 if (err==ZIP_OK)
1748 {
1749 if ((zi->flags & ZIP_SEQUENTIAL) == 0) {
1750 /* Update the LocalFileHeader with the new values. */
1751
1752 ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
1753
1754 if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
1755 err = ZIP_ERRNO;
1756
1757 if (err==ZIP_OK)
1758 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
1759
1760 if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff)
1761 {
1762 if(zi->ci.pos_zip64extrainfo > 0)
1763 {
1764 /* Update the size in the ZIP64 extended field. */
1765 if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
1766 err = ZIP_ERRNO;
1767
1768 if (err==ZIP_OK) /* compressed size, unknown */
1769 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
1770
1771 if (err==ZIP_OK) /* uncompressed size, unknown */
1772 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
1773 }
1774 }
1775 else
1776 {
1777 if (err==ZIP_OK) /* compressed size, unknown */
1778 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
1779
1780 if (err==ZIP_OK) /* uncompressed size, unknown */
1781 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
1782 }
1783
1784 if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
1785 err = ZIP_ERRNO;
1786 }
1787
1788 if ((zi->ci.flag & 8) != 0) {
1789 /* Write local Descriptor after file data */
1790 if (err==ZIP_OK)
1791 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)DESCRIPTORHEADERMAGIC,4);
1792 if (err==ZIP_OK)
1793 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
1794 if (zi->ci.zip64) {
1795 if (err==ZIP_OK) /* compressed size, unknown */
1796 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,8);
1797
1798 if (err==ZIP_OK) /* uncompressed size, unknown */
1799 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,8);
1800 } else {
1801 if (err==ZIP_OK) /* compressed size, unknown */
1802 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
1803 if (err==ZIP_OK) /* uncompressed size, unknown */
1804 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
1805 }
1806 }
1807 }
1808
1809 zi->number_entry ++;
1810 zi->in_opened_file_inzip = 0;
1811
1812 return err;
1813}
1814
1815extern int ZEXPORT zipCloseFileInZip (zipFile file)
1816{
1817 return zipCloseFileInZipRaw (file,0,0);
1818}
1819
1820int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
1821{
1822 int err = ZIP_OK;
1823 ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
1824
1825 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
1826
1827 /*num disks*/
1828 if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1829 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
1830
1831 /*relative offset*/
1832 if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
1833 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
1834
1835 /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
1836 if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1837 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
1838
1839 return err;
1840}
1841
1842int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
1843{
1844 int err = ZIP_OK;
1845
1846 uLong Zip64DataSize = 44;
1847
1848 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
1849
1850 if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
1851 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); /* why ZPOS64_T of this ? */
1852
1853 if (err==ZIP_OK) /* version made by */
1854 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
1855
1856 if (err==ZIP_OK) /* version needed */
1857 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)((zi->ci.flag & ZIP_ENCODING_UTF8) ? 63 : 45),2);
1858
1859 if (err==ZIP_OK) /* number of this disk */
1860 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
1861
1862 if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1863 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
1864
1865 if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
1866 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
1867
1868 if (err==ZIP_OK) /* total number of entries in the central dir */
1869 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
1870
1871 if (err==ZIP_OK) /* size of the central directory */
1872 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
1873
1874 if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
1875 {
1876 ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
1877 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
1878 }
1879 return err;
1880}
1881int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
1882{
1883 int err = ZIP_OK;
1884
1885 /*signature*/
1886 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
1887
1888 if (err==ZIP_OK) /* number of this disk */
1889 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1890
1891 if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1892 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1893
1894 if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
1895 {
1896 {
1897 if(zi->number_entry >= 0xFFFF)
1898 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); /* use value in ZIP64 record */
1899 else
1900 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1901 }
1902 }
1903
1904 if (err==ZIP_OK) /* total number of entries in the central dir */
1905 {
1906 if(zi->number_entry >= 0xFFFF)
1907 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); /* use value in ZIP64 record */
1908 else
1909 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1910 }
1911
1912 if (err==ZIP_OK) /* size of the central directory */
1913 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
1914
1915 if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
1916 {
1917 ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
1918 if(pos >= 0xffffffff)
1919 {
1920 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
1921 }
1922 else
1923 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
1924 }
1925
1926 return err;
1927}
1928
1929int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
1930{
1931 int err = ZIP_OK;
1932 uInt size_global_comment = 0;
1933
1934 if(global_comment != NULL)
1935 size_global_comment = (uInt)strlen(global_comment);
1936
1937 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
1938
1939 if (err == ZIP_OK && size_global_comment > 0)
1940 {
1941 if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
1942 err = ZIP_ERRNO;
1943 }
1944 return err;
1945}
1946
1947extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
1948{
1949 zip64_internal* zi;
1950 int err = 0;
1951 uLong size_centraldir = 0;
1952 ZPOS64_T centraldir_pos_inzip;
1953 ZPOS64_T pos;
1954
1955 if (file == NULL)
1956 return ZIP_PARAMERROR;
1957
1958 zi = (zip64_internal*)file;
1959
1960 if (zi->in_opened_file_inzip == 1)
1961 {
1962 err = zipCloseFileInZip (file);
1963 }
1964
1965#ifndef NO_ADDFILEINEXISTINGZIP
1966 if (global_comment==NULL)
1967 global_comment = zi->globalcomment;
1968#endif
1969
1970 centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
1971
1972 if (err==ZIP_OK)
1973 {
1974 linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
1975 while (ldi!=NULL)
1976 {
1977 if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
1978 {
1979 if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
1980 err = ZIP_ERRNO;
1981 }
1982
1983 size_centraldir += ldi->filled_in_this_block;
1984 ldi = ldi->next_datablock;
1985 }
1986 }
1987 free_linkedlist(&(zi->central_dir));
1988
1989 pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
1990 if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
1991 {
1992 ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
1993 Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
1994
1995 Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
1996 }
1997
1998 if (err==ZIP_OK)
1999 err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
2000
2001 if(err == ZIP_OK)
2002 err = Write_GlobalComment(zi, global_comment);
2003
2004 if ((zi->flags & ZIP_AUTO_CLOSE) != 0) {
2005 if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) {
2006 if (err == ZIP_OK)
2007 err = ZIP_ERRNO;
2008 }
2009 } else {
2010 if (ZFAKECLOSE64(zi->z_filefunc,zi->filestream) != 0) {
2011 if (err == ZIP_OK)
2012 err = ZIP_ERRNO;
2013 }
2014 }
2015
2016#ifndef NO_ADDFILEINEXISTINGZIP
2017 TRYFREE(zi->globalcomment);
2018#endif
2019 TRYFREE(zi);
2020
2021 return err;
2022}
2023
2024extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
2025{
2026 char* p = pData;
2027 int size = 0;
2028 char* pNewHeader;
2029 char* pTmp;
2030 short header;
2031 short dataSize;
2032
2033 int retVal = ZIP_OK;
2034
2035 if(pData == NULL || *dataLen < 4)
2036 return ZIP_PARAMERROR;
2037
2038 pNewHeader = (char*)ALLOC(*dataLen);
2039 if(!pNewHeader) {
2040 return Z_MEM_ERROR;
2041 }
2042 pTmp = pNewHeader;
2043
2044 while(p < (pData + *dataLen))
2045 {
2046 header = *(short*)p;
2047 dataSize = *(((short*)p)+1);
2048
2049 if( header == sHeader ) /* Header found. */
2050 {
2051 p += dataSize + 4; /* skip it. do not copy to temp buffer */
2052 }
2053 else
2054 {
2055 /* Extra Info block should not be removed, So copy it to the temp buffer. */
2056 memcpy(pTmp, p, dataSize + 4);
2057 p += dataSize + 4;
2058 size += dataSize + 4;
2059 }
2060
2061 }
2062
2063 if(size < *dataLen)
2064 {
2065 /* clean old extra info block. */
2066 memset(pData,0, *dataLen);
2067
2068 /* copy the new extra info block over the old */
2069 if(size > 0)
2070 memcpy(pData, pNewHeader, size);
2071
2072 /* set the new extra info size */
2073 *dataLen = size;
2074
2075 retVal = ZIP_OK;
2076 }
2077 else
2078 retVal = ZIP_ERRNO;
2079
2080 TRYFREE(pNewHeader);
2081
2082 return retVal;
2083}
2084
2085int ZEXPORT zipSetFlags(zipFile file, unsigned flags)
2086{
2087 zip64_internal* zi;
2088 if (file == NULL)
2089 return ZIP_PARAMERROR;
2090 zi = (zip64_internal*)file;
2091 zi->flags |= flags;
2092 // If the output is non-seekable, the data descriptor is needed.
2093 if ((zi->flags & ZIP_SEQUENTIAL) != 0) {
2094 zi->flags |= ZIP_WRITE_DATA_DESCRIPTOR;
2095 }
2096 return ZIP_OK;
2097}
2098
2099int ZEXPORT zipClearFlags(zipFile file, unsigned flags)
2100{
2101 zip64_internal* zi;
2102 if (file == NULL)
2103 return ZIP_PARAMERROR;
2104 zi = (zip64_internal*)file;
2105 zi->flags &= ~flags;
2106 // If the data descriptor is not written, we can't use a non-seekable output.
2107 if ((zi->flags & ZIP_WRITE_DATA_DESCRIPTOR) == 0) {
2108 zi->flags &= ~ZIP_SEQUENTIAL;
2109 }
2110 return ZIP_OK;
2111}
diff --git a/utils/rbutilqt/quazip/zip.h b/utils/rbutilqt/quazip/zip.h
new file mode 100644
index 0000000000..114a1bf6e7
--- /dev/null
+++ b/utils/rbutilqt/quazip/zip.h
@@ -0,0 +1,391 @@
1/* zip.h -- IO on .zip files using zlib
2 Version 1.1, February 14h, 2010
3 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
4
5 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
6
7 Modifications for Zip64 support
8 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
9
10 For more info read MiniZip_info.txt
11
12 ---------------------------------------------------------------------------
13
14 Condition of use and distribution are the same than zlib :
15
16 This software is provided 'as-is', without any express or implied
17 warranty. In no event will the authors be held liable for any damages
18 arising from the use of this software.
19
20 Permission is granted to anyone to use this software for any purpose,
21 including commercial applications, and to alter it and redistribute it
22 freely, subject to the following restrictions:
23
24 1. The origin of this software must not be misrepresented; you must not
25 claim that you wrote the original software. If you use this software
26 in a product, an acknowledgment in the product documentation would be
27 appreciated but is not required.
28 2. Altered source versions must be plainly marked as such, and must not be
29 misrepresented as being the original software.
30 3. This notice may not be removed or altered from any source distribution.
31
32 ---------------------------------------------------------------------------
33
34 Changes
35
36 See header of zip.h
37
38 ---------------------------------------------------------------------------
39
40 As per the requirement above, this file is plainly marked as modified
41 by Sergey A. Tachenov. Most modifications include the I/O API redesign
42 to support QIODevice interface. Some improvements and small fixes were also made.
43
44*/
45
46#ifndef _zip12_H
47#define _zip12_H
48
49#ifdef __cplusplus
50extern "C" {
51#endif
52
53//#define HAVE_BZIP2
54
55#ifndef _ZLIB_H
56#include <zlib.h>
57#endif
58
59#ifndef _ZLIBIOAPI_H
60#include "ioapi.h"
61#endif
62
63#ifdef HAVE_BZIP2
64#include "bzlib.h"
65#endif
66
67#define Z_BZIP2ED 12
68
69#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
70/* like the STRICT of WIN32, we define a pointer that cannot be converted
71 from (void*) without cast */
72typedef struct TagzipFile__ { int unused; } zipFile__;
73typedef zipFile__ *zipFile;
74#else
75typedef voidp zipFile;
76#endif
77
78#define ZIP_OK (0)
79#define ZIP_EOF (0)
80#define ZIP_ERRNO (Z_ERRNO)
81#define ZIP_PARAMERROR (-102)
82#define ZIP_BADZIPFILE (-103)
83#define ZIP_INTERNALERROR (-104)
84
85#define ZIP_WRITE_DATA_DESCRIPTOR 0x8u
86#define ZIP_AUTO_CLOSE 0x1u
87#define ZIP_SEQUENTIAL 0x2u
88#define ZIP_ENCODING_UTF8 0x0800u
89#define ZIP_DEFAULT_FLAGS (ZIP_AUTO_CLOSE | ZIP_WRITE_DATA_DESCRIPTOR)
90
91#ifndef DEF_MEM_LEVEL
92# if MAX_MEM_LEVEL >= 8
93# define DEF_MEM_LEVEL 8
94# else
95# define DEF_MEM_LEVEL MAX_MEM_LEVEL
96# endif
97#endif
98/* default memLevel */
99
100/* tm_zip contain date/time info */
101typedef struct tm_zip_s
102{
103 uInt tm_sec; /* seconds after the minute - [0,59] */
104 uInt tm_min; /* minutes after the hour - [0,59] */
105 uInt tm_hour; /* hours since midnight - [0,23] */
106 uInt tm_mday; /* day of the month - [1,31] */
107 uInt tm_mon; /* months since January - [0,11] */
108 uInt tm_year; /* years - [1980..2044] */
109} tm_zip;
110
111typedef struct
112{
113 tm_zip tmz_date; /* date in understandable format */
114 uLong dosDate; /* if dos_date == 0, tmu_date is used */
115/* uLong flag; */ /* general purpose bit flag 2 bytes */
116
117 uLong internal_fa; /* internal file attributes 2 bytes */
118 uLong external_fa; /* external file attributes 4 bytes */
119} zip_fileinfo;
120
121typedef const char* zipcharpc;
122
123
124#define APPEND_STATUS_CREATE (0)
125#define APPEND_STATUS_CREATEAFTER (1)
126#define APPEND_STATUS_ADDINZIP (2)
127
128extern zipFile ZEXPORT zipOpen OF((voidpf file, int append));
129extern zipFile ZEXPORT zipOpen64 OF((voidpf file, int append));
130/*
131 Create a zipfile.
132 the file argument depends on the API used, for QuaZIP it's a QIODevice
133 pointer.
134 if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
135 will be created at the end of the file.
136 (useful if the file contain a self extractor code)
137 if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
138 add files in existing zip (be sure you don't add file that doesn't exist)
139 If the zipfile cannot be opened, the return value is NULL.
140 Else, the return value is a zipFile Handle, usable with other function
141 of this zip package.
142*/
143
144/* Note : there is no delete function into a zipfile.
145 If you want delete file into a zipfile, you must open a zipfile, and create another
146 Of couse, you can use RAW reading and writing to copy the file you did not want delte
147*/
148
149extern zipFile ZEXPORT zipOpen2 OF((voidpf file,
150 int append,
151 zipcharpc* globalcomment,
152 zlib_filefunc_def* pzlib_filefunc_def));
153
154extern zipFile ZEXPORT zipOpen2_64 OF((voidpf file,
155 int append,
156 zipcharpc* globalcomment,
157 zlib_filefunc64_def* pzlib_filefunc_def));
158
159/*
160 * Exported by Sergey A. Tachenov to suit the needs of QuaZIP.
161 * Note that this function MAY change signature in order to
162 * provide new QuaZIP features. You have been warned!
163 * */
164extern zipFile ZEXPORT zipOpen3 (voidpf file,
165 int append,
166 zipcharpc* globalcomment,
167 zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
168 unsigned flags);
169
170extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
171 const char* filename,
172 const zip_fileinfo* zipfi,
173 const void* extrafield_local,
174 uInt size_extrafield_local,
175 const void* extrafield_global,
176 uInt size_extrafield_global,
177 const char* comment,
178 int method,
179 int level));
180
181extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file,
182 const char* filename,
183 const zip_fileinfo* zipfi,
184 const void* extrafield_local,
185 uInt size_extrafield_local,
186 const void* extrafield_global,
187 uInt size_extrafield_global,
188 const char* comment,
189 int method,
190 int level,
191 int zip64));
192
193/*
194 Open a file in the ZIP for writing.
195 filename : the filename in zip (if NULL, '-' without quote will be used
196 *zipfi contain supplemental information
197 if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
198 contains the extrafield data the the local header
199 if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
200 contains the extrafield data the the local header
201 if comment != NULL, comment contain the comment string
202 method contain the compression method (0 for store, Z_DEFLATED for deflate)
203 level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
204 zip64 is set to 1 if a zip64 extended information block should be added to the local file header.
205 this MUST be '1' if the uncompressed size is >= 0xffffffff.
206
207*/
208
209
210extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
211 const char* filename,
212 const zip_fileinfo* zipfi,
213 const void* extrafield_local,
214 uInt size_extrafield_local,
215 const void* extrafield_global,
216 uInt size_extrafield_global,
217 const char* comment,
218 int method,
219 int level,
220 int raw));
221
222
223extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file,
224 const char* filename,
225 const zip_fileinfo* zipfi,
226 const void* extrafield_local,
227 uInt size_extrafield_local,
228 const void* extrafield_global,
229 uInt size_extrafield_global,
230 const char* comment,
231 int method,
232 int level,
233 int raw,
234 int zip64));
235/*
236 Same than zipOpenNewFileInZip, except if raw=1, we write raw file
237 */
238
239extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
240 const char* filename,
241 const zip_fileinfo* zipfi,
242 const void* extrafield_local,
243 uInt size_extrafield_local,
244 const void* extrafield_global,
245 uInt size_extrafield_global,
246 const char* comment,
247 int method,
248 int level,
249 int raw,
250 int windowBits,
251 int memLevel,
252 int strategy,
253 const char* password,
254 uLong crcForCrypting));
255
256extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file,
257 const char* filename,
258 const zip_fileinfo* zipfi,
259 const void* extrafield_local,
260 uInt size_extrafield_local,
261 const void* extrafield_global,
262 uInt size_extrafield_global,
263 const char* comment,
264 int method,
265 int level,
266 int raw,
267 int windowBits,
268 int memLevel,
269 int strategy,
270 const char* password,
271 uLong crcForCrypting,
272 int zip64
273 ));
274
275/*
276 Same than zipOpenNewFileInZip2, except
277 windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
278 password : crypting password (NULL for no crypting)
279 crcForCrypting : crc of file to compress (needed for crypting)
280 */
281
282extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file,
283 const char* filename,
284 const zip_fileinfo* zipfi,
285 const void* extrafield_local,
286 uInt size_extrafield_local,
287 const void* extrafield_global,
288 uInt size_extrafield_global,
289 const char* comment,
290 int method,
291 int level,
292 int raw,
293 int windowBits,
294 int memLevel,
295 int strategy,
296 const char* password,
297 uLong crcForCrypting,
298 uLong versionMadeBy,
299 uLong flagBase
300 ));
301
302
303extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file,
304 const char* filename,
305 const zip_fileinfo* zipfi,
306 const void* extrafield_local,
307 uInt size_extrafield_local,
308 const void* extrafield_global,
309 uInt size_extrafield_global,
310 const char* comment,
311 int method,
312 int level,
313 int raw,
314 int windowBits,
315 int memLevel,
316 int strategy,
317 const char* password,
318 uLong crcForCrypting,
319 uLong versionMadeBy,
320 uLong flagBase,
321 int zip64
322 ));
323/*
324 Same than zipOpenNewFileInZip4, except
325 versionMadeBy : value for Version made by field
326 flag : value for flag field (compression level info will be added)
327 */
328
329
330extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
331 const void* buf,
332 unsigned len));
333/*
334 Write data in the zipfile
335*/
336
337extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
338/*
339 Close the current file in the zipfile
340*/
341
342extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
343 uLong uncompressed_size,
344 uLong crc32));
345
346extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file,
347 ZPOS64_T uncompressed_size,
348 uLong crc32));
349
350/*
351 Close the current file in the zipfile, for file opened with
352 parameter raw=1 in zipOpenNewFileInZip2
353 uncompressed_size and crc32 are value for the uncompressed size
354*/
355
356extern int ZEXPORT zipClose OF((zipFile file,
357 const char* global_comment));
358/*
359 Close the zipfile
360*/
361
362
363extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader));
364/*
365 zipRemoveExtraInfoBlock - Added by Mathias Svensson
366
367 Remove extra information block from a extra information data for the local file header or central directory header
368
369 It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode.
370
371 0x0001 is the signature header for the ZIP64 extra information blocks
372
373 usage.
374 Remove ZIP64 Extra information from a central director extra field data
375 zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001);
376
377 Remove ZIP64 Extra information from a Local File Header extra field data
378 zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001);
379*/
380
381/*
382 Added by Sergey A. Tachenov to tweak zipping behaviour.
383*/
384extern int ZEXPORT zipSetFlags(zipFile file, unsigned flags);
385extern int ZEXPORT zipClearFlags(zipFile file, unsigned flags);
386
387#ifdef __cplusplus
388}
389#endif
390
391#endif /* _zip64_H */
diff --git a/utils/rbutilqt/rbutil.ini b/utils/rbutilqt/rbutil.ini
new file mode 100644
index 0000000000..ff074ff38e
--- /dev/null
+++ b/utils/rbutilqt/rbutil.ini
@@ -0,0 +1,1000 @@
1[general]
2; server information
3build_info_url=http://download.rockbox.org/build-info
4; genlang -- used to get list of strings (only really old builds)
5genlang_url=http://www.rockbox.org/genlang/?lang=%LANG%&t=%TARGET%&rev=%REVISION%&f=%FEATURES%
6; themes
7themes_url=http://themes.rockbox.org/
8themes_info_url=http://themes.rockbox.org/rbutilqt.php?target=%TARGET%&release=%RELEASE%&revision=%REVISION%&rbutilver=%RBUTILVER%
9
10; other
11doom_url=http://download.rockbox.org/useful/rockdoom.zip
12duke3d_url=http://download.rockbox.org/useful/duke3d.zip
13quake_url=http://download.rockbox.org/useful/quake.zip
14puzzfonts_url=http://download.rockbox.org/useful/sgt-fonts.zip
15wolf3d_url=http://download.rockbox.org/useful/wolf3d.zip
16xworld_url=http://download.rockbox.org/useful/xworld.zip
17rbutil_url=http://download.rockbox.org/rbutil/
18
19[bootloader]
20info_url=http://download.rockbox.org/bootloader/bootloaders-info
21download_url=http://download.rockbox.org/bootloader
22
23; [platforms] is used to determine the order in the device tree.
24; Only devices present in this section will get displayed!
25[platforms]
26platform01=archosplayer
27platform02=archosrecorder
28platform04=archosrecorderv2
29platform05=archosfmrecorder
30platform07=archosondiosp
31platform08=archosondiofm
32platform10=iriverh100
33platform11=iriverh120
34platform12=iriverh300
35platform13=iriverh10_5gb
36platform14=iriverh10_5gb.mtp
37platform15=iriverh10
38platform20=ipod1g2g
39platform21=ipod3g
40platform22=ipod4g
41platform23=ipodcolor
42platform24=ipodvideo
43platform25=ipod6g
44platform26=ipodmini1g
45platform27=ipodmini2g
46platform28=ipodnano1g
47platform29=ipodnano2g
48platform30=iaudiox5
49platform31=iaudiom5
50platform32=iaudiox5.v
51platform33=iaudiom3
52platform40=gigabeatfx
53platform41=gigabeats
54platform44=ondavx747
55platform45=ondavx747p
56platform46=ondavx777
57platform50=sansae200
58platform51=sansae200v2
59platform52=sansac200
60platform53=sansac200v2
61platform54=sansafuze
62platform55=sansafuzev2
63platform56=sansafuzeplus
64platform57=sansaclip
65platform58=sansaclipv2
66platform59=sansaclipplus
67platform60=sansaclipzip
68platform61=sansam200v4
69platform65=mrobe100
70platform70=samsungyh820
71platform71=samsungyh920
72platform72=samsungyh925
73platform73=cowond2
74platform80=vibe500
75platform90=mpiohd200
76platform101=gogearhdd1630
77platform102=gogearhdd6330
78platform103=gogearsa9200
79platform110=creativezenxfi3
80platform120=xduoox3
81platform130=xduoox3ii
82platform131=xduoox20
83platform132=agptekrocker
84platform133=aigoerosq
85; clones of aigoerosq, treat them as variants of it (identical build, different bootloaders)
86platform134=aigoerosq.k
87platform135=aigoerosq.agptekh3
88platform136=aigoerosq.hifiwalkerh2
89platform137=aigoerosq.hifiwalkerh2.v13
90platform138=aigoerosq.surfansf20
91
92; devices sections
93;
94; Each device has a section here that corresponds to an entry in the
95; [platforms] section.
96; ** The [section] is using the same string configure uses. **
97; It might add a postfix (separated with a .) to distinguish variants like
98; iaudiox5 vs. iaudiox5.v which are identical for Rockbox itself, but have
99; differences (in this case: require different bootloaders.)
100; When downloading the build from rockbox.org the [section] string is used.
101;
102; name: the human readable name that is displayed to the user
103; bootloadermethod: the installation method for the bootloader. See
104; base/bootloader* classes
105; bootloadername: name of the bootloader file on the server
106; bootloaderfile: name of the bootloader file on the device
107; manualname: different target name to use for manual. F.e. ipodmini2g uses the
108; same manual as ipodmini1g.
109; brand: the manufacturer of the device. Used to group in device tree
110; encoder: encoder to use for talk clips and voice files
111; usbid: VID / PID value for detecting the player. Can be a list.
112; If multiple players use the same ID the detection will be ambiguous
113; and the user has to manually choose.
114; usberror: VID / PID value for detecting the player in an incompatible mode
115; (MTP vs MSC). Can be a list.
116; status: allows hiding the target from the list of devices.
117;
118[archosplayer]
119name="Jukebox Player 6000 / Jukebox Studio 5 / 10 / 20"
120bootloadermethod=none
121bootloadername=
122manualname=
123brand=Archos
124usbid=0x05ab0031
125playerpic=archosplayer
126encoder=lame
127
128[archosrecorder]
129name="Jukebox Recorder 6 / 10 / 15 / 20"
130bootloadermethod=none
131bootloadername=
132manualname=
133brand=Archos
134usbid=0x05ab0031,0x05ab0060
135playerpic=archosrecorder
136encoder=lame
137
138[archosrecorderv2]
139name="Jukebox Recorder v2 (20GB)"
140bootloadermethod=none
141bootloadername=
142manualname=archosfmrecorder
143brand=Archos
144usbid=0x05ab0060
145playerpic=archosrecorderv2
146encoder=lame
147
148[archosfmrecorder]
149name="Jukebox Recorder FM"
150bootloadermethod=none
151bootloadername=
152manualname=
153brand=Archos
154usbid=0x05ab0060
155playerpic=archosfmrecorder
156encoder=lame
157
158[archosondiosp]
159name="Ondio SP"
160bootloadermethod=none
161bootloadername=
162manualname=
163brand=Archos
164usbid=0x058f9330
165playerpic=archosondiosp
166encoder=lame
167
168[archosondiofm]
169name="Ondio FM"
170bootloadermethod=none
171bootloadername=
172manualname=
173brand=Archos
174usbid=0x058f9330
175playerpic=archosondiofm
176encoder=lame
177
178[iriverh100]
179name="iHP100 / iHP110"
180bootloadermethod=hex
181bootloadername=/iriver/8.0/bootloader-h100.bin
182bootloaderfile=/ihp_100.hex
183bootloaderfilter=*.hex *.zip
184manualname=iriverh100
185brand=Iriver
186usbid=0x10063001
187playerpic=iriverh100
188encoder=rbspeex
189
190[iriverh120]
191name="iHP120 / iHP140 / H120 / H140"
192bootloadermethod=hex
193bootloadername=/iriver/8.0/bootloader-h120.bin
194bootloaderfile=/ihp_120.hex
195bootloaderfilter=*.hex *.zip
196manualname=iriverh100
197brand=Iriver
198usbid=0x10063002
199playerpic=iriverh100
200encoder=rbspeex
201
202[iriverh300]
203name="H320 / H340"
204bootloadermethod=hex
205bootloadername=/iriver/8.0/bootloader-h300.bin
206bootloaderfile=/H300.hex
207bootloaderfilter=*.hex *.zip
208manualname=iriverh300
209brand=Iriver
210usbid=0x10063003
211playerpic=iriverh300
212encoder=rbspeex
213
214[iriverh10_5gb]
215name="H10 (5 / 6GB) UMS"
216bootloadermethod=mi4
217bootloadername=/iriver/H10.mi4
218bootloaderfile=/System/H10.mi4, /System/H10EMP.mi4
219manualname=
220brand=Iriver
221usbid=0x41022002
222playerpic=iriverh10_5gb
223encoder=rbspeex
224
225[iriverh10_5gb.mtp]
226name="H10 (5 / 6GB) MTP"
227bootloadermethod=mi4
228bootloadername=/iriver/H10_5GB-MTP/H10.mi4
229bootloaderfile=/System/H10.mi4, /System/H10EMP.mi4
230manualname=
231brand=Iriver
232usbid=0x41022105, 0x41022102
233playerpic=iriverh10_5gb
234encoder=rbspeex
235
236[iriverh10]
237name="H10 (20GB)"
238bootloadermethod=mi4
239bootloadername=/iriver/H10_20GC.mi4
240bootloaderfile=/System/H10_20GC.mi4
241manualname=
242brand=Iriver
243usbid=0x0b7000ba
244usberror=0x41022101
245playerpic=iriverh10
246encoder=rbspeex
247
248[ipod1g2g]
249name="Ipod (1st / 2nd gen)"
250bootloadermethod=ipod
251bootloadername=/ipod/bootloader-ipod1g2g.ipod
252manualname=
253brand=Apple
254; no usb
255playerpic=ipod1g2g
256encoder=rbspeex
257
258[ipodcolor]
259name="Ipod Color / Photo / U2 (4th gen)"
260bootloadermethod=ipod
261bootloadername=/ipod/bootloader-ipodcolor.ipod
262manualname=
263brand=Apple
264usbid=0x05ac1204
265playerpic=ipodcolor
266encoder=rbspeex
267
268[ipodnano1g]
269name="Ipod Nano (1st gen)"
270bootloadermethod=ipod
271bootloadername=/ipod/bootloader-ipodnano1g.ipod
272manualname=
273brand=Apple
274usbid=0x05ac120a
275playerpic=ipodnano1g
276encoder=rbspeex
277
278[ipodnano2g]
279name="Ipod Nano (2nd gen)"
280bootloadermethod=ipod
281bootloadername=/ipod/bootloader-ipodnano2g.ipodx
282manualname=
283brand=Apple
284usbid=0x05ac1260
285playerpic=ipodnano2g
286encoder=rbspeex
287
288[ipod4g]
289name="Ipod (4th gen, greyscale)"
290bootloadermethod=ipod
291bootloadername=/ipod/bootloader-ipod4g.ipod
292manualname=
293brand=Apple
294usbid=0x05ac1203
295playerpic=ipod4g
296encoder=rbspeex
297
298[ipodvideo]
299name="Ipod Video (5th gen)"
300bootloadermethod=ipod
301bootloadername=/ipod/bootloader-ipodvideo.ipod
302manualname=
303brand=Apple
304usbid=0x05ac1209
305playerpic=ipodvideo
306encoder=rbspeex
307
308[ipod6g]
309name="Ipod Classic (6th gen)"
310bootloadermethod=s5l
311bootloadername=/ipod/bootloader-ipod6g.ipod
312manualname=
313brand=Apple
314usbid=0x05ac1261
315playerpic=ipod6g
316encoder=rbspeex
317
318[ipod3g]
319name="Ipod (3rd gen)"
320bootloadermethod=ipod
321bootloadername=/ipod/bootloader-ipod3g.ipod
322manualname=
323brand=Apple
324usbid=0x05ac1201
325playerpic=ipod3g
326encoder=rbspeex
327
328[ipodmini1g]
329name="Ipod Mini (1st gen)"
330bootloadermethod=ipod
331bootloadername=/ipod/bootloader-ipodmini1g.ipod
332brand=Apple
333usbid=0x05ac1205
334playerpic=ipodmini1g
335encoder=rbspeex
336
337[ipodmini2g]
338name="Ipod Mini (2nd gen)"
339bootloadermethod=ipod
340bootloadername=/ipod/bootloader-ipodmini2g.ipod
341manualname=ipodmini1g
342brand=Apple
343usbid=0x05ac1205
344playerpic=ipodmini1g
345encoder=rbspeex
346
347[iaudiox5]
348name="iAudio X5 / X5L"
349bootloadermethod=file
350bootloadername=/iaudio/x5_fw.bin
351bootloaderfile=/FIRMWARE/x5_fw.bin
352manualname=
353brand=Cowon
354usbid=0x0e210510, 0x0e210513
355playerpic=iaudiox5
356encoder=rbspeex
357
358[iaudiox5.v]
359name="iAudio X5V"
360bootloadermethod=file
361bootloadername=/iaudio/x5v_fw.bin
362bootloaderfile=/FIRMWARE/x5v_fw.bin
363manualname=
364brand=Cowon
365usbid=0x0e210510, 0x0e210513
366playerpic=iaudiox5
367encoder=rbspeex
368
369[iaudiom5]
370name="iAudio M5 / M5L"
371bootloadermethod=file
372bootloadername=/iaudio/m5_fw.bin
373bootloaderfile=/FIRMWARE/m5_fw.bin
374manualname=
375brand=Cowon
376usbid=0x0e210520
377playerpic=iaudiom5
378encoder=rbspeex
379
380[iaudiom3]
381name="iAudio M3 / M3L"
382bootloadermethod=file
383bootloadername=/iaudio/cowon_m3.bin
384bootloaderfile=/FIRMWARE/cowon_m3.bin
385manualname=
386brand=Cowon
387usbid=0x0e210500
388playerpic=iaudiom3
389encoder=rbspeex
390
391[gigabeatfx]
392name="Gigabeat F / X"
393bootloadermethod=file
394bootloadername=/toshiba/gigabeat-fx/FWIMG01.DAT
395bootloaderfile=/GBSYSTEM/FWIMG/FWIMG01.DAT
396manualname=
397brand=Toshiba
398usbid=0x09300009
399playerpic=gigabeatfx
400encoder=rbspeex
401
402[gigabeats]
403name="Gigabeat S"
404bootloadermethod=none
405manualname=
406brand=Toshiba
407usbid=0x09300010
408playerpic=gigabeats
409encoder=rbspeex
410status=disabled
411
412[sansae200]
413name="Sansa e200v1 series"
414bootloadermethod=sansa
415bootloadername=/sandisk-sansa/e200/PP5022.mi4
416manualname=
417brand=Sandisk
418usbid=0x07817421
419usberror=0x07817420
420playerpic=sansae200
421encoder=rbspeex
422
423[sansac200]
424name="Sansa c200v1 series"
425bootloadermethod=sansa
426bootloadername=/sandisk-sansa/c200/firmware.mi4
427manualname=
428brand=Sandisk
429usbid=0x07817450, 0x07817451
430playerpic=sansac200
431encoder=rbspeex
432
433[sansae200v2]
434name="Sansa e200v2 series"
435bootloadermethod=ams
436bootloadername=/sandisk-sansa/e200v2/bootloader-e200v2.sansa
437bootloaderfile=/e200pa.bin,/e200pe.bin,/e200pf.bin
438bootloaderfilter=*.bin *.zip
439manualname=
440brand=Sandisk
441usbid=0x07817423
442usberror=0x07817422
443playerpic=sansae200
444encoder=rbspeex
445
446[sansac200v2]
447name="Sansa c200v2 series"
448bootloadermethod=ams
449bootloadername=/sandisk-sansa/c200v2/bootloader-c200v2.sansa
450bootloaderfile=/c200pa.bin,/c200pe.bin,/c200pf.bin
451bootloaderfilter=*.bin *.zip
452manualname=
453brand=Sandisk
454usbid=0x07817453
455usberror=0x07817452
456playerpic=sansac200
457encoder=rbspeex
458
459[sansafuze]
460name="Sansa Fuze"
461bootloadermethod=ams
462bootloadername=/sandisk-sansa/fuze/bootloader-fuze.sansa
463bootloaderfile=/fuzea.bin
464bootloaderfilter=*.bin *.zip
465manualname=
466brand=Sandisk
467usbid=0x078174c1
468usberror=0x078174c0
469playerpic=sansafuze
470encoder=rbspeex
471
472[sansafuzev2]
473name="Sansa Fuze V2"
474bootloadermethod=ams
475bootloadername=/sandisk-sansa/fuzev2/bootloader-fuzev2.sansa
476bootloaderfile=/fuzpa.bin
477bootloaderfilter=*.bin *.zip
478manualname=
479brand=Sandisk
480usbid=0x078174c3
481usberror=0x078174c2
482playerpic=sansafuze
483encoder=rbspeex
484
485[sansafuzeplus]
486name="Sansa Fuze+"
487bootloadermethod=imx
488bootloadername=/sandisk-sansa/fuzeplus/bootloader-fuzeplus.sansa
489bootloaderfile=/firmware.sb
490bootloaderfilter=*.sb *.zip
491manualname=
492brand=Sandisk
493usbid=0x078174e1
494usberror=
495playerpic=sansafuzeplus
496encoder=rbspeex
497
498[sansam200v4]
499name="Sansa m200v4"
500bootloadermethod=ams
501bootloadername=/sandisk-sansa/m200v4/bootloader-m200v4.sansa
502bootloaderfile=/m200a.bin
503bootloaderfilter=*.bin *.zip
504manualname=
505brand=Sandisk
506usbid=
507usberror=
508playerpic=sansam200v4
509encoder=rbspeex
510status=disabled
511
512[sansaclip]
513name="Sansa Clip"
514bootloadermethod=ams
515bootloadername=/sandisk-sansa/clip/bootloader-clip.sansa
516bootloaderfile=/m300a.bin
517bootloaderfilter=*.bin *.zip
518manualname=
519brand=Sandisk
520usbid=0x07817433
521usberror=0x07817432
522playerpic=sansaclip
523encoder=rbspeex
524
525[sansaclipv2]
526name="Sansa Clip V2"
527bootloadermethod=ams
528bootloadername=/sandisk-sansa/clipv2/bootloader-clipv2.sansa
529bootloaderfile=/m30pa.bin
530bootloaderfilter=*.bin *.zip
531manualname=
532brand=Sandisk
533usbid=0x07817435
534usberror=0x07817434
535playerpic=sansaclip
536encoder=rbspeex
537
538[sansaclipplus]
539name="Sansa Clip+"
540bootloadermethod=ams
541bootloadername=/sandisk-sansa/clipplus/bootloader-clipplus.sansa
542bootloaderfile=/clppa.bin
543bootloaderfilter=*.bin *.zip
544manualname=
545brand=Sandisk
546usbid=0x078174d1
547usberror=0x078174d0
548playerpic=sansaclipplus
549encoder=rbspeex
550
551[sansaclipzip]
552name="Sansa Clip Zip"
553bootloadermethod=ams
554bootloadername=/sandisk-sansa/clipzip/bootloader-clipzip.sansa
555bootloaderfile=/clpza.bin
556bootloaderfilter=*.bin *.zip
557manualname=
558brand=Sandisk
559usbid=0x078174e5
560usberror=0x078174e4
561playerpic=sansaclipzip
562encoder=rbspeex
563
564[mrobe100]
565name="m:robe100"
566bootloadermethod=mi4
567bootloadername=/olympus/mrobe100/pp5020.mi4
568bootloaderfile=/System/pp5020.mi4
569manualname=
570brand=Olympus
571usbid=0x07b40280
572playerpic=mrobe100
573encoder=rbspeex
574
575[ondavx747]
576name="VX747"
577bootloadermethod=chinachip
578bootloadername=/onda/vx747/ccpmp.bin
579bootloaderfile=/SG301.HXF
580bootloaderfilter=*.hxf *.zip
581manualname=
582brand=Onda
583usbid=0x07c4a4a5
584playerpic=vx747
585encoder=rbspeex
586status=disabled
587
588[ondavx747p]
589name="VX747+"
590bootloadermethod=chinachip
591bootloadername=/onda/vx747p/ccpmp.bin
592bootloaderfile=/SG301.HXF
593bootloaderfilter=*.hxf *.zip
594manualname=
595brand=Onda
596usbid=0x07c4a4a5
597playerpic=vx747
598encoder=rbspeex
599status=disabled
600
601[ondavx777]
602name="VX777"
603bootloadermethod=chinachip
604bootloadername=/onda/vx777/ccpmp.bin
605bootloaderfile=/VX777.HXF
606bootloaderfilter=*.hxf *.zip
607manualname=
608brand=Onda
609usbid=0x07c4a4a5
610playerpic=vx777
611encoder=rbspeex
612status=disabled
613
614[samsungyh820]
615name="YH-820"
616bootloadermethod=mi4
617bootloadername=/samsung/yh820/FW_YH820.mi4
618bootloaderfile=/SYSTEM/FW_YH820.mi4
619manualname=
620brand=Samsung
621usbid=0x04e85023
622playerpic=samsungyh820
623encoder=rbspeex
624
625[samsungyh920]
626name="YH-920"
627bootloadermethod=mi4
628bootloadername=/samsung/yh920/PP5020.mi4
629bootloaderfile=/SYSTEM/FW_YH920.mi4, /SYSTEM/PP5020.mi4
630manualname=
631brand=Samsung
632usbid=0x04e85022, 0x04e8501d
633playerpic=samsungyh920
634encoder=rbspeex
635
636[samsungyh925]
637name="YH-925"
638bootloadermethod=mi4
639bootloadername=/samsung/yh925/FW_YH925.mi4
640bootloaderfile=/SYSTEM/FW_YH925.mi4
641manualname=
642brand=Samsung
643usbid=0x04e85024
644playerpic=samsungyh925
645encoder=rbspeex
646
647[cowond2]
648name="D2"
649bootloadermethod=tcc
650bootloadername=/cowon/d2/bootloader-cowond2.bin
651bootloaderfile=/
652bootloaderfilter=*.bin *.zip
653manualname=
654brand=Cowon
655usbid=0x0e210800, 0x0e210860, 0x0e210870, 0x0e210880, 0x0e210890
656usberror=0x0e210801, 0x0e210861, 0x0e210871, 0x0e210881, 0x0e210891
657playerpic=cowond2
658encoder=rbspeex
659status=disabled
660
661[vibe500]
662name="Vibe 500"
663bootloadermethod=mi4
664bootloadername=/vibe500/jukebox.mi4
665bootloaderfile=/System/jukebox.mi4
666manualname=
667brand=Packard Bell
668usbid=0x04098038
669usberror=0x04098039
670playerpic=vibe500
671encoder=rbspeex
672
673[mpiohd200]
674name="MPIO HD200"
675bootloadermethod=mpio
676bootloadername=/mpiohd200/bootloader.mpio
677bootloaderfile=/SYSTEM/HD200_UPG.SYS
678bootloaderfilter=*.bin *.zip
679manualname=
680brand=MPIO
681usbid=0x27351004
682playerpic=mpiohd200
683encoder=rbspeex
684
685[mpiohd300]
686name="MPIO HD300"
687bootloadermethod=mpio
688bootloadername=/mpiohd300/bootloader.mpio
689bootloaderfile=/SYSTEM/HD300_UPG.SYS
690bootloaderfilter=*.bin *.zip
691manualname=
692brand=MPIO
693usbid=0x27351005
694playerpic=mpiohd300
695encoder=rbspeex
696
697[gogearhdd1630]
698name="Philips GoGear HDD16x0 & HDD18x0 Series"
699bootloadermethod=mi4
700bootloadername=/gogear/hdd1630/FWImage.ebn
701bootloaderfile=/System/FWImage.ebn
702manualname=
703brand=Philips
704usbid=0x0471014c
705playerpic=gogearhdd1630
706encoder=rbspeex
707
708[gogearhdd6330]
709name="Philips GoGear HDD63x0 Series"
710bootloadermethod=mi4
711booloadername=/gogear/hdd6330/FWImage.ebn
712bootloaderfile=/System/FWImage.ebn
713manualname=
714brand=Philips
715usbid=0x0471014b
716playerpic=gogearhdd6330
717encoder=rbspeex
718
719[gogearsa9200]
720name="Philips GoGear SA9200"
721bootloadermethod=none
722bootloaderfile=/System/FWImage.ebn
723manualname=
724brand=Philips
725usbid=0x0471014f
726playerpic=gogearsa9200
727encoder=rbspeex
728status=disabled
729
730[creativezenxfi3]
731name="Creative Zen X-Fi3"
732bootloadermethod=imx
733bootloadername=/creative/zenxfi3/bootloader-zenxfi3.creative
734bootloaderfile=/firmware.sb
735bootloaderfilter=*.sb *.exe
736manualname=
737brand=Creative
738usbid=0x041e2020
739usberror=
740playerpic=creativezenxfi3
741encoder=rbspeex
742
743[xduoox3]
744name="xDuoo X3"
745bootloadermethod=bspatch
746bootloadername=/xduoo/X3-v11.bsdiff
747bootloaderfile=/update.zip
748bootloaderfilter=*.zip
749manualname=
750brand=xDuoo
751usbid=0x0525a4a5
752usberror=
753playerpic=xduoox3
754encoder=rbspeex
755
756[xduoox3ii]
757name="xDuoo X3 II"
758bootloadermethod=bspatch
759bootloadername=/xduoo/X3II-v13.bsdiff
760bootloaderfile=/update.upt
761bootloaderfilter=*.upt *.zip
762manualname=
763brand=xDuoo
764usbid=0xc502003c ; shared with X20
765usberror=
766playerpic=xduoox3ii
767encoder=rbspeex
768
769[xduoox20]
770name="xDuoo X20"
771bootloadermethod=bspatch
772bootloadername=/xduoo/X20-v18.bsdiff
773bootloaderfile=/update.upt
774bootloaderfilter=*.upt *.zip
775manualname=
776brand=xDuoo
777usbid=0xc502003c ; shared with X3ii
778usberror=
779playerpic=xduoox20
780encoder=rbspeex
781
782[agptekrocker]
783name="AGPTek Rocker"
784bootloadermethod=bspatch
785bootloadername=/agptek/ROCKER-20171101.bsdiff
786bootloaderfile=/update.upt
787bootloaderfilter=*.upt *.zip
788manualname=
789brand=AGPTek
790usbid=0xc5020029
791usberror=
792playerpic=agptekrocker
793encoder=rbspeex
794
795[aigoerosq]
796name="AIGO Eros Q"
797bootloadermethod=bspatch
798bootloadername=/aigo/EROSQ-v18.bsdiff
799bootloaderfile=/update.upt
800bootloaderfilter=*.upt *.zip
801manualname=
802brand=AIGO/EROS
803usbid=0xc5020023 ; shared across EROS Q/K series
804usberror=
805playerpic=aigoerosq
806encoder=rbspeex
807
808[aigoerosq.k]
809name="AIGO Eros K"
810bootloadermethod=bspatch
811bootloadername=/aigo/EROSK-v13.bsdiff
812bootloaderfile=/update.upt
813bootloaderfilter=*.upt *.zip
814manualname=
815brand=AIGO/EROS
816usbid=0xc5020023 ; shared across EROS Q/K series
817usberror=
818playerpic=aigoerosk
819encoder=rbspeex
820
821[aigoerosq.agptekh3]
822name="AGPTek H3"
823bootloadermethod=bspatch
824bootloadername=/agptek/H3-20180905.bsdiff
825bootloaderfile=/update.upt
826bootloaderfilter=*.upt *.zip
827manualname=aigoerosk
828brand=AGPTek
829usbid=0xc5020023 ; shared across EROS Q / K series
830usberror=
831playerpic=aigoerosk
832encoder=rbspeex
833
834[aigoerosq.surfansf20]
835name="Surfans F20"
836bootloadermethod=bspatch
837bootloadername=/surfans/F20-v22.bsdiff
838bootloaderfile=/update.upt
839bootloaderfilter=*.upt *.zip
840manualname=aigoerosq
841brand=Surfans
842usbid=0xc5020023 ; shared across EROS Q / K series
843usberror=
844playerpic=aigoerosk
845encoder=rbspeex
846
847[aigoerosq.hifiwalkerh2]
848name="HIFI WALKER H2"
849bootloadermethod=bspatch
850bootloadername=/hifiwalker/H2-v12.bsdiff
851bootloaderfile=/update.upt
852bootloaderfilter=*.upt *.zip
853manualname=erosq
854brand=HIFI WALKER
855usbid=0xc5020023 ; shared across EROS Q / K series
856usberror=
857playerpic=aigoerosq
858encoder=rbspeex
859
860[aigoerosq.hifiwalkerh2.v13]
861name="HIFI WALKER H2 (v1.3+)"
862bootloadermethod=file
863bootloadername=/hifiwalker/H2-v13-patched.upt
864bootloaderfile=/update.upt
865manualname=erosq
866brand=HIFI WALKER
867usbid=0xc5020023 ; shared across EROS Q / K series
868usberror=
869playerpic=aigoerosq
870encoder=rbspeex
871
872; incompatible devices sections
873; each section uses a USB VID / PID string as section name.
874; name: human readable string to show the user when this device is detected.
875[05ac1240]
876name="Apple Ipod Nano (Second Generation, DFU Mode)"
877
878[05ac1262]
879name="Apple Ipod Nano (Third Generation)"
880
881[05ac1263]
882name="Apple Ipod Nano (Fourth Generation)"
883
884[05ac1255]
885name="Apple Ipod Nano (Fourth Generation, DFU Mode)"
886
887[05ac1265]
888name="Apple Ipod Nano (Fifth Generation)"
889
890[05ac1266]
891name="Apple Ipod Nano (Sixth Generation)"
892
893[05ac1267]
894name="Apple Ipod Nano (Seventh Generation)"
895
896[041e4133]
897name="Creative Zen series (Removable Disk Mode)"
898
899[041e4151]
900name="Creative Zen Vision:M (MTP)"
901
902[041e4150]
903name="Creative Zen V (MTP)"
904
905[041e4152]
906name="Creative Zen V Plus (MTP)"
907
908[066f3600]
909name="Creative Zen V (HW recovery mode)"
910
911[041e4157]
912name="Creative ZEN (MTP)"
913
914[041e4128]
915name="Creative NOMAD Jukebox Zen Xtra (MTP)"
916
917[041e4111]
918name="Dell Digital Jukebox (First Generation, MTP)"
919
920[041e412f]
921name="Dell Digital Jukebox (Second Generation, MTP)"
922
923[09300014]
924name="Toshiba Gigabeat V Series, MTP"
925
926[09300019]
927name="Toshiba Gigabeat T Series, MTP (No UMS mode)"
928
929[07817480]
930name="Sansa Connect (Normal Connection)"
931
932[07817481]
933name="Sansa Connect (Recovery Mode)"
934
935[07817400]
936name="Sansa m200-tcc (UMS/MSC)"
937
938[07817401]
939name="Sansa m200-tcc (MTP)"
940
941[078174b1]
942name="Sansa View"
943
944[066f3780]
945name="Sansa Fuze+ (Recovery Mode)"
946
947; languages to be shown for voicefile creation.
948; The language string is sent to the server when retrieving the list of
949; strings. Each entry name is the code for the language and used for storing in
950; the configuration.
951; Format:
952; <language code>=<language string as sent to server>,<human readable string>
953[languages]
954af=afrikaans,Afrikaans
955ar=arabic,Arabic
956bg=bulgarian,Bulgarian
957ca=catala,Catala
958cs=czech,Czech
959da=dansk,Dansk
960de=deutsch,Deutsch
961de_WAE=wallisertitsch,Wallisertitsch
962el=greek,Greek
963en=english,English (UK)
964en_US=english-us,English (US)
965eo=esperanto,Esperanto
966es=espanol,Espanol
967et=eesti,Eesti
968eu=basque,Basque
969fi=finnish,Finnish
970fr=francais,Francais
971gl=galego,Galego
972he=hebrew,Hebrew
973hi=hindi,Hindi
974hu=magyar,Magyar
975hr=hrvatski,Hrvatski
976is=islenska,Islenska
977it=italiano,Italiano
978ja=japanese,Japanese
979ko=korean,Korean
980lt=lietuviu,Lietuviu
981lv=latviesu,Latviesu
982nb=norsk,Norsk
983nl=nederlands,Netherlands
984nl_NLD=vlaams,Vlaams
985nn=norsk-nynorsk,Norsk (Nyorsk)
986pl=polski,Polski
987pt=portugues,Portugues
988pt_BR=portugues-brasileiro,Portugues (Brasileiro)
989ro=romaneste,Romaneste
990ru=russian,Russian
991sk=slovak,Slovakscina,Slovenscina
992sr=srpski,Srpski
993sv=svenska,Svenska
994th=thai,Thai
995tl=tagalog,Tagalog
996tr=turkce,Turkce
997uk=ukranian,Ukgranian
998wa=walon,Wallon
999zh_CN=chinese-simp,Chinese (simplified)
1000zh_TW=chinese-trad,Chinese (traditional)
diff --git a/utils/rbutilqt/rbutilqt-lang.qrc b/utils/rbutilqt/rbutilqt-lang.qrc
new file mode 100644
index 0000000000..df6e2f98c7
--- /dev/null
+++ b/utils/rbutilqt/rbutilqt-lang.qrc
@@ -0,0 +1,19 @@
1<RCC>
2 <qresource prefix="/" >
3 <file>lang/rbutil_cs.qm</file>
4 <file>lang/rbutil_de.qm</file>
5 <file>lang/rbutil_fi.qm</file>
6 <file>lang/rbutil_fr.qm</file>
7 <file>lang/rbutil_gr.qm</file>
8 <file>lang/rbutil_he.qm</file>
9 <file>lang/rbutil_it.qm</file>
10 <file>lang/rbutil_ja.qm</file>
11 <file>lang/rbutil_nl.qm</file>
12 <file>lang/rbutil_pl.qm</file>
13 <file>lang/rbutil_pt.qm</file>
14 <file>lang/rbutil_pt_BR.qm</file>
15 <file>lang/rbutil_ru.qm</file>
16 <file>lang/rbutil_zh_CN.qm</file>
17 <file>lang/rbutil_zh_TW.qm</file>
18 </qresource>
19</RCC>
diff --git a/utils/rbutilqt/rbutilqt-win.qrc b/utils/rbutilqt/rbutilqt-win.qrc
new file mode 100644
index 0000000000..470b99a7ee
--- /dev/null
+++ b/utils/rbutilqt/rbutilqt-win.qrc
@@ -0,0 +1,5 @@
1<RCC>
2 <qresource>
3 <file alias="builtin/sapi_voice.vbs">../../tools/sapi_voice.vbs</file>
4 </qresource>
5</RCC>
diff --git a/utils/rbutilqt/rbutilqt.cpp b/utils/rbutilqt/rbutilqt.cpp
new file mode 100644
index 0000000000..16735dc83a
--- /dev/null
+++ b/utils/rbutilqt/rbutilqt.cpp
@@ -0,0 +1,721 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QMainWindow>
20#include <QMessageBox>
21
22#include "version.h"
23#include "rbutilqt.h"
24#include "ui_rbutilqtfrm.h"
25#include "ui_aboutbox.h"
26#include "configure.h"
27#include "installtalkwindow.h"
28#include "createvoicewindow.h"
29#include "httpget.h"
30#include "themesinstallwindow.h"
31#include "uninstallwindow.h"
32#include "utils.h"
33#include "rockboxinfo.h"
34#include "sysinfo.h"
35#include "system.h"
36#include "systrace.h"
37#include "rbsettings.h"
38#include "playerbuildinfo.h"
39#include "ziputil.h"
40#include "infowidget.h"
41#include "selectiveinstallwidget.h"
42#include "backupdialog.h"
43#include "changelog.h"
44
45#include "progressloggerinterface.h"
46
47#include "bootloaderinstallbase.h"
48#include "bootloaderinstallhelper.h"
49
50#include "Logger.h"
51
52#if defined(Q_OS_LINUX)
53#include <stdio.h>
54#endif
55#if defined(Q_OS_WIN32)
56#if !defined(_UNICODE)
57#define _UNICODE
58#endif
59#include <stdio.h>
60#include <tchar.h>
61#include <windows.h>
62#endif
63
64QList<QTranslator*> RbUtilQt::translators;
65
66RbUtilQt::RbUtilQt(QWidget *parent) : QMainWindow(parent)
67{
68 // startup log
69 LOG_INFO() << "======================================";
70 LOG_INFO() << "Rockbox Utility" << VERSION;
71 LOG_INFO() << "Qt version:" << qVersion();
72#if defined(__clang__)
73 LOG_INFO("compiled using clang %i.%i.%i",
74 __clang_major__, __clang_minor__, __clang_patchlevel__);
75#elif defined(__GNUC__)
76 LOG_INFO("compiled using gcc %i.%i.%i",
77 __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
78#elif defined(_MSC_VER)
79 LOG_INFO() << "compiled using MSVC" << _MSC_FULL_VER;
80#endif
81 LOG_INFO() << "======================================";
82
83 absolutePath = qApp->applicationDirPath();
84
85 QString c = RbSettings::value(RbSettings::CachePath).toString();
86 HttpGet::setGlobalCache(c.isEmpty() ? QDir::tempPath() : c);
87 HttpGet::setGlobalUserAgent("rbutil/" VERSION);
88 HttpGet::setGlobalProxy(proxy());
89 // init startup & autodetection
90 ui.setupUi(this);
91 QIcon windowIcon(":/icons/rockbox-clef.svg");
92 this->setWindowIcon(windowIcon);
93#if defined(Q_OS_MACX)
94 // don't translate menu entries that are handled specially on OS X
95 // (Configure, Quit). Qt handles them for us if they use english string.
96 ui.action_Configure->setText("Configure");
97 ui.actionE_xit->setText("Quit");
98#endif
99#if defined(Q_OS_WIN32)
100 long ret;
101 HKEY hk;
102 ret = RegOpenKeyEx(HKEY_CURRENT_USER, _TEXT("Software\\Wine"),
103 0, KEY_QUERY_VALUE, &hk);
104 if(ret == ERROR_SUCCESS) {
105 QMessageBox::warning(this, tr("Wine detected!"),
106 tr("It seems you are trying to run this program under Wine. "
107 "Please don't do this, running under Wine will fail. "
108 "Use the native Linux binary instead."),
109 QMessageBox::Ok, QMessageBox::Ok);
110 LOG_WARNING() << "WINE DETECTED!";
111 RegCloseKey(hk);
112 }
113#endif
114
115#if !defined(Q_OS_WIN32) && !defined(Q_OS_MACX)
116 /* eject funtionality is not available on Linux right now. */
117 ui.buttonEject->setEnabled(false);
118#endif
119 updateDevice();
120 downloadInfo();
121
122 m_gotInfo = false;
123 m_auto = false;
124
125 // selective "install" tab.
126 QGridLayout *selectivetablayout = new QGridLayout(this);
127 ui.selective->setLayout(selectivetablayout);
128 selectiveinstallwidget = new SelectiveInstallWidget(this);
129 selectivetablayout->addWidget(selectiveinstallwidget);
130 connect(ui.buttonChangeDevice, SIGNAL(clicked()), selectiveinstallwidget, SLOT(saveSettings()));
131
132 // info tab
133 QGridLayout *infotablayout = new QGridLayout(this);
134 ui.info->setLayout(infotablayout);
135 info = new InfoWidget(this);
136 infotablayout->addWidget(info);
137
138 connect(ui.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(updateTabs(int)));
139 connect(ui.actionAbout_Qt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
140 connect(ui.action_About, SIGNAL(triggered()), this, SLOT(about()));
141 connect(ui.action_Help, SIGNAL(triggered()), this, SLOT(help()));
142 connect(ui.action_Configure, SIGNAL(triggered()), this, SLOT(configDialog()));
143 connect(ui.actionE_xit, SIGNAL(triggered()), this, SLOT(shutdown()));
144 connect(ui.buttonChangeDevice, SIGNAL(clicked()), this, SLOT(configDialog()));
145 connect(ui.buttonEject, SIGNAL(clicked()), this, SLOT(eject()));
146 connect(ui.buttonTalk, SIGNAL(clicked()), this, SLOT(createTalkFiles()));
147 connect(ui.buttonCreateVoice, SIGNAL(clicked()), this, SLOT(createVoiceFile()));
148 connect(ui.buttonRemoveRockbox, SIGNAL(clicked()), this, SLOT(uninstall()));
149 connect(ui.buttonRemoveBootloader, SIGNAL(clicked()), this, SLOT(uninstallBootloader()));
150 connect(ui.buttonBackup, SIGNAL(clicked()), this, SLOT(backup()));
151
152 // actions accessible from the menu
153 connect(ui.actionCreate_Voice_File, SIGNAL(triggered()), this, SLOT(createVoiceFile()));
154 connect(ui.actionCreate_Talk_Files, SIGNAL(triggered()), this, SLOT(createTalkFiles()));
155 connect(ui.actionRemove_bootloader, SIGNAL(triggered()), this, SLOT(uninstallBootloader()));
156 connect(ui.actionUninstall_Rockbox, SIGNAL(triggered()), this, SLOT(uninstall()));
157 connect(ui.action_System_Info, SIGNAL(triggered()), this, SLOT(sysinfo()));
158 connect(ui.action_Trace, SIGNAL(triggered()), this, SLOT(trace()));
159 connect(ui.actionShow_Changelog, SIGNAL(triggered()), this, SLOT(changelog()));
160
161#if !defined(STATIC)
162 ui.actionInstall_Rockbox_Utility_on_player->setEnabled(false);
163#else
164 connect(ui.actionInstall_Rockbox_Utility_on_player, SIGNAL(triggered()), this, SLOT(installPortable()));
165#endif
166 Utils::findRunningProcess(QStringList("iTunes"));
167
168}
169
170
171void RbUtilQt::shutdown(void)
172{
173 this->close();
174}
175
176
177void RbUtilQt::trace(void)
178{
179 SysTrace wnd(this);
180 wnd.exec();
181}
182
183void RbUtilQt::sysinfo(void)
184{
185 Sysinfo sysinfo(this);
186 sysinfo.exec();
187}
188
189void RbUtilQt::changelog(void)
190{
191
192 Changelog cl(this);
193 cl.exec();
194}
195
196
197void RbUtilQt::updateTabs(int count)
198{
199 if(count == ui.tabWidget->indexOf(info->parentWidget()))
200 info->updateInfo();
201}
202
203
204void RbUtilQt::downloadInfo()
205{
206 // try to get the current build information
207 daily = new HttpGet(this);
208 connect(daily, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
209 connect(qApp, SIGNAL(lastWindowClosed()), daily, SLOT(abort()));
210 daily->setCache(false);
211 ui.statusbar->showMessage(tr("Downloading build information, please wait ..."));
212 LOG_INFO() << "downloading build info";
213 daily->setFile(&buildInfo);
214 daily->getFile(QUrl(PlayerBuildInfo::instance()->value(PlayerBuildInfo::BuildInfoUrl).toString()));
215}
216
217
218void RbUtilQt::downloadDone(bool error)
219{
220 if(error) {
221 LOG_INFO() << "network error:" << daily->errorString();
222 ui.statusbar->showMessage(tr("Can't get version information!"));
223 QMessageBox::critical(this, tr("Network error"),
224 tr("Can't get version information.\n"
225 "Network error: %1. Please check your network and proxy settings.")
226 .arg(daily->errorString()));
227 return;
228 }
229 LOG_INFO() << "network status:" << daily->errorString();
230
231 // read info into PlayerBuildInfo object
232 buildInfo.open();
233 PlayerBuildInfo::instance()->setBuildInfo(buildInfo.fileName());
234 buildInfo.close();
235
236 ui.statusbar->showMessage(tr("Download build information finished."), 5000);
237 if(RbSettings::value(RbSettings::RbutilVersion) != PUREVERSION
238 || RbSettings::value(RbSettings::ShowChangelog).toBool()) {
239 changelog();
240 }
241 updateSettings();
242 m_gotInfo = true;
243
244 //start check for updates
245 checkUpdate();
246
247}
248
249
250void RbUtilQt::about()
251{
252 QDialog *window = new QDialog(this);
253 Ui::aboutBox about;
254 about.setupUi(window);
255 window->setLayoutDirection(Qt::LeftToRight);
256 window->setModal(true);
257
258 QFile licence(":/docs/gpl-2.0.html");
259 licence.open(QIODevice::ReadOnly);
260 QTextStream c(&licence);
261 about.browserLicense->insertHtml(c.readAll());
262 about.browserLicense->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
263 licence.close();
264
265 QString html = "<p>" + tr("Libraries used") + "</p>";
266 html += "<ul>";
267 html += "<li>Speex: <a href='#speex'>Speex License</a></li>";
268 html += "<li>bspatch: <a href='#bspatch'>bspatch License</a></li>";
269 html += "<li>bzip2: <a href='#bzip2'>bzip2 License</a></li>";
270 html += "<li>mspack: <a href='#lgpl2'>LGPL v2.1 License</a></li>";
271 html += "<li>quazip: <a href='#lgpl2'>LGPL v2.1 License</a></li>";
272 html += "<li>tomcrypt: <a href='#tomcrypt'>Tomcrypt License</a></li>";
273 html += "<li>CuteLogger: <a href='#lgpl2'>LGPL v2.1 License</a></li>";
274 html += "</ul>";
275 about.browserLicenses->insertHtml(html);
276
277 QMap<QString, QString> licenses;
278 licenses[":/docs/COPYING.SPEEX"] = "<a id='speex'>Speex License</a>";
279 licenses[":/docs/lgpl-2.1.txt"] = "<a id='lgpl2'>LGPL v2.1</a>";
280 licenses[":/docs/LICENSE.TOMCRYPT"] = "<a id='tomcrypt'>Tomcrypt License</a>";
281 licenses[":/docs/LICENSE.BZIP2"] = "<a id='bzip2'>bzip2 License</a>";
282 licenses[":/docs/LICENSE.BSPATCH"] = "<a id='bspatch'>bspatch License</a>";
283
284 for (int i = 0; i < licenses.size(); i++) {
285 QString key = licenses.keys().at(i);
286 QFile license(key);
287 license.open(QIODevice::ReadOnly);
288 QTextStream s(&license);
289 about.browserLicenses->insertHtml("<hr/><h2>" + licenses[key] + "</h2><br/>\n");
290 about.browserLicenses->insertHtml("<pre>" + s.readAll() + "</pre>");
291 license.close();
292 }
293 about.browserLicenses->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
294
295 QFile credits(":/docs/CREDITS");
296 credits.open(QIODevice::ReadOnly);
297 QTextStream r(&credits);
298#if QT_VERSION < 0x060000
299 r.setCodec(QTextCodec::codecForName("UTF-8"));
300#else
301 r.setEncoding(QStringConverter::Utf8);
302#endif
303 while(!r.atEnd()) {
304 QString line = r.readLine();
305 // filter out header.
306 line.remove(QRegExp("^ +.*"));
307 line.remove(QRegExp("^People.*"));
308 about.browserCredits->append(line);
309 }
310 credits.close();
311 about.browserCredits->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
312 QString title = QString("<b>The Rockbox Utility</b><br/>Version %1").arg(FULLVERSION);
313 about.labelTitle->setText(title);
314
315 window->show();
316
317}
318
319
320void RbUtilQt::help()
321{
322 QUrl helpurl("http://www.rockbox.org/wiki/RockboxUtility");
323 QDesktopServices::openUrl(helpurl);
324}
325
326
327void RbUtilQt::configDialog()
328{
329 Config *cw = new Config(this);
330 connect(cw, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
331 cw->show();
332}
333
334
335void RbUtilQt::updateSettings()
336{
337 LOG_INFO() << "updating current settings";
338 updateDevice();
339 QString c = RbSettings::value(RbSettings::CachePath).toString();
340 HttpGet::setGlobalCache(c.isEmpty() ? QDir::tempPath() : c);
341 HttpGet::setGlobalProxy(proxy());
342
343 if(RbSettings::value(RbSettings::RbutilVersion) != PUREVERSION) {
344 QApplication::processEvents();
345 QMessageBox::information(this, tr("New installation"),
346 tr("This is a new installation of Rockbox Utility, or a new version. "
347 "The configuration dialog will now open to allow you to setup the program, "
348 " or review your settings."));
349 configDialog();
350 }
351 else if(chkConfig(nullptr)) {
352 QApplication::processEvents();
353 QMessageBox::critical(this, tr("Configuration error"),
354 tr("Your configuration is invalid. This is most likely due "
355 "to a changed device path. The configuration dialog will "
356 "now open to allow you to correct the problem."));
357 configDialog();
358 }
359 selectiveinstallwidget->updateVersion();
360}
361
362
363void RbUtilQt::updateDevice()
364{
365 /* TODO: We should check the flags of the bootloaderinstall classes, and not
366 * just check if its != none or != "fwpatcher" */
367
368 /* Enable bootloader installation, if possible */
369 bool bootloaderInstallable =
370 PlayerBuildInfo::instance()->value(PlayerBuildInfo::BootloaderMethod).toString() != "none";
371
372 /* Enable bootloader uninstallation, if possible */
373 bool bootloaderUninstallable = bootloaderInstallable &&
374 PlayerBuildInfo::instance()->value(PlayerBuildInfo::BootloaderMethod) != "fwpatcher";
375 ui.labelRemoveBootloader->setEnabled(bootloaderUninstallable);
376 ui.buttonRemoveBootloader->setEnabled(bootloaderUninstallable);
377 ui.actionRemove_bootloader->setEnabled(bootloaderUninstallable);
378
379 /* Disable the whole tab widget if configuration is invalid */
380 bool configurationValid = !chkConfig(nullptr);
381 ui.tabWidget->setEnabled(configurationValid);
382 ui.menuA_ctions->setEnabled(configurationValid);
383
384 // displayed device info
385 QString brand = PlayerBuildInfo::instance()->value(PlayerBuildInfo::Brand).toString();
386 QString name
387 = QString("%1 (%2)").arg(
388 PlayerBuildInfo::instance()->value(PlayerBuildInfo::DisplayName).toString(),
389 PlayerBuildInfo::instance()->statusAsString());
390 ui.labelDevice->setText(QString("<b>%1 %2</b>").arg(brand, name));
391
392 QString mountpoint = RbSettings::value(RbSettings::Mountpoint).toString();
393 QString mountdisplay = QDir::toNativeSeparators(mountpoint);
394 if(!mountdisplay.isEmpty()) {
395 QString label = Utils::filesystemName(mountpoint);
396 if(!label.isEmpty()) mountdisplay += QString(" (%1)").arg(label);
397 ui.labelMountpoint->setText(QString("<b>%1</b>").arg(mountdisplay));
398 }
399 else {
400 mountdisplay = "(unknown)";
401 }
402
403 QPixmap pm;
404 QString m = PlayerBuildInfo::instance()->value(PlayerBuildInfo::PlayerPicture).toString();
405 pm.load(":/icons/players/" + m + "-small.png");
406 pm = pm.scaledToHeight(QFontMetrics(QApplication::font()).height() * 3);
407 ui.labelPlayerPic->setPixmap(pm);
408
409}
410
411
412void RbUtilQt::backup(void)
413{
414 backupdialog = new BackupDialog(this);
415 backupdialog->show();
416
417}
418
419
420void RbUtilQt::installdone(bool error)
421{
422 LOG_INFO() << "install done";
423 m_installed = true;
424 m_error = error;
425}
426
427
428void RbUtilQt::createTalkFiles(void)
429{
430 if(chkConfig(this)) return;
431 InstallTalkWindow *installWindow = new InstallTalkWindow(this);
432 connect(installWindow, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
433 installWindow->show();
434
435}
436
437void RbUtilQt::createVoiceFile(void)
438{
439 if(chkConfig(this)) return;
440 CreateVoiceWindow *installWindow = new CreateVoiceWindow(this);
441
442 connect(installWindow, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
443 installWindow->show();
444}
445
446void RbUtilQt::uninstall(void)
447{
448 if(chkConfig(this)) return;
449 UninstallWindow *uninstallWindow = new UninstallWindow(this);
450 uninstallWindow->show();
451
452}
453
454void RbUtilQt::uninstallBootloader(void)
455{
456 if(chkConfig(this)) return;
457 if(QMessageBox::question(this, tr("Confirm Uninstallation"),
458 tr("Do you really want to uninstall the Bootloader?"),
459 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
460 // create logger
461 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
462 logger->show();
463
464 QString platform = RbSettings::value(RbSettings::Platform).toString();
465
466 // create installer
467 BootloaderInstallBase *bl
468 = BootloaderInstallHelper::createBootloaderInstaller(this,
469 PlayerBuildInfo::instance()->value(PlayerBuildInfo::BootloaderMethod).toString());
470
471 if(bl == nullptr) {
472 logger->addItem(tr("No uninstall method for this target known."), LOGERROR);
473 logger->setFinished();
474 return;
475 }
476 QStringList blfile = PlayerBuildInfo::instance()->value(PlayerBuildInfo::BootloaderFile).toStringList();
477 QStringList blfilepath;
478 for(int a = 0; a < blfile.size(); a++) {
479 blfilepath.append(RbSettings::value(RbSettings::Mountpoint).toString()
480 + blfile.at(a));
481 }
482 bl->setBlFile(blfilepath);
483 bl->setLogfile(RbSettings::value(RbSettings::Mountpoint).toString()
484 + "/.rockbox/rbutil.log");
485
486 BootloaderInstallBase::BootloaderType currentbl = bl->installed();
487 if((bl->capabilities() & BootloaderInstallBase::Uninstall) == 0) {
488 logger->addItem(tr("Rockbox Utility can not uninstall the bootloader on your player. "
489 "Please perform a firmware update using your player vendors "
490 "firmware update process."), LOGERROR);
491 logger->addItem(tr("Important: make sure to boot your player into the original "
492 "firmware before using the vendors firmware update process."), LOGERROR);
493 logger->setFinished();
494 delete bl;
495 return;
496 }
497 if(currentbl == BootloaderInstallBase::BootloaderUnknown
498 || currentbl == BootloaderInstallBase::BootloaderOther) {
499 logger->addItem(tr("No Rockbox bootloader found."), LOGERROR);
500 logger->setFinished();
501 delete bl;
502 return;
503 }
504
505 connect(bl, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
506 connect(bl, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
507 connect(bl, SIGNAL(done(bool)), logger, SLOT(setFinished()));
508 // pass Abort button click signal to current installer
509 connect(logger, SIGNAL(aborted()), bl, SLOT(progressAborted()));
510
511 bl->uninstall();
512
513}
514
515
516void RbUtilQt::installPortable(void)
517{
518 if(QMessageBox::question(this, tr("Confirm installation"),
519 tr("Do you really want to install Rockbox Utility to your player? "
520 "After installation you can run it from the players hard drive."),
521 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
522 return;
523
524 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
525 logger->setProgressMax(0);
526 logger->setProgressValue(0);
527 logger->show();
528 logger->addItem(tr("Installing Rockbox Utility"), LOGINFO);
529
530 // check mountpoint
531 if(!QFileInfo(RbSettings::value(RbSettings::Mountpoint).toString()).isDir()) {
532 logger->addItem(tr("Mount point is wrong!"),LOGERROR);
533 logger->setFinished();
534 return;
535 }
536
537 // remove old files first.
538 QFile::remove(RbSettings::value(RbSettings::Mountpoint).toString()
539 + "/RockboxUtility.exe");
540 QFile::remove(RbSettings::value(RbSettings::Mountpoint).toString()
541 + "/RockboxUtility.ini");
542 // copy currently running binary and currently used settings file
543 if(!QFile::copy(qApp->applicationFilePath(),
544 RbSettings::value(RbSettings::Mountpoint).toString()
545 + "/RockboxUtility.exe")) {
546 logger->addItem(tr("Error installing Rockbox Utility"), LOGERROR);
547 logger->setFinished();
548 return;
549 }
550 logger->addItem(tr("Installing user configuration"), LOGINFO);
551 if(!QFile::copy(RbSettings::userSettingFilename(),
552 RbSettings::value(RbSettings::Mountpoint).toString()
553 + "/RockboxUtility.ini")) {
554 logger->addItem(tr("Error installing user configuration"), LOGERROR);
555 logger->setFinished();
556 return;
557 }
558 logger->addItem(tr("Successfully installed Rockbox Utility."), LOGOK);
559 logger->setFinished();
560 logger->setProgressMax(1);
561 logger->setProgressValue(1);
562
563}
564
565
566QUrl RbUtilQt::proxy()
567{
568 QUrl proxy;
569 QString proxytype = RbSettings::value(RbSettings::ProxyType).toString();
570 if(proxytype == "manual") {
571 proxy.setUrl(RbSettings::value(RbSettings::Proxy).toString(),
572 QUrl::TolerantMode);
573 QByteArray pw = QByteArray::fromBase64(proxy.password().toUtf8());
574 proxy.setPassword(pw);
575 }
576 else if(proxytype == "system")
577 proxy = System::systemProxy();
578
579 LOG_INFO() << "Proxy is" << proxy;
580 return proxy;
581}
582
583
584bool RbUtilQt::chkConfig(QWidget *parent)
585{
586 bool error = false;
587 if(RbSettings::value(RbSettings::Platform).toString().isEmpty()
588 || RbSettings::value(RbSettings::Mountpoint).toString().isEmpty()
589 || !QFileInfo(RbSettings::value(RbSettings::Mountpoint).toString()).isWritable()) {
590 error = true;
591
592 if(parent) QMessageBox::critical(parent, tr("Configuration error"),
593 tr("Your configuration is invalid. Please go to the configuration "
594 "dialog and make sure the selected values are correct."));
595 }
596 return error;
597}
598
599void RbUtilQt::checkUpdate(void)
600{
601 QString url = PlayerBuildInfo::instance()->value(PlayerBuildInfo::RbutilUrl).toString();
602#if defined(Q_OS_WIN32)
603 url += "win32/";
604#elif defined(Q_OS_LINUX)
605 url += "linux/";
606#elif defined(Q_OS_MACX)
607 url += "macosx/";
608#endif
609
610 update = new HttpGet(this);
611 connect(update, SIGNAL(done(bool)), this, SLOT(downloadUpdateDone(bool)));
612 connect(qApp, SIGNAL(lastWindowClosed()), update, SLOT(abort()));
613
614 ui.statusbar->showMessage(tr("Checking for update ..."));
615 update->getFile(QUrl(url));
616}
617
618void RbUtilQt::downloadUpdateDone(bool error)
619{
620 if(error) {
621 LOG_INFO() << "network error:" << update->errorString();
622 }
623 else {
624 QString toParse(update->readAll());
625
626 QRegExp searchString("<a[^>]*>([a-zA-Z]+[^<]*)</a>");
627 QStringList rbutilList;
628 int pos = 0;
629 while ((pos = searchString.indexIn(toParse, pos)) != -1)
630 {
631 rbutilList << searchString.cap(1);
632 pos += searchString.matchedLength();
633 }
634 LOG_INFO() << "Checking for update";
635
636 QString newVersion = "";
637 QString foundVersion = "";
638 // check if there is a binary with higher version in this list
639 for(int i=0; i < rbutilList.size(); i++)
640 {
641 QString item = rbutilList.at(i);
642#if defined(Q_OS_LINUX)
643#if defined(__amd64__)
644 // skip if it isn't a 64 bit build
645 if( !item.contains("64bit"))
646 continue;
647 // strip the "64bit" suffix for comparison
648 item = item.remove("64bit");
649#else
650 //skip if it is a 64bit build
651 if(item.contains("64bit"))
652 continue;
653#endif
654#endif
655 // check if it is newer, and remember newest
656 if(Utils::compareVersionStrings(VERSION, item) == 1)
657 {
658 if(Utils::compareVersionStrings(newVersion, item) == 1)
659 {
660 newVersion = item;
661 foundVersion = rbutilList.at(i);
662 }
663 }
664 }
665
666 // if we found something newer, display info
667 if(foundVersion != "")
668 {
669 QString url = PlayerBuildInfo::instance()->value(PlayerBuildInfo::RbutilUrl).toString();
670#if defined(Q_OS_WIN32)
671 url += "win32/";
672#elif defined(Q_OS_LINUX)
673 url += "linux/";
674#elif defined(Q_OS_MACX)
675 url += "macosx/";
676#endif
677 url += foundVersion;
678
679 QMessageBox::information(this,tr("Rockbox Utility Update available"),
680 tr("<b>New Rockbox Utility version available.</b><br><br>"
681 "You are currently using version %1. "
682 "Get version %2 at <a href='%3'>%3</a>")
683 .arg(VERSION).arg(Utils::trimVersionString(foundVersion)).arg(url));
684 ui.statusbar->showMessage(tr("New version of Rockbox Utility available."));
685 }
686 else {
687 ui.statusbar->showMessage(tr("Rockbox Utility is up to date."), 5000);
688 }
689 }
690}
691
692
693void RbUtilQt::changeEvent(QEvent *e)
694{
695 if(e->type() == QEvent::LanguageChange) {
696 ui.retranslateUi(this);
697 buildInfo.open();
698 PlayerBuildInfo::instance()->setBuildInfo(buildInfo.fileName());
699 buildInfo.close();
700 updateDevice();
701 } else {
702 QMainWindow::changeEvent(e);
703 }
704}
705
706void RbUtilQt::eject(void)
707{
708 QString mountpoint = RbSettings::value(RbSettings::Mountpoint).toString();
709 if(Utils::ejectDevice(mountpoint)) {
710 QMessageBox::information(this, tr("Device ejected"),
711 tr("Device successfully ejected. "
712 "You may now disconnect the player from the PC."));
713 }
714 else {
715 QMessageBox::critical(this, tr("Ejecting failed"),
716 tr("Ejecting the device failed. Please make sure no programs "
717 "are accessing files on the device. If ejecting still "
718 "fails please use your computers eject funtionality."));
719 }
720}
721
diff --git a/utils/rbutilqt/rbutilqt.h b/utils/rbutilqt/rbutilqt.h
new file mode 100644
index 0000000000..e20749d438
--- /dev/null
+++ b/utils/rbutilqt/rbutilqt.h
@@ -0,0 +1,104 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Riebeling
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21
22#ifndef QRBUTIL_H
23#define QRBUTIL_H
24
25#include <QSettings>
26#include <QTemporaryFile>
27#include <QList>
28#include <QTranslator>
29
30#include "ui_rbutilqtfrm.h"
31#include "httpget.h"
32#include "zipinstaller.h"
33#include "progressloggergui.h"
34#include "bootloaderinstallbase.h"
35#include "infowidget.h"
36#include "selectiveinstallwidget.h"
37#include "backupdialog.h"
38
39class RbUtilQt : public QMainWindow
40{
41 Q_OBJECT
42
43 public:
44 RbUtilQt(QWidget *parent = nullptr);
45 static QList<QTranslator*> translators;
46 static bool chkConfig(QWidget *parent = nullptr);
47
48 private:
49 InfoWidget *info;
50 SelectiveInstallWidget* selectiveinstallwidget;
51 BackupDialog *backupdialog;
52 Ui::RbUtilQtFrm ui;
53
54 void changeEvent(QEvent *e);
55 void initDeviceNames(void);
56 QString deviceName(QString);
57 QString platform;
58 HttpGet *daily;
59 HttpGet *bleeding;
60 HttpGet *update;
61 QString absolutePath;
62 QTemporaryFile buildInfo;
63 QTemporaryFile bleedingInfo;
64 ProgressLoggerGui *logger;
65 ZipInstaller *installer;
66 QUrl proxy(void);
67
68 volatile bool m_installed;
69 volatile bool m_error;
70 QString m_networkerror;
71 bool m_gotInfo;
72 bool m_auto;
73
74 private slots:
75 void shutdown(void);
76 void about(void);
77 void help(void);
78 void sysinfo(void);
79 void changelog(void);
80 void trace(void);
81 void eject(void);
82 void configDialog(void);
83 void updateDevice(void);
84 void updateSettings(void);
85
86 void installdone(bool error);
87
88 void createTalkFiles(void);
89 void createVoiceFile(void);
90 void downloadDone(bool);
91 void downloadInfo(void);
92 void backup(void);
93
94 void uninstall(void);
95 void uninstallBootloader(void);
96 void installPortable(void);
97 void updateTabs(int);
98
99 void checkUpdate(void);
100 void downloadUpdateDone(bool errror);
101};
102
103#endif
104
diff --git a/utils/rbutilqt/rbutilqt.manifest b/utils/rbutilqt/rbutilqt.manifest
new file mode 100644
index 0000000000..27586d99dd
--- /dev/null
+++ b/utils/rbutilqt/rbutilqt.manifest
@@ -0,0 +1,19 @@
1<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
3 <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="RockboxUtility.exe" type="win32"/>
4
5 <!-- Identify the application security requirements. -->
6 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
7 <security>
8 <requestedPrivileges>
9 <requestedExecutionLevel level="requireAdministrator"/>
10 </requestedPrivileges>
11 </security>
12 </trustInfo>
13 <asmv3:application>
14 <asmv3:windowsSettings>
15 <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
16 <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
17 </asmv3:windowsSettings>
18 </asmv3:application>
19</assembly>
diff --git a/utils/rbutilqt/rbutilqt.pri b/utils/rbutilqt/rbutilqt.pri
new file mode 100644
index 0000000000..15d415289f
--- /dev/null
+++ b/utils/rbutilqt/rbutilqt.pri
@@ -0,0 +1,229 @@
1#
2# __________ __ ___.
3# Open \______ \ ____ ____ | | _\_ |__ _______ ___
4# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7# \/ \/ \/ \/ \/
8# $Id$
9#
10# All files in this archive are subject to the GNU General Public License.
11# See the file COPYING in the source tree root for full license agreement.
12#
13# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
14# KIND, either express or implied.
15#
16
17
18# common files
19SOURCES += \
20 gui/infowidget.cpp \
21 rbutilqt.cpp \
22 main.cpp \
23 base/httpget.cpp \
24 configure.cpp \
25 base/zipinstaller.cpp \
26 progressloggergui.cpp \
27 installtalkwindow.cpp \
28 base/talkfile.cpp \
29 base/talkgenerator.cpp \
30 base/autodetection.cpp \
31 themesinstallwindow.cpp \
32 base/uninstall.cpp \
33 uninstallwindow.cpp \
34 base/utils.cpp \
35 preview.cpp \
36 base/encoderbase.cpp \
37 base/encoderrbspeex.cpp \
38 base/encoderlame.cpp \
39 base/encoderexe.cpp \
40 encttscfggui.cpp \
41 base/encttssettings.cpp \
42 base/ttsbase.cpp \
43 base/ttsexes.cpp \
44 base/ttssapi.cpp \
45 base/ttsfestival.cpp \
46 ../../tools/wavtrim.c \
47 ../../tools/voicefont.c \
48 base/voicefile.cpp \
49 createvoicewindow.cpp \
50 base/rbsettings.cpp \
51 base/system.cpp \
52 sysinfo.cpp \
53 systrace.cpp \
54 base/bootloaderinstallbase.cpp \
55 base/bootloaderinstallbspatch.cpp \
56 base/bootloaderinstallhelper.cpp \
57 base/bootloaderinstallmi4.cpp \
58 base/bootloaderinstallhex.cpp \
59 base/bootloaderinstallipod.cpp \
60 base/bootloaderinstallsansa.cpp \
61 base/bootloaderinstallfile.cpp \
62 base/bootloaderinstallchinachip.cpp \
63 base/bootloaderinstallams.cpp \
64 base/bootloaderinstalltcc.cpp \
65 base/bootloaderinstallmpio.cpp \
66 base/bootloaderinstallimx.cpp \
67 base/bootloaderinstalls5l.cpp \
68 base/rockboxinfo.cpp \
69 ../../tools/mkboot.c \
70 ../../tools/iriver.c \
71 base/ziputil.cpp \
72 gui/comboboxviewdelegate.cpp \
73 gui/selectiveinstallwidget.cpp \
74 gui/backupdialog.cpp \
75 gui/changelog.cpp \
76 mspack/cabd.c \
77 mspack/lzxd.c \
78 mspack/mszipd.c \
79 mspack/qtmd.c \
80 mspack/system-mspack.c \
81 base/mspackutil.cpp \
82 base/archiveutil.cpp \
83 base/playerbuildinfo.cpp
84
85
86HEADERS += \
87 gui/infowidget.h \
88 rbutilqt.h \
89 base/httpget.h \
90 configure.h \
91 version.h \
92 base/zipinstaller.h \
93 installtalkwindow.h \
94 base/talkfile.h \
95 base/talkgenerator.h \
96 base/autodetection.h \
97 base/progressloggerinterface.h \
98 progressloggergui.h \
99 irivertools/h100sums.h \
100 irivertools/h120sums.h \
101 irivertools/h300sums.h \
102 themesinstallwindow.h \
103 base/uninstall.h \
104 uninstallwindow.h \
105 base/utils.h \
106 preview.h \
107 base/encoderbase.h \
108 base/encoderrbspeex.h \
109 base/encoderlame.h \
110 base/encoderexe.h \
111 encttscfggui.h \
112 base/encttssettings.h \
113 base/ttsbase.h \
114 base/ttsexes.h \
115 base/ttsespeak.h \
116 base/ttsespeakng.h \
117 base/ttsflite.h \
118 base/ttsfestival.h \
119 base/ttsmimic.h \
120 base/ttsswift.h \
121 base/ttssapi.h \
122 base/ttssapi4.h \
123 base/ttsmssp.h \
124 ../../tools/wavtrim.h \
125 ../../tools/voicefont.h \
126 base/voicefile.h \
127 createvoicewindow.h \
128 base/rbsettings.h \
129 sysinfo.h \
130 base/system.h \
131 systrace.h \
132 base/bootloaderinstallbase.h \
133 base/bootloaderinstallbspatch.h \
134 base/bootloaderinstallhelper.h \
135 base/bootloaderinstallmi4.h \
136 base/bootloaderinstallhex.h \
137 base/bootloaderinstallipod.h \
138 base/bootloaderinstallsansa.h \
139 base/bootloaderinstallfile.h \
140 base/bootloaderinstallchinachip.h \
141 base/bootloaderinstallams.h \
142 base/bootloaderinstalltcc.h \
143 base/bootloaderinstallmpio.h \
144 base/bootloaderinstallimx.h \
145 base/bootloaderinstalls5l.h \
146 base/rockboxinfo.h \
147 ../../tools/mkboot.h \
148 ../../tools/iriver.h \
149 base/ziputil.h \
150 lame/lame.h \
151 gui/comboboxviewdelegate.h \
152 gui/selectiveinstallwidget.h \
153 gui/backupdialog.h \
154 gui/changelog.h \
155 mspack/cab.h \
156 mspack/chm.h \
157 mspack/des.h \
158 mspack/hlp.h \
159 mspack/kwaj.h \
160 mspack/lit.h \
161 mspack/lzss.h \
162 mspack/lzx.h \
163 mspack/mspack.h \
164 mspack/mszip.h \
165 mspack/qtm.h \
166 mspack/readbits.h \
167 mspack/readhuff.h \
168 mspack/sha.h \
169 mspack/system-mspack.h \
170 mspack/szdd.h \
171 base/mspackutil.h \
172 base/archiveutil.h \
173 base/playerbuildinfo.h
174
175
176FORMS += \
177 gui/infowidgetfrm.ui \
178 rbutilqtfrm.ui \
179 aboutbox.ui \
180 progressloggerfrm.ui \
181 configurefrm.ui \
182 installtalkfrm.ui \
183 themesinstallfrm.ui \
184 uninstallfrm.ui \
185 previewfrm.ui \
186 createvoicefrm.ui \
187 sysinfofrm.ui \
188 systracefrm.ui \
189 gui/selectiveinstallwidgetfrm.ui \
190 gui/backupdialogfrm.ui \
191 gui/changelogfrm.ui
192
193
194TRANSLATIONS += \
195 lang/rbutil_cs.ts \
196 lang/rbutil_de.ts \
197 lang/rbutil_fi.ts \
198 lang/rbutil_fr.ts \
199 lang/rbutil_gr.ts \
200 lang/rbutil_he.ts \
201 lang/rbutil_it.ts \
202 lang/rbutil_ja.ts \
203 lang/rbutil_nl.ts \
204 lang/rbutil_pl.ts \
205 lang/rbutil_pt.ts \
206 lang/rbutil_pt_BR.ts \
207 lang/rbutil_ru.ts \
208 lang/rbutil_tr.ts \
209 lang/rbutil_zh_CN.ts \
210 lang/rbutil_zh_TW.ts \
211
212RESOURCES += $$_PRO_FILE_PWD_/rbutilqt.qrc
213!dbg {
214 RESOURCES += $$_PRO_FILE_PWD_/rbutilqt-lang.qrc
215}
216# windows specific files
217win32 {
218 RC_FILE = rbutilqt.rc
219 RESOURCES += $$_PRO_FILE_PWD_/rbutilqt-win.qrc
220}
221
222# mac specific files
223macx {
224 SOURCES += base/ttscarbon.cpp
225 HEADERS += base/ttscarbon.h
226 QMAKE_INFO_PLIST = Info.plist
227 RC_FILE = icons/rbutilqt.icns
228}
229
diff --git a/utils/rbutilqt/rbutilqt.pro b/utils/rbutilqt/rbutilqt.pro
new file mode 100644
index 0000000000..f172e231bf
--- /dev/null
+++ b/utils/rbutilqt/rbutilqt.pro
@@ -0,0 +1,248 @@
1#
2# __________ __ ___.
3# Open \______ \ ____ ____ | | _\_ |__ _______ ___
4# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7# \/ \/ \/ \/ \/
8#
9# All files in this archive are subject to the GNU General Public License.
10# See the file COPYING in the source tree root for full license agreement.
11#
12# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
13# KIND, either express or implied.
14#
15
16# The external Makefiles use ar to create libs. To allow cross-compiling pass
17# the ar that matches the current gcc. Since qmake doesn't provide a variable
18# holding the correct ar without any additions we need to figure it ourselves
19# here.
20# Only do this if CC is gcc. Also, do this before ccache support is enabled.
21contains(QMAKE_CC,($$find(QMAKE_CC,.*gcc.*))) {
22 EXTRALIBS_OPTS = "EXTRALIBS_AR=\""$$replace(QMAKE_CC,gcc.*,ar)\"
23}
24# ccache
25unix:!mac:!noccache {
26 CCACHE = $$system(which ccache)
27 !isEmpty(CCACHE) {
28 message("using ccache at $$CCACHE")
29 QMAKE_CXX = ccache $$QMAKE_CXX
30 QMAKE_CC = ccache $$QMAKE_CC
31 }
32}
33MACHINEFLAGS = $$find(QMAKE_CFLAGS, -m[63][42])
34EXTRALIBS_OPTS += EXTRALIBS_CC=\"$$QMAKE_CC\"
35EXTRALIBS_OPTS += EXTRALIBS_CXX=\"$$QMAKE_CXX\"
36EXTRALIBS_OPTS += EXTRALIB_CFLAGS=\"$$MACHINEFLAGS\"
37EXTRALIBS_OPTS += EXTRALIB_CXXFLAGS=\"$$MACHINEFLAGS\"
38macx {
39# on recent macOS we need to pass isysroot to the libs, otherwise it won't find
40# the standard libaries. This is caused by the passed compiler (doesn't rely on
41# default compiler but passed full path)
42 EXTRALIBS_OPTS += EXTRALIB_ISYSROOT=\"$$QMAKE_MAC_SDK.macosx.Path\"
43}
44
45MYBUILDDIR = $$OUT_PWD/build/
46MYLIBBUILDDIR = $$MYBUILDDIR/libs/
47OBJECTS_DIR = $$MYBUILDDIR/o
48UI_DIR = $$MYBUILDDIR/ui
49MOC_DIR = $$MYBUILDDIR/moc
50RCC_DIR = $$MYBUILDDIR/rcc
51
52!silent {
53 VERBOSE = "V=1"
54} else {
55 VERBOSE =
56}
57
58# check version of Qt installation
59contains(QT_MAJOR_VERSION, 4) {
60 error("Qt 4 is not supported anymore.")
61}
62
63RBBASE_DIR = $$_PRO_FILE_PWD_
64RBBASE_DIR = $$replace(RBBASE_DIR,/utils/rbutilqt,)
65
66message("using Rockbox basedir $$RBBASE_DIR")
67
68# check for system speex. Add a custom rule for pre-building librbspeex if not
69# found. Newer versions of speex are split up into libspeex and libspeexdsp,
70# and some distributions package them separately. Check for both and fall back
71# to librbspeex if not found.
72# NOTE: keep adding the linker option after -lrbspeex, otherwise linker errors
73# occur if the linker defaults to --as-needed
74# (see http://www.gentoo.org/proj/en/qa/asneeded.xml)
75#
76# Always use our own copy when building statically. Don't search for libspeex
77# on Mac, since we don't deploy statically there.
78!static:unix:!mac {
79 LIBSPEEX = $$system(pkg-config --silence-errors --libs speex speexdsp)
80}
81
82extralibs.commands = $$SILENT \
83 $(MAKE) -f $$RBBASE_DIR/utils/rbutilqt/Makefile.libs \
84 $$VERBOSE \
85 SYS_SPEEX=\"$$LIBSPEEX\" \
86 BUILD_DIR=$$MYLIBBUILDDIR/ \
87 TARGET_DIR=$$MYLIBBUILDDIR \
88 RBBASE_DIR=$$RBBASE_DIR \
89 $$EXTRALIBS_OPTS \
90 libs
91# Note: order is important for RBLIBS! The libs are appended to the linker
92# flags in this order, put libucl at the end.
93RBLIBS = rbspeex ipodpatcher sansapatcher mkamsboot mktccboot \
94 mkmpioboot chinachippatcher mkimxboot mks5lboot bspatch ucl \
95 rbtomcrypt
96# NOTE: Our copy of libbzip2 has to use the name "bz2" to match up with the
97# distro name. Otherwise cross compiling would end up linking two copies of
98# bzip2 using different names, causing symbol clashes. Using the same name
99# makes the compiler pick the one he likes.
100RBLIBS += bz2
101!win32-msvc* {
102 QMAKE_EXTRA_TARGETS += extralibs
103 PRE_TARGETDEPS += extralibs
104}
105win32-msvc* {
106 INCLUDEPATH += msvc
107 LIBS += -L$$_PRO_FILE_PWD_/msvc
108 LIBS += -ladvapi32 # required for MSVC / Qt Creator combination
109}
110
111# rule for creating ctags file
112tags.commands = ctags -R --c++-kinds=+p --fields=+iaS --extra=+q $(SOURCES)
113tags.depends = $(SOURCES)
114QMAKE_EXTRA_TARGETS += tags
115
116# add a custom rule for making the translations
117LRELEASE = $$[QT_INSTALL_BINS]/lrelease
118
119win32:!cross:!exists($$LRELEASE) {
120 LRELEASE = $$[QT_INSTALL_BINS]/lrelease.exe
121}
122lrelease.commands = $$LRELEASE -silent $$_PRO_FILE_
123QMAKE_EXTRA_TARGETS += lrelease
124exists($$LRELEASE) {
125 message("using lrelease at $$LRELEASE")
126 PRE_TARGETDEPS += lrelease
127}
128!exists($$LRELEASE) {
129 warning("could not find lrelease. Skipping translations.")
130}
131
132# Needed by QT on Win
133INCLUDEPATH += $$_PRO_FILE_PWD_ $$_PRO_FILE_PWD_/irivertools \
134 $$_PRO_FILE_PWD_/zlib $$_PRO_FILE_PWD_/base \
135 $$_PRO_FILE_PWD_/zlib $$_PRO_FILE_PWD_/gui
136INCLUDEPATH += $$RBBASE_DIR/utils/ipodpatcher $$RBBASE_DIR/utils/sansapatcher \
137 $$RBBASE_DIR/tools/rbspeex $$RBBASE_DIR/tools
138INCLUDEPATH += logger
139
140DEPENDPATH = $$INCLUDEPATH
141
142LIBS += -L$$OUT_PWD -L$$MYLIBBUILDDIR
143# append all RBLIBS to LIBS
144for(rblib, RBLIBS) {
145 LIBS += -l$$rblib
146}
147
148LIBS += -lz
149
150# Add a (possibly found) libspeex now, don't do this before -lrbspeex!
151!static:!isEmpty(LIBSPEEX) {
152 LIBS += $$LIBSPEEX
153}
154
155TEMPLATE = app
156TARGET = RockboxUtility
157QT += network widgets svg
158
159message("Qt$$QT_MAJOR_VERSION found")
160lessThan(QT_MAJOR_VERSION, 6) {
161 QT += multimedia
162}
163if (greaterThan(QT_MAJOR_VERSION, 5)) {
164 QT += core5compat
165}
166
167CONFIG += c++11
168
169dbg {
170 CONFIG += debug thread qt warn_on
171 DEFINES += DBG
172 message("creating debug version")
173}
174!dbg {
175 CONFIG += release thread qt
176 DEFINES += NODEBUG
177 message("creating release version")
178}
179
180DEFINES += RBUTIL _LARGEFILE64_SOURCE
181DEFINES += QT_DEPRECATED_WARNINGS
182
183# platform specific
184win32 {
185 # use MinGW's implementation of stdio functions for extended format string
186 # support.
187 DEFINES += __USE_MINGW_ANSI_STDIO=1
188 DEFINES += _CRT_SECURE_NO_WARNINGS
189 DEFINES += UNICODE
190 LIBS += -lsetupapi -lnetapi32
191}
192win32:static {
193 QMAKE_LFLAGS += -static-libgcc -static-libstdc++
194}
195unix:!static:!macx {
196 LIBS += -lusb-1.0
197}
198
199unix:!macx:static {
200 # force statically linking of libusb. Libraries that are appended
201 # later will get linked dynamically again.
202 LIBS += -Wl,-Bstatic -lusb-1.0 -Wl,-Bdynamic
203}
204
205macx {
206 QMAKE_MAC_SDK=macosx
207 contains(QT_MAJOR_VERSION, 5) {
208 greaterThan(QT_MINOR_VERSION, 5) {
209 QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
210 message("Qt 5.6+ detected: setting deploy target to 10.7")
211 }
212 !greaterThan(QT_MINOR_VERSION, 5) {
213 QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
214 message("Qt up to 5.5 detected: setting deploy target to 10.6")
215 }
216 }
217
218 CONFIG += x86
219 LIBS += -L/usr/local/lib \
220 -framework IOKit -framework CoreFoundation -framework Carbon \
221 -framework SystemConfiguration -framework CoreServices
222 INCLUDEPATH += /usr/local/include
223
224 # rule for creating a dmg file
225 dmg.commands = hdiutil create -ov -srcfolder RockboxUtility.app/ RockboxUtility.dmg
226 QMAKE_EXTRA_TARGETS += dmg
227}
228
229static {
230 if(equals(QT_MAJOR_VERSION, 5) : lessThan(QT_MINOR_VERSION, 4)) {
231 QTPLUGIN += qtaccessiblewidgets
232 LIBS += -L$$(QT_BUILD_TREE)/plugins/accessible -lqtaccessiblewidgets
233 }
234 LIBS += -L.
235 DEFINES += STATIC
236 message("using static plugin")
237}
238
239unix {
240 target.path = /usr/local/bin
241 INSTALLS += target
242}
243
244
245# source files are separate.
246include(rbutilqt.pri)
247include(quazip/quazip.pri)
248include(logger/logger.pri)
diff --git a/utils/rbutilqt/rbutilqt.qrc b/utils/rbutilqt/rbutilqt.qrc
new file mode 100644
index 0000000000..7ea638c54b
--- /dev/null
+++ b/utils/rbutilqt/rbutilqt.qrc
@@ -0,0 +1,97 @@
1<RCC>
2 <qresource prefix="/">
3 <file alias="docs/CREDITS">../../docs/CREDITS</file>
4 <file alias="docs/gpl-2.0.html">../../docs/gpl-2.0.html</file>
5 <file alias="docs/lgpl-2.1.txt">logger/LICENSE.LGPL</file>
6 <file alias="docs/COPYING.SPEEX">../../lib/rbcodec/codecs/libspeex/COPYING</file>
7 <file alias="docs/LICENSE.TOMCRYPT">../../utils/tomcrypt/LICENSE</file>
8 <file alias="docs/LICENSE.BZIP2">../bzip2/LICENSE</file>
9 <file alias="docs/LICENSE.BSPATCH">../bspatch/LICENSE</file>
10 <file alias="docs/changelog.txt">changelog.txt</file>
11 </qresource>
12 <qresource>
13 <file alias="builtin/VOICE_PAUSE.wav">../../tools/VOICE_PAUSE.wav</file>
14 <file alias="builtin/voice-corrections.txt">../../tools/voice-corrections.txt</file>
15 </qresource>
16 <qresource prefix="/">
17 <file>icons/audio-volume-high.svg</file>
18 <file>icons/edit-clear.svg</file>
19 <file>icons/preferences-desktop-font.svg</file>
20 <file>icons/preferences-desktop-theme.svg</file>
21 <file>icons/multimedia-player.svg</file>
22 <file>icons/input-gaming.svg</file>
23 <file>icons/audio-input-microphone.svg</file>
24 <file>icons/dialog-error.svg</file>
25 <file>icons/dialog-information.svg</file>
26 <file>icons/dialog-warning.svg</file>
27 <file>icons/document-save.svg</file>
28 <file>icons/edit-find.svg</file>
29 <file>icons/go-next.svg</file>
30 <file>icons/media-eject.svg</file>
31 <file>icons/network-idle.svg</file>
32 <file>icons/package-x-generic.svg</file>
33 <file>icons/preferences-desktop-locale.svg</file>
34 <file>icons/preferences-system.svg</file>
35 <file>icons/process-stop.svg</file>
36 <file>icons/system-search.svg</file>
37 <file>icons/user-trash-full.svg</file>
38 <file>icons/view-refresh.svg</file>
39 <file>icons/wizard.jpg</file>
40 <file alias="icons/rockbox-clef.svg">../../docs/logo/rockbox-clef.svg</file>
41 <file alias="icons/rockbox-logo.svg">../../docs/logo/rockbox-logo.svg</file>
42 </qresource>
43 <qresource>
44 <file>icons/players/archosfmrecorder-small.png</file>
45 <file>icons/players/archosondiofm-small.png</file>
46 <file>icons/players/archosondiosp-small.png</file>
47 <file>icons/players/archosplayer-small.png</file>
48 <file>icons/players/archosrecorder-small.png</file>
49 <file>icons/players/archosrecorderv2-small.png</file>
50 <file>icons/players/cowond2-small.png</file>
51 <file>icons/players/gigabeatfx-small.png</file>
52 <file>icons/players/gigabeats-small.png</file>
53 <file>icons/players/gogearhdd1630-small.png</file>
54 <file>icons/players/gogearhdd6330-small.png</file>
55 <file>icons/players/gogearsa9200-small.png</file>
56 <file>icons/players/hifimanhm60x-small.png</file>
57 <file>icons/players/hifimanhm801-small.png</file>
58 <file>icons/players/iaudiom3-small.png</file>
59 <file>icons/players/iaudiom5-small.png</file>
60 <file>icons/players/iaudiox5-small.png</file>
61 <file>icons/players/ipod1g2g-small.png</file>
62 <file>icons/players/ipod3g-small.png</file>
63 <file>icons/players/ipod4g-small.png</file>
64 <file>icons/players/ipodcolor-small.png</file>
65 <file>icons/players/ipodmini1g-small.png</file>
66 <file>icons/players/ipodnano1g-small.png</file>
67 <file>icons/players/ipodnano2g-small.png</file>
68 <file>icons/players/ipodvideo-small.png</file>
69 <file>icons/players/ipod6g-small.png</file>
70 <file>icons/players/iriverh100-small.png</file>
71 <file>icons/players/iriverh10_5gb-small.png</file>
72 <file>icons/players/iriverh10-small.png</file>
73 <file>icons/players/iriverh300-small.png</file>
74 <file>icons/players/mpiohd200-small.png</file>
75 <file>icons/players/mpiohd300-small.png</file>
76 <file>icons/players/mrobe100-small.png</file>
77 <file>icons/players/mrobe500-small.png</file>
78 <file>icons/players/samsungyh820-small.png</file>
79 <file>icons/players/samsungyh920-small.png</file>
80 <file>icons/players/samsungyh925-small.png</file>
81 <file>icons/players/samsungypr0-small.png</file>
82 <file>icons/players/sansac200-small.png</file>
83 <file>icons/players/sansaclipplus-small.png</file>
84 <file>icons/players/sansaclip-small.png</file>
85 <file>icons/players/sansaclipzip-small.png</file>
86 <file>icons/players/sansaconnect-small.png</file>
87 <file>icons/players/sansae200-small.png</file>
88 <file>icons/players/sansafuzeplus-small.png</file>
89 <file>icons/players/sansafuze-small.png</file>
90 <file>icons/players/vibe500-small.png</file>
91 <file>icons/players/vx747-small.png</file>
92 <file>icons/players/vx777-small.png</file>
93 </qresource>
94 <qresource prefix="/ini">
95 <file>rbutil.ini</file>
96 </qresource>
97</RCC>
diff --git a/utils/rbutilqt/rbutilqt.rc b/utils/rbutilqt/rbutilqt.rc
new file mode 100644
index 0000000000..8ffe2b2424
--- /dev/null
+++ b/utils/rbutilqt/rbutilqt.rc
@@ -0,0 +1,34 @@
1#include <windows.h>
2#include "version.h"
31 MANIFEST MOVEABLE PURE "rbutilqt.manifest"
4RBUTIL_ICON ICON DISCARDABLE "icons/rockbox.ico"
5
6// Version Info
7
8VS_VERSION_INFO VERSIONINFO
9FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_MICRO,VERSION_PATCH
10PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_MICRO,VERSION_PATCH
11FILEFLAGSMASK 0x17L
12FILEFLAGS 0x0L
13FILEOS 0x4L
14FILETYPE 0x0L
15FILESUBTYPE 0x0L
16BEGIN
17 BLOCK "StringFileInfo"
18 BEGIN
19 BLOCK "000004b0"
20 BEGIN
21 VALUE "FileDescription", "Rockbox Utility"
22 VALUE "FileVersion", VERSIONSTRING(VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO)
23 VALUE "LegalCopyright", "Rockbox developers"
24 VALUE "ProductName", "Rockbox Utility"
25 VALUE "ProductVersion", VERSIONSTRING(VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO)
26 VALUE "OriginalFilename", "RockboxUtility.exe"
27 END
28 END
29 BLOCK "VarFileInfo"
30 BEGIN
31 VALUE "Translation", 0x0, 1200
32 END
33END
34
diff --git a/utils/rbutilqt/rbutilqtfrm.ui b/utils/rbutilqt/rbutilqtfrm.ui
new file mode 100644
index 0000000000..af47fea72c
--- /dev/null
+++ b/utils/rbutilqt/rbutilqtfrm.ui
@@ -0,0 +1,647 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>RbUtilQtFrm</class>
4 <widget class="QMainWindow" name="RbUtilQtFrm">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>650</width>
10 <height>399</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Rockbox Utility</string>
15 </property>
16 <property name="windowIcon">
17 <iconset resource="rbutilqt.qrc">
18 <normaloff>:/icons/rockbox-clef.svg</normaloff>:/icons/rockbox-clef.svg</iconset>
19 </property>
20 <widget class="QWidget" name="centralwidget">
21 <layout class="QGridLayout" name="gridLayout_3">
22 <item row="0" column="0">
23 <widget class="QLabel" name="logoLabel">
24 <property name="minimumSize">
25 <size>
26 <width>200</width>
27 <height>62</height>
28 </size>
29 </property>
30 <property name="maximumSize">
31 <size>
32 <width>200</width>
33 <height>62</height>
34 </size>
35 </property>
36 <property name="baseSize">
37 <size>
38 <width>200</width>
39 <height>62</height>
40 </size>
41 </property>
42 <property name="text">
43 <string comment="Welcome to Rockbox Utility, the installation and housekeeping tool for Rockbox."/>
44 </property>
45 <property name="pixmap">
46 <pixmap resource="rbutilqt.qrc">:/icons/rockbox-logo.svg</pixmap>
47 </property>
48 <property name="scaledContents">
49 <bool>true</bool>
50 </property>
51 <property name="alignment">
52 <set>Qt::AlignCenter</set>
53 </property>
54 </widget>
55 </item>
56 <item row="0" column="1">
57 <widget class="QGroupBox" name="groupBoxDevice">
58 <property name="sizePolicy">
59 <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
60 <horstretch>0</horstretch>
61 <verstretch>0</verstretch>
62 </sizepolicy>
63 </property>
64 <property name="title">
65 <string>Device</string>
66 </property>
67 <layout class="QGridLayout" name="gridLayout">
68 <item row="0" column="0" rowspan="3">
69 <widget class="QLabel" name="labelPlayerPic">
70 <property name="lineWidth">
71 <number>1</number>
72 </property>
73 <property name="text">
74 <string/>
75 </property>
76 <property name="pixmap">
77 <pixmap resource="rbutilqt.qrc">:/icons/rockbox-32.png</pixmap>
78 </property>
79 <property name="scaledContents">
80 <bool>false</bool>
81 </property>
82 <property name="alignment">
83 <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
84 </property>
85 <property name="margin">
86 <number>3</number>
87 </property>
88 </widget>
89 </item>
90 <item row="0" column="1">
91 <widget class="QLabel" name="labelDeviceTitle">
92 <property name="sizePolicy">
93 <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
94 <horstretch>0</horstretch>
95 <verstretch>0</verstretch>
96 </sizepolicy>
97 </property>
98 <property name="text">
99 <string>Device:</string>
100 </property>
101 </widget>
102 </item>
103 <item row="0" column="2">
104 <widget class="QLabel" name="labelDevice">
105 <property name="text">
106 <string>device unknown or invalid</string>
107 </property>
108 </widget>
109 </item>
110 <item row="0" column="3">
111 <spacer name="horizontalSpacer">
112 <property name="orientation">
113 <enum>Qt::Horizontal</enum>
114 </property>
115 <property name="sizeHint" stdset="0">
116 <size>
117 <width>40</width>
118 <height>20</height>
119 </size>
120 </property>
121 </spacer>
122 </item>
123 <item row="0" column="4">
124 <widget class="QPushButton" name="buttonChangeDevice">
125 <property name="text">
126 <string>&amp;Change</string>
127 </property>
128 <property name="icon">
129 <iconset resource="rbutilqt.qrc">
130 <normaloff>:/icons/edit-find.svg</normaloff>:/icons/edit-find.svg</iconset>
131 </property>
132 </widget>
133 </item>
134 <item row="1" column="4" rowspan="2">
135 <widget class="QPushButton" name="buttonEject">
136 <property name="text">
137 <string>&amp;Eject</string>
138 </property>
139 <property name="icon">
140 <iconset resource="rbutilqt.qrc">
141 <normaloff>:/icons/media-eject.svg</normaloff>:/icons/media-eject.svg</iconset>
142 </property>
143 </widget>
144 </item>
145 <item row="1" column="1">
146 <widget class="QLabel" name="labelMountpointTitle">
147 <property name="text">
148 <string>Mountpoint:</string>
149 </property>
150 </widget>
151 </item>
152 <item row="1" column="2">
153 <widget class="QLabel" name="labelMountpoint">
154 <property name="text">
155 <string>mountpoint unknown or invalid</string>
156 </property>
157 </widget>
158 </item>
159 </layout>
160 </widget>
161 </item>
162 <item row="1" column="0" colspan="2">
163 <widget class="QTabWidget" name="tabWidget">
164 <property name="currentIndex">
165 <number>0</number>
166 </property>
167 <widget class="QWidget" name="selective">
168 <attribute name="title">
169 <string>&amp;Installation</string>
170 </attribute>
171 <attribute name="toolTip">
172 <string>Welcome</string>
173 </attribute>
174 </widget>
175 <widget class="QWidget" name="accessibility">
176 <attribute name="title">
177 <string>&amp;Accessibility</string>
178 </attribute>
179 <attribute name="toolTip">
180 <string>Install accessibility add-ons</string>
181 </attribute>
182 <layout class="QGridLayout">
183 <item row="1" column="0">
184 <widget class="QToolButton" name="buttonTalk">
185 <property name="text">
186 <string>Install Talk files</string>
187 </property>
188 <property name="icon">
189 <iconset resource="rbutilqt.qrc">
190 <normaloff>:/icons/audio-volume-high.svg</normaloff>:/icons/audio-volume-high.svg</iconset>
191 </property>
192 <property name="iconSize">
193 <size>
194 <width>56</width>
195 <height>46</height>
196 </size>
197 </property>
198 </widget>
199 </item>
200 <item row="1" column="1">
201 <widget class="QLabel" name="labelTalk">
202 <property name="text">
203 <string>&lt;b&gt;Create Talk Files&lt;/b&gt;&lt;br/&gt;Talkfiles are needed to let Rockbox speak File and Foldernames</string>
204 </property>
205 </widget>
206 </item>
207 <item row="2" column="0">
208 <spacer>
209 <property name="orientation">
210 <enum>Qt::Vertical</enum>
211 </property>
212 <property name="sizeHint" stdset="0">
213 <size>
214 <width>20</width>
215 <height>51</height>
216 </size>
217 </property>
218 </spacer>
219 </item>
220 <item row="2" column="1">
221 <spacer>
222 <property name="orientation">
223 <enum>Qt::Vertical</enum>
224 </property>
225 <property name="sizeHint" stdset="0">
226 <size>
227 <width>20</width>
228 <height>51</height>
229 </size>
230 </property>
231 </spacer>
232 </item>
233 <item row="0" column="0">
234 <widget class="QToolButton" name="buttonCreateVoice">
235 <property name="text">
236 <string>Create Voice files</string>
237 </property>
238 <property name="icon">
239 <iconset resource="rbutilqt.qrc">
240 <normaloff>:/icons/audio-volume-high.svg</normaloff>:/icons/audio-volume-high.svg</iconset>
241 </property>
242 <property name="iconSize">
243 <size>
244 <width>56</width>
245 <height>46</height>
246 </size>
247 </property>
248 </widget>
249 </item>
250 <item row="0" column="1">
251 <widget class="QLabel" name="labelCreateVoice">
252 <property name="text">
253 <string>&lt;b&gt;Create Voice file&lt;/b&gt;&lt;br/&gt;Voice files are needed to make Rockbox speak the user interface. Speaking is enabled by default, so
254 if you installed the voice file Rockbox will speak.</string>
255 </property>
256 <property name="wordWrap">
257 <bool>true</bool>
258 </property>
259 </widget>
260 </item>
261 </layout>
262 </widget>
263 <widget class="QWidget" name="uninstall">
264 <attribute name="title">
265 <string>Backup &amp;&amp; &amp;Uninstallation</string>
266 </attribute>
267 <attribute name="toolTip">
268 <string>Uninstall Rockbox</string>
269 </attribute>
270 <layout class="QGridLayout" name="gridLayout_2">
271 <item row="0" column="0">
272 <widget class="QToolButton" name="buttonRemoveBootloader">
273 <property name="text">
274 <string>Uninstall Bootloader</string>
275 </property>
276 <property name="icon">
277 <iconset resource="rbutilqt.qrc">
278 <normaloff>:/icons/edit-clear.svg</normaloff>:/icons/edit-clear.svg</iconset>
279 </property>
280 <property name="iconSize">
281 <size>
282 <width>56</width>
283 <height>46</height>
284 </size>
285 </property>
286 </widget>
287 </item>
288 <item row="0" column="1">
289 <widget class="QLabel" name="labelRemoveBootloader">
290 <property name="text">
291 <string>&lt;b&gt;Remove the bootloader&lt;/b&gt;&lt;br/&gt;After removing the bootloader you won't be able to start Rockbox.</string>
292 </property>
293 <property name="wordWrap">
294 <bool>true</bool>
295 </property>
296 </widget>
297 </item>
298 <item row="1" column="0">
299 <widget class="QToolButton" name="buttonRemoveRockbox">
300 <property name="text">
301 <string>Uninstall Rockbox</string>
302 </property>
303 <property name="icon">
304 <iconset resource="rbutilqt.qrc">
305 <normaloff>:/icons/edit-clear.svg</normaloff>:/icons/edit-clear.svg</iconset>
306 </property>
307 <property name="iconSize">
308 <size>
309 <width>56</width>
310 <height>46</height>
311 </size>
312 </property>
313 </widget>
314 </item>
315 <item row="1" column="1">
316 <widget class="QLabel" name="labelUninstall">
317 <property name="text">
318 <string>&lt;b&gt;Uninstall Rockbox from your audio player.&lt;/b&gt;&lt;br/&gt;This will leave the bootloader in place (you need to remove it manually).</string>
319 </property>
320 <property name="alignment">
321 <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
322 </property>
323 <property name="wordWrap">
324 <bool>true</bool>
325 </property>
326 </widget>
327 </item>
328 <item row="2" column="0">
329 <widget class="QToolButton" name="buttonBackup">
330 <property name="text">
331 <string>Backup</string>
332 </property>
333 <property name="icon">
334 <iconset resource="rbutilqt.qrc">
335 <normaloff>:/icons/package-x-generic.svg</normaloff>:/icons/package-x-generic.svg</iconset>
336 </property>
337 <property name="iconSize">
338 <size>
339 <width>56</width>
340 <height>46</height>
341 </size>
342 </property>
343 </widget>
344 </item>
345 <item row="2" column="1">
346 <widget class="QLabel" name="labelBackup">
347 <property name="text">
348 <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Backup current installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Create a backup by archiving the contents of the Rockbox installation folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
349 </property>
350 <property name="alignment">
351 <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
352 </property>
353 <property name="wordWrap">
354 <bool>true</bool>
355 </property>
356 </widget>
357 </item>
358 <item row="3" column="0">
359 <spacer>
360 <property name="orientation">
361 <enum>Qt::Vertical</enum>
362 </property>
363 <property name="sizeHint" stdset="0">
364 <size>
365 <width>20</width>
366 <height>40</height>
367 </size>
368 </property>
369 </spacer>
370 </item>
371 </layout>
372 </widget>
373 <widget class="QWidget" name="info">
374 <attribute name="title">
375 <string>Inf&amp;o</string>
376 </attribute>
377 </widget>
378 </widget>
379 </item>
380 </layout>
381 </widget>
382 <widget class="QMenuBar" name="menubar">
383 <property name="geometry">
384 <rect>
385 <x>0</x>
386 <y>0</y>
387 <width>650</width>
388 <height>22</height>
389 </rect>
390 </property>
391 <widget class="QMenu" name="menu_File">
392 <property name="title">
393 <string>&amp;File</string>
394 </property>
395 <addaction name="actionInstall_Rockbox_Utility_on_player"/>
396 <addaction name="action_Configure"/>
397 <addaction name="separator"/>
398 <addaction name="actionE_xit"/>
399 </widget>
400 <widget class="QMenu" name="menuAbout">
401 <property name="title">
402 <string>&amp;Help</string>
403 </property>
404 <addaction name="action_About"/>
405 <addaction name="actionAbout_Qt"/>
406 <addaction name="separator"/>
407 <addaction name="actionShow_Changelog"/>
408 <addaction name="action_System_Info"/>
409 <addaction name="action_Trace"/>
410 <addaction name="separator"/>
411 <addaction name="action_Help"/>
412 </widget>
413 <widget class="QMenu" name="menuA_ctions">
414 <property name="title">
415 <string>Action&amp;s</string>
416 </property>
417 <widget class="QMenu" name="menuAccessibility">
418 <property name="title">
419 <string>&amp;Accessibility</string>
420 </property>
421 <addaction name="actionCreate_Voice_File"/>
422 <addaction name="actionCreate_Talk_Files"/>
423 </widget>
424 <widget class="QMenu" name="menuUninstallation">
425 <property name="title">
426 <string>&amp;Uninstallation</string>
427 </property>
428 <addaction name="actionRemove_bootloader"/>
429 <addaction name="actionUninstall_Rockbox"/>
430 </widget>
431 <addaction name="action_Installation"/>
432 <addaction name="menuAccessibility"/>
433 <addaction name="menuUninstallation"/>
434 </widget>
435 <addaction name="menu_File"/>
436 <addaction name="menuA_ctions"/>
437 <addaction name="menuAbout"/>
438 </widget>
439 <widget class="QStatusBar" name="statusbar"/>
440 <action name="actionEmpty_local_download_cache">
441 <property name="text">
442 <string>Empty local download cache</string>
443 </property>
444 </action>
445 <action name="actionInstall_Rockbox_Utility_on_player">
446 <property name="text">
447 <string>Install Rockbox Utility on player</string>
448 </property>
449 </action>
450 <action name="action_Configure">
451 <property name="text">
452 <string>&amp;Configure</string>
453 </property>
454 </action>
455 <action name="actionE_xit">
456 <property name="text">
457 <string>E&amp;xit</string>
458 </property>
459 <property name="shortcut">
460 <string>Ctrl+Q</string>
461 </property>
462 </action>
463 <action name="action_About">
464 <property name="text">
465 <string>&amp;About</string>
466 </property>
467 </action>
468 <action name="actionAbout_Qt">
469 <property name="text">
470 <string>About &amp;Qt</string>
471 </property>
472 </action>
473 <action name="action_Help">
474 <property name="text">
475 <string>&amp;Help</string>
476 </property>
477 </action>
478 <action name="actionInfo">
479 <property name="text">
480 <string>Info</string>
481 </property>
482 </action>
483 <action name="actionComplete_Installation">
484 <property name="icon">
485 <iconset>
486 <normaloff>:/icons/bootloader_btn.png</normaloff>:/icons/bootloader_btn.png</iconset>
487 </property>
488 <property name="text">
489 <string>&amp;Complete Installation</string>
490 </property>
491 </action>
492 <action name="actionSmall_Installation">
493 <property name="icon">
494 <iconset>
495 <normaloff>:/icons/rbinstall_btn.png</normaloff>:/icons/rbinstall_btn.png</iconset>
496 </property>
497 <property name="text">
498 <string>&amp;Minimal Installation</string>
499 </property>
500 </action>
501 <action name="actionInstall_Bootloader">
502 <property name="icon">
503 <iconset>
504 <normaloff>:/icons/bootloader_btn.png</normaloff>:/icons/bootloader_btn.png</iconset>
505 </property>
506 <property name="text">
507 <string>Install &amp;Bootloader</string>
508 </property>
509 </action>
510 <action name="actionInstall_Rockbox">
511 <property name="icon">
512 <iconset>
513 <normaloff>:/icons/rbinstall_btn.png</normaloff>:/icons/rbinstall_btn.png</iconset>
514 </property>
515 <property name="text">
516 <string>Install &amp;Rockbox</string>
517 </property>
518 </action>
519 <action name="actionFonts_Package">
520 <property name="icon">
521 <iconset>
522 <normaloff>:/icons/font_btn.png</normaloff>:/icons/font_btn.png</iconset>
523 </property>
524 <property name="text">
525 <string>Install &amp;Fonts Package</string>
526 </property>
527 </action>
528 <action name="actionInstall_Themes">
529 <property name="icon">
530 <iconset resource="rbutilqt.qrc">
531 <normaloff>:/icons/preferences-desktop-theme.svg</normaloff>:/icons/preferences-desktop-theme.svg</iconset>
532 </property>
533 <property name="text">
534 <string>Install &amp;Themes</string>
535 </property>
536 </action>
537 <action name="actionInstall_Game_Files">
538 <property name="icon">
539 <iconset resource="rbutilqt.qrc">
540 <normaloff>:/icons/input-gaming.svg</normaloff>:/icons/input-gaming.svg</iconset>
541 </property>
542 <property name="text">
543 <string>Install &amp;Game Files</string>
544 </property>
545 </action>
546 <action name="actionInstall_Voice_File">
547 <property name="icon">
548 <iconset resource="rbutilqt.qrc">
549 <normaloff>:/icons/audio-volume-high.svg</normaloff>:/icons/audio-volume-high.svg</iconset>
550 </property>
551 <property name="text">
552 <string>&amp;Install Voice File</string>
553 </property>
554 </action>
555 <action name="actionCreate_Talk_Files">
556 <property name="icon">
557 <iconset resource="rbutilqt.qrc">
558 <normaloff>:/icons/audio-volume-high.svg</normaloff>:/icons/audio-volume-high.svg</iconset>
559 </property>
560 <property name="text">
561 <string>Create &amp;Talk Files</string>
562 </property>
563 </action>
564 <action name="actionRemove_bootloader">
565 <property name="icon">
566 <iconset resource="rbutilqt.qrc">
567 <normaloff>:/icons/edit-clear.svg</normaloff>:/icons/edit-clear.svg</iconset>
568 </property>
569 <property name="text">
570 <string>Remove &amp;bootloader</string>
571 </property>
572 </action>
573 <action name="actionUninstall_Rockbox">
574 <property name="icon">
575 <iconset resource="rbutilqt.qrc">
576 <normaloff>:/icons/edit-clear.svg</normaloff>:/icons/edit-clear.svg</iconset>
577 </property>
578 <property name="text">
579 <string>Uninstall &amp;Rockbox</string>
580 </property>
581 </action>
582 <action name="actionRead_PDF_manual">
583 <property name="text">
584 <string>Read PDF manual</string>
585 </property>
586 </action>
587 <action name="actionRead_HTML_manual">
588 <property name="text">
589 <string>Read HTML manual</string>
590 </property>
591 </action>
592 <action name="actionDownload_PDF_manual">
593 <property name="text">
594 <string>Download PDF manual</string>
595 </property>
596 </action>
597 <action name="actionDownload_HTML_manual_zip">
598 <property name="text">
599 <string>Download HTML manual (zip)</string>
600 </property>
601 </action>
602 <action name="actionCreate_Voice_File">
603 <property name="icon">
604 <iconset resource="rbutilqt.qrc">
605 <normaloff>:/icons/audio-volume-high.svg</normaloff>:/icons/audio-volume-high.svg</iconset>
606 </property>
607 <property name="text">
608 <string>Create &amp;Voice File</string>
609 </property>
610 <property name="iconText">
611 <string>Create Voice File</string>
612 </property>
613 </action>
614 <action name="action_System_Info">
615 <property name="text">
616 <string>&amp;System Info</string>
617 </property>
618 </action>
619 <action name="action_Trace">
620 <property name="text">
621 <string>System &amp;Trace</string>
622 </property>
623 </action>
624 <action name="action_Installation">
625 <property name="text">
626 <string>&amp;Installation</string>
627 </property>
628 </action>
629 <action name="actionShow_Changelog">
630 <property name="text">
631 <string>Show &amp;Changelog</string>
632 </property>
633 </action>
634 </widget>
635 <tabstops>
636 <tabstop>tabWidget</tabstop>
637 <tabstop>buttonChangeDevice</tabstop>
638 <tabstop>buttonRemoveBootloader</tabstop>
639 <tabstop>buttonRemoveRockbox</tabstop>
640 <tabstop>buttonCreateVoice</tabstop>
641 <tabstop>buttonTalk</tabstop>
642 </tabstops>
643 <resources>
644 <include location="rbutilqt.qrc"/>
645 </resources>
646 <connections/>
647</ui>
diff --git a/utils/rbutilqt/sysinfo.cpp b/utils/rbutilqt/sysinfo.cpp
new file mode 100644
index 0000000000..7d05bb8c9a
--- /dev/null
+++ b/utils/rbutilqt/sysinfo.cpp
@@ -0,0 +1,95 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QDialog>
20#include <QDir>
21#include "sysinfo.h"
22#include "ui_sysinfofrm.h"
23#include "system.h"
24#include "utils.h"
25#include "autodetection.h"
26
27
28Sysinfo::Sysinfo(QWidget *parent) : QDialog(parent)
29{
30 ui.setupUi(this);
31
32 updateSysinfo();
33 connect(ui.buttonOk, &QAbstractButton::clicked, this, &Sysinfo::close);
34 connect(ui.buttonRefresh, &QAbstractButton::clicked, this, &Sysinfo::updateSysinfo);
35}
36
37void Sysinfo::updateSysinfo(void)
38{
39 ui.textBrowser->setHtml(getInfo());
40}
41
42QString Sysinfo::getInfo(Sysinfo::InfoType type)
43{
44 QString info;
45 info += tr("<b>OS</b><br/>") + System::osVersionString() + "<hr/>";
46 info += tr("<b>Username</b><br/>%1<hr/>").arg(System::userName());
47#if defined(Q_OS_WIN32)
48 info += tr("<b>Permissions</b><br/>%1<hr/>").arg(System::userPermissionsString());
49#endif
50 info += tr("<b>Attached USB devices</b><br/>");
51 QMultiMap<uint32_t, QString> usbids = System::listUsbDevices();
52 QList<uint32_t> usbkeys = usbids.keys();
53 for(int i = 0; i < usbkeys.size(); i++) {
54 info += tr("VID: %1 PID: %2, %3")
55 .arg((usbkeys.at(i)&0xffff0000)>>16, 4, 16, QChar('0'))
56 .arg(usbkeys.at(i)&0xffff, 4, 16, QChar('0'))
57 .arg(usbids.value(usbkeys.at(i)));
58 if(i + 1 < usbkeys.size())
59 info += "<br/>";
60 }
61 info += "<hr/>";
62
63 info += "<b>" + tr("Filesystem") + "</b>";
64 QStringList drives = Utils::mountpoints();
65 info += "<table>";
66 info += "<tr><td>" + tr("Mountpoint") + "</td><td>" + tr("Label")
67 + "</td><td>" + tr("Free") + "</td><td>" + tr("Total") + "</td><td>"
68 + tr("Type") + "</td><td></tr>";
69 for(int i = 0; i < drives.size(); i++) {
70 info += tr("<tr><td>%1</td><td>%4</td><td>%2 GiB</td><td>%3 GiB</td><td>%5</td></tr>")
71 .arg(QDir::toNativeSeparators(drives.at(i)))
72 .arg((double)Utils::filesystemFree(drives.at(i)) / (1<<30), 0, 'f', 2)
73 .arg((double)Utils::filesystemTotal(drives.at(i)) / (1<<30), 0, 'f', 2)
74 .arg(Utils::filesystemName(drives.at(i)))
75 .arg(Utils::filesystemType(drives.at(i)));
76 }
77 info += "</table>";
78 info += "<hr/>";
79 if(type == InfoText) {
80 info.replace(QRegExp("(<[^>]+>)+"),"\n");
81 }
82
83 return info;
84}
85
86
87void Sysinfo::changeEvent(QEvent *e)
88{
89 if(e->type() == QEvent::LanguageChange) {
90 ui.retranslateUi(this);
91 } else {
92 QWidget::changeEvent(e);
93 }
94}
95
diff --git a/utils/rbutilqt/sysinfo.h b/utils/rbutilqt/sysinfo.h
new file mode 100644
index 0000000000..3211151bf0
--- /dev/null
+++ b/utils/rbutilqt/sysinfo.h
@@ -0,0 +1,50 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Riebeling
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#ifndef SYSINFO_H
22#define SYSINFO_H
23
24#include <QDialog>
25#include <QWidget>
26#include "ui_sysinfofrm.h"
27
28class Sysinfo : public QDialog
29{
30 Q_OBJECT
31
32 public:
33 enum InfoType {
34 InfoHtml,
35 InfoText,
36 };
37 Sysinfo(QWidget *parent = nullptr);
38
39 static QString getInfo(InfoType type = InfoHtml);
40 private:
41 void changeEvent(QEvent *event);
42 Ui::SysinfoFrm ui;
43
44 private slots:
45 void updateSysinfo(void);
46
47};
48
49#endif
50
diff --git a/utils/rbutilqt/sysinfofrm.ui b/utils/rbutilqt/sysinfofrm.ui
new file mode 100644
index 0000000000..82fb5daa22
--- /dev/null
+++ b/utils/rbutilqt/sysinfofrm.ui
@@ -0,0 +1,68 @@
1<ui version="4.0" >
2 <class>SysinfoFrm</class>
3 <widget class="QWidget" name="SysinfoFrm" >
4 <property name="geometry" >
5 <rect>
6 <x>0</x>
7 <y>0</y>
8 <width>600</width>
9 <height>400</height>
10 </rect>
11 </property>
12 <property name="windowTitle" >
13 <string>System Info</string>
14 </property>
15 <layout class="QGridLayout" >
16 <item row="0" column="0" colspan="3" >
17 <widget class="QTextBrowser" name="textBrowser" />
18 </item>
19 <item row="1" column="0" >
20 <widget class="QPushButton" name="buttonRefresh" >
21 <property name="text" >
22 <string>&amp;Refresh</string>
23 </property>
24 <property name="icon" >
25 <iconset resource="rbutilqt.qrc" >
26 <normaloff>:/icons/view-refresh.svg</normaloff>:/icons/view-refresh.svg</iconset>
27 </property>
28 </widget>
29 </item>
30 <item row="1" column="1" >
31 <spacer>
32 <property name="orientation" >
33 <enum>Qt::Horizontal</enum>
34 </property>
35 <property name="sizeHint" >
36 <size>
37 <width>40</width>
38 <height>20</height>
39 </size>
40 </property>
41 </spacer>
42 </item>
43 <item row="1" column="2" >
44 <widget class="QPushButton" name="buttonOk" >
45 <property name="text" >
46 <string>&amp;OK</string>
47 </property>
48 <property name="icon" >
49 <iconset resource="rbutilqt.qrc" >
50 <normaloff>:/icons/go-next.svg</normaloff>:/icons/go-next.svg</iconset>
51 </property>
52 <property name="default" >
53 <bool>true</bool>
54 </property>
55 </widget>
56 </item>
57 </layout>
58 </widget>
59 <tabstops>
60 <tabstop>buttonOk</tabstop>
61 <tabstop>buttonRefresh</tabstop>
62 <tabstop>textBrowser</tabstop>
63 </tabstops>
64 <resources>
65 <include location="rbutilqt.qrc" />
66 </resources>
67 <connections/>
68</ui>
diff --git a/utils/rbutilqt/systrace.cpp b/utils/rbutilqt/systrace.cpp
new file mode 100644
index 0000000000..a20056b508
--- /dev/null
+++ b/utils/rbutilqt/systrace.cpp
@@ -0,0 +1,138 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QFileDialog>
20#include <QScrollBar>
21#include "systrace.h"
22#include "ui_systracefrm.h"
23
24#include "rbsettings.h"
25#include "Logger.h"
26
27
28SysTrace::SysTrace(QWidget *parent) : QDialog(parent)
29{
30 ui.setupUi(this);
31 ui.textTrace->setReadOnly(true);
32 ui.textTrace->setLayoutDirection(Qt::LeftToRight);
33 refresh();
34
35 connect(ui.buttonClose, &QAbstractButton::clicked, this, &SysTrace::close);
36 connect(ui.buttonSave, &QAbstractButton::clicked, this, &SysTrace::saveCurrentTrace);
37 connect(ui.buttonSavePrevious, &QAbstractButton::clicked, this, &SysTrace::savePreviousTrace);
38 connect(ui.buttonRefresh, &QAbstractButton::clicked, this, &SysTrace::refresh);
39}
40
41void SysTrace::refresh(void)
42{
43 int pos = ui.textTrace->verticalScrollBar()->value();
44
45 QString debugbuffer;
46 QFile tracefile(QDir::tempPath() + "/rbutil-trace.log");
47 tracefile.open(QIODevice::ReadOnly);
48 QTextStream c(&tracefile);
49 QString line;
50 QString color;
51 while(!c.atEnd()) {
52 line = c.readLine();
53 if(line.contains("Warning"))
54 color = "orange";
55 else if(line.contains("Error"))
56 color = "red";
57 else if(line.contains("Debug"))
58 color = "blue";
59#if 0
60 else if(line.contains("INFO"))
61 color = "green";
62#endif
63 else
64 color = "black";
65 debugbuffer += QString("<div style='color:%1;'>%2</div>").arg(color, line);
66 }
67 tracefile.close();
68 ui.textTrace->setHtml("<pre>" + debugbuffer + "</pre>");
69 ui.textTrace->verticalScrollBar()->setValue(pos);
70 QString oldlog = RbSettings::value(RbSettings::CachePath).toString()
71 + "/rbutil-trace.log";
72 ui.buttonSavePrevious->setEnabled(QFileInfo(oldlog).isFile());
73}
74
75
76QString SysTrace::getTrace(void)
77{
78 QString debugbuffer;
79 QFile tracefile(QDir::tempPath() + "/rbutil-trace.log");
80 tracefile.open(QIODevice::ReadOnly);
81 QTextStream c(&tracefile);
82 debugbuffer = c.readAll();
83 tracefile.close();
84
85 return debugbuffer;
86}
87
88
89void SysTrace::save(QString filename)
90{
91 if(filename.isEmpty())
92 return;
93 LOG_INFO() << "saving trace at" << QDateTime::currentDateTime().toString(Qt::ISODate);
94 QFile::copy(QDir::tempPath() + "/rbutil-trace.log", filename);
95
96}
97
98void SysTrace::saveCurrentTrace(void)
99{
100 QString fp = QFileDialog::getSaveFileName(this, tr("Save system trace log"),
101 QDir::homePath(), "*.log");
102 if(!fp.isEmpty())
103 save(fp);
104}
105
106
107void SysTrace::savePreviousTrace(void)
108{
109 QString fp = QFileDialog::getSaveFileName(this, tr("Save system trace log"),
110 QDir::homePath(), "*.log");
111 if(fp.isEmpty())
112 return;
113
114 QString oldlog = QDir::tempPath() + "/rbutil-trace.log.1";
115 QFile::copy(oldlog, fp);
116 return;
117}
118
119
120void SysTrace::rotateTrace(void)
121{
122 QString f = QDir::tempPath() + "/rbutil-trace.log.1";
123 if(QFileInfo::exists(f)) {
124 QFile::remove(f);
125 }
126 QFile::rename(QDir::tempPath() + "/rbutil-trace.log", f);
127}
128
129
130void SysTrace::changeEvent(QEvent *e)
131{
132 if(e->type() == QEvent::LanguageChange) {
133 ui.retranslateUi(this);
134 } else {
135 QWidget::changeEvent(e);
136 }
137}
138
diff --git a/utils/rbutilqt/systrace.h b/utils/rbutilqt/systrace.h
new file mode 100644
index 0000000000..b0a6f70fa6
--- /dev/null
+++ b/utils/rbutilqt/systrace.h
@@ -0,0 +1,47 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Riebeling
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#ifndef SYSTRACE_H
22#define SYSTRACE_H
23
24#include <QDialog>
25#include "ui_systracefrm.h"
26
27class SysTrace : public QDialog
28{
29 Q_OBJECT
30 public:
31 SysTrace(QWidget *parent);
32 static QString getTrace(void);
33 static void save(QString filename = "");
34 static void rotateTrace(void);
35 private:
36 void changeEvent(QEvent *event);
37 Ui::SysTraceFrm ui;
38
39 private slots:
40 void saveCurrentTrace(void);
41 void savePreviousTrace(void);
42 void refresh(void);
43
44};
45
46#endif
47
diff --git a/utils/rbutilqt/systracefrm.ui b/utils/rbutilqt/systracefrm.ui
new file mode 100644
index 0000000000..6452c852ff
--- /dev/null
+++ b/utils/rbutilqt/systracefrm.ui
@@ -0,0 +1,93 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>SysTraceFrm</class>
4 <widget class="QDialog" name="SysTraceFrm">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>600</width>
10 <height>550</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>System Trace</string>
15 </property>
16 <layout class="QGridLayout" name="gridLayout">
17 <item row="0" column="0" colspan="6">
18 <widget class="QLabel" name="label">
19 <property name="text">
20 <string>System State trace</string>
21 </property>
22 <property name="wordWrap">
23 <bool>true</bool>
24 </property>
25 </widget>
26 </item>
27 <item row="1" column="0" colspan="6">
28 <widget class="QTextEdit" name="textTrace"/>
29 </item>
30 <item row="2" column="1" colspan="2">
31 <spacer name="horizontalSpacer">
32 <property name="orientation">
33 <enum>Qt::Horizontal</enum>
34 </property>
35 <property name="sizeHint" stdset="0">
36 <size>
37 <width>487</width>
38 <height>26</height>
39 </size>
40 </property>
41 </spacer>
42 </item>
43 <item row="2" column="5">
44 <widget class="QPushButton" name="buttonClose">
45 <property name="text">
46 <string>&amp;Close</string>
47 </property>
48 <property name="icon">
49 <iconset resource="rbutilqt.qrc">
50 <normaloff>:/icons/process-stop.svg</normaloff>:/icons/process-stop.svg</iconset>
51 </property>
52 </widget>
53 </item>
54 <item row="2" column="4">
55 <widget class="QPushButton" name="buttonSave">
56 <property name="text">
57 <string>&amp;Save</string>
58 </property>
59 <property name="icon">
60 <iconset resource="rbutilqt.qrc">
61 <normaloff>:/icons/document-save.svg</normaloff>:/icons/document-save.svg</iconset>
62 </property>
63 </widget>
64 </item>
65 <item row="2" column="0">
66 <widget class="QPushButton" name="buttonRefresh">
67 <property name="text">
68 <string>&amp;Refresh</string>
69 </property>
70 <property name="icon">
71 <iconset resource="rbutilqt.qrc">
72 <normaloff>:/icons/view-refresh.svg</normaloff>:/icons/view-refresh.svg</iconset>
73 </property>
74 </widget>
75 </item>
76 <item row="2" column="3">
77 <widget class="QPushButton" name="buttonSavePrevious">
78 <property name="text">
79 <string>Save &amp;previous</string>
80 </property>
81 <property name="icon">
82 <iconset resource="rbutilqt.qrc">
83 <normaloff>:/icons/document-save.svg</normaloff>:/icons/document-save.svg</iconset>
84 </property>
85 </widget>
86 </item>
87 </layout>
88 </widget>
89 <resources>
90 <include location="rbutilqt.qrc"/>
91 </resources>
92 <connections/>
93</ui>
diff --git a/utils/rbutilqt/test/stubs/Logger.h b/utils/rbutilqt/test/stubs/Logger.h
new file mode 100644
index 0000000000..6640646b24
--- /dev/null
+++ b/utils/rbutilqt/test/stubs/Logger.h
@@ -0,0 +1,11 @@
1#ifndef LOGGER_H
2#define LOGGER_H
3
4#include <QtDebug>
5
6#define LOG_INFO qDebug
7#define LOG_WARNING qWarning
8#define LOG_ERROR qCritical
9
10#endif
11
diff --git a/utils/rbutilqt/test/stubs/stubs-compareversion.cpp b/utils/rbutilqt/test/stubs/stubs-compareversion.cpp
new file mode 100644
index 0000000000..07e2d18f19
--- /dev/null
+++ b/utils/rbutilqt/test/stubs/stubs-compareversion.cpp
@@ -0,0 +1,31 @@
1
2#include "playerbuildinfo.h"
3#include "rbsettings.h"
4#include "rockboxinfo.h"
5
6// not used by the test, just to make things compile.
7QVariant RbSettings::value(RbSettings::UserSettings setting)
8{
9 (void)setting;
10 return QVariant();
11}
12
13
14// not used in the test. If used the test will crash!
15PlayerBuildInfo* PlayerBuildInfo::instance()
16{
17 return nullptr;
18}
19
20QVariant PlayerBuildInfo::value(PlayerBuildInfo::DeviceInfo item, QString target)
21{
22 (void)item;
23 (void)target;
24 return QVariant();
25}
26
27RockboxInfo::RockboxInfo(QString, QString)
28{
29}
30
31
diff --git a/utils/rbutilqt/test/stubs/stubs-playerbuildinfo.cpp b/utils/rbutilqt/test/stubs/stubs-playerbuildinfo.cpp
new file mode 100644
index 0000000000..8856645e89
--- /dev/null
+++ b/utils/rbutilqt/test/stubs/stubs-playerbuildinfo.cpp
@@ -0,0 +1,36 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2020 Dominik Riebeling
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21// Stubs for PlayerBuildInfo unit test.
22
23#include "rbsettings.h"
24
25static QMap<RbSettings::UserSettings, QVariant> stubUserSettings;
26
27void RbSettings::setValue(UserSettings setting, QVariant value)
28{
29 stubUserSettings[setting] = value;
30}
31
32QVariant RbSettings::value(UserSettings setting)
33{
34 return stubUserSettings[setting];
35}
36
diff --git a/utils/rbutilqt/test/test-compareversion.cpp b/utils/rbutilqt/test/test-compareversion.cpp
new file mode 100644
index 0000000000..94d7697646
--- /dev/null
+++ b/utils/rbutilqt/test/test-compareversion.cpp
@@ -0,0 +1,145 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2010 Dominik Riebeling
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include <QtTest/QtTest>
22#include <QObject>
23#include "utils.h"
24
25
26class TestVersionCompare : public QObject
27{
28 Q_OBJECT
29 private slots:
30 void testCompare();
31 void testCompare_data();
32 void testTrim();
33 void testTrim_data();
34};
35
36
37struct {
38 const char* first;
39 const char* second;
40 const int expected;
41} const compdata[] =
42{
43 { "1.2.3", "1.2.3 ", 0 },
44 { "1.2.3", " 1.2.3", 0 },
45 { "1.2.3", "1.2.4", 1 },
46 { "1.2.3", "1.3.0", 1 },
47 { "1.2.3", "2.0.0", 1 },
48 { "10.22.33", "10.22.33", 0 },
49 { "10.22.33", "10.23.0", 1 },
50 { "10.22.33", "11.0.0", 1 },
51 { "1.2.3", "1.2.3.1", 1 },
52 { "1.2.3", "1.2.3-1", 1 },
53 { "1.2.3-1", "1.2.3.1", 1 },
54 { "1.2.3-10", "1.2.3.0", 1 },
55 { "1.2.3-1", "1.2.3.10", 1 },
56 { "1.2.3-1", "1.2.3a", 1 },
57 { "1.2.3", "1.2.3a", 1 },
58 { "1.2.3a", "1.2.3b", 1 },
59 { "1.2.3", "1.2.3b", 1 },
60 { "1.2.3.0", "2.0.0", 1 },
61 { "1.2.3b", "2.0.0", 1 },
62 { "1.2.3", "2.0.0.1", 1 },
63 { "test-1.2.3", "test-1.2.3.tar.gz", 0 },
64 { "1.2.3", "test-1.2.3.tar.bz2", 0 },
65 { "test-1.2.3.tar.gz", "test-1.2.3.tar.bz2", 0 },
66 { "test-1.2.3.tar.gz", "program-1.2.3.1.tar.bz2", 1 },
67 { "program-1.2.3.zip", "program-1.2.3a.zip", 1 },
68 { "program-1.2.3.tar.bz2", "2.0.0", 1 },
69 { "prog-1.2-64bit.tar.bz2", "prog-1.2.3.tar.bz2", 1 },
70 { "prog-1.2-64bit.tar.bz2", "prog-1.2-64bit.tar.bz2", 0 },
71 { "prog-1.2-64bit.tar.bz2", "prog-1.2.3-64bit.tar.bz2", 1 },
72 { "prog-1.2a-64bit.tar.bz2","prog-1.2b-64bit.tar.bz2", 1 },
73 { "prog-1.2-64bit.tar.bz2", "prog-1.2.3a-64bit.tar.bz2", 1 },
74 { "prog-1.2a-64bit.tar.bz2","prog-1.2.3-64bit.tar.bz2", 1 },
75};
76
77struct {
78 const char* input;
79 const QString expected;
80} const trimdata[] =
81{
82 { "prog-1.2-64bit.tar.bz2", "1.2" },
83 { "prog-1.2.tar.bz2", "1.2" },
84 { "1.2.3", "1.2.3" },
85 { " 1.2.3", "1.2.3" },
86 { "1.2.3 ", "1.2.3" },
87 { "10.22.33", "10.22.33" },
88 { "test-1.2.3", "1.2.3" },
89 { "1.2.3", "1.2.3" },
90 { "test-1.2.3.tar.gz", "1.2.3" },
91 { "prog-1.2-64bit.tar.bz2", "1.2" },
92 { "prog-1.2a.tar.bz2", "1.2a" },
93 { "prog-1.2a-64bit.tar.bz2","1.2a" },
94};
95
96
97void TestVersionCompare::testCompare_data()
98{
99 QTest::addColumn<QString>("first");
100 QTest::addColumn<QString>("second");
101 QTest::addColumn<int>("expected");
102 for(size_t i = 0; i < sizeof(compdata) / sizeof(compdata[0]); i++) {
103 QTest::newRow("") << compdata[i].first << compdata[i].second << compdata[i].expected;
104 }
105}
106
107
108void TestVersionCompare::testCompare()
109{
110 QFETCH(QString, first);
111 QFETCH(QString, second);
112 QFETCH(int, expected);
113
114 QCOMPARE(Utils::compareVersionStrings(first, second), expected);
115 if(expected != 0) {
116 QCOMPARE(Utils::compareVersionStrings(second, first), -expected);
117 }
118}
119
120
121void TestVersionCompare::testTrim_data()
122{
123 QTest::addColumn<QString>("input");
124 QTest::addColumn<QString>("expected");
125 for(size_t i = 0; i < sizeof(trimdata) / sizeof(trimdata[0]); i++) {
126 QTest::newRow("") << trimdata[i].input << trimdata[i].expected;
127 }
128}
129
130
131void TestVersionCompare::testTrim()
132{
133 QFETCH(QString, input);
134 QFETCH(QString, expected);
135
136 QCOMPARE(Utils::trimVersionString(input), expected);
137}
138
139
140QTEST_MAIN(TestVersionCompare)
141
142// this include is needed because we don't use a separate header file for the
143// test class. It also needs to be at the end.
144#include "test-compareversion.moc"
145
diff --git a/utils/rbutilqt/test/test-compareversion.pro b/utils/rbutilqt/test/test-compareversion.pro
new file mode 100644
index 0000000000..c8e5a899ac
--- /dev/null
+++ b/utils/rbutilqt/test/test-compareversion.pro
@@ -0,0 +1,37 @@
1#
2# __________ __ ___.
3# Open \______ \ ____ ____ | | _\_ |__ _______ ___
4# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7# \/ \/ \/ \/ \/
8# $Id$
9#
10# All files in this archive are subject to the GNU General Public License.
11# See the file COPYING in the source tree root for full license agreement.
12#
13# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
14# KIND, either express or implied.
15#
16
17# Test: Utils::compareVersionStrings().
18#
19
20QT += testlib
21
22TEMPLATE = app
23TARGET = test-compareversion
24INCLUDEPATH += . ../base stubs
25
26# Input
27SOURCES += \
28 test-compareversion.cpp \
29 stubs/stubs-compareversion.cpp \
30 ../base/utils.cpp
31
32HEADERS += \
33 ../base/rbsettings.h \
34 ../base/playerbuildinfo.h \
35 ../base/rockboxinfo.h \
36 ../base/utils.h
37
diff --git a/utils/rbutilqt/test/test-httpget.cpp b/utils/rbutilqt/test/test-httpget.cpp
new file mode 100644
index 0000000000..144adc62df
--- /dev/null
+++ b/utils/rbutilqt/test/test-httpget.cpp
@@ -0,0 +1,547 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2013 Dominik Riebeling
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include <QtTest/QtTest>
22#include <QtCore/QObject>
23#include "httpget.h"
24
25#define TEST_USER_AGENT "TestAgent/2.3"
26#define TEST_HTTP_TIMEOUT 1000
27#define TEST_BINARY_BLOB "\x01\x10\x20\x30\x40\x50\x60\x70" \
28 "\x80\x90\xff\xee\xdd\xcc\xbb\xaa"
29
30 // HttpDaemon is the the class that implements the simple HTTP server.
31 class HttpDaemon : public QTcpServer
32{
33 Q_OBJECT
34 public:
35 HttpDaemon(quint16 port = 0, QObject* parent = 0) : QTcpServer(parent)
36 {
37 listen(QHostAddress::Any, port);
38 }
39
40 quint16 port(void) { return this->serverPort(); }
41
42#if QT_VERSION < 0x050000
43 void incomingConnection(int socket)
44#else
45 // Qt 5 uses a different prototype for this function!
46 void incomingConnection(qintptr socket)
47#endif
48 {
49 // When a new client connects, the server constructs a QTcpSocket and all
50 // communication with the client is done over this QTcpSocket. QTcpSocket
51 // works asynchronously, this means that all the communication is done
52 // in the two slots readClient() and discardClient().
53 QTcpSocket* s = new QTcpSocket(this);
54 connect(s, SIGNAL(readyRead()), this, SLOT(readClient()));
55 connect(s, SIGNAL(disconnected()), this, SLOT(discardClient()));
56 s->setSocketDescriptor(socket);
57 }
58 QList<QString> lastRequestData(void)
59 {
60 return m_lastRequestData;
61 }
62 void setResponsesToSend(QList<QByteArray> response)
63 {
64 m_requestNumber = 0;
65 m_responsesToSend = response;
66 }
67 void reset(void)
68 {
69 m_requestNumber = 0;
70 m_lastRequestData.clear();
71 QString now =
72 QDateTime::currentDateTime().toString("ddd, d MMM yyyy hh:mm:ss");
73 m_defaultResponse = QByteArray(
74 "HTTP/1.1 404 Not Found\r\n"
75 "Date: " + now.toLatin1() + "\r\n"
76 "Last-Modified: " + now.toLatin1() + "\r\n"
77 "Connection: close\r\n"
78 "\r\n");
79 }
80
81 private slots:
82 void readClient()
83 {
84 // This slot is called when the client sent data to the server.
85 QTcpSocket* socket = (QTcpSocket*)sender();
86 // read whole request
87 QString request;
88 while(socket->canReadLine()) {
89 QString line = socket->readLine();
90 request.append(line);
91 if(request.endsWith("\r\n\r\n")) {
92 m_lastRequestData.append(request);
93
94 if(m_requestNumber < m_responsesToSend.size())
95 socket->write(m_responsesToSend.at(m_requestNumber));
96 else
97 socket->write(m_defaultResponse);
98 socket->close();
99 m_requestNumber++;
100 }
101 if (socket->state() == QTcpSocket::UnconnectedState)
102 delete socket;
103 }
104 }
105 void discardClient()
106 {
107 QTcpSocket* socket = (QTcpSocket*)sender();
108 socket->deleteLater();
109 }
110
111 private:
112 int m_requestNumber;
113 QList<QByteArray> m_responsesToSend;
114 QList<QString> m_lastRequestData;
115 QByteArray m_defaultResponse;
116};
117
118
119class TestHttpGet : public QObject
120{
121 Q_OBJECT
122 private slots:
123 void testFileUrlRequest(void);
124 void testCachedRequest(void);
125 void testUncachedRepeatedRequest(void);
126 void testUncachedMovedRequest(void);
127 void testUserAgent(void);
128 void testResponseCode(void);
129 void testContentToBuffer(void);
130 void testContentToFile(void);
131 void testNoServer(void);
132 void testServerTimestamp(void);
133 void testMovedQuery(void);
134 void init(void);
135 void cleanup(void);
136
137 public slots:
138 void waitTimeout(void)
139 {
140 m_waitTimeoutOccured = true;
141 }
142 QDir temporaryFolder(void)
143 {
144 // Qt unfortunately doesn't support creating temporary folders so
145 // we need to do that ourselves.
146 QString tempdir;
147 for(int i = 0; i < 100000; i++) {
148 tempdir = QDir::tempPath() + QString("/qttest-temp-%1").arg(i);
149 if(!QFileInfo(tempdir).exists()) break;
150 }
151 QDir().mkpath(tempdir);
152 return QDir(tempdir);
153 }
154 void rmTree(QString folder)
155 {
156 // no function in Qt to recursively delete a folder :(
157 QDir dir(folder);
158 Q_FOREACH(QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot
159 | QDir::System | QDir::Hidden | QDir::AllDirs
160 | QDir::Files, QDir::DirsFirst)) {
161 if(info.isDir()) rmTree(info.absoluteFilePath());
162 else QFile::remove(info.absoluteFilePath());
163 }
164 dir.rmdir(folder);
165 }
166 private:
167 HttpDaemon *m_daemon;
168 QByteArray m_port;
169 bool m_waitTimeoutOccured;
170 QString m_now;
171 QDir m_cachedir;
172 HttpGet *m_getter;
173 QSignalSpy *m_doneSpy;
174 QSignalSpy *m_progressSpy;
175};
176
177
178void TestHttpGet::init(void)
179{
180 m_now = QDateTime::currentDateTime().toString("ddd, d MMM yyyy hh:mm:ss");
181 m_daemon = new HttpDaemon(0, this); // use port 0 to auto-pick
182 m_daemon->reset();
183 m_port = QString("%1").arg(m_daemon->port()).toLatin1();
184 m_cachedir = temporaryFolder();
185 m_getter = new HttpGet(this);
186 m_doneSpy = new QSignalSpy(m_getter, SIGNAL(done(bool)));
187 m_progressSpy = new QSignalSpy(m_getter, SIGNAL(dataReadProgress(int, int)));
188 m_waitTimeoutOccured = false;
189}
190
191void TestHttpGet::cleanup(void)
192{
193 rmTree(m_cachedir.absolutePath());
194 if(m_getter) {
195 m_getter->abort(); delete m_getter; m_getter = NULL;
196 }
197 if(m_daemon) { delete m_daemon; m_daemon = NULL; }
198 if(m_doneSpy) { delete m_doneSpy; m_doneSpy = NULL; }
199 if(m_progressSpy) { delete m_progressSpy; m_progressSpy = NULL; }
200}
201
202void TestHttpGet::testFileUrlRequest(void)
203{
204 QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void)));
205
206 QString teststring = "The quick brown fox jumps over the lazy dog.";
207 QTemporaryFile datafile;
208 datafile.open();
209 datafile.write(teststring.toLatin1());
210 m_getter->getFile(QUrl::fromLocalFile(datafile.fileName()));
211 datafile.close();
212 while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false)
213 QCoreApplication::processEvents();
214
215 QCOMPARE(m_doneSpy->count(), 1);
216 QCOMPARE(m_waitTimeoutOccured, false);
217 QCOMPARE(m_daemon->lastRequestData().size(), 0);
218 QCOMPARE(m_getter->readAll(), teststring.toLatin1());
219 QCOMPARE(m_getter->httpResponse(), 200);
220 QCOMPARE(m_progressSpy->at(0).at(0).toInt(), 0);
221}
222
223
224/* On uncached requests, HttpGet is supposed to sent a GET request only.
225 */
226void TestHttpGet::testUncachedRepeatedRequest(void)
227{
228 QList<QByteArray> responses;
229 responses << QByteArray(
230 "HTTP/1.1 200 OK\r\n"
231 "Date: " + m_now.toLatin1() + "\r\n"
232 "Last-Modified: " + m_now.toLatin1() + "\r\n"
233 "\r\n\r\n");
234 responses << QByteArray(
235 "HTTP/1.1 200 OK\r\n"
236 "Last-Modified: " + m_now.toLatin1() + "\r\n"
237 "Date: " + m_now.toLatin1() + "\r\n"
238 "\r\n"
239 "<html></html>\r\n\r\n");
240 m_daemon->setResponsesToSend(responses);
241
242 QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void)));
243
244 m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.txt"));
245 while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false)
246 QCoreApplication::processEvents();
247
248 QCOMPARE(m_doneSpy->count(), 1);
249 QCOMPARE(m_waitTimeoutOccured, false);
250 QCOMPARE(m_daemon->lastRequestData().size(), 1);
251 QCOMPARE(m_daemon->lastRequestData().at(0).startsWith("GET"), true);
252
253 // request second time
254 m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.txt"));
255 while(m_doneSpy->count() < 2 && m_waitTimeoutOccured == false)
256 QCoreApplication::processEvents();
257 QCOMPARE(m_doneSpy->count(), 2);
258 QCOMPARE(m_waitTimeoutOccured, false);
259 QCOMPARE(m_daemon->lastRequestData().size(), 2);
260 QCOMPARE(m_daemon->lastRequestData().at(1).startsWith("GET"), true);
261 QCOMPARE(m_getter->httpResponse(), 200);
262}
263
264/* With enabled cache HttpGet is supposed to check the server file using a HEAD
265 * request first, then request the file using GET if the server file is newer
266 * than the cached one (or the file does not exist in the cache)
267 */
268void TestHttpGet::testCachedRequest(void)
269{
270 QList<QByteArray> responses;
271 responses << QByteArray(
272 "HTTP/1.1 302 Found\r\n"
273 "Location: http://localhost:" + m_port + "/test2.txt\r\n"
274 "Date: " + m_now.toLatin1() + "\r\n"
275 "Last-Modified: " + m_now.toLatin1() + "\r\n"
276 "\r\n");
277 responses << QByteArray(
278 "HTTP/1.1 200 OK\r\n"
279 "Last-Modified: " + m_now.toLatin1() + "\r\n"
280 "Date: " + m_now.toLatin1() + "\r\n"
281 "\r\n"
282 "<html></html>\r\n\r\n");
283 responses << QByteArray(
284 "HTTP/1.1 200 OK\r\n"
285 "Last-Modified: 1 Jan 2000 00:00:00\r\n"
286 "Date: " + m_now.toLatin1() + "\r\n"
287 "\r\n");
288 m_daemon->setResponsesToSend(responses);
289
290 QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void)));
291
292 m_getter->setCache(m_cachedir);
293 m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.txt"));
294 while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false)
295 QCoreApplication::processEvents();
296
297 QList<QString> requests = m_daemon->lastRequestData();
298 QCOMPARE(m_doneSpy->count(), 1);
299 QCOMPARE(m_doneSpy->at(0).at(0).toBool(), false);
300 QCOMPARE(m_waitTimeoutOccured, false);
301 QCOMPARE(requests.size(), 2);
302 QCOMPARE(requests.at(0).startsWith("GET"), true);
303 QCOMPARE(requests.at(1).startsWith("GET"), true);
304 QCOMPARE(m_getter->httpResponse(), 200);
305
306 // request real file, this time the response should come from cache.
307 m_getter->getFile(QUrl("http://localhost:" + m_port + "/test2.txt"));
308 while(m_doneSpy->count() < 2 && m_waitTimeoutOccured == false)
309 QCoreApplication::processEvents();
310 QCOMPARE(m_doneSpy->count(), 2); // 2 requests, 2 times done()
311 QCOMPARE(m_doneSpy->at(1).at(0).toBool(), false);
312 QCOMPARE(m_waitTimeoutOccured, false);
313 QCOMPARE(m_daemon->lastRequestData().size(), 3);
314 // redirect will not cache as the redirection target file.
315 QCOMPARE(m_daemon->lastRequestData().at(2).startsWith("GET"), true);
316 QCOMPARE(m_getter->httpResponse(), 200);
317}
318
319/* When a custom user agent is set all requests are supposed to contain it.
320 * Enable cache to make HttpGet performs a HEAD request. Answer with 302, so
321 * HttpGet follows and sends another HEAD request before finally doing a GET.
322 */
323void TestHttpGet::testUserAgent(void)
324{
325 QList<QByteArray> responses;
326 responses << QByteArray(
327 "HTTP/1.1 200 OK\r\n"
328 "Date: " + m_now.toLatin1() + "\r\n"
329 "Last-Modified: " + m_now.toLatin1() + "\r\n"
330 "\r\n\r\n");
331 responses << QByteArray(
332 "HTTP/1.1 200 OK\r\n"
333 "Last-Modified: " + m_now.toLatin1() + "\r\n"
334 "Date: " + m_now.toLatin1() + "\r\n"
335 "\r\n"
336 "<html></html>\r\n\r\n");
337 m_daemon->setResponsesToSend(responses);
338
339 QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void)));
340
341 m_getter->setGlobalUserAgent(TEST_USER_AGENT);
342 m_getter->setCache(m_cachedir);
343 m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.txt"));
344 while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false)
345 QCoreApplication::processEvents();
346
347 QList<QString> requests = m_daemon->lastRequestData();
348 QCOMPARE(m_doneSpy->count(), 1);
349 QCOMPARE(m_waitTimeoutOccured, false);
350 QCOMPARE(requests.size(), 1);
351 QCOMPARE(requests.at(0).startsWith("GET"), true);
352
353 for(int i = 0; i < requests.size(); ++i) {
354 QRegExp rx("User-Agent:[\t ]+([a-zA-Z0-9\\./]+)");
355 bool userAgentFound = rx.indexIn(requests.at(i)) > 0 ? true : false;
356 QCOMPARE(userAgentFound, true);
357 QString userAgentString = rx.cap(1);
358 QCOMPARE(userAgentString, QString(TEST_USER_AGENT));
359 }
360}
361
362void TestHttpGet::testUncachedMovedRequest(void)
363{
364 QList<QByteArray> responses;
365 responses << QByteArray(
366 "HTTP/1.1 302 Found\r\n"
367 "Location: http://localhost:" + m_port + "/test2.txt\r\n"
368 "Date: " + m_now.toLatin1() + "\r\n"
369 "Last-Modified: " + m_now.toLatin1() + "\r\n"
370 "\r\n");
371 responses << QByteArray(
372 "HTTP/1.1 200 OK\r\n"
373 "Last-Modified: " + m_now.toLatin1() + "\r\n"
374 "Date: " + m_now.toLatin1() + "\r\n"
375 "\r\n"
376 "<html></html>\r\n\r\n");
377 m_daemon->setResponsesToSend(responses);
378
379 QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void)));
380
381 m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.php?var=1&b=foo"));
382 while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false)
383 QCoreApplication::processEvents();
384
385 QCOMPARE(m_doneSpy->count(), 1);
386 QCOMPARE(m_waitTimeoutOccured, false);
387 QCOMPARE(m_daemon->lastRequestData().size(), 2);
388 QCOMPARE(m_daemon->lastRequestData().at(0).startsWith("GET"), true);
389 QCOMPARE(m_daemon->lastRequestData().at(1).startsWith("GET"), true);
390}
391
392void TestHttpGet::testResponseCode(void)
393{
394 QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void)));
395
396 m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.txt"));
397 while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false)
398 QCoreApplication::processEvents();
399
400 QCOMPARE(m_doneSpy->count(), 1);
401 QCOMPARE(m_doneSpy->at(0).at(0).toBool(), true);
402 QCOMPARE(m_waitTimeoutOccured, false);
403 QCOMPARE(m_daemon->lastRequestData().size(), 1);
404 QCOMPARE(m_daemon->lastRequestData().at(0).startsWith("GET"), true);
405 QCOMPARE(m_getter->httpResponse(), 404);
406}
407
408void TestHttpGet::testContentToBuffer(void)
409{
410 QList<QByteArray> responses;
411 responses << QByteArray(
412 "HTTP/1.1 200 OK\r\n"
413 "Last-Modified: " + m_now.toLatin1() + "\r\n"
414 "Date: " + m_now.toLatin1() + "\r\n"
415 "\r\n"
416 TEST_BINARY_BLOB);
417 m_daemon->setResponsesToSend(responses);
418
419 QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void)));
420
421 m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.txt"));
422 while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false)
423 QCoreApplication::processEvents();
424
425 QCOMPARE(m_doneSpy->count(), 1);
426 QCOMPARE(m_waitTimeoutOccured, false);
427 QCOMPARE(m_getter->readAll(), QByteArray(TEST_BINARY_BLOB));
428 // sizeof(TEST_BINARY_BLOB) will include an additional terminating NULL.
429 QCOMPARE(m_getter->readAll().size(), (int)sizeof(TEST_BINARY_BLOB) - 1);
430 QCOMPARE(m_progressSpy->at(m_progressSpy->count() - 1).at(0).toInt(), (int)sizeof(TEST_BINARY_BLOB) - 1);
431 QCOMPARE(m_progressSpy->at(m_progressSpy->count() - 1).at(1).toInt(), (int)sizeof(TEST_BINARY_BLOB) - 1);
432}
433
434void TestHttpGet::testContentToFile(void)
435{
436 QTemporaryFile tf(this);
437 QList<QByteArray> responses;
438 responses << QByteArray(
439 "HTTP/1.1 200 OK\r\n"
440 "Last-Modified: " + m_now.toLatin1() + "\r\n"
441 "Date: " + m_now.toLatin1() + "\r\n"
442 "\r\n"
443 TEST_BINARY_BLOB);
444 m_daemon->setResponsesToSend(responses);
445
446 QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void)));
447
448 m_getter->setFile(&tf);
449 m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.txt"));
450 while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false)
451 QCoreApplication::processEvents();
452
453 QCOMPARE(m_doneSpy->count(), 1);
454 QCOMPARE(m_waitTimeoutOccured, false);
455
456 tf.open();
457 QByteArray data = tf.readAll();
458 QCOMPARE(data, QByteArray(TEST_BINARY_BLOB));
459 QCOMPARE((unsigned long)data.size(), sizeof(TEST_BINARY_BLOB) - 1);
460 tf.close();
461}
462
463void TestHttpGet::testNoServer(void)
464{
465 QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void)));
466 m_getter->getFile(QUrl("http://localhost:53/test1.txt"));
467 while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false)
468 QCoreApplication::processEvents();
469
470 QCOMPARE(m_doneSpy->count(), 1);
471 QCOMPARE(m_doneSpy->at(0).at(0).toBool(), true);
472 QCOMPARE(m_waitTimeoutOccured, false);
473}
474
475void TestHttpGet::testServerTimestamp(void)
476{
477 QList<QByteArray> responses;
478 responses << QByteArray(
479 "HTTP/1.1 200 OK\r\n"
480 "Last-Modified: Wed, 20 Jan 2010 10:20:30\r\n" // RFC 822
481 "Date: Wed, 20 Jan 2010 10:20:30\r\n"
482 "\r\n"
483 "\r\n");
484 responses << QByteArray(
485 "HTTP/1.1 200 OK\r\n"
486 "Last-Modified: Sat Feb 19 09:08:07 2011\r\n" // asctime
487 "Date: Sat Feb 19 09:08:07 2011\r\n"
488 "\r\n"
489 "\r\n");
490
491 QList<QDateTime> times;
492 times << QDateTime::fromString("2010-01-20T11:20:30", Qt::ISODate);
493 times << QDateTime::fromString("2011-02-19T10:08:07", Qt::ISODate);
494
495 m_daemon->setResponsesToSend(responses);
496
497 QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void)));
498
499 int count = m_doneSpy->count();
500 for(int i = 0; i < responses.size(); ++i) {
501 m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.txt"));
502 while(m_doneSpy->count() == count && m_waitTimeoutOccured == false)
503 QCoreApplication::processEvents();
504 count = m_doneSpy->count();
505 QCOMPARE(m_getter->timestamp(), times.at(i));
506 }
507}
508
509void TestHttpGet::testMovedQuery(void)
510{
511 QList<QByteArray> responses;
512 responses << QByteArray(
513 "HTTP/1.1 302 Found\r\n"
514 "Location: http://localhost:" + m_port + "/test2.php\r\n"
515 "Date: " + m_now.toLatin1() + "\r\n"
516 "Last-Modified: " + m_now.toLatin1() + "\r\n"
517 "\r\n");
518 responses << QByteArray(
519 "HTTP/1.1 200 OK\r\n"
520 "Last-Modified: " + m_now.toLatin1() + "\r\n"
521 "Date: " + m_now.toLatin1() + "\r\n"
522 "\r\n"
523 "<html></html>\r\n\r\n");
524 m_daemon->setResponsesToSend(responses);
525
526 QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void)));
527
528 m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.php?var=1&b=foo"));
529 while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false)
530 QCoreApplication::processEvents();
531
532 QCOMPARE(m_doneSpy->count(), 1);
533 QCOMPARE(m_waitTimeoutOccured, false);
534 QCOMPARE(m_getter->httpResponse(), 200);
535 QCOMPARE(m_daemon->lastRequestData().size(), 2);
536 QCOMPARE(m_daemon->lastRequestData().at(0).startsWith("GET"), true);
537 QCOMPARE(m_daemon->lastRequestData().at(1).startsWith("GET"), true);
538 // current implementation keeps order of query items.
539 QCOMPARE((bool)m_daemon->lastRequestData().at(1).contains("/test2.php?var=1&b=foo"), true);
540}
541
542QTEST_MAIN(TestHttpGet)
543
544// this include is needed because we don't use a separate header file for the
545// test class. It also needs to be at the end.
546#include "test-httpget.moc"
547
diff --git a/utils/rbutilqt/test/test-httpget.pro b/utils/rbutilqt/test/test-httpget.pro
new file mode 100644
index 0000000000..3189ad2266
--- /dev/null
+++ b/utils/rbutilqt/test/test-httpget.pro
@@ -0,0 +1,31 @@
1#
2# __________ __ ___.
3# Open \______ \ ____ ____ | | _\_ |__ _______ ___
4# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7# \/ \/ \/ \/ \/
8#
9# All files in this archive are subject to the GNU General Public License.
10# See the file COPYING in the source tree root for full license agreement.
11#
12# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
13# KIND, either express or implied.
14#
15
16#
17include(tests.pri)
18
19TEMPLATE = app
20TARGET = test-httpget
21INCLUDEPATH += . ../base stubs
22QT += network
23
24# Input
25SOURCES += \
26 test-httpget.cpp
27
28SOURCES += ../base/httpget.cpp
29
30HEADERS += ../base/httpget.h
31
diff --git a/utils/rbutilqt/test/test-playerbuildinfo.cpp b/utils/rbutilqt/test/test-playerbuildinfo.cpp
new file mode 100644
index 0000000000..a250e37979
--- /dev/null
+++ b/utils/rbutilqt/test/test-playerbuildinfo.cpp
@@ -0,0 +1,240 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2020 Dominik Riebeling
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include <QtTest>
22#include <QObject>
23#include "playerbuildinfo.h"
24#include "rbsettings.h"
25
26class TestPlayerBuildInfo : public QObject
27{
28 Q_OBJECT
29
30 private slots:
31 void testBuildInfo();
32 void testBuildInfo_data();
33 void testPlayerInfo();
34 void testPlayerInfo_data();
35};
36
37const char* testinfo =
38 "[release]\n"
39 "build_url=https://buildurl/release/%VERSION%/rockbox-%TARGET%-%VERSION%.zip\n"
40 "voice_url=https://buildurl/release/%VERSION%/voice-%TARGET%-%VERSION%.zip\n"
41 "manual_url=https://buildurl/release/%VERSION%/manual-%TARGET%-%VERSION%.zip\n"
42 "source_url=https://buildurl/release/%VERSION%/rockbox-%TARGET%-src-%VERSION%.zip\n"
43 "font_url=https://buildurl/release/%VERSION%/fonts-%VERSION%.zip\n"
44 "archosfmrecorder=3.11.2\n"
45 "iaudiom3=3.11.2,http://dl.rockbox.org/release/3.11.2/rockbox-iaudiom5-3.11.2.zip\n"
46 "sansae200 = 3.15\n"
47 "iriverh100 = 3.11.2, http://dl.rockbox.org/release/3.11.2/rockbox-iriverh100-3.11.2.zip\n"
48 "iriverh120 = 3.3\n"
49 "iriverh300 = \n"
50 "[release-candidate]\n"
51 "build_url=https://buildurl/rc/%VERSION%/rockbox-%TARGET%-%VERSION%.zip\n"
52 "gigabeatfx=f9dce96,http://dl.rockbox.org/rc/f9dce96/rockbox-gigabeatfx.zip\n"
53 "archosfmrecorder=f9dce96\n"
54 "archosrecorder = f9dce96\n"
55 "iaudiox5=f9dce96,http://dl.rockbox.org/rc/f9dce96/rockbox-iaudiox5.zip\n"
56 "[development]\n"
57 "build_url=https://buildurl/dev/rockbox-%TARGET%.zip\n"
58 "iriverh100 = be1be79\n"
59 "iaudiox5 = be1be76\n"
60 "[dailies]\n"
61 "timestamp = 20201113\n"
62 "rev = 362f7a3\n"
63 "[daily]\n"
64 "build_url=https://buildurl/daily/rockbox-%TARGET%-%VERSION%.zip\n"
65 "iriverh100 = f9dce00\n"
66 "[bleeding]\n"
67 "timestamp = 20201114T105723Z\n"
68 "rev = be1be79\n"
69 "[status]\n"
70 "archosfmrecorder=3\n"
71 "iriverh100=2\n"
72 "iriverh300=1\n"
73 "iriverh10=0\n"
74 "[voices]\n"
75 "3.15=english,francais\n"
76 "3.11.2=english\n"
77 "daily=deutsch,english,francais\n"
78 ;
79
80Q_DECLARE_METATYPE(PlayerBuildInfo::BuildInfo);
81Q_DECLARE_METATYPE(PlayerBuildInfo::BuildType);
82Q_DECLARE_METATYPE(PlayerBuildInfo::DeviceInfo);
83
84struct {
85 QString target;
86 PlayerBuildInfo::BuildInfo item;
87 PlayerBuildInfo::BuildType type;
88 QString expected;
89} testdataBuild[] =
90{
91 // release builds
92 { "iriverh100", PlayerBuildInfo::BuildVoiceLangs, PlayerBuildInfo::TypeRelease, "english" },
93 { "iriverh300", PlayerBuildInfo::BuildVersion, PlayerBuildInfo::TypeRelease, "" },
94 { "iriverh300", PlayerBuildInfo::BuildUrl, PlayerBuildInfo::TypeRelease, "" },
95 { "iriverh10", PlayerBuildInfo::BuildVersion, PlayerBuildInfo::TypeRelease, "" },
96 { "iriverh10", PlayerBuildInfo::BuildUrl, PlayerBuildInfo::TypeRelease, "" },
97 { "archosfmrecorder", PlayerBuildInfo::BuildVersion, PlayerBuildInfo::TypeRelease, "3.11.2" },
98 { "iaudiom3", PlayerBuildInfo::BuildVersion, PlayerBuildInfo::TypeRelease, "3.11.2" },
99 { "iaudiom3", PlayerBuildInfo::BuildUrl, PlayerBuildInfo::TypeRelease, "http://dl.rockbox.org/release/3.11.2/rockbox-iaudiom5-3.11.2.zip" },
100 { "sansae200", PlayerBuildInfo::BuildVersion, PlayerBuildInfo::TypeRelease, "3.15" },
101 { "sansae200", PlayerBuildInfo::BuildUrl, PlayerBuildInfo::TypeRelease, "https://buildurl/release/3.15/rockbox-sansae200-3.15.zip" },
102 { "iriverh100", PlayerBuildInfo::BuildVersion, PlayerBuildInfo::TypeRelease, "3.11.2" },
103 { "iriverh100", PlayerBuildInfo::BuildUrl, PlayerBuildInfo::TypeRelease, "http://dl.rockbox.org/release/3.11.2/rockbox-iriverh100-3.11.2.zip" },
104 { "iriverh100", PlayerBuildInfo::BuildVoiceUrl, PlayerBuildInfo::TypeRelease, "https://buildurl/release/3.11.2/voice-iriverh100-3.11.2.zip" },
105 { "iriverh100", PlayerBuildInfo::BuildManualUrl, PlayerBuildInfo::TypeRelease, "https://buildurl/release/3.11.2/manual-iriverh100-3.11.2.zip" },
106 { "iriverh100", PlayerBuildInfo::BuildSourceUrl, PlayerBuildInfo::TypeRelease, "https://buildurl/release/3.11.2/rockbox-iriverh100-src-3.11.2.zip" },
107 // h120 uses the same manual as h100.
108 { "iriverh120", PlayerBuildInfo::BuildManualUrl, PlayerBuildInfo::TypeRelease, "https://buildurl/release/3.3/manual-iriverh100-3.3.zip" },
109 { "iriverh100", PlayerBuildInfo::BuildFontUrl, PlayerBuildInfo::TypeRelease, "https://buildurl/release/3.11.2/fonts-3.11.2.zip" },
110
111 // rc builds
112 { "gigabeatfx", PlayerBuildInfo::BuildVersion, PlayerBuildInfo::TypeCandidate, "f9dce96" },
113 { "gigabeatfx", PlayerBuildInfo::BuildUrl, PlayerBuildInfo::TypeCandidate, "http://dl.rockbox.org/rc/f9dce96/rockbox-gigabeatfx.zip" },
114 { "archosfmrecorder", PlayerBuildInfo::BuildVersion, PlayerBuildInfo::TypeCandidate, "f9dce96" },
115 { "archosfmrecorder", PlayerBuildInfo::BuildUrl, PlayerBuildInfo::TypeCandidate, "https://buildurl/rc/f9dce96/rockbox-archosfmrecorder-f9dce96.zip" },
116 { "archosrecorder", PlayerBuildInfo::BuildVersion, PlayerBuildInfo::TypeCandidate, "f9dce96" },
117 { "archosrecorder", PlayerBuildInfo::BuildUrl, PlayerBuildInfo::TypeCandidate, "https://buildurl/rc/f9dce96/rockbox-archosrecorder-f9dce96.zip" },
118 { "iaudiox5", PlayerBuildInfo::BuildVersion, PlayerBuildInfo::TypeCandidate, "f9dce96" },
119 { "iaudiox5", PlayerBuildInfo::BuildUrl, PlayerBuildInfo::TypeCandidate, "http://dl.rockbox.org/rc/f9dce96/rockbox-iaudiox5.zip" },
120 { "iaudiox5.v", PlayerBuildInfo::BuildVersion, PlayerBuildInfo::TypeCandidate, "f9dce96" },
121 { "iaudiox5.v", PlayerBuildInfo::BuildUrl, PlayerBuildInfo::TypeCandidate, "http://dl.rockbox.org/rc/f9dce96/rockbox-iaudiox5.zip" },
122
123 // devel builds
124 { "iriverh100", PlayerBuildInfo::BuildUrl, PlayerBuildInfo::TypeDevel, "https://buildurl/dev/rockbox-iriverh100.zip" },
125 { "iaudiox5.v", PlayerBuildInfo::BuildVersion, PlayerBuildInfo::TypeDevel, "be1be76" },
126 { "iaudiox5.v", PlayerBuildInfo::BuildUrl, PlayerBuildInfo::TypeDevel, "https://buildurl/dev/rockbox-iaudiox5.zip" },
127
128 // daily builds
129 { "iriverh100", PlayerBuildInfo::BuildVoiceLangs, PlayerBuildInfo::TypeDaily, "deutsch,english,francais" },
130 { "iriverh100", PlayerBuildInfo::BuildVersion, PlayerBuildInfo::TypeDaily, "f9dce00" },
131 { "iriverh100", PlayerBuildInfo::BuildUrl, PlayerBuildInfo::TypeDaily, "https://buildurl/daily/rockbox-iriverh100-f9dce00.zip" },
132};
133
134struct {
135 QString target;
136 PlayerBuildInfo::DeviceInfo item;
137 QString expected;
138} testdataPlayer[] =
139{
140 { "archosfmrecorder", PlayerBuildInfo::BuildStatus, "3" },
141 { "iriverh10", PlayerBuildInfo::BuildStatus, "0" },
142 { "iriverh100", PlayerBuildInfo::BuildStatus, "2" },
143 { "iriverh300", PlayerBuildInfo::BuildStatus, "1" },
144 { "archosfmrecorder", PlayerBuildInfo::BuildStatus, "3" },
145 { "archosfmrecorder", PlayerBuildInfo::DisplayName, "Jukebox Recorder FM"},
146 { "archosfmrecorder", PlayerBuildInfo::BootloaderMethod, "none" },
147 { "archosfmrecorder", PlayerBuildInfo::BootloaderName, "" },
148 { "archosfmrecorder", PlayerBuildInfo::BootloaderFile, "" },
149 { "archosfmrecorder", PlayerBuildInfo::BootloaderFilter, "" },
150 { "archosfmrecorder", PlayerBuildInfo::Encoder, "lame" },
151 { "archosfmrecorder", PlayerBuildInfo::Brand, "Archos" },
152 { "archosfmrecorder", PlayerBuildInfo::PlayerPicture, "archosfmrecorder"},
153 { "iriverh100", PlayerBuildInfo::BuildStatus, "2" },
154 { "iriverh100", PlayerBuildInfo::BootloaderMethod, "hex" },
155 { "iriverh100", PlayerBuildInfo::BootloaderFilter, "*.hex *.zip" },
156 { "ipodmini2g", PlayerBuildInfo::Encoder, "rbspeex" },
157 { "078174b1", PlayerBuildInfo::DisplayName, "Sansa View" },
158 { "de", PlayerBuildInfo::LanguageInfo, "deutsch,Deutsch" },
159 { "en_US", PlayerBuildInfo::LanguageInfo, "english-us,English (US)" },
160};
161
162void TestPlayerBuildInfo::testBuildInfo_data()
163{
164 QTest::addColumn<QString>("target");
165 QTest::addColumn<PlayerBuildInfo::BuildInfo>("item");
166 QTest::addColumn<PlayerBuildInfo::BuildType>("type");
167 QTest::addColumn<QString>("expected");
168 for (size_t i = 0; i < sizeof(testdataBuild) / sizeof(testdataBuild[0]); i++)
169 QTest::newRow("") << testdataBuild[i].target << testdataBuild[i].item
170 << testdataBuild[i].type << testdataBuild[i].expected;
171}
172
173
174void TestPlayerBuildInfo::testBuildInfo()
175{
176 // create a temporary file for test input. Do not use QSettings() to allow
177 // creating different format variations.
178 QTemporaryFile tf(this);
179 tf.open();
180 QString filename = tf.fileName();
181 tf.write(testinfo);
182 tf.close();
183
184 PlayerBuildInfo::instance()->setBuildInfo(filename);
185
186 QFETCH(QString, target);
187 QFETCH(PlayerBuildInfo::BuildInfo, item);
188 QFETCH(PlayerBuildInfo::BuildType, type);
189 QFETCH(QString, expected);
190
191 RbSettings::setValue(RbSettings::CurrentPlatform, target);
192 QVariant result = PlayerBuildInfo::instance()->value(item, type);
193 if(result.canConvert(QMetaType::QString))
194 QCOMPARE(result.toString(), QString(expected));
195 else
196 QCOMPARE(result.toStringList().join(","), QString(expected));
197}
198
199
200// NOTE: These tests rely on rbutil.ini
201void TestPlayerBuildInfo::testPlayerInfo_data()
202{
203 QTest::addColumn<QString>("target");
204 QTest::addColumn<PlayerBuildInfo::DeviceInfo>("item");
205 QTest::addColumn<QString>("expected");
206 for (size_t i = 0; i < sizeof(testdataPlayer) / sizeof(testdataPlayer[0]); i++)
207 QTest::newRow("") << testdataPlayer[i].target << testdataPlayer[i].item
208 << testdataPlayer[i].expected;
209}
210
211void TestPlayerBuildInfo::testPlayerInfo()
212{
213 // create a temporary file for test input. Do not use QSettings() to allow
214 // creating different format variations.
215 QTemporaryFile tf(this);
216 tf.open();
217 QString filename = tf.fileName();
218 tf.write(testinfo);
219 tf.close();
220
221 PlayerBuildInfo::instance()->setBuildInfo(filename);
222
223 QFETCH(QString, target);
224 QFETCH(PlayerBuildInfo::DeviceInfo, item);
225 QFETCH(QString, expected);
226
227 QVariant result = PlayerBuildInfo::instance()->value(item, target);
228 if(result.canConvert(QMetaType::QString))
229 QCOMPARE(result.toString(), QString(expected));
230 else
231 QCOMPARE(result.toStringList().join(","), QString(expected));
232}
233
234
235QTEST_MAIN(TestPlayerBuildInfo)
236
237// this include is needed because we don't use a separate header file for the
238// test class. It also needs to be at the end.
239#include "test-playerbuildinfo.moc"
240
diff --git a/utils/rbutilqt/test/test-playerbuildinfo.pro b/utils/rbutilqt/test/test-playerbuildinfo.pro
new file mode 100644
index 0000000000..724da59162
--- /dev/null
+++ b/utils/rbutilqt/test/test-playerbuildinfo.pro
@@ -0,0 +1,35 @@
1#
2# __________ __ ___.
3# Open \______ \ ____ ____ | | _\_ |__ _______ ___
4# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7# \/ \/ \/ \/ \/
8#
9# All files in this archive are subject to the GNU General Public License.
10# See the file COPYING in the source tree root for full license agreement.
11#
12# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
13# KIND, either express or implied.
14#
15
16#
17
18QT += testlib
19
20TEMPLATE = app
21TARGET = test-playerbuildinfo
22INCLUDEPATH += . ../base stubs
23
24# Input
25SOURCES += \
26 test-playerbuildinfo.cpp \
27 stubs/stubs-playerbuildinfo.cpp \
28 ../base/playerbuildinfo.cpp
29
30HEADERS += \
31 ../base/rbsettings.h \
32 ../base/rockboxinfo.h \
33 ../base/systeminfo.h \
34
35RESOURCES += ../rbutilqt.qrc
diff --git a/utils/rbutilqt/test/test-rockboxinfo.cpp b/utils/rbutilqt/test/test-rockboxinfo.cpp
new file mode 100644
index 0000000000..9d2b53b3ab
--- /dev/null
+++ b/utils/rbutilqt/test/test-rockboxinfo.cpp
@@ -0,0 +1,187 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2012 Dominik Riebeling
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include <QtTest/QtTest>
22#include <QObject>
23#include "rockboxinfo.h"
24
25
26class TestRockboxInfo : public QObject
27{
28 Q_OBJECT
29 private slots:
30 void testVersion();
31 void testVersion_data();
32 void testMemory();
33 void testMemory_data();
34 void testTarget();
35 void testTarget_data();
36 void testFeatures();
37 void testFeatures_data();
38};
39
40
41void TestRockboxInfo::testVersion_data()
42{
43 struct {
44 const char* input;
45 const char* revision;
46 const char* version;
47 const char* release;
48 } const testdata[] =
49 {
50 /* Input string revision full version release version */
51 { "Version: r29629-110321", "29629", "r29629-110321", "" },
52 { "Version: r29629M-110321", "29629M", "r29629M-110321", "" },
53 { "Version: 3.10", "", "3.10", "3.10" },
54 { "Version:\t3.10", "", "3.10", "3.10" },
55 { "#Version: r29629-110321", "", "", "" },
56 { "Version: e5b1b0f-120218", "e5b1b0f", "e5b1b0f-120218", "" },
57 { "Version: e5b1b0fM-120218", "e5b1b0fM", "e5b1b0fM-120218", "" },
58 { "#Version: e5b1b0f-120218", "", "", "" },
59 { "Version: 3448f5b-120310", "3448f5b", "3448f5b-120310", "" },
60 };
61
62
63 QTest::addColumn<QString>("input");
64 QTest::addColumn<QString>("revision");
65 QTest::addColumn<QString>("version");
66 QTest::addColumn<QString>("release");
67 unsigned int i;
68 for(i = 0; i < sizeof(testdata) / sizeof(testdata[0]); i++) {
69 for (size_t i = 0; i < sizeof(testdata) / sizeof(testdata[0]); i++) {
70 QTest::newRow(testdata[i].input)
71 << testdata[i].input << testdata[i].revision
72 << testdata[i].version << testdata[i].release;
73 }
74 }
75}
76
77
78void TestRockboxInfo::testVersion()
79{
80 QFETCH(QString, input);
81 QFETCH(QString, revision);
82 QFETCH(QString, version);
83 QFETCH(QString, release);
84 QTemporaryFile tf(this);
85 tf.open();
86 QString filename = tf.fileName();
87 tf.write(input.toLatin1());
88 tf.write("\n");
89 tf.close();
90
91 RockboxInfo info("", filename);
92 QCOMPARE(info.version(), QString(version));
93 QCOMPARE(info.revision(), QString(revision));
94 QCOMPARE(info.release(), QString(release));
95}
96
97void TestRockboxInfo::testTarget_data()
98{
99 QTest::addColumn<QString>("target");
100 QTest::newRow("sansae200") << "sansae200";
101 QTest::newRow("gigabeats") << "gigabeats";
102 QTest::newRow("iriverh100") << "iriverh100";
103 QTest::newRow("unknown") << "unknown";
104}
105
106void TestRockboxInfo::testTarget()
107{
108 int j;
109 QStringList prefix;
110 prefix << "Target: "; // << "Target:\t" << "Target: ";
111 for(j = 0; j < prefix.size(); ++j) {
112 QFETCH(QString, target);
113 QTemporaryFile tf(this);
114 tf.open();
115 QString filename = tf.fileName();
116 tf.write(prefix.at(j).toLatin1());
117 tf.write(target.toLatin1());
118 tf.write("\n");
119 tf.close();
120
121 RockboxInfo info("", filename);
122 QCOMPARE(info.target(), target);
123 }
124}
125
126void TestRockboxInfo::testMemory_data()
127{
128 QTest::addColumn<QString>("memory");
129 QTest::newRow("8") << "8";
130 QTest::newRow("16") << "16";
131 QTest::newRow("32") << "32";
132 QTest::newRow("64") << "64";
133}
134
135void TestRockboxInfo::testMemory()
136{
137 int j;
138 QStringList prefix;
139 prefix << "Memory: " << "Memory:\t" << "Memory: ";
140 for(j = 0; j < prefix.size(); ++j) {
141 QFETCH(QString, memory);
142 QTemporaryFile tf(this);
143 tf.open();
144 QString filename = tf.fileName();
145 tf.write(prefix.at(j).toLatin1());
146 tf.write(memory.toLatin1());
147 tf.write("\n");
148 tf.close();
149
150 RockboxInfo info("", filename);
151 QCOMPARE(info.ram(), memory.toInt());
152 }
153}
154
155void TestRockboxInfo::testFeatures_data()
156{
157 QTest::addColumn<QString>("features");
158 QTest::newRow("1") << "backlight_brightness:button_light:dircache:flash_storage";
159 QTest::newRow("2") << "pitchscreen:multivolume:multidrive_usb:quickscreen";
160}
161
162void TestRockboxInfo::testFeatures()
163{
164 int j;
165 QStringList prefix;
166 prefix << "Features: " << "Features:\t" << "Features: ";
167 for(j = 0; j < prefix.size(); ++j) {
168 QFETCH(QString, features);
169 QTemporaryFile tf(this);
170 tf.open();
171 QString filename = tf.fileName();
172 tf.write(prefix.at(j).toLatin1());
173 tf.write(features.toLatin1());
174 tf.write("\n");
175 tf.close();
176
177 RockboxInfo info("", filename);
178 QCOMPARE(info.features(), features);
179 }
180}
181
182QTEST_MAIN(TestRockboxInfo)
183
184// this include is needed because we don't use a separate header file for the
185// test class. It also needs to be at the end.
186#include "test-rockboxinfo.moc"
187
diff --git a/utils/rbutilqt/test/test-rockboxinfo.pro b/utils/rbutilqt/test/test-rockboxinfo.pro
new file mode 100644
index 0000000000..88bc83a5b7
--- /dev/null
+++ b/utils/rbutilqt/test/test-rockboxinfo.pro
@@ -0,0 +1,30 @@
1#
2# __________ __ ___.
3# Open \______ \ ____ ____ | | _\_ |__ _______ ___
4# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7# \/ \/ \/ \/ \/
8#
9# All files in this archive are subject to the GNU General Public License.
10# See the file COPYING in the source tree root for full license agreement.
11#
12# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
13# KIND, either express or implied.
14#
15
16#
17QT += testlib
18
19TEMPLATE = app
20TARGET = test-rockboxinfo
21INCLUDEPATH += . ../base stubs
22
23# Input
24SOURCES += \
25 test-rockboxinfo.cpp \
26 ../base/rockboxinfo.cpp
27
28HEADERS += \
29 ../base/rockboxinfo.h
30
diff --git a/utils/rbutilqt/test/tests.pri b/utils/rbutilqt/test/tests.pri
new file mode 100644
index 0000000000..7dc6ffda7b
--- /dev/null
+++ b/utils/rbutilqt/test/tests.pri
@@ -0,0 +1,24 @@
1#
2# __________ __ ___.
3# Open \______ \ ____ ____ | | _\_ |__ _______ ___
4# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7# \/ \/ \/ \/ \/
8#
9# All files in this archive are subject to the GNU General Public License.
10# See the file COPYING in the source tree root for full license agreement.
11#
12# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
13# KIND, either express or implied.
14#
15
16# common settings for tests.
17
18CONFIG += qtestlib
19DEPENDPATH += .
20OBJECTS_DIR = build/$$TARGET
21UI_DIR = build/$$TARGET
22MOC_DIR = build/$$TARGET
23RCC_DIR = build/$$TARGET
24QT -= gui
diff --git a/utils/rbutilqt/themesinstallfrm.ui b/utils/rbutilqt/themesinstallfrm.ui
new file mode 100644
index 0000000000..b3795febdc
--- /dev/null
+++ b/utils/rbutilqt/themesinstallfrm.ui
@@ -0,0 +1,149 @@
1<ui version="4.0" >
2 <class>ThemeInstallFrm</class>
3 <widget class="QDialog" name="ThemeInstallFrm" >
4 <property name="geometry" >
5 <rect>
6 <x>0</x>
7 <y>0</y>
8 <width>750</width>
9 <height>450</height>
10 </rect>
11 </property>
12 <property name="windowTitle" >
13 <string>Theme Installation</string>
14 </property>
15 <layout class="QGridLayout" >
16 <item rowspan="2" row="0" column="0" >
17 <widget class="QLabel" name="label" >
18 <property name="text" >
19 <string/>
20 </property>
21 <property name="pixmap" >
22 <pixmap resource="rbutilqt.qrc" >:/icons/wizard.jpg</pixmap>
23 </property>
24 <property name="alignment" >
25 <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
26 </property>
27 </widget>
28 </item>
29 <item row="0" column="1" >
30 <widget class="QListWidget" name="listThemes" >
31 <property name="sizePolicy" >
32 <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
33 <horstretch>0</horstretch>
34 <verstretch>0</verstretch>
35 </sizepolicy>
36 </property>
37 </widget>
38 </item>
39 <item row="0" column="2" colspan="3" >
40 <widget class="QGroupBox" name="groupBox" >
41 <property name="sizePolicy" >
42 <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
43 <horstretch>0</horstretch>
44 <verstretch>0</verstretch>
45 </sizepolicy>
46 </property>
47 <property name="title" >
48 <string>Selected Theme</string>
49 </property>
50 <layout class="QGridLayout" >
51 <item row="0" column="0" colspan="3" >
52 <widget class="PreviewLabel" name="themePreview" >
53 <property name="sizePolicy" >
54 <sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
55 <horstretch>0</horstretch>
56 <verstretch>0</verstretch>
57 </sizepolicy>
58 </property>
59 <property name="text" >
60 <string/>
61 </property>
62 <property name="scaledContents" >
63 <bool>true</bool>
64 </property>
65 <property name="alignment" >
66 <set>Qt::AlignCenter</set>
67 </property>
68 </widget>
69 </item>
70 <item row="2" column="0" colspan="3" >
71 <widget class="QLabel" name="label_3" >
72 <property name="text" >
73 <string>Description</string>
74 </property>
75 </widget>
76 </item>
77 <item row="3" column="0" colspan="3" >
78 <widget class="QTextBrowser" name="themeDescription" />
79 </item>
80 <item row="4" column="0" colspan="3" >
81 <widget class="QLabel" name="labelSize" >
82 <property name="text" >
83 <string>Download size:</string>
84 </property>
85 </widget>
86 </item>
87 </layout>
88 </widget>
89 </item>
90 <item row="1" column="1" colspan="2" >
91 <widget class="QLabel" name="label_2" >
92 <property name="text" >
93 <string>Hold Ctrl to select multiple item, Shift for a range</string>
94 </property>
95 </widget>
96 </item>
97 <item row="1" column="3" >
98 <spacer>
99 <property name="orientation" >
100 <enum>Qt::Horizontal</enum>
101 </property>
102 <property name="sizeHint" >
103 <size>
104 <width>241</width>
105 <height>20</height>
106 </size>
107 </property>
108 </spacer>
109 </item>
110 <item row="1" column="4" >
111 <layout class="QHBoxLayout" >
112 <item>
113 <widget class="QPushButton" name="buttonOk" >
114 <property name="text" >
115 <string>&amp;Install</string>
116 </property>
117 <property name="icon" >
118 <iconset resource="rbutilqt.qrc" >
119 <normaloff>:/icons/go-next.svg</normaloff>:/icons/go-next.svg</iconset>
120 </property>
121 </widget>
122 </item>
123 <item>
124 <widget class="QPushButton" name="buttonCancel" >
125 <property name="text" >
126 <string>&amp;Cancel</string>
127 </property>
128 <property name="icon" >
129 <iconset resource="rbutilqt.qrc" >
130 <normaloff>:/icons/process-stop.svg</normaloff>:/icons/process-stop.svg</iconset>
131 </property>
132 </widget>
133 </item>
134 </layout>
135 </item>
136 </layout>
137 </widget>
138 <customwidgets>
139 <customwidget>
140 <class>PreviewLabel</class>
141 <extends>QLabel</extends>
142 <header>preview.h</header>
143 </customwidget>
144 </customwidgets>
145 <resources>
146 <include location="rbutilqt.qrc" />
147 </resources>
148 <connections/>
149</ui>
diff --git a/utils/rbutilqt/themesinstallwindow.cpp b/utils/rbutilqt/themesinstallwindow.cpp
new file mode 100644
index 0000000000..c1a54feb74
--- /dev/null
+++ b/utils/rbutilqt/themesinstallwindow.cpp
@@ -0,0 +1,393 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QDialog>
20#include <QMessageBox>
21#include <QTextCodec>
22
23#include "ui_themesinstallfrm.h"
24#include "themesinstallwindow.h"
25#include "zipinstaller.h"
26#include "progressloggergui.h"
27#include "utils.h"
28#include "rbsettings.h"
29#include "playerbuildinfo.h"
30#include "rockboxinfo.h"
31#include "version.h"
32#include "Logger.h"
33
34ThemesInstallWindow::ThemesInstallWindow(QWidget *parent) : QDialog(parent)
35{
36 ui.setupUi(this);
37 ui.listThemes->setAlternatingRowColors(true);
38 ui.listThemes->setSelectionMode(QAbstractItemView::ExtendedSelection);
39 ui.listThemes->setSortingEnabled(true);
40 ui.themePreview->clear();
41 ui.themePreview->setText(tr("no theme selected"));
42 ui.labelSize->setText(tr("no selection"));
43 ui.listThemes->setLayoutDirection(Qt::LeftToRight);
44 ui.themeDescription->setLayoutDirection(Qt::LeftToRight);
45
46 connect(ui.buttonCancel, SIGNAL(clicked()), this, SLOT(close()));
47 connect(ui.buttonOk, SIGNAL(clicked()), this, SLOT(accept()));
48 connect(ui.listThemes, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
49 this, SLOT(updateDetails(QListWidgetItem*, QListWidgetItem*)));
50 connect(ui.listThemes, SIGNAL(itemSelectionChanged()), this, SLOT(updateSize()));
51 connect(&igetter, SIGNAL(done(bool)), this, SLOT(updateImage(bool)));
52
53 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
54 igetter.setCache(true);
55 else
56 {
57 if(infocachedir.isEmpty())
58 {
59 infocachedir = QDir::tempPath() + "rbutil-themeinfo";
60 QDir d = QDir::temp();
61 d.mkdir("rbutil-themeinfo");
62 }
63 igetter.setCache(infocachedir);
64 }
65
66 logger = nullptr;
67}
68
69ThemesInstallWindow::~ThemesInstallWindow()
70{
71 if(!infocachedir.isEmpty())
72 Utils::recursiveRmdir(infocachedir);
73}
74
75
76void ThemesInstallWindow::downloadInfo()
77{
78 // try to get the current build information
79 getter = new HttpGet(this);
80 RockboxInfo installInfo
81 = RockboxInfo(RbSettings::value(RbSettings::Mountpoint).toString());
82
83 themesInfo.open();
84 LOG_INFO() << "downloading info to" << themesInfo.fileName();
85 themesInfo.close();
86
87 QString infoUrl = PlayerBuildInfo::instance()->value(PlayerBuildInfo::ThemesInfoUrl).toString();
88 infoUrl.replace("%TARGET%",
89 RbSettings::value(RbSettings::CurrentPlatform).toString().split(".").at(0));
90 infoUrl.replace("%REVISION%", installInfo.revision());
91 infoUrl.replace("%RELEASE%", installInfo.release());
92 infoUrl.replace("%RBUTILVER%", VERSION);
93 QUrl url = QUrl(infoUrl);
94 LOG_INFO() << "Info URL:" << url;
95 getter->setFile(&themesInfo);
96
97 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
98 connect(logger, SIGNAL(aborted()), getter, SLOT(abort()));
99 getter->getFile(url);
100}
101
102
103void ThemesInstallWindow::downloadDone(int id, bool error)
104{
105 downloadDone(error);
106 LOG_INFO() << "Download" << id << "done, error:" << error;
107}
108
109
110void ThemesInstallWindow::downloadDone(bool error)
111{
112 LOG_INFO() << "Download done, error:" << error;
113
114 disconnect(logger, SIGNAL(aborted()), getter, SLOT(abort()));
115 disconnect(logger, SIGNAL(aborted()), this, SLOT(close()));
116 themesInfo.open();
117
118 QSettings iniDetails(themesInfo.fileName(), QSettings::IniFormat, this);
119 iniDetails.setIniCodec(QTextCodec::codecForName("UTF-8"));
120 QStringList tl = iniDetails.childGroups();
121 LOG_INFO() << "Theme site result:"
122 << iniDetails.value("error/code").toString()
123 << iniDetails.value("error/description").toString()
124 << iniDetails.value("error/query").toString();
125
126 if(error) {
127 logger->addItem(tr("Network error: %1.\n"
128 "Please check your network and proxy settings.")
129 .arg(getter->errorString()), LOGERROR);
130 getter->abort();
131 logger->setFinished();
132 disconnect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
133 connect(logger, SIGNAL(closed()), this, SLOT(close()));
134 return;
135 }
136 // handle possible error codes
137 if(iniDetails.value("error/code").toInt() != 0 || !iniDetails.contains("error/code")) {
138 LOG_ERROR() << "Theme site returned an error:"
139 << iniDetails.value("error/code");
140 logger->addItem(tr("the following error occured:\n%1")
141 .arg(iniDetails.value("error/description", "unknown error").toString()), LOGERROR);
142 logger->setFinished();
143 connect(logger, SIGNAL(closed()), this, SLOT(close()));
144 return;
145 }
146 logger->addItem(tr("done."), LOGOK);
147 logger->setFinished();
148 logger->close();
149
150 // setup list
151 for(int i = 0; i < tl.size(); i++) {
152 iniDetails.beginGroup(tl.at(i));
153 // skip all themes without name field set (i.e. error section)
154 if(iniDetails.value("name").toString().isEmpty()) {
155 iniDetails.endGroup();
156 continue;
157 }
158 LOG_INFO() << "adding to list:" << tl.at(i);
159 // convert to unicode and replace HTML-specific entities
160 QByteArray raw = iniDetails.value("name").toByteArray();
161 QTextCodec* codec = QTextCodec::codecForHtml(raw);
162 QString name = codec->toUnicode(raw);
163 name.replace("&quot;", "\"").replace("&amp;", "&");
164 name.replace("&lt;", "<").replace("&gt;", ">");
165 QListWidgetItem *w = new QListWidgetItem;
166 w->setData(Qt::DisplayRole, name.trimmed());
167 w->setData(Qt::UserRole, tl.at(i));
168 ui.listThemes->addItem(w);
169
170 iniDetails.endGroup();
171 }
172 // check if there's a themes "MOTD" available
173 if(iniDetails.contains("status/msg")) {
174 // check if there's a localized msg available
175 QString lang = RbSettings::value(RbSettings::Language).toString().split("_").at(0);
176 QString msg;
177 if(iniDetails.contains("status/msg." + lang))
178 msg = iniDetails.value("status/msg." + lang).toString();
179 else
180 msg = iniDetails.value("status/msg").toString();
181 LOG_INFO() << "MOTD" << msg;
182 if(!msg.isEmpty())
183 QMessageBox::information(this, tr("Information"), msg);
184 }
185}
186
187
188void ThemesInstallWindow::updateSize(void)
189{
190 long size = 0;
191 // sum up size for all selected themes
192 QSettings iniDetails(themesInfo.fileName(), QSettings::IniFormat, this);
193 iniDetails.setIniCodec(QTextCodec::codecForName("UTF-8"));
194 int items = ui.listThemes->selectedItems().size();
195 for(int i = 0; i < items; i++) {
196 iniDetails.beginGroup(ui.listThemes->selectedItems()
197 .at(i)->data(Qt::UserRole).toString());
198 size += iniDetails.value("size").toInt();
199 iniDetails.endGroup();
200 }
201 ui.labelSize->setText(tr("Download size %L1 kiB (%n item(s))", "", items)
202 .arg((size + 512) / 1024));
203}
204
205
206void ThemesInstallWindow::updateDetails(QListWidgetItem* cur, QListWidgetItem* prev)
207{
208 if(cur == prev)
209 return;
210
211 QSettings iniDetails(themesInfo.fileName(), QSettings::IniFormat, this);
212 iniDetails.setIniCodec(QTextCodec::codecForName("UTF-8"));
213
214 QCoreApplication::processEvents();
215 ui.themeDescription->setText(tr("fetching details for %1")
216 .arg(cur->data(Qt::DisplayRole).toString()));
217 ui.themePreview->clear();
218 ui.themePreview->setText(tr("fetching preview ..."));
219 imgData.clear();
220
221 iniDetails.beginGroup(cur->data(Qt::UserRole).toString());
222
223 QUrl img, txt;
224 txt = QUrl(QString(PlayerBuildInfo::instance()->value(PlayerBuildInfo::ThemesUrl).toString() + "/"
225 + iniDetails.value("descriptionfile").toString()));
226 img = QUrl(QString(PlayerBuildInfo::instance()->value(PlayerBuildInfo::ThemesUrl).toString() + "/"
227 + iniDetails.value("image").toString()));
228
229 QString text;
230 QTextCodec* codec = QTextCodec::codecForName("UTF-8");
231 text = tr("<b>Author:</b> %1<hr/>").arg(codec->toUnicode(iniDetails
232 .value("author", tr("unknown")).toByteArray()));
233 text += tr("<b>Version:</b> %1<hr/>").arg(codec->toUnicode(iniDetails
234 .value("version", tr("unknown")).toByteArray()));
235 text += tr("<b>Description:</b> %1<hr/>").arg(codec->toUnicode(iniDetails
236 .value("about", tr("no description")).toByteArray()));
237
238 text.replace("\n", "<br/>");
239 ui.themeDescription->setHtml(text);
240 iniDetails.endGroup();
241 igetter.abort();
242 igetter.getFile(img);
243}
244
245
246void ThemesInstallWindow::updateImage(bool error)
247{
248 LOG_INFO() << "Updating image:"<< !error;
249
250 if(error) {
251 ui.themePreview->clear();
252 ui.themePreview->setText(tr("Retrieving theme preview failed.\n"
253 "HTTP response code: %1").arg(igetter.httpResponse()));
254 return;
255 }
256
257 QPixmap p;
258 if(!error) {
259 imgData = igetter.readAll();
260 if(imgData.isNull()) return;
261 p.loadFromData(imgData);
262 if(p.isNull()) {
263 ui.themePreview->clear();
264 ui.themePreview->setText(tr("no theme preview"));
265 }
266 else
267 ui.themePreview->setPixmap(p);
268 }
269}
270
271
272void ThemesInstallWindow::resizeEvent(QResizeEvent* e)
273{
274 (void)e;
275 QPixmap p, q;
276 QSize img;
277 img.setHeight(ui.themePreview->height());
278 img.setWidth(ui.themePreview->width());
279
280 p.loadFromData(imgData);
281 if(p.isNull()) return;
282 q = p.scaled(img, Qt::KeepAspectRatio, Qt::SmoothTransformation);
283 ui.themePreview->setScaledContents(false);
284 ui.themePreview->setPixmap(p);
285}
286
287
288
289void ThemesInstallWindow::show()
290{
291 QDialog::show();
292 if(windowSelectOnly)
293 ui.buttonOk->setText(tr("Select"));
294
295 if(!logger)
296 logger = new ProgressLoggerGui(this);
297
298 if(ui.listThemes->count() == 0) {
299 logger->show();
300 logger->addItem(tr("getting themes information ..."), LOGINFO);
301
302 connect(logger, SIGNAL(aborted()), this, SLOT(close()));
303
304 downloadInfo();
305 }
306
307}
308
309
310void ThemesInstallWindow::abort()
311{
312 igetter.abort();
313 logger->setFinished();
314 this->close();
315}
316
317
318void ThemesInstallWindow::accept(void)
319{
320 if(!windowSelectOnly)
321 install();
322 else
323 close();
324}
325
326
327void ThemesInstallWindow::install()
328{
329 if(ui.listThemes->selectedItems().size() == 0) {
330 logger->addItem(tr("No themes selected, skipping"), LOGINFO);
331 emit done(false);
332 return;
333 }
334 QStringList themes;
335 QStringList names;
336 QStringList version;
337 QString zip;
338 QSettings iniDetails(themesInfo.fileName(), QSettings::IniFormat, this);
339 for(int i = 0; i < ui.listThemes->selectedItems().size(); i++) {
340 iniDetails.beginGroup(ui.listThemes->selectedItems().at(i)->data(Qt::UserRole).toString());
341 zip = PlayerBuildInfo::instance()->value(PlayerBuildInfo::ThemesUrl).toString()
342 + "/" + iniDetails.value("archive").toString();
343 themes.append(zip);
344 names.append("Theme: " +
345 ui.listThemes->selectedItems().at(i)->data(Qt::DisplayRole).toString());
346 // if no version info is available use installation (current) date
347 version.append(iniDetails.value("version",
348 QDate().currentDate().toString("yyyyMMdd")).toString());
349 iniDetails.endGroup();
350 }
351 LOG_INFO() << "installing:" << themes;
352
353 if(logger == nullptr)
354 logger = new ProgressLoggerGui(this);
355 logger->show();
356 QString mountPoint = RbSettings::value(RbSettings::Mountpoint).toString();
357 LOG_INFO() << "mountpoint:" << mountPoint;
358 // show dialog with error if mount point is wrong
359 if(!QFileInfo(mountPoint).isDir()) {
360 logger->addItem(tr("Mount point is wrong!"),LOGERROR);
361 logger->setFinished();
362 return;
363 }
364
365 installer = new ZipInstaller(this);
366 installer->setUrl(themes);
367 installer->setLogSection(names);
368 installer->setLogVersion(version);
369 installer->setMountPoint(mountPoint);
370 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
371 installer->setCache(true);
372
373 if(!windowSelectOnly) {
374 connect(logger, SIGNAL(closed()), this, SLOT(close()));
375 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
376 }
377 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
378 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
379 connect(installer, SIGNAL(done(bool)), this, SIGNAL(done(bool)));
380 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
381 installer->install();
382}
383
384
385void ThemesInstallWindow::changeEvent(QEvent *e)
386{
387 if(e->type() == QEvent::LanguageChange) {
388 ui.retranslateUi(this);
389 } else {
390 QWidget::changeEvent(e);
391 }
392}
393
diff --git a/utils/rbutilqt/themesinstallwindow.h b/utils/rbutilqt/themesinstallwindow.h
new file mode 100644
index 0000000000..9214e5ccbf
--- /dev/null
+++ b/utils/rbutilqt/themesinstallwindow.h
@@ -0,0 +1,77 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Riebeling
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#ifndef INSTALLTHEMES_H
22#define INSTALLTHEMES_H
23
24#include <QtGui>
25#include <QTemporaryFile>
26
27#include "ui_themesinstallfrm.h"
28#include "httpget.h"
29#include "zipinstaller.h"
30#include "progressloggergui.h"
31
32class ThemesInstallWindow : public QDialog
33{
34 Q_OBJECT
35
36 public:
37 ThemesInstallWindow(QWidget* parent = 0);
38 ~ThemesInstallWindow();
39 void downloadInfo(void);
40 void show(void);
41 void setLogger(ProgressLoggerGui* l) { logger = l; }
42 void setSelectOnly(bool state) { windowSelectOnly = state; }
43 void install(void);
44
45 public slots:
46 void accept(void);
47
48 signals:
49 void done(bool);
50
51 private:
52 Ui::ThemeInstallFrm ui;
53 HttpGet *getter;
54 HttpGet igetter;
55 QTemporaryFile themesInfo;
56 void resizeEvent(QResizeEvent*);
57 void changeEvent(QEvent *event);
58 QByteArray imgData;
59 ProgressLoggerGui *logger;
60 ZipInstaller *installer;
61 QString file;
62 QString fileName;
63
64 QString infocachedir;
65 bool windowSelectOnly;
66
67 private slots:
68 void downloadDone(bool);
69 void downloadDone(int, bool);
70 void updateImage(bool);
71 void abort(void);
72 void updateDetails(QListWidgetItem* cur, QListWidgetItem* prev);
73 void updateSize(void);
74};
75
76
77#endif
diff --git a/utils/rbutilqt/uninstallfrm.ui b/utils/rbutilqt/uninstallfrm.ui
new file mode 100644
index 0000000000..7b72b44e1e
--- /dev/null
+++ b/utils/rbutilqt/uninstallfrm.ui
@@ -0,0 +1,188 @@
1<ui version="4.0" >
2 <class>UninstallFrm</class>
3 <widget class="QDialog" name="UninstallFrm" >
4 <property name="windowModality" >
5 <enum>Qt::WindowModal</enum>
6 </property>
7 <property name="geometry" >
8 <rect>
9 <x>0</x>
10 <y>0</y>
11 <width>574</width>
12 <height>451</height>
13 </rect>
14 </property>
15 <property name="windowTitle" >
16 <string>Uninstall Rockbox</string>
17 </property>
18 <layout class="QGridLayout" >
19 <item rowspan="6" row="0" column="0" >
20 <widget class="QLabel" name="label" >
21 <property name="text" >
22 <string/>
23 </property>
24 <property name="pixmap" >
25 <pixmap resource="rbutilqt.qrc" >:/icons/wizard.jpg</pixmap>
26 </property>
27 <property name="alignment" >
28 <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
29 </property>
30 </widget>
31 </item>
32 <item row="0" column="1" colspan="2" >
33 <widget class="QLabel" name="label_5" >
34 <property name="text" >
35 <string>Please select the Uninstallation Method</string>
36 </property>
37 <property name="wordWrap" >
38 <bool>true</bool>
39 </property>
40 </widget>
41 </item>
42 <item row="1" column="1" colspan="2" >
43 <widget class="QGroupBox" name="groupBox" >
44 <property name="title" >
45 <string>Uninstallation Method</string>
46 </property>
47 <layout class="QGridLayout" >
48 <item row="0" column="0" >
49 <widget class="QRadioButton" name="CompleteRadioBtn" >
50 <property name="text" >
51 <string>Complete Uninstallation</string>
52 </property>
53 </widget>
54 </item>
55 <item row="1" column="0" >
56 <widget class="QRadioButton" name="smartRadioButton" >
57 <property name="text" >
58 <string>Smart Uninstallation</string>
59 </property>
60 </widget>
61 </item>
62 </layout>
63 </widget>
64 </item>
65 <item row="2" column="1" colspan="2" >
66 <widget class="QLabel" name="label_4" >
67 <property name="text" >
68 <string>Please select what you want to uninstall</string>
69 </property>
70 <property name="wordWrap" >
71 <bool>true</bool>
72 </property>
73 </widget>
74 </item>
75 <item row="3" column="1" colspan="2" >
76 <widget class="QGroupBox" name="smartGroupBox" >
77 <property name="title" >
78 <string>Installed Parts</string>
79 </property>
80 <layout class="QHBoxLayout" >
81 <item>
82 <widget class="QListWidget" name="UninstalllistWidget" >
83 <property name="minimumSize" >
84 <size>
85 <width>0</width>
86 <height>0</height>
87 </size>
88 </property>
89 <property name="selectionMode" >
90 <enum>QAbstractItemView::MultiSelection</enum>
91 </property>
92 </widget>
93 </item>
94 </layout>
95 </widget>
96 </item>
97 <item row="4" column="1" colspan="2" >
98 <spacer>
99 <property name="orientation" >
100 <enum>Qt::Vertical</enum>
101 </property>
102 <property name="sizeHint" >
103 <size>
104 <width>341</width>
105 <height>31</height>
106 </size>
107 </property>
108 </spacer>
109 </item>
110 <item row="5" column="1" >
111 <spacer>
112 <property name="orientation" >
113 <enum>Qt::Horizontal</enum>
114 </property>
115 <property name="sizeHint" >
116 <size>
117 <width>291</width>
118 <height>20</height>
119 </size>
120 </property>
121 </spacer>
122 </item>
123 <item row="5" column="2" >
124 <layout class="QHBoxLayout" >
125 <item>
126 <widget class="QPushButton" name="buttonOk" >
127 <property name="text" >
128 <string>&amp;Uninstall</string>
129 </property>
130 <property name="icon" >
131 <iconset resource="rbutilqt.qrc" >
132 <normaloff>:/icons/go-next.svg</normaloff>:/icons/go-next.svg</iconset>
133 </property>
134 </widget>
135 </item>
136 <item>
137 <widget class="QPushButton" name="buttonCancel" >
138 <property name="text" >
139 <string>&amp;Cancel</string>
140 </property>
141 <property name="icon" >
142 <iconset resource="rbutilqt.qrc" >
143 <normaloff>:/icons/process-stop.svg</normaloff>:/icons/process-stop.svg</iconset>
144 </property>
145 </widget>
146 </item>
147 </layout>
148 </item>
149 </layout>
150 </widget>
151 <resources>
152 <include location="rbutilqt.qrc" />
153 </resources>
154 <connections>
155 <connection>
156 <sender>buttonOk</sender>
157 <signal>clicked()</signal>
158 <receiver>UninstallFrm</receiver>
159 <slot>accept()</slot>
160 <hints>
161 <hint type="sourcelabel" >
162 <x>562</x>
163 <y>420</y>
164 </hint>
165 <hint type="destinationlabel" >
166 <x>500</x>
167 <y>352</y>
168 </hint>
169 </hints>
170 </connection>
171 <connection>
172 <sender>buttonCancel</sender>
173 <signal>clicked()</signal>
174 <receiver>UninstallFrm</receiver>
175 <slot>reject()</slot>
176 <hints>
177 <hint type="sourcelabel" >
178 <x>658</x>
179 <y>429</y>
180 </hint>
181 <hint type="destinationlabel" >
182 <x>611</x>
183 <y>360</y>
184 </hint>
185 </hints>
186 </connection>
187 </connections>
188</ui>
diff --git a/utils/rbutilqt/uninstallwindow.cpp b/utils/rbutilqt/uninstallwindow.cpp
new file mode 100644
index 0000000000..264b73f544
--- /dev/null
+++ b/utils/rbutilqt/uninstallwindow.cpp
@@ -0,0 +1,100 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include "uninstallwindow.h"
20#include "ui_uninstallfrm.h"
21#include "rbsettings.h"
22
23UninstallWindow::UninstallWindow(QWidget *parent) : QDialog(parent)
24{
25 ui.setupUi(this);
26 ui.UninstalllistWidget->setAlternatingRowColors(true);
27 connect(ui.UninstalllistWidget,SIGNAL(itemSelectionChanged()),this,SLOT(selectionChanged()));
28 connect(ui.CompleteRadioBtn,SIGNAL(toggled(bool)),this,SLOT(UninstallMethodChanged(bool)));
29
30 QString mountpoint = RbSettings::value(RbSettings::Mountpoint).toString();
31
32 uninstaller = new Uninstaller(this,mountpoint);
33 logger = new ProgressLoggerGui(this);
34 connect(uninstaller, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
35 connect(uninstaller, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
36 connect(uninstaller, SIGNAL(logFinished(void)), logger, SLOT(setFinished(void)));
37 connect(logger, SIGNAL(closed()), this, SLOT(close()));
38
39 // disable smart uninstall, if not possible
40 if(!uninstaller->uninstallPossible())
41 {
42 ui.smartRadioButton->setEnabled(false);
43 ui.smartGroupBox->setEnabled(false);
44 ui.CompleteRadioBtn->setChecked(true);
45 }
46 else // fill in installed parts
47 {
48 ui.smartRadioButton->setChecked(true);
49 ui.UninstalllistWidget->addItems(uninstaller->getAllSections());
50 }
51
52}
53
54
55void UninstallWindow::accept()
56{
57 logger->show();
58
59 if(ui.CompleteRadioBtn->isChecked())
60 {
61 uninstaller->deleteAll();
62 }
63 else
64 {
65 uninstaller->uninstall();
66 }
67
68}
69
70
71void UninstallWindow::selectionChanged()
72{
73 QList<QListWidgetItem *> itemlist = ui.UninstalllistWidget->selectedItems();
74 QStringList seletedStrings;
75 for(int i=0;i < itemlist.size(); i++ )
76 {
77 seletedStrings << itemlist.at(i)->text();
78 }
79
80 uninstaller->setSections(seletedStrings);
81}
82
83void UninstallWindow::UninstallMethodChanged(bool complete)
84{
85 if(complete)
86 ui.smartGroupBox->setEnabled(false);
87 else
88 ui.smartGroupBox->setEnabled(true);
89}
90
91
92void UninstallWindow::changeEvent(QEvent *e)
93{
94 if(e->type() == QEvent::LanguageChange) {
95 ui.retranslateUi(this);
96 } else {
97 QWidget::changeEvent(e);
98 }
99}
100
diff --git a/utils/rbutilqt/uninstallwindow.h b/utils/rbutilqt/uninstallwindow.h
new file mode 100644
index 0000000000..74e149aa02
--- /dev/null
+++ b/utils/rbutilqt/uninstallwindow.h
@@ -0,0 +1,51 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#ifndef UNINSTALLWINDOW_H
22#define UNINSTALLWINDOW_H
23
24#include <QtGui>
25
26#include "ui_uninstallfrm.h"
27#include "progressloggergui.h"
28#include "uninstall.h"
29
30class UninstallWindow : public QDialog
31{
32 Q_OBJECT
33 public:
34 UninstallWindow(QWidget *parent = nullptr);
35
36 public slots:
37 void accept(void);
38
39 private slots:
40 void selectionChanged();
41 void UninstallMethodChanged(bool complete);
42
43 private:
44 void changeEvent(QEvent *event);
45 Uninstaller* uninstaller;
46 Ui::UninstallFrm ui;
47 ProgressLoggerGui* logger;
48};
49
50
51#endif
diff --git a/utils/rbutilqt/version.h b/utils/rbutilqt/version.h
new file mode 100644
index 0000000000..b2d24d369b
--- /dev/null
+++ b/utils/rbutilqt/version.h
@@ -0,0 +1,44 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Riebeling
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21// PUREVERSION is needed to be able to just compare versions. It does not
22// contain a build timestamp because it needs to be the same in different
23// files
24// VERSION is the plain version number, used for http User-Agent string.
25// It is concatenated from separate digits to allow reusing for the Windows
26// resource information
27// BUILDID is an additional build string to handle package updates (i.e.
28// rebuilds because of issues like dependency problems or library updates).
29// Usually empty.
30#define BUILDID ""
31// Version string is constructed from parts, since the Windows rc file needs it
32// combined differently.
33#define VERSION_MAJOR 1
34#define VERSION_MINOR 4
35#define VERSION_MICRO 1
36#define VERSION_PATCH 0
37#define STR(x) #x
38#define VERSIONSTRING(a, b, c) STR(a) "." STR(b) "." STR(c)
39#define VERSION VERSIONSTRING(VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO) BUILDID
40// PUREVERSION should identify the build uniquely. Use version string for now.
41#define PUREVERSION "$Rev$"
42
43#define FULLVERSION VERSION " (" PUREVERSION "), built " __DATE__ " " __TIME__
44
diff --git a/utils/rbutilqt/zlib/zconf.h b/utils/rbutilqt/zlib/zconf.h
new file mode 100644
index 0000000000..3c21403fce
--- /dev/null
+++ b/utils/rbutilqt/zlib/zconf.h
@@ -0,0 +1,326 @@
1/* zconf.h -- configuration of the zlib compression library
2 * Copyright (C) 1995-2004 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6/* @(#) $Id$ */
7
8#ifndef ZCONF_H
9#define ZCONF_H
10
11/*
12 * If you *really* need a unique prefix for all types and library functions,
13 * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
14 */
15#ifdef Z_PREFIX
16# define deflateInit_ z_deflateInit_
17# define deflate z_deflate
18# define deflateEnd z_deflateEnd
19# define inflateInit_ z_inflateInit_
20# define inflate z_inflate
21# define inflateEnd z_inflateEnd
22# define deflateInit2_ z_deflateInit2_
23# define deflateSetDictionary z_deflateSetDictionary
24# define deflateCopy z_deflateCopy
25# define deflateReset z_deflateReset
26# define deflateParams z_deflateParams
27# define deflateBound z_deflateBound
28# define deflatePrime z_deflatePrime
29# define inflateInit2_ z_inflateInit2_
30# define inflateSetDictionary z_inflateSetDictionary
31# define inflateSync z_inflateSync
32# define inflateSyncPoint z_inflateSyncPoint
33# define inflateCopy z_inflateCopy
34# define inflateReset z_inflateReset
35# define inflateBack z_inflateBack
36# define inflateBackEnd z_inflateBackEnd
37# define compress z_compress
38# define compress2 z_compress2
39# define compressBound z_compressBound
40# define uncompress z_uncompress
41# define adler32 z_adler32
42# define crc32 z_crc32
43# define get_crc_table z_get_crc_table
44# define zError z_zError
45
46# define Byte z_Byte
47# define uInt z_uInt
48# define uLong z_uLong
49# define Bytef z_Bytef
50# define charf z_charf
51# define intf z_intf
52# define uIntf z_uIntf
53# define uLongf z_uLongf
54# define voidpf z_voidpf
55# define voidp z_voidp
56#endif
57
58#if defined(__MSDOS__) && !defined(MSDOS)
59# define MSDOS
60#endif
61#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
62# define OS2
63#endif
64#if defined(_WINDOWS) && !defined(WINDOWS)
65# define WINDOWS
66#endif
67#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
68# define WIN32
69#endif
70#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
71# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
72# ifndef SYS16BIT
73# define SYS16BIT
74# endif
75# endif
76#endif
77
78/*
79 * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
80 * than 64k bytes at a time (needed on systems with 16-bit int).
81 */
82#ifdef SYS16BIT
83# define MAXSEG_64K
84#endif
85#ifdef MSDOS
86# define UNALIGNED_OK
87#endif
88
89#ifdef __STDC_VERSION__
90# ifndef STDC
91# define STDC
92# endif
93# if __STDC_VERSION__ >= 199901L
94# ifndef STDC99
95# define STDC99
96# endif
97# endif
98#endif
99#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
100# define STDC
101#endif
102#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
103# define STDC
104#endif
105#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
106# define STDC
107#endif
108#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
109# define STDC
110#endif
111
112#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
113# define STDC
114#endif
115
116#ifndef STDC
117# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
118# define const /* note: need a more gentle solution here */
119# endif
120#endif
121
122/* Some Mac compilers merge all .h files incorrectly: */
123#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
124# define NO_DUMMY_DECL
125#endif
126
127/* Maximum value for memLevel in deflateInit2 */
128#ifndef MAX_MEM_LEVEL
129# ifdef MAXSEG_64K
130# define MAX_MEM_LEVEL 8
131# else
132# define MAX_MEM_LEVEL 9
133# endif
134#endif
135
136/* Maximum value for windowBits in deflateInit2 and inflateInit2.
137 * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
138 * created by gzip. (Files created by minigzip can still be extracted by
139 * gzip.)
140 */
141#ifndef MAX_WBITS
142# define MAX_WBITS 15 /* 32K LZ77 window */
143#endif
144
145/* The memory requirements for deflate are (in bytes):
146 (1 << (windowBits+2)) + (1 << (memLevel+9))
147 that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
148 plus a few kilobytes for small objects. For example, if you want to reduce
149 the default memory requirements from 256K to 128K, compile with
150 make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
151 Of course this will generally degrade compression (there's no free lunch).
152
153 The memory requirements for inflate are (in bytes) 1 << windowBits
154 that is, 32K for windowBits=15 (default value) plus a few kilobytes
155 for small objects.
156*/
157
158 /* Type declarations */
159
160#ifndef OF /* function prototypes */
161# ifdef STDC
162# define OF(args) args
163# else
164# define OF(args) ()
165# endif
166#endif
167
168/* The following definitions for FAR are needed only for MSDOS mixed
169 * model programming (small or medium model with some far allocations).
170 * This was tested only with MSC; for other MSDOS compilers you may have
171 * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
172 * just define FAR to be empty.
173 */
174#ifdef SYS16BIT
175# if defined(M_I86SM) || defined(M_I86MM)
176 /* MSC small or medium model */
177# define SMALL_MEDIUM
178# ifdef _MSC_VER
179# define FAR _far
180# else
181# define FAR far
182# endif
183# endif
184# if (defined(__SMALL__) || defined(__MEDIUM__))
185 /* Turbo C small or medium model */
186# define SMALL_MEDIUM
187# ifdef __BORLANDC__
188# define FAR _far
189# else
190# define FAR far
191# endif
192# endif
193#endif
194
195#if defined(WINDOWS) || defined(WIN32)
196 /* If building or using zlib as a DLL, define ZLIB_DLL.
197 * This is not mandatory, but it offers a little performance increase.
198 */
199# ifdef ZLIB_DLL
200# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
201# ifdef ZLIB_INTERNAL
202# define ZEXTERN extern __declspec(dllexport)
203# else
204# define ZEXTERN extern __declspec(dllimport)
205# endif
206# endif
207# endif /* ZLIB_DLL */
208 /* If building or using zlib with the WINAPI/WINAPIV calling convention,
209 * define ZLIB_WINAPI.
210 * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
211 */
212# ifdef ZLIB_WINAPI
213# ifdef FAR
214# undef FAR
215# endif
216# include <windows.h>
217 /* No need for _export, use ZLIB.DEF instead. */
218 /* For complete Windows compatibility, use WINAPI, not __stdcall. */
219# define ZEXPORT WINAPI
220# ifdef WIN32
221# define ZEXPORTVA WINAPIV
222# else
223# define ZEXPORTVA FAR CDECL
224# endif
225# endif
226#endif
227
228#if defined (__BEOS__)
229# ifdef ZLIB_DLL
230# ifdef ZLIB_INTERNAL
231# define ZEXPORT __declspec(dllexport)
232# define ZEXPORTVA __declspec(dllexport)
233# else
234# define ZEXPORT __declspec(dllimport)
235# define ZEXPORTVA __declspec(dllimport)
236# endif
237# endif
238#endif
239
240#ifndef ZEXTERN
241# define ZEXTERN extern
242#endif
243#ifndef ZEXPORT
244# define ZEXPORT
245#endif
246#ifndef ZEXPORTVA
247# define ZEXPORTVA
248#endif
249
250#ifndef FAR
251# define FAR
252#endif
253
254#if !defined(__MACTYPES__)
255typedef unsigned char Byte; /* 8 bits */
256#endif
257typedef unsigned int uInt; /* 16 bits or more */
258typedef unsigned long uLong; /* 32 bits or more */
259
260#ifdef SMALL_MEDIUM
261 /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
262# define Bytef Byte FAR
263#else
264 typedef Byte FAR Bytef;
265#endif
266typedef char FAR charf;
267typedef int FAR intf;
268typedef uInt FAR uIntf;
269typedef uLong FAR uLongf;
270
271#ifdef STDC
272 typedef void const *voidpc;
273 typedef void FAR *voidpf;
274 typedef void *voidp;
275#else
276 typedef Byte const *voidpc;
277 typedef Byte FAR *voidpf;
278 typedef Byte *voidp;
279#endif
280
281#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
282# include <sys/types.h> /* for off_t */
283# include <unistd.h> /* for SEEK_* and off_t */
284# ifdef VMS
285# include <unixio.h> /* for off_t */
286# endif
287# define z_off_t off_t
288#endif
289#ifndef SEEK_SET
290# define SEEK_SET 0 /* Seek from beginning of file. */
291# define SEEK_CUR 1 /* Seek from current position. */
292# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
293#endif
294#ifndef z_off_t
295# define z_off_t long
296#endif
297
298#if defined(__OS400__)
299# define NO_vsnprintf
300#endif
301
302#if defined(__MVS__)
303# define NO_vsnprintf
304# ifdef FAR
305# undef FAR
306# endif
307#endif
308
309/* MVS linker does not support external names larger than 8 bytes */
310#if defined(__MVS__)
311# pragma map(deflateInit_,"DEIN")
312# pragma map(deflateInit2_,"DEIN2")
313# pragma map(deflateEnd,"DEEND")
314# pragma map(deflateBound,"DEBND")
315# pragma map(inflateInit_,"ININ")
316# pragma map(inflateInit2_,"ININ2")
317# pragma map(inflateEnd,"INEND")
318# pragma map(inflateSync,"INSY")
319# pragma map(inflateSetDictionary,"INSEDI")
320# pragma map(compressBound,"CMBND")
321# pragma map(inflate_table,"INTABL")
322# pragma map(inflate_fast,"INFA")
323# pragma map(inflate_copyright,"INCOPY")
324#endif
325
326#endif /* ZCONF_H */
diff --git a/utils/rbutilqt/zlib/zlib.h b/utils/rbutilqt/zlib/zlib.h
new file mode 100644
index 0000000000..b4ddd34395
--- /dev/null
+++ b/utils/rbutilqt/zlib/zlib.h
@@ -0,0 +1,1200 @@
1/* zlib.h -- interface of the 'zlib' general purpose compression library
2 version 1.2.2, October 3rd, 2004
3
4 Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
5
6 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages
8 arising from the use of this software.
9
10 Permission is granted to anyone to use this software for any purpose,
11 including commercial applications, and to alter it and redistribute it
12 freely, subject to the following restrictions:
13
14 1. The origin of this software must not be misrepresented; you must not
15 claim that you wrote the original software. If you use this software
16 in a product, an acknowledgment in the product documentation would be
17 appreciated but is not required.
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20 3. This notice may not be removed or altered from any source distribution.
21
22 Jean-loup Gailly Mark Adler
23 jloup@gzip.org madler@alumni.caltech.edu
24
25
26 The data format used by the zlib library is described by RFCs (Request for
27 Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
28 (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
29*/
30
31#ifndef ZLIB_H
32#define ZLIB_H
33
34#include "zconf.h"
35
36#ifdef __cplusplus
37extern "C" {
38#endif
39
40#define ZLIB_VERSION "1.2.2"
41#define ZLIB_VERNUM 0x1220
42
43/*
44 The 'zlib' compression library provides in-memory compression and
45 decompression functions, including integrity checks of the uncompressed
46 data. This version of the library supports only one compression method
47 (deflation) but other algorithms will be added later and will have the same
48 stream interface.
49
50 Compression can be done in a single step if the buffers are large
51 enough (for example if an input file is mmap'ed), or can be done by
52 repeated calls of the compression function. In the latter case, the
53 application must provide more input and/or consume the output
54 (providing more output space) before each call.
55
56 The compressed data format used by default by the in-memory functions is
57 the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
58 around a deflate stream, which is itself documented in RFC 1951.
59
60 The library also supports reading and writing files in gzip (.gz) format
61 with an interface similar to that of stdio using the functions that start
62 with "gz". The gzip format is different from the zlib format. gzip is a
63 gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
64
65 This library can optionally read and write gzip streams in memory as well.
66
67 The zlib format was designed to be compact and fast for use in memory
68 and on communications channels. The gzip format was designed for single-
69 file compression on file systems, has a larger header than zlib to maintain
70 directory information, and uses a different, slower check method than zlib.
71
72 The library does not install any signal handler. The decoder checks
73 the consistency of the compressed data, so the library should never
74 crash even in case of corrupted input.
75*/
76
77typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
78typedef void (*free_func) OF((voidpf opaque, voidpf address));
79
80struct internal_state;
81
82typedef struct z_stream_s {
83 Bytef *next_in; /* next input byte */
84 uInt avail_in; /* number of bytes available at next_in */
85 uLong total_in; /* total nb of input bytes read so far */
86
87 Bytef *next_out; /* next output byte should be put there */
88 uInt avail_out; /* remaining free space at next_out */
89 uLong total_out; /* total nb of bytes output so far */
90
91 char *msg; /* last error message, NULL if no error */
92 struct internal_state FAR *state; /* not visible by applications */
93
94 alloc_func zalloc; /* used to allocate the internal state */
95 free_func zfree; /* used to free the internal state */
96 voidpf opaque; /* private data object passed to zalloc and zfree */
97
98 int data_type; /* best guess about the data type: ascii or binary */
99 uLong adler; /* adler32 value of the uncompressed data */
100 uLong reserved; /* reserved for future use */
101} z_stream;
102
103typedef z_stream FAR *z_streamp;
104
105/*
106 The application must update next_in and avail_in when avail_in has
107 dropped to zero. It must update next_out and avail_out when avail_out
108 has dropped to zero. The application must initialize zalloc, zfree and
109 opaque before calling the init function. All other fields are set by the
110 compression library and must not be updated by the application.
111
112 The opaque value provided by the application will be passed as the first
113 parameter for calls of zalloc and zfree. This can be useful for custom
114 memory management. The compression library attaches no meaning to the
115 opaque value.
116
117 zalloc must return Z_NULL if there is not enough memory for the object.
118 If zlib is used in a multi-threaded application, zalloc and zfree must be
119 thread safe.
120
121 On 16-bit systems, the functions zalloc and zfree must be able to allocate
122 exactly 65536 bytes, but will not be required to allocate more than this
123 if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
124 pointers returned by zalloc for objects of exactly 65536 bytes *must*
125 have their offset normalized to zero. The default allocation function
126 provided by this library ensures this (see zutil.c). To reduce memory
127 requirements and avoid any allocation of 64K objects, at the expense of
128 compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
129
130 The fields total_in and total_out can be used for statistics or
131 progress reports. After compression, total_in holds the total size of
132 the uncompressed data and may be saved for use in the decompressor
133 (particularly if the decompressor wants to decompress everything in
134 a single step).
135*/
136
137 /* constants */
138
139#define Z_NO_FLUSH 0
140#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
141#define Z_SYNC_FLUSH 2
142#define Z_FULL_FLUSH 3
143#define Z_FINISH 4
144#define Z_BLOCK 5
145/* Allowed flush values; see deflate() and inflate() below for details */
146
147#define Z_OK 0
148#define Z_STREAM_END 1
149#define Z_NEED_DICT 2
150#define Z_ERRNO (-1)
151#define Z_STREAM_ERROR (-2)
152#define Z_DATA_ERROR (-3)
153#define Z_MEM_ERROR (-4)
154#define Z_BUF_ERROR (-5)
155#define Z_VERSION_ERROR (-6)
156/* Return codes for the compression/decompression functions. Negative
157 * values are errors, positive values are used for special but normal events.
158 */
159
160#define Z_NO_COMPRESSION 0
161#define Z_BEST_SPEED 1
162#define Z_BEST_COMPRESSION 9
163#define Z_DEFAULT_COMPRESSION (-1)
164/* compression levels */
165
166#define Z_FILTERED 1
167#define Z_HUFFMAN_ONLY 2
168#define Z_RLE 3
169#define Z_DEFAULT_STRATEGY 0
170/* compression strategy; see deflateInit2() below for details */
171
172#define Z_BINARY 0
173#define Z_ASCII 1
174#define Z_UNKNOWN 2
175/* Possible values of the data_type field (though see inflate()) */
176
177#define Z_DEFLATED 8
178/* The deflate compression method (the only one supported in this version) */
179
180#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
181
182#define zlib_version zlibVersion()
183/* for compatibility with versions < 1.0.2 */
184
185 /* basic functions */
186
187ZEXTERN const char * ZEXPORT zlibVersion OF((void));
188/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
189 If the first character differs, the library code actually used is
190 not compatible with the zlib.h header file used by the application.
191 This check is automatically made by deflateInit and inflateInit.
192 */
193
194/*
195ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
196
197 Initializes the internal stream state for compression. The fields
198 zalloc, zfree and opaque must be initialized before by the caller.
199 If zalloc and zfree are set to Z_NULL, deflateInit updates them to
200 use default allocation functions.
201
202 The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
203 1 gives best speed, 9 gives best compression, 0 gives no compression at
204 all (the input data is simply copied a block at a time).
205 Z_DEFAULT_COMPRESSION requests a default compromise between speed and
206 compression (currently equivalent to level 6).
207
208 deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
209 enough memory, Z_STREAM_ERROR if level is not a valid compression level,
210 Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
211 with the version assumed by the caller (ZLIB_VERSION).
212 msg is set to null if there is no error message. deflateInit does not
213 perform any compression: this will be done by deflate().
214*/
215
216
217ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
218/*
219 deflate compresses as much data as possible, and stops when the input
220 buffer becomes empty or the output buffer becomes full. It may introduce some
221 output latency (reading input without producing any output) except when
222 forced to flush.
223
224 The detailed semantics are as follows. deflate performs one or both of the
225 following actions:
226
227 - Compress more input starting at next_in and update next_in and avail_in
228 accordingly. If not all input can be processed (because there is not
229 enough room in the output buffer), next_in and avail_in are updated and
230 processing will resume at this point for the next call of deflate().
231
232 - Provide more output starting at next_out and update next_out and avail_out
233 accordingly. This action is forced if the parameter flush is non zero.
234 Forcing flush frequently degrades the compression ratio, so this parameter
235 should be set only when necessary (in interactive applications).
236 Some output may be provided even if flush is not set.
237
238 Before the call of deflate(), the application should ensure that at least
239 one of the actions is possible, by providing more input and/or consuming
240 more output, and updating avail_in or avail_out accordingly; avail_out
241 should never be zero before the call. The application can consume the
242 compressed output when it wants, for example when the output buffer is full
243 (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
244 and with zero avail_out, it must be called again after making room in the
245 output buffer because there might be more output pending.
246
247 If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
248 flushed to the output buffer and the output is aligned on a byte boundary, so
249 that the decompressor can get all input data available so far. (In particular
250 avail_in is zero after the call if enough output space has been provided
251 before the call.) Flushing may degrade compression for some compression
252 algorithms and so it should be used only when necessary.
253
254 If flush is set to Z_FULL_FLUSH, all output is flushed as with
255 Z_SYNC_FLUSH, and the compression state is reset so that decompression can
256 restart from this point if previous compressed data has been damaged or if
257 random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
258 the compression.
259
260 If deflate returns with avail_out == 0, this function must be called again
261 with the same value of the flush parameter and more output space (updated
262 avail_out), until the flush is complete (deflate returns with non-zero
263 avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
264 avail_out is greater than six to avoid repeated flush markers due to
265 avail_out == 0 on return.
266
267 If the parameter flush is set to Z_FINISH, pending input is processed,
268 pending output is flushed and deflate returns with Z_STREAM_END if there
269 was enough output space; if deflate returns with Z_OK, this function must be
270 called again with Z_FINISH and more output space (updated avail_out) but no
271 more input data, until it returns with Z_STREAM_END or an error. After
272 deflate has returned Z_STREAM_END, the only possible operations on the
273 stream are deflateReset or deflateEnd.
274
275 Z_FINISH can be used immediately after deflateInit if all the compression
276 is to be done in a single step. In this case, avail_out must be at least
277 the value returned by deflateBound (see below). If deflate does not return
278 Z_STREAM_END, then it must be called again as described above.
279
280 deflate() sets strm->adler to the adler32 checksum of all input read
281 so far (that is, total_in bytes).
282
283 deflate() may update data_type if it can make a good guess about
284 the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
285 binary. This field is only for information purposes and does not affect
286 the compression algorithm in any manner.
287
288 deflate() returns Z_OK if some progress has been made (more input
289 processed or more output produced), Z_STREAM_END if all input has been
290 consumed and all output has been produced (only when flush is set to
291 Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
292 if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
293 (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
294 fatal, and deflate() can be called again with more input and more output
295 space to continue compressing.
296*/
297
298
299ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
300/*
301 All dynamically allocated data structures for this stream are freed.
302 This function discards any unprocessed input and does not flush any
303 pending output.
304
305 deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
306 stream state was inconsistent, Z_DATA_ERROR if the stream was freed
307 prematurely (some input or output was discarded). In the error case,
308 msg may be set but then points to a static string (which must not be
309 deallocated).
310*/
311
312
313/*
314ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
315
316 Initializes the internal stream state for decompression. The fields
317 next_in, avail_in, zalloc, zfree and opaque must be initialized before by
318 the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
319 value depends on the compression method), inflateInit determines the
320 compression method from the zlib header and allocates all data structures
321 accordingly; otherwise the allocation will be deferred to the first call of
322 inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
323 use default allocation functions.
324
325 inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
326 memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
327 version assumed by the caller. msg is set to null if there is no error
328 message. inflateInit does not perform any decompression apart from reading
329 the zlib header if present: this will be done by inflate(). (So next_in and
330 avail_in may be modified, but next_out and avail_out are unchanged.)
331*/
332
333
334ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
335/*
336 inflate decompresses as much data as possible, and stops when the input
337 buffer becomes empty or the output buffer becomes full. It may introduce
338 some output latency (reading input without producing any output) except when
339 forced to flush.
340
341 The detailed semantics are as follows. inflate performs one or both of the
342 following actions:
343
344 - Decompress more input starting at next_in and update next_in and avail_in
345 accordingly. If not all input can be processed (because there is not
346 enough room in the output buffer), next_in is updated and processing
347 will resume at this point for the next call of inflate().
348
349 - Provide more output starting at next_out and update next_out and avail_out
350 accordingly. inflate() provides as much output as possible, until there
351 is no more input data or no more space in the output buffer (see below
352 about the flush parameter).
353
354 Before the call of inflate(), the application should ensure that at least
355 one of the actions is possible, by providing more input and/or consuming
356 more output, and updating the next_* and avail_* values accordingly.
357 The application can consume the uncompressed output when it wants, for
358 example when the output buffer is full (avail_out == 0), or after each
359 call of inflate(). If inflate returns Z_OK and with zero avail_out, it
360 must be called again after making room in the output buffer because there
361 might be more output pending.
362
363 The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
364 Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
365 output as possible to the output buffer. Z_BLOCK requests that inflate() stop
366 if and when it get to the next deflate block boundary. When decoding the zlib
367 or gzip format, this will cause inflate() to return immediately after the
368 header and before the first block. When doing a raw inflate, inflate() will
369 go ahead and process the first block, and will return when it gets to the end
370 of that block, or when it runs out of data.
371
372 The Z_BLOCK option assists in appending to or combining deflate streams.
373 Also to assist in this, on return inflate() will set strm->data_type to the
374 number of unused bits in the last byte taken from strm->next_in, plus 64
375 if inflate() is currently decoding the last block in the deflate stream,
376 plus 128 if inflate() returned immediately after decoding an end-of-block
377 code or decoding the complete header up to just before the first byte of the
378 deflate stream. The end-of-block will not be indicated until all of the
379 uncompressed data from that block has been written to strm->next_out. The
380 number of unused bits may in general be greater than seven, except when
381 bit 7 of data_type is set, in which case the number of unused bits will be
382 less than eight.
383
384 inflate() should normally be called until it returns Z_STREAM_END or an
385 error. However if all decompression is to be performed in a single step
386 (a single call of inflate), the parameter flush should be set to
387 Z_FINISH. In this case all pending input is processed and all pending
388 output is flushed; avail_out must be large enough to hold all the
389 uncompressed data. (The size of the uncompressed data may have been saved
390 by the compressor for this purpose.) The next operation on this stream must
391 be inflateEnd to deallocate the decompression state. The use of Z_FINISH
392 is never required, but can be used to inform inflate that a faster approach
393 may be used for the single inflate() call.
394
395 In this implementation, inflate() always flushes as much output as
396 possible to the output buffer, and always uses the faster approach on the
397 first call. So the only effect of the flush parameter in this implementation
398 is on the return value of inflate(), as noted below, or when it returns early
399 because Z_BLOCK is used.
400
401 If a preset dictionary is needed after this call (see inflateSetDictionary
402 below), inflate sets strm->adler to the adler32 checksum of the dictionary
403 chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
404 strm->adler to the adler32 checksum of all output produced so far (that is,
405 total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
406 below. At the end of the stream, inflate() checks that its computed adler32
407 checksum is equal to that saved by the compressor and returns Z_STREAM_END
408 only if the checksum is correct.
409
410 inflate() will decompress and check either zlib-wrapped or gzip-wrapped
411 deflate data. The header type is detected automatically. Any information
412 contained in the gzip header is not retained, so applications that need that
413 information should instead use raw inflate, see inflateInit2() below, or
414 inflateBack() and perform their own processing of the gzip header and
415 trailer.
416
417 inflate() returns Z_OK if some progress has been made (more input processed
418 or more output produced), Z_STREAM_END if the end of the compressed data has
419 been reached and all uncompressed output has been produced, Z_NEED_DICT if a
420 preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
421 corrupted (input stream not conforming to the zlib format or incorrect check
422 value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
423 if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
424 Z_BUF_ERROR if no progress is possible or if there was not enough room in the
425 output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
426 inflate() can be called again with more input and more output space to
427 continue decompressing. If Z_DATA_ERROR is returned, the application may then
428 call inflateSync() to look for a good compression block if a partial recovery
429 of the data is desired.
430*/
431
432
433ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
434/*
435 All dynamically allocated data structures for this stream are freed.
436 This function discards any unprocessed input and does not flush any
437 pending output.
438
439 inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
440 was inconsistent. In the error case, msg may be set but then points to a
441 static string (which must not be deallocated).
442*/
443
444 /* Advanced functions */
445
446/*
447 The following functions are needed only in some special applications.
448*/
449
450/*
451ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
452 int level,
453 int method,
454 int windowBits,
455 int memLevel,
456 int strategy));
457
458 This is another version of deflateInit with more compression options. The
459 fields next_in, zalloc, zfree and opaque must be initialized before by
460 the caller.
461
462 The method parameter is the compression method. It must be Z_DEFLATED in
463 this version of the library.
464
465 The windowBits parameter is the base two logarithm of the window size
466 (the size of the history buffer). It should be in the range 8..15 for this
467 version of the library. Larger values of this parameter result in better
468 compression at the expense of memory usage. The default value is 15 if
469 deflateInit is used instead.
470
471 windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
472 determines the window size. deflate() will then generate raw deflate data
473 with no zlib header or trailer, and will not compute an adler32 check value.
474
475 windowBits can also be greater than 15 for optional gzip encoding. Add
476 16 to windowBits to write a simple gzip header and trailer around the
477 compressed data instead of a zlib wrapper. The gzip header will have no
478 file name, no extra data, no comment, no modification time (set to zero),
479 no header crc, and the operating system will be set to 255 (unknown). If a
480 gzip stream is being written, strm->adler is a crc32 instead of an adler32.
481
482 The memLevel parameter specifies how much memory should be allocated
483 for the internal compression state. memLevel=1 uses minimum memory but
484 is slow and reduces compression ratio; memLevel=9 uses maximum memory
485 for optimal speed. The default value is 8. See zconf.h for total memory
486 usage as a function of windowBits and memLevel.
487
488 The strategy parameter is used to tune the compression algorithm. Use the
489 value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
490 filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
491 string match), or Z_RLE to limit match distances to one (run-length
492 encoding). Filtered data consists mostly of small values with a somewhat
493 random distribution. In this case, the compression algorithm is tuned to
494 compress them better. The effect of Z_FILTERED is to force more Huffman
495 coding and less string matching; it is somewhat intermediate between
496 Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
497 Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
498 parameter only affects the compression ratio but not the correctness of the
499 compressed output even if it is not set appropriately.
500
501 deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
502 memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
503 method). msg is set to null if there is no error message. deflateInit2 does
504 not perform any compression: this will be done by deflate().
505*/
506
507ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
508 const Bytef *dictionary,
509 uInt dictLength));
510/*
511 Initializes the compression dictionary from the given byte sequence
512 without producing any compressed output. This function must be called
513 immediately after deflateInit, deflateInit2 or deflateReset, before any
514 call of deflate. The compressor and decompressor must use exactly the same
515 dictionary (see inflateSetDictionary).
516
517 The dictionary should consist of strings (byte sequences) that are likely
518 to be encountered later in the data to be compressed, with the most commonly
519 used strings preferably put towards the end of the dictionary. Using a
520 dictionary is most useful when the data to be compressed is short and can be
521 predicted with good accuracy; the data can then be compressed better than
522 with the default empty dictionary.
523
524 Depending on the size of the compression data structures selected by
525 deflateInit or deflateInit2, a part of the dictionary may in effect be
526 discarded, for example if the dictionary is larger than the window size in
527 deflate or deflate2. Thus the strings most likely to be useful should be
528 put at the end of the dictionary, not at the front.
529
530 Upon return of this function, strm->adler is set to the adler32 value
531 of the dictionary; the decompressor may later use this value to determine
532 which dictionary has been used by the compressor. (The adler32 value
533 applies to the whole dictionary even if only a subset of the dictionary is
534 actually used by the compressor.) If a raw deflate was requested, then the
535 adler32 value is not computed and strm->adler is not set.
536
537 deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
538 parameter is invalid (such as NULL dictionary) or the stream state is
539 inconsistent (for example if deflate has already been called for this stream
540 or if the compression method is bsort). deflateSetDictionary does not
541 perform any compression: this will be done by deflate().
542*/
543
544ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
545 z_streamp source));
546/*
547 Sets the destination stream as a complete copy of the source stream.
548
549 This function can be useful when several compression strategies will be
550 tried, for example when there are several ways of pre-processing the input
551 data with a filter. The streams that will be discarded should then be freed
552 by calling deflateEnd. Note that deflateCopy duplicates the internal
553 compression state which can be quite large, so this strategy is slow and
554 can consume lots of memory.
555
556 deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
557 enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
558 (such as zalloc being NULL). msg is left unchanged in both source and
559 destination.
560*/
561
562ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
563/*
564 This function is equivalent to deflateEnd followed by deflateInit,
565 but does not free and reallocate all the internal compression state.
566 The stream will keep the same compression level and any other attributes
567 that may have been set by deflateInit2.
568
569 deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
570 stream state was inconsistent (such as zalloc or state being NULL).
571*/
572
573ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
574 int level,
575 int strategy));
576/*
577 Dynamically update the compression level and compression strategy. The
578 interpretation of level and strategy is as in deflateInit2. This can be
579 used to switch between compression and straight copy of the input data, or
580 to switch to a different kind of input data requiring a different
581 strategy. If the compression level is changed, the input available so far
582 is compressed with the old level (and may be flushed); the new level will
583 take effect only at the next call of deflate().
584
585 Before the call of deflateParams, the stream state must be set as for
586 a call of deflate(), since the currently available input may have to
587 be compressed and flushed. In particular, strm->avail_out must be non-zero.
588
589 deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
590 stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
591 if strm->avail_out was zero.
592*/
593
594ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
595 uLong sourceLen));
596/*
597 deflateBound() returns an upper bound on the compressed size after
598 deflation of sourceLen bytes. It must be called after deflateInit()
599 or deflateInit2(). This would be used to allocate an output buffer
600 for deflation in a single pass, and so would be called before deflate().
601*/
602
603ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
604 int bits,
605 int value));
606/*
607 deflatePrime() inserts bits in the deflate output stream. The intent
608 is that this function is used to start off the deflate output with the
609 bits leftover from a previous deflate stream when appending to it. As such,
610 this function can only be used for raw deflate, and must be used before the
611 first deflate() call after a deflateInit2() or deflateReset(). bits must be
612 less than or equal to 16, and that many of the least significant bits of
613 value will be inserted in the output.
614
615 deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
616 stream state was inconsistent.
617*/
618
619/*
620ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
621 int windowBits));
622
623 This is another version of inflateInit with an extra parameter. The
624 fields next_in, avail_in, zalloc, zfree and opaque must be initialized
625 before by the caller.
626
627 The windowBits parameter is the base two logarithm of the maximum window
628 size (the size of the history buffer). It should be in the range 8..15 for
629 this version of the library. The default value is 15 if inflateInit is used
630 instead. windowBits must be greater than or equal to the windowBits value
631 provided to deflateInit2() while compressing, or it must be equal to 15 if
632 deflateInit2() was not used. If a compressed stream with a larger window
633 size is given as input, inflate() will return with the error code
634 Z_DATA_ERROR instead of trying to allocate a larger window.
635
636 windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
637 determines the window size. inflate() will then process raw deflate data,
638 not looking for a zlib or gzip header, not generating a check value, and not
639 looking for any check values for comparison at the end of the stream. This
640 is for use with other formats that use the deflate compressed data format
641 such as zip. Those formats provide their own check values. If a custom
642 format is developed using the raw deflate format for compressed data, it is
643 recommended that a check value such as an adler32 or a crc32 be applied to
644 the uncompressed data as is done in the zlib, gzip, and zip formats. For
645 most applications, the zlib format should be used as is. Note that comments
646 above on the use in deflateInit2() applies to the magnitude of windowBits.
647
648 windowBits can also be greater than 15 for optional gzip decoding. Add
649 32 to windowBits to enable zlib and gzip decoding with automatic header
650 detection, or add 16 to decode only the gzip format (the zlib format will
651 return a Z_DATA_ERROR. If a gzip stream is being decoded, strm->adler is
652 a crc32 instead of an adler32.
653
654 inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
655 memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
656 memLevel). msg is set to null if there is no error message. inflateInit2
657 does not perform any decompression apart from reading the zlib header if
658 present: this will be done by inflate(). (So next_in and avail_in may be
659 modified, but next_out and avail_out are unchanged.)
660*/
661
662ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
663 const Bytef *dictionary,
664 uInt dictLength));
665/*
666 Initializes the decompression dictionary from the given uncompressed byte
667 sequence. This function must be called immediately after a call of inflate
668 if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
669 can be determined from the adler32 value returned by this call of
670 inflate. The compressor and decompressor must use exactly the same
671 dictionary (see deflateSetDictionary).
672
673 inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
674 parameter is invalid (such as NULL dictionary) or the stream state is
675 inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
676 expected one (incorrect adler32 value). inflateSetDictionary does not
677 perform any decompression: this will be done by subsequent calls of
678 inflate().
679*/
680
681ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
682/*
683 Skips invalid compressed data until a full flush point (see above the
684 description of deflate with Z_FULL_FLUSH) can be found, or until all
685 available input is skipped. No output is provided.
686
687 inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
688 if no more input was provided, Z_DATA_ERROR if no flush point has been found,
689 or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
690 case, the application may save the current current value of total_in which
691 indicates where valid compressed data was found. In the error case, the
692 application may repeatedly call inflateSync, providing more input each time,
693 until success or end of the input data.
694*/
695
696ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
697 z_streamp source));
698/*
699 Sets the destination stream as a complete copy of the source stream.
700
701 This function can be useful when randomly accessing a large stream. The
702 first pass through the stream can periodically record the inflate state,
703 allowing restarting inflate at those points when randomly accessing the
704 stream.
705
706 inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
707 enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
708 (such as zalloc being NULL). msg is left unchanged in both source and
709 destination.
710*/
711
712ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
713/*
714 This function is equivalent to inflateEnd followed by inflateInit,
715 but does not free and reallocate all the internal decompression state.
716 The stream will keep attributes that may have been set by inflateInit2.
717
718 inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
719 stream state was inconsistent (such as zalloc or state being NULL).
720*/
721
722/*
723ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits,
724 unsigned char FAR *window));
725
726 Initialize the internal stream state for decompression using inflateBack()
727 calls. The fields zalloc, zfree and opaque in strm must be initialized
728 before the call. If zalloc and zfree are Z_NULL, then the default library-
729 derived memory allocation routines are used. windowBits is the base two
730 logarithm of the window size, in the range 8..15. window is a caller
731 supplied buffer of that size. Except for special applications where it is
732 assured that deflate was used with small window sizes, windowBits must be 15
733 and a 32K byte window must be supplied to be able to decompress general
734 deflate streams.
735
736 See inflateBack() for the usage of these routines.
737
738 inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
739 the paramaters are invalid, Z_MEM_ERROR if the internal state could not
740 be allocated, or Z_VERSION_ERROR if the version of the library does not
741 match the version of the header file.
742*/
743
744typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
745typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
746
747ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm,
748 in_func in, void FAR *in_desc,
749 out_func out, void FAR *out_desc));
750/*
751 inflateBack() does a raw inflate with a single call using a call-back
752 interface for input and output. This is more efficient than inflate() for
753 file i/o applications in that it avoids copying between the output and the
754 sliding window by simply making the window itself the output buffer. This
755 function trusts the application to not change the output buffer passed by
756 the output function, at least until inflateBack() returns.
757
758 inflateBackInit() must be called first to allocate the internal state
759 and to initialize the state with the user-provided window buffer.
760 inflateBack() may then be used multiple times to inflate a complete, raw
761 deflate stream with each call. inflateBackEnd() is then called to free
762 the allocated state.
763
764 A raw deflate stream is one with no zlib or gzip header or trailer.
765 This routine would normally be used in a utility that reads zip or gzip
766 files and writes out uncompressed files. The utility would decode the
767 header and process the trailer on its own, hence this routine expects
768 only the raw deflate stream to decompress. This is different from the
769 normal behavior of inflate(), which expects either a zlib or gzip header and
770 trailer around the deflate stream.
771
772 inflateBack() uses two subroutines supplied by the caller that are then
773 called by inflateBack() for input and output. inflateBack() calls those
774 routines until it reads a complete deflate stream and writes out all of the
775 uncompressed data, or until it encounters an error. The function's
776 parameters and return types are defined above in the in_func and out_func
777 typedefs. inflateBack() will call in(in_desc, &buf) which should return the
778 number of bytes of provided input, and a pointer to that input in buf. If
779 there is no input available, in() must return zero--buf is ignored in that
780 case--and inflateBack() will return a buffer error. inflateBack() will call
781 out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
782 should return zero on success, or non-zero on failure. If out() returns
783 non-zero, inflateBack() will return with an error. Neither in() nor out()
784 are permitted to change the contents of the window provided to
785 inflateBackInit(), which is also the buffer that out() uses to write from.
786 The length written by out() will be at most the window size. Any non-zero
787 amount of input may be provided by in().
788
789 For convenience, inflateBack() can be provided input on the first call by
790 setting strm->next_in and strm->avail_in. If that input is exhausted, then
791 in() will be called. Therefore strm->next_in must be initialized before
792 calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
793 immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
794 must also be initialized, and then if strm->avail_in is not zero, input will
795 initially be taken from strm->next_in[0 .. strm->avail_in - 1].
796
797 The in_desc and out_desc parameters of inflateBack() is passed as the
798 first parameter of in() and out() respectively when they are called. These
799 descriptors can be optionally used to pass any information that the caller-
800 supplied in() and out() functions need to do their job.
801
802 On return, inflateBack() will set strm->next_in and strm->avail_in to
803 pass back any unused input that was provided by the last in() call. The
804 return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
805 if in() or out() returned an error, Z_DATA_ERROR if there was a format
806 error in the deflate stream (in which case strm->msg is set to indicate the
807 nature of the error), or Z_STREAM_ERROR if the stream was not properly
808 initialized. In the case of Z_BUF_ERROR, an input or output error can be
809 distinguished using strm->next_in which will be Z_NULL only if in() returned
810 an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
811 out() returning non-zero. (in() will always be called before out(), so
812 strm->next_in is assured to be defined if out() returns non-zero.) Note
813 that inflateBack() cannot return Z_OK.
814*/
815
816ZEXTERN int ZEXPORT inflateBackEnd OF((z_stream FAR *strm));
817/*
818 All memory allocated by inflateBackInit() is freed.
819
820 inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
821 state was inconsistent.
822*/
823
824ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
825/* Return flags indicating compile-time options.
826
827 Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
828 1.0: size of uInt
829 3.2: size of uLong
830 5.4: size of voidpf (pointer)
831 7.6: size of z_off_t
832
833 Compiler, assembler, and debug options:
834 8: DEBUG
835 9: ASMV or ASMINF -- use ASM code
836 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
837 11: 0 (reserved)
838
839 One-time table building (smaller code, but not thread-safe if true):
840 12: BUILDFIXED -- build static block decoding tables when needed
841 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
842 14,15: 0 (reserved)
843
844 Library content (indicates missing functionality):
845 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
846 deflate code when not needed)
847 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
848 and decode gzip streams (to avoid linking crc code)
849 18-19: 0 (reserved)
850
851 Operation variations (changes in library functionality):
852 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
853 21: FASTEST -- deflate algorithm with only one, lowest compression level
854 22,23: 0 (reserved)
855
856 The sprintf variant used by gzprintf (zero is best):
857 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
858 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
859 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
860
861 Remainder:
862 27-31: 0 (reserved)
863 */
864
865
866 /* utility functions */
867
868/*
869 The following utility functions are implemented on top of the
870 basic stream-oriented functions. To simplify the interface, some
871 default options are assumed (compression level and memory usage,
872 standard memory allocation functions). The source code of these
873 utility functions can easily be modified if you need special options.
874*/
875
876ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
877 const Bytef *source, uLong sourceLen));
878/*
879 Compresses the source buffer into the destination buffer. sourceLen is
880 the byte length of the source buffer. Upon entry, destLen is the total
881 size of the destination buffer, which must be at least the value returned
882 by compressBound(sourceLen). Upon exit, destLen is the actual size of the
883 compressed buffer.
884 This function can be used to compress a whole file at once if the
885 input file is mmap'ed.
886 compress returns Z_OK if success, Z_MEM_ERROR if there was not
887 enough memory, Z_BUF_ERROR if there was not enough room in the output
888 buffer.
889*/
890
891ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
892 const Bytef *source, uLong sourceLen,
893 int level));
894/*
895 Compresses the source buffer into the destination buffer. The level
896 parameter has the same meaning as in deflateInit. sourceLen is the byte
897 length of the source buffer. Upon entry, destLen is the total size of the
898 destination buffer, which must be at least the value returned by
899 compressBound(sourceLen). Upon exit, destLen is the actual size of the
900 compressed buffer.
901
902 compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
903 memory, Z_BUF_ERROR if there was not enough room in the output buffer,
904 Z_STREAM_ERROR if the level parameter is invalid.
905*/
906
907ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
908/*
909 compressBound() returns an upper bound on the compressed size after
910 compress() or compress2() on sourceLen bytes. It would be used before
911 a compress() or compress2() call to allocate the destination buffer.
912*/
913
914ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
915 const Bytef *source, uLong sourceLen));
916/*
917 Decompresses the source buffer into the destination buffer. sourceLen is
918 the byte length of the source buffer. Upon entry, destLen is the total
919 size of the destination buffer, which must be large enough to hold the
920 entire uncompressed data. (The size of the uncompressed data must have
921 been saved previously by the compressor and transmitted to the decompressor
922 by some mechanism outside the scope of this compression library.)
923 Upon exit, destLen is the actual size of the compressed buffer.
924 This function can be used to decompress a whole file at once if the
925 input file is mmap'ed.
926
927 uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
928 enough memory, Z_BUF_ERROR if there was not enough room in the output
929 buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
930*/
931
932
933typedef voidp gzFile;
934
935ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
936/*
937 Opens a gzip (.gz) file for reading or writing. The mode parameter
938 is as in fopen ("rb" or "wb") but can also include a compression level
939 ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
940 Huffman only compression as in "wb1h", or 'R' for run-length encoding
941 as in "wb1R". (See the description of deflateInit2 for more information
942 about the strategy parameter.)
943
944 gzopen can be used to read a file which is not in gzip format; in this
945 case gzread will directly read from the file without decompression.
946
947 gzopen returns NULL if the file could not be opened or if there was
948 insufficient memory to allocate the (de)compression state; errno
949 can be checked to distinguish the two cases (if errno is zero, the
950 zlib error is Z_MEM_ERROR). */
951
952ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
953/*
954 gzdopen() associates a gzFile with the file descriptor fd. File
955 descriptors are obtained from calls like open, dup, creat, pipe or
956 fileno (in the file has been previously opened with fopen).
957 The mode parameter is as in gzopen.
958 The next call of gzclose on the returned gzFile will also close the
959 file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
960 descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
961 gzdopen returns NULL if there was insufficient memory to allocate
962 the (de)compression state.
963*/
964
965ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
966/*
967 Dynamically update the compression level or strategy. See the description
968 of deflateInit2 for the meaning of these parameters.
969 gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
970 opened for writing.
971*/
972
973ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
974/*
975 Reads the given number of uncompressed bytes from the compressed file.
976 If the input file was not in gzip format, gzread copies the given number
977 of bytes into the buffer.
978 gzread returns the number of uncompressed bytes actually read (0 for
979 end of file, -1 for error). */
980
981ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
982 voidpc buf, unsigned len));
983/*
984 Writes the given number of uncompressed bytes into the compressed file.
985 gzwrite returns the number of uncompressed bytes actually written
986 (0 in case of error).
987*/
988
989ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
990/*
991 Converts, formats, and writes the args to the compressed file under
992 control of the format string, as in fprintf. gzprintf returns the number of
993 uncompressed bytes actually written (0 in case of error). The number of
994 uncompressed bytes written is limited to 4095. The caller should assure that
995 this limit is not exceeded. If it is exceeded, then gzprintf() will return
996 return an error (0) with nothing written. In this case, there may also be a
997 buffer overflow with unpredictable consequences, which is possible only if
998 zlib was compiled with the insecure functions sprintf() or vsprintf()
999 because the secure snprintf() or vsnprintf() functions were not available.
1000*/
1001
1002ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
1003/*
1004 Writes the given null-terminated string to the compressed file, excluding
1005 the terminating null character.
1006 gzputs returns the number of characters written, or -1 in case of error.
1007*/
1008
1009ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
1010/*
1011 Reads bytes from the compressed file until len-1 characters are read, or
1012 a newline character is read and transferred to buf, or an end-of-file
1013 condition is encountered. The string is then terminated with a null
1014 character.
1015 gzgets returns buf, or Z_NULL in case of error.
1016*/
1017
1018ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
1019/*
1020 Writes c, converted to an unsigned char, into the compressed file.
1021 gzputc returns the value that was written, or -1 in case of error.
1022*/
1023
1024ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
1025/*
1026 Reads one byte from the compressed file. gzgetc returns this byte
1027 or -1 in case of end of file or error.
1028*/
1029
1030ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
1031/*
1032 Push one character back onto the stream to be read again later.
1033 Only one character of push-back is allowed. gzungetc() returns the
1034 character pushed, or -1 on failure. gzungetc() will fail if a
1035 character has been pushed but not read yet, or if c is -1. The pushed
1036 character will be discarded if the stream is repositioned with gzseek()
1037 or gzrewind().
1038*/
1039
1040ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
1041/*
1042 Flushes all pending output into the compressed file. The parameter
1043 flush is as in the deflate() function. The return value is the zlib
1044 error number (see function gzerror below). gzflush returns Z_OK if
1045 the flush parameter is Z_FINISH and all output could be flushed.
1046 gzflush should be called only when strictly necessary because it can
1047 degrade compression.
1048*/
1049
1050ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
1051 z_off_t offset, int whence));
1052/*
1053 Sets the starting position for the next gzread or gzwrite on the
1054 given compressed file. The offset represents a number of bytes in the
1055 uncompressed data stream. The whence parameter is defined as in lseek(2);
1056 the value SEEK_END is not supported.
1057 If the file is opened for reading, this function is emulated but can be
1058 extremely slow. If the file is opened for writing, only forward seeks are
1059 supported; gzseek then compresses a sequence of zeroes up to the new
1060 starting position.
1061
1062 gzseek returns the resulting offset location as measured in bytes from
1063 the beginning of the uncompressed stream, or -1 in case of error, in
1064 particular if the file is opened for writing and the new starting position
1065 would be before the current position.
1066*/
1067
1068ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
1069/*
1070 Rewinds the given file. This function is supported only for reading.
1071
1072 gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
1073*/
1074
1075ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
1076/*
1077 Returns the starting position for the next gzread or gzwrite on the
1078 given compressed file. This position represents a number of bytes in the
1079 uncompressed data stream.
1080
1081 gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
1082*/
1083
1084ZEXTERN int ZEXPORT gzeof OF((gzFile file));
1085/*
1086 Returns 1 when EOF has previously been detected reading the given
1087 input stream, otherwise zero.
1088*/
1089
1090ZEXTERN int ZEXPORT gzclose OF((gzFile file));
1091/*
1092 Flushes all pending output if necessary, closes the compressed file
1093 and deallocates all the (de)compression state. The return value is the zlib
1094 error number (see function gzerror below).
1095*/
1096
1097ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
1098/*
1099 Returns the error message for the last error which occurred on the
1100 given compressed file. errnum is set to zlib error number. If an
1101 error occurred in the file system and not in the compression library,
1102 errnum is set to Z_ERRNO and the application may consult errno
1103 to get the exact error code.
1104*/
1105
1106ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
1107/*
1108 Clears the error and end-of-file flags for file. This is analogous to the
1109 clearerr() function in stdio. This is useful for continuing to read a gzip
1110 file that is being written concurrently.
1111*/
1112
1113 /* checksum functions */
1114
1115/*
1116 These functions are not related to compression but are exported
1117 anyway because they might be useful in applications using the
1118 compression library.
1119*/
1120
1121ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
1122
1123/*
1124 Update a running Adler-32 checksum with the bytes buf[0..len-1] and
1125 return the updated checksum. If buf is NULL, this function returns
1126 the required initial value for the checksum.
1127 An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
1128 much faster. Usage example:
1129
1130 uLong adler = adler32(0L, Z_NULL, 0);
1131
1132 while (read_buffer(buffer, length) != EOF) {
1133 adler = adler32(adler, buffer, length);
1134 }
1135 if (adler != original_adler) error();
1136*/
1137
1138ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
1139/*
1140 Update a running crc with the bytes buf[0..len-1] and return the updated
1141 crc. If buf is NULL, this function returns the required initial value
1142 for the crc. Pre- and post-conditioning (one's complement) is performed
1143 within this function so it shouldn't be done by the application.
1144 Usage example:
1145
1146 uLong crc = crc32(0L, Z_NULL, 0);
1147
1148 while (read_buffer(buffer, length) != EOF) {
1149 crc = crc32(crc, buffer, length);
1150 }
1151 if (crc != original_crc) error();
1152*/
1153
1154
1155 /* various hacks, don't look :) */
1156
1157/* deflateInit and inflateInit are macros to allow checking the zlib version
1158 * and the compiler's view of z_stream:
1159 */
1160ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
1161 const char *version, int stream_size));
1162ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
1163 const char *version, int stream_size));
1164ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
1165 int windowBits, int memLevel,
1166 int strategy, const char *version,
1167 int stream_size));
1168ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
1169 const char *version, int stream_size));
1170ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits,
1171 unsigned char FAR *window,
1172 const char *version,
1173 int stream_size));
1174#define deflateInit(strm, level) \
1175 deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
1176#define inflateInit(strm) \
1177 inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
1178#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
1179 deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
1180 (strategy), ZLIB_VERSION, sizeof(z_stream))
1181#define inflateInit2(strm, windowBits) \
1182 inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
1183#define inflateBackInit(strm, windowBits, window) \
1184 inflateBackInit_((strm), (windowBits), (window), \
1185 ZLIB_VERSION, sizeof(z_stream))
1186
1187
1188#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
1189 struct internal_state {int dummy;}; /* hack for buggy compilers */
1190#endif
1191
1192ZEXTERN const char * ZEXPORT zError OF((int));
1193ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
1194ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
1195
1196#ifdef __cplusplus
1197}
1198#endif
1199
1200#endif /* ZLIB_H */
diff --git a/utils/sansapatcher/Makefile b/utils/sansapatcher/Makefile
new file mode 100644
index 0000000000..85c36c6d14
--- /dev/null
+++ b/utils/sansapatcher/Makefile
@@ -0,0 +1,52 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7
8TARGET_DIR ?= $(shell pwd)/
9CFLAGS += -Wall -W -D_LARGEFILE64_SOURCE
10
11OUTPUT = sansapatcher
12
13# inputs
14LIBSOURCES := sansapatcher.c sansaio-posix.c sansaio-win32.c
15SOURCES := main.c
16# additional link dependencies for the standalone executable
17EXTRADEPS :=
18
19# Releases of sansapatcher are created with "make RELEASE=1". This
20# enables BOOTOBJS and uses the VERSION string defined in main.c
21ifdef RELEASE
22CFLAGS += -DRELEASE
23BOOTOBJS=1
24endif
25
26ifdef WITH_BOOTOBJS
27BOOTSRC = bootimg_c200.c bootimg_e200.c
28SOURCES += $(BOOTSRC)
29CFLAGS += -DWITH_BOOTOBJS
30endif
31
32include ../libtools.make
33
34# find out if we need to link the manifest resource.
35# Since libtools.make sets up BINARY we check it for the file extension .exe.
36ifeq ($(findstring exe,$(BINARY)),exe)
37$(BINARY): $(OBJDIR)sansapatcher-rc.o
38endif
39
40$(OBJDIR)main.o: $(BOOTSRC)
41$(OBJDIR)sansapatcher-rc.o: sansapatcher.rc sansapatcher.manifest
42 @echo WINDRES $(notdir $<)
43 $(SILENT)$(CROSS)$(WINDRES) -i sansapatcher.rc -o $@
44
45bootimg_c200.c: firmware.mi4 $(BIN2C)
46 @echo BIN2C $<
47 $(SILENT)$(BIN2C) $< $*
48
49bootimg_e200.c: PP5022.mi4 $(BIN2C)
50 @echo BIN2C $< $*
51 $(SILENT)$(BIN2C) $< $*
52
diff --git a/utils/sansapatcher/README b/utils/sansapatcher/README
new file mode 100644
index 0000000000..c62f676110
--- /dev/null
+++ b/utils/sansapatcher/README
@@ -0,0 +1,36 @@
1sansapatcher
2------------
3
4To compile sansapatcher, you need both the C200 and E200 Rockbox
5bootloaders. The latest bootloaders can always be found here:
6
7http://download.rockbox.org/bootloader/sandisk-sansa/e200/PP5022.mi4
8http://download.rockbox.org/bootloader/sandisk-sansa/c200/firmware.mi4
9
10Place both these files in the sansapatcher source directory, and type "make".
11
12
13Building your own bootloaders
14-----------------------------
15
16If you would like to compile the bootloaders yourself, they are the output of
17running the "Bootloader" build for the E200 and C200 targets.
18
19NOTE: Unless you know what you are doing, it is recommended that you
20 use the official pre-built binary bootloaders linked to above.
21 Bootloaders compiled from current Rockbox SVN are untested and
22 may contain bugs preventing you from starting the device (or
23 worse...).
24
25In the Rockbox source directory, do:
26
27mkdir build-e200-bootloader
28cd build-e200-bootloader
29../tools/configure
30[Select E200, then B for bootloader]
31make
32
33This will create PP5022.mi4 which you should copy to the sansapatcher
34build directory.
35
36A similar process for the C200 will create firmware.mi4.
diff --git a/utils/sansapatcher/main.c b/utils/sansapatcher/main.c
new file mode 100644
index 0000000000..d12e33c22b
--- /dev/null
+++ b/utils/sansapatcher/main.c
@@ -0,0 +1,420 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006-2007 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdio.h>
23#include <unistd.h>
24#include <fcntl.h>
25#include <string.h>
26#include <stdlib.h>
27#include <inttypes.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30
31#include "sansapatcher.h"
32#include "sansaio.h"
33#include "parttypes.h"
34#ifdef WITH_BOOTOBJS
35#include "bootimg_c200.h"
36#include "bootimg_e200.h"
37#endif
38
39#ifndef VERSION
40#define VERSION "0.8 with v6.0 bootloaders"
41#endif
42
43enum {
44 NONE,
45 INSTALL,
46 INTERACTIVE,
47 SHOW_INFO,
48 LIST_IMAGES,
49 DELETE_BOOTLOADER,
50 ADD_BOOTLOADER,
51 READ_FIRMWARE,
52 WRITE_FIRMWARE,
53 READ_PARTITION,
54 WRITE_PARTITION,
55 UPDATE_OF,
56 UPDATE_PPBL
57};
58
59static void print_usage(void)
60{
61 fprintf(stderr,"Usage: sansapatcher --scan\n");
62#ifdef __WIN32__
63 fprintf(stderr," or sansapatcher [DISKNO] [action]\n");
64#else
65 fprintf(stderr," or sansapatcher [device] [action]\n");
66#endif
67 fprintf(stderr,"\n");
68 fprintf(stderr,"Where [action] is one of the following options:\n");
69 fprintf(stderr," --install\n");
70 fprintf(stderr," -l, --list\n");
71 fprintf(stderr," -rf, --read-firmware filename.mi4\n");
72 fprintf(stderr," -a, --add-bootloader filename.mi4\n");
73 fprintf(stderr," -d, --delete-bootloader\n");
74 fprintf(stderr," -of --update-original-firmware filename.mi4\n");
75 fprintf(stderr," -bl --update-ppbl filename.bin\n");
76 fprintf(stderr,"\n");
77
78#ifdef __WIN32__
79 fprintf(stderr,"DISKNO is the number (e.g. 2) Windows has assigned to your sansa's hard disk.\n");
80 fprintf(stderr,"The first hard disk in your computer (i.e. C:\\) will be disk 0, the next disk\n");
81 fprintf(stderr,"will be disk 1 etc. sansapatcher will refuse to access a disk unless it\n");
82 fprintf(stderr,"can identify it as being an E200 or C200.\n");
83 fprintf(stderr,"\n");
84#else
85#if defined(linux) || defined (__linux)
86 fprintf(stderr,"\"device\" is the device node (e.g. /dev/sda) assigned to your sansa.\n");
87#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
88 fprintf(stderr,"\"device\" is the device node (e.g. /dev/da1) assigned to your sansa.\n");
89#elif defined(__APPLE__) && defined(__MACH__)
90 fprintf(stderr,"\"device\" is the device node (e.g. /dev/disk1) assigned to your sansa.\n");
91#endif
92 fprintf(stderr,"sansapatcher will refuse to access a disk unless it can identify it as being\n");
93 fprintf(stderr,"an E200 or C200.\n");
94#endif
95}
96
97static const char* get_parttype(int pt)
98{
99 int i;
100 static const char unknown[]="Unknown";
101
102 if (pt == -1) {
103 return "HFS/HFS+";
104 }
105
106 i=0;
107 while (parttypes[i].name != NULL) {
108 if (parttypes[i].type == pt) {
109 return (parttypes[i].name);
110 }
111 i++;
112 }
113
114 return unknown;
115}
116
117static void display_partinfo(struct sansa_t* sansa)
118{
119 int i;
120 double sectors_per_MB = (1024.0*1024.0)/sansa->sector_size;
121
122 printf("[INFO] Part Start Sector End Sector Size (MB) Type\n");
123 for ( i = 0; i < 4; i++ ) {
124 if (sansa->pinfo[i].start != 0) {
125 printf("[INFO] %d %10ld %10ld %10.1f %s (0x%02x)\n",
126 i,
127 sansa->pinfo[i].start,
128 sansa->pinfo[i].start+sansa->pinfo[i].size-1,
129 sansa->pinfo[i].size/sectors_per_MB,
130 get_parttype(sansa->pinfo[i].type),
131 sansa->pinfo[i].type);
132 }
133 }
134}
135
136
137int main(int argc, char* argv[])
138{
139 char yesno[4];
140 int i;
141 int n;
142 char* filename;
143 int action = SHOW_INFO;
144 struct sansa_t sansa;
145 int res = 0;
146 unsigned char* buf = NULL;
147 unsigned int len;
148
149 fprintf(stderr,"sansapatcher v" VERSION " - (C) Dave Chapman 2006-2007\n");
150 fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n");
151 fprintf(stderr,"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
152
153 if ((argc > 1) && ((strcmp(argv[1],"-h")==0) || (strcmp(argv[1],"--help")==0))) {
154 print_usage();
155 return SANSA_OK;
156 }
157
158 if (sansa_alloc_buffer(&sansa, BUFFER_SIZE) < 0) {
159 fprintf(stderr,"Failed to allocate memory buffer\n");
160 return SANSA_INTERNAL_ERROR;
161 }
162
163 if ((argc > 1) && (strcmp(argv[1],"--scan")==0)) {
164 if (sansa_scan(&sansa) == 0)
165 fprintf(stderr,"[ERR] No E200s or C200s found.\n");
166 return SANSA_NOT_FOUND;
167 }
168
169 /* If the first parameter doesn't start with -, then we interpret it as a device */
170 if ((argc > 1) && (argv[1][0] != '-')) {
171 sansa.diskname[0]=0;
172#ifdef __WIN32__
173 snprintf(sansa.diskname,sizeof(sansa.diskname),"\\\\.\\PhysicalDrive%s",argv[1]);
174#else
175 strncpy(sansa.diskname,argv[1],sizeof(sansa.diskname));
176#endif
177 i = 2;
178 } else {
179 /* Autoscan for C200/E200s */
180 n = sansa_scan(&sansa);
181 if (n==0) {
182 fprintf(stderr,"[ERR] No E200s or C200s found, aborting\n");
183 fprintf(stderr,"[ERR] Please connect your sansa and ensure it is in UMS mode\n");
184#if defined(__APPLE__) && defined(__MACH__)
185 fprintf(stderr,"[ERR] Also ensure that your Sansa's main partition is not mounted.\n");
186#elif !defined(__WIN32__)
187 if (geteuid()!=0) {
188 fprintf(stderr,"[ERR] You may also need to run sansapatcher as root.\n");
189 }
190#endif
191 fprintf(stderr,"[ERR] Please refer to the Rockbox manual if you continue to have problems.\n");
192 } else if (n > 1) {
193 fprintf(stderr,"[ERR] %d Sansas found, aborting\n",n);
194 fprintf(stderr,"[ERR] Please connect only one Sansa and re-run sansapatcher.\n");
195 }
196
197 if (n != 1) {
198#ifdef WITH_BOOTOBJS
199 if (argc==1) {
200 printf("\nPress ENTER to exit sansapatcher :");
201 fgets(yesno,4,stdin);
202 }
203#endif
204 return n > 1 ? SANSA_MULTIPLE_DEVICES : SANSA_NOT_FOUND;
205 }
206
207 i = 1;
208 }
209
210#ifdef WITH_BOOTOBJS
211 action = INTERACTIVE;
212#endif
213
214 while (i < argc) {
215 if ((strcmp(argv[i],"-l")==0) || (strcmp(argv[i],"--list")==0)) {
216 action = LIST_IMAGES;
217 i++;
218 } else if (strcmp(argv[i],"--install")==0) {
219 action = INSTALL;
220 i++;
221 } else if ((strcmp(argv[i],"-d")==0) ||
222 (strcmp(argv[i],"--delete-bootloader")==0)) {
223 action = DELETE_BOOTLOADER;
224 i++;
225 } else if ((strcmp(argv[i],"-a")==0) ||
226 (strcmp(argv[i],"--add-bootloader")==0)) {
227 action = ADD_BOOTLOADER;
228 i++;
229 if (i == argc) { print_usage(); return SANSA_WRONG_ARGUMENTS; }
230 filename=argv[i];
231 i++;
232 } else if ((strcmp(argv[i],"-of")==0) ||
233 (strcmp(argv[i],"--update-original-firmware")==0)) {
234 action = UPDATE_OF;
235 i++;
236 if (i == argc) { print_usage(); return SANSA_WRONG_ARGUMENTS; }
237 filename=argv[i];
238 i++;
239 } else if ((strcmp(argv[i],"-bl")==0) ||
240 (strcmp(argv[i],"--update-ppbl")==0)) {
241 action = UPDATE_PPBL;
242 i++;
243 if (i == argc) { print_usage(); return SANSA_WRONG_ARGUMENTS; }
244 filename=argv[i];
245 i++;
246 } else if ((strcmp(argv[i],"-rf")==0) ||
247 (strcmp(argv[i],"--read-firmware")==0)) {
248 action = READ_FIRMWARE;
249 i++;
250 if (i == argc) { print_usage(); return SANSA_WRONG_ARGUMENTS; }
251 filename=argv[i];
252 i++;
253 }
254 }
255
256 if (sansa.diskname[0]==0) {
257 print_usage();
258 return SANSA_WRONG_ARGUMENTS;
259 }
260
261 if (sansa_open(&sansa, 0) < 0) {
262 return SANSA_ACCESS_DENIED;
263 }
264
265 fprintf(stderr,"[INFO] Reading partition table from %s\n",sansa.diskname);
266 fprintf(stderr,"[INFO] Sector size is %d bytes\n",sansa.sector_size);
267
268 if (sansa_read_partinfo(&sansa,0) < 0) {
269 return SANSA_PARTITION_ERROR;
270 }
271
272 display_partinfo(&sansa);
273
274 i = is_sansa(&sansa);
275 if (i < 0) {
276 fprintf(stderr,"[ERR] Disk is not an E200 or C200 (%d), aborting.\n",i);
277 return SANSA_WRONG_TYPE;
278 }
279
280 if (sansa.hasoldbootloader) {
281 printf("[ERR] ************************************************************************\n");
282 printf("[ERR] *** OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n");
283 printf("[ERR] *** You must reinstall the original Sansa firmware before running\n");
284 printf("[ERR] *** sansapatcher for the first time.\n");
285 printf("[ERR] *** See http://www.rockbox.org/wiki/SansaE200Install\n");
286 printf("[ERR] ************************************************************************\n");
287 res = SANSA_OLD_INSTALL;
288 } else {
289 if (action==LIST_IMAGES) {
290 sansa_list_images(&sansa);
291#ifdef WITH_BOOTOBJS
292 } else if (action==INTERACTIVE) {
293
294 printf("Enter i to install the Rockbox bootloader, u to uninstall\n or c to cancel and do nothing (i/u/c) :");
295
296 if (fgets(yesno,4,stdin)) {
297 if (yesno[0]=='i') {
298 if (sansa_reopen_rw(&sansa) < 0) {
299 res = SANSA_CANNOT_REOPEN;
300 }
301 if (strcmp(sansa.targetname,"c200") == 0) {
302 len = LEN_bootimg_c200;
303 buf = bootimg_c200;
304 } else {
305 len = LEN_bootimg_e200;
306 buf = bootimg_e200;
307 }
308 if (sansa_add_bootloader(&sansa, buf, len)==0) {
309 fprintf(stderr,"[INFO] Bootloader installed successfully.\n");
310 } else {
311 fprintf(stderr,"[ERR] --install failed.\n");
312 res = SANSA_INSTALL_FAILED;
313 }
314 } else if (yesno[0]=='u') {
315 if (sansa_reopen_rw(&sansa) < 0) {
316 res = SANSA_CANNOT_REOPEN;
317 }
318
319 if (sansa_delete_bootloader(&sansa)==0) {
320 fprintf(stderr,"[INFO] Bootloader removed.\n");
321 } else {
322 fprintf(stderr,"[ERR] Bootloader removal failed.\n");
323 res = SANSA_UNINSTALL_FAILED;
324 }
325 }
326 }
327#endif
328 } else if (action==READ_FIRMWARE) {
329 if (sansa_read_firmware(&sansa, filename)==0) {
330 fprintf(stderr,"[INFO] Firmware read to file %s.\n",filename);
331 } else {
332 fprintf(stderr,"[ERR] --read-firmware failed.\n");
333 }
334#ifdef WITH_BOOTOBJS
335 } else if (action==INSTALL) {
336 if (sansa_reopen_rw(&sansa) < 0) {
337 return SANSA_CANNOT_REOPEN;
338 }
339
340 if (strcmp(sansa.targetname,"c200") == 0) {
341 len = LEN_bootimg_c200;
342 buf = bootimg_c200;
343 } else {
344 len = LEN_bootimg_e200;
345 buf = bootimg_e200;
346 }
347
348 if (sansa_add_bootloader(&sansa, buf, len)==0) {
349 fprintf(stderr,"[INFO] Bootloader installed successfully.\n");
350 } else {
351 fprintf(stderr,"[ERR] --install failed.\n");
352 }
353#endif
354 } else if (action==ADD_BOOTLOADER) {
355 if (sansa_reopen_rw(&sansa) < 0) {
356 return SANSA_CANNOT_REOPEN;
357 }
358
359 len = sansa_read_bootloader(&sansa, filename, &buf);
360 if (len > 0) {
361 if (sansa_add_bootloader(&sansa, buf, len)==0) {
362 fprintf(stderr,"[INFO] Bootloader %s written to device.\n",filename);
363 } else {
364 fprintf(stderr,"[ERR] --add-bootloader failed.\n");
365 }
366 }
367 } else if (action==DELETE_BOOTLOADER) {
368 if (sansa_reopen_rw(&sansa) < 0) {
369 return SANSA_CANNOT_REOPEN;
370 }
371
372 if (sansa_delete_bootloader(&sansa)==0) {
373 fprintf(stderr,"[INFO] Bootloader removed successfully.\n");
374 } else {
375 fprintf(stderr,"[ERR] --delete-bootloader failed.\n");
376 }
377 } else if (action==UPDATE_OF) {
378 if (sansa_reopen_rw(&sansa) < 0) {
379 return SANSA_CANNOT_REOPEN;
380 }
381
382 if (sansa_update_of(&sansa, filename)==0) {
383 fprintf(stderr,"[INFO] OF updated successfully.\n");
384 } else {
385 fprintf(stderr,"[ERR] --update-original-firmware failed.\n");
386 }
387 } else if (action==UPDATE_PPBL) {
388 printf("[WARN] PPBL installation will overwrite your bootloader. This will lead to a\n");
389 printf(" Sansa that won't boot if the bootloader file is invalid. Only continue if\n");
390 printf(" you're sure you know what you're doing.\n");
391 printf(" Continue (y/n)? ");
392
393 if (fgets(yesno,4,stdin)) {
394 if (yesno[0]=='y') {
395 if (sansa_reopen_rw(&sansa) < 0) {
396 return SANSA_CANNOT_REOPEN;
397 }
398
399 if (sansa_update_ppbl(&sansa, filename)==0) {
400 fprintf(stderr,"[INFO] PPBL updated successfully.\n");
401 } else {
402 fprintf(stderr,"[ERR] --update-ppbl failed.\n");
403 }
404 }
405 }
406 }
407 }
408
409 sansa_close(&sansa);
410 sansa_dealloc_buffer(&sansa);
411
412#ifdef WITH_BOOTOBJS
413 if (action==INTERACTIVE) {
414 printf("Press ENTER to exit sansapatcher :");
415 fgets(yesno,4,stdin);
416 }
417#endif
418
419 return res;
420}
diff --git a/utils/sansapatcher/parttypes.h b/utils/sansapatcher/parttypes.h
new file mode 100644
index 0000000000..f8de303553
--- /dev/null
+++ b/utils/sansapatcher/parttypes.h
@@ -0,0 +1,109 @@
1/* DOS partition types - taken from fdisk */
2
3struct parttype {
4 unsigned char type;
5 char *name;
6};
7
8struct parttype parttypes[] = {
9 {0x00, "Empty"},
10 {0x01, "FAT12"},
11 {0x02, "XENIX root"},
12 {0x03, "XENIX usr"},
13 {0x04, "FAT16 <32M"},
14 {0x05, "Extended"}, /* DOS 3.3+ extended partition */
15 {0x06, "FAT16"}, /* DOS 16-bit >=32M */
16 {0x07, "HPFS/NTFS"}, /* OS/2 IFS, eg, HPFS or NTFS or QNX */
17 {0x08, "AIX"}, /* AIX boot (AIX -- PS/2 port) or SplitDrive */
18 {0x09, "AIX bootable"}, /* AIX data or Coherent */
19 {0x0a, "OS/2 Boot Manager"},/* OS/2 Boot Manager */
20 {0x0b, "W95 FAT32"},
21 {0x0c, "W95 FAT32 (LBA)"},/* LBA really is `Extended Int 13h' */
22 {0x0e, "W95 FAT16 (LBA)"},
23 {0x0f, "W95 Ext'd (LBA)"},
24 {0x10, "OPUS"},
25 {0x11, "Hidden FAT12"},
26 {0x12, "Compaq diagnostics"},
27 {0x14, "Hidden FAT16 <32M"},
28 {0x16, "Hidden FAT16"},
29 {0x17, "Hidden HPFS/NTFS"},
30 {0x18, "AST SmartSleep"},
31 {0x1b, "Hidden W95 FAT32"},
32 {0x1c, "Hidden W95 FAT32 (LBA)"},
33 {0x1e, "Hidden W95 FAT16 (LBA)"},
34 {0x24, "NEC DOS"},
35 {0x39, "Plan 9"},
36 {0x3c, "PartitionMagic recovery"},
37 {0x40, "Venix 80286"},
38 {0x41, "PPC PReP Boot"},
39 {0x42, "SFS"},
40 {0x4d, "QNX4.x"},
41 {0x4e, "QNX4.x 2nd part"},
42 {0x4f, "QNX4.x 3rd part"},
43 {0x50, "OnTrack DM"},
44 {0x51, "OnTrack DM6 Aux1"}, /* (or Novell) */
45 {0x52, "CP/M"}, /* CP/M or Microport SysV/AT */
46 {0x53, "OnTrack DM6 Aux3"},
47 {0x54, "OnTrackDM6"},
48 {0x55, "EZ-Drive"},
49 {0x56, "Golden Bow"},
50 {0x5c, "Priam Edisk"},
51 {0x61, "SpeedStor"},
52 {0x63, "GNU HURD or SysV"}, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */
53 {0x64, "Novell Netware 286"},
54 {0x65, "Novell Netware 386"},
55 {0x70, "DiskSecure Multi-Boot"},
56 {0x75, "PC/IX"},
57 {0x80, "Old Minix"}, /* Minix 1.4a and earlier */
58 {0x81, "Minix / old Linux"},/* Minix 1.4b and later */
59 {0x82, "Linux swap / Solaris"},
60 {0x83, "Linux"},
61 {0x84, "OS/2 hidden C: drive"},
62 {0x85, "Linux extended"},
63 {0x86, "NTFS volume set"},
64 {0x87, "NTFS volume set"},
65 {0x88, "Linux plaintext"},
66 {0x8e, "Linux LVM"},
67 {0x93, "Amoeba"},
68 {0x94, "Amoeba BBT"}, /* (bad block table) */
69 {0x9f, "BSD/OS"}, /* BSDI */
70 {0xa0, "IBM Thinkpad hibernation"},
71 {0xa5, "FreeBSD"}, /* various BSD flavours */
72 {0xa6, "OpenBSD"},
73 {0xa7, "NeXTSTEP"},
74 {0xa8, "Darwin UFS"},
75 {0xa9, "NetBSD"},
76 {0xab, "Darwin boot"},
77 {0xb7, "BSDI fs"},
78 {0xb8, "BSDI swap"},
79 {0xbb, "Boot Wizard hidden"},
80 {0xbe, "Solaris boot"},
81 {0xbf, "Solaris"},
82 {0xc1, "DRDOS/sec (FAT-12)"},
83 {0xc4, "DRDOS/sec (FAT-16 < 32M)"},
84 {0xc6, "DRDOS/sec (FAT-16)"},
85 {0xc7, "Syrinx"},
86 {0xda, "Non-FS data"},
87 {0xdb, "CP/M / CTOS / ..."},/* CP/M or Concurrent CP/M or
88 Concurrent DOS or CTOS */
89 {0xde, "Dell Utility"}, /* Dell PowerEdge Server utilities */
90 {0xdf, "BootIt"}, /* BootIt EMBRM */
91 {0xe1, "DOS access"}, /* DOS access or SpeedStor 12-bit FAT
92 extended partition */
93 {0xe3, "DOS R/O"}, /* DOS R/O or SpeedStor */
94 {0xe4, "SpeedStor"}, /* SpeedStor 16-bit FAT extended
95 partition < 1024 cyl. */
96 {0xeb, "BeOS fs"},
97 {0xee, "EFI GPT"}, /* Intel EFI GUID Partition Table */
98 {0xef, "EFI (FAT-12/16/32)"},/* Intel EFI System Partition */
99 {0xf0, "Linux/PA-RISC boot"},/* Linux/PA-RISC boot loader */
100 {0xf1, "SpeedStor"},
101 {0xf4, "SpeedStor"}, /* SpeedStor large partition */
102 {0xf2, "DOS secondary"}, /* DOS 3.3+ secondary */
103 {0xfd, "Linux raid autodetect"},/* New (2.2.x) raid partition with
104 autodetect using persistent
105 superblock */
106 {0xfe, "LANstep"}, /* SpeedStor >1024 cyl. or LANstep */
107 {0xff, "BBT"}, /* Xenix Bad Block Table */
108 { 0, 0 }
109};
diff --git a/utils/sansapatcher/sansaio-posix.c b/utils/sansapatcher/sansaio-posix.c
new file mode 100644
index 0000000000..44c4dcc95c
--- /dev/null
+++ b/utils/sansapatcher/sansaio-posix.c
@@ -0,0 +1,157 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006-2007 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#if !defined(_WIN32) /* all non-Windows platforms supported are POSIX. */
23#include <stdio.h>
24#include <unistd.h>
25#include <fcntl.h>
26#include <string.h>
27#include <stdlib.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <sys/ioctl.h>
31#include <errno.h>
32
33#if defined(linux) || defined (__linux)
34#include <sys/mount.h>
35#define SANSA_SECTORSIZE_IOCTL BLKSSZGET
36#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \
37 || defined(__bsdi__) || defined(__DragonFly__)
38#include <sys/disk.h>
39#define SANSA_SECTORSIZE_IOCTL DIOCGSECTORSIZE
40#elif defined(__APPLE__) && defined(__MACH__)
41#include <sys/disk.h>
42#define SANSA_SECTORSIZE_IOCTL DKIOCGETBLOCKSIZE
43#else
44 #error No sector-size detection implemented for this platform
45#endif
46
47#include "sansaio.h"
48
49#if defined(__APPLE__) && defined(__MACH__)
50static int sansa_unmount(struct sansa_t* sansa)
51{
52 char cmd[4096];
53 int res;
54
55 sprintf(cmd, "/usr/sbin/diskutil unmount \"%ss1\"",sansa->diskname);
56 fprintf(stderr,"[INFO] ");
57 res = system(cmd);
58
59 if (res==0) {
60 return 0;
61 } else {
62 perror("Unmount failed");
63 return -1;
64 }
65}
66#endif
67
68
69void sansa_print_error(char* msg)
70{
71 perror(msg);
72}
73
74int sansa_open(struct sansa_t* sansa, int silent)
75{
76 sansa->dh=open(sansa->diskname,O_RDONLY);
77 if (sansa->dh < 0) {
78 if (!silent) perror(sansa->diskname);
79 if(errno == EACCES) return -2;
80 else return -1;
81 }
82
83 if(ioctl(sansa->dh,SANSA_SECTORSIZE_IOCTL,&sansa->sector_size) < 0) {
84 sansa->sector_size=512;
85 if (!silent) {
86 fprintf(stderr,"[ERR] ioctl() call to get sector size failed, defaulting to %d\n"
87 ,sansa->sector_size);
88 }
89 }
90 return 0;
91}
92
93
94int sansa_reopen_rw(struct sansa_t* sansa)
95{
96#if defined(__APPLE__) && defined(__MACH__)
97 if (sansa_unmount(sansa) < 0)
98 return -1;
99#endif
100
101 close(sansa->dh);
102 sansa->dh=open(sansa->diskname,O_RDWR);
103 if (sansa->dh < 0) {
104 perror(sansa->diskname);
105 return -1;
106 }
107 return 0;
108}
109
110int sansa_close(struct sansa_t* sansa)
111{
112 close(sansa->dh);
113 return 0;
114}
115
116int sansa_alloc_buffer(struct sansa_t *sansa, int bufsize)
117{
118 sansa->sectorbuf=malloc(bufsize);
119 if (sansa->sectorbuf == NULL) {
120 return -1;
121 }
122 return 0;
123}
124
125int sansa_dealloc_buffer(struct sansa_t* sansa)
126{
127 if (sansa->sectorbuf == NULL) {
128 return -1;
129 }
130 free(sansa->sectorbuf);
131 sansa->sectorbuf = NULL;
132 return 0;
133}
134
135int sansa_seek(struct sansa_t* sansa, loff_t pos)
136{
137 off_t res;
138
139 res = lseek64(sansa->dh, pos, SEEK_SET);
140
141 if (res == -1) {
142 return -1;
143 }
144 return 0;
145}
146
147int sansa_read(struct sansa_t* sansa, unsigned char* buf, int nbytes)
148{
149 return read(sansa->dh, buf, nbytes);
150}
151
152int sansa_write(struct sansa_t* sansa, int nbytes)
153{
154 return write(sansa->dh, sansa->sectorbuf, nbytes);
155}
156#endif
157
diff --git a/utils/sansapatcher/sansaio-win32.c b/utils/sansapatcher/sansaio-win32.c
new file mode 100644
index 0000000000..ee6a8cd93d
--- /dev/null
+++ b/utils/sansapatcher/sansaio-win32.c
@@ -0,0 +1,217 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006-2007 Dave Chapman
11 *
12 * error(), lock_volume() and unlock_volume() functions and inspiration taken
13 * from:
14 * RawDisk - Direct Disk Read/Write Access for NT/2000/XP
15 * Copyright (c) 2003 Jan Kiszka
16 * http://www.stud.uni-hannover.de/user/73174/RawDisk/
17 *
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
22 *
23 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
24 * KIND, either express or implied.
25 *
26 ****************************************************************************/
27
28#if defined(_WIN32)
29#include <stdio.h>
30#include <unistd.h>
31#include <fcntl.h>
32#include <string.h>
33#include <stdlib.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#ifdef __WIN32__
37#include <windows.h>
38#include <winioctl.h>
39#endif
40
41#include "sansaio.h"
42
43static int lock_volume(HANDLE hDisk)
44{
45 DWORD dummy;
46
47 return DeviceIoControl(hDisk, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0,
48 &dummy, NULL);
49}
50
51static int unlock_volume(HANDLE hDisk)
52{
53 DWORD dummy;
54
55 return DeviceIoControl(hDisk, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0,
56 &dummy, NULL);
57}
58
59void sansa_print_error(char* msg)
60{
61 LPSTR pMsgBuf = NULL;
62
63 printf(msg);
64 FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
65 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(),
66 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), pMsgBuf,
67 0, NULL);
68 printf(pMsgBuf);
69 LocalFree(pMsgBuf);
70}
71
72int sansa_open(struct sansa_t* sansa, int silent)
73{
74 DISK_GEOMETRY_EX diskgeometry_ex;
75 DISK_GEOMETRY diskgeometry;
76 unsigned long n;
77
78 sansa->dh = CreateFileA(sansa->diskname, GENERIC_READ,
79 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
80 FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL);
81
82 if (sansa->dh == INVALID_HANDLE_VALUE) {
83 if (!silent) sansa_print_error(" Error opening disk: ");
84 if(GetLastError() == ERROR_ACCESS_DENIED)
85 return -2;
86 else
87 return -1;
88 }
89
90 if (!lock_volume(sansa->dh)) {
91 if (!silent) sansa_print_error(" Error locking disk: ");
92 return -1;
93 }
94
95 if (!DeviceIoControl(sansa->dh,
96 IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
97 NULL,
98 0,
99 &diskgeometry_ex,
100 sizeof(diskgeometry_ex),
101 &n,
102 NULL)) {
103 if (!DeviceIoControl(sansa->dh,
104 IOCTL_DISK_GET_DRIVE_GEOMETRY,
105 NULL,
106 0,
107 &diskgeometry,
108 sizeof(diskgeometry),
109 &n,
110 NULL)) {
111 if (!silent) sansa_print_error(" Error reading disk geometry: ");
112 return -1;
113 } else {
114 sansa->sector_size=diskgeometry.BytesPerSector;
115 }
116 } else {
117 sansa->sector_size=diskgeometry_ex.Geometry.BytesPerSector;
118 }
119
120 return 0;
121}
122
123int sansa_reopen_rw(struct sansa_t* sansa)
124{
125 /* Close existing file and re-open for writing */
126 unlock_volume(sansa->dh);
127 CloseHandle(sansa->dh);
128
129 sansa->dh = CreateFileA(sansa->diskname, GENERIC_READ | GENERIC_WRITE,
130 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
131 FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL);
132
133 if (sansa->dh == INVALID_HANDLE_VALUE) {
134 sansa_print_error(" Error opening disk: ");
135 return -1;
136 }
137
138 if (!lock_volume(sansa->dh)) {
139 sansa_print_error(" Error locking disk: ");
140 return -1;
141 }
142
143 return 0;
144}
145
146int sansa_close(struct sansa_t* sansa)
147{
148 unlock_volume(sansa->dh);
149 CloseHandle(sansa->dh);
150 return 0;
151}
152
153int sansa_alloc_buffer(struct sansa_t* sansa, int bufsize)
154{
155 /* The ReadFile function requires a memory buffer aligned to a multiple of
156 the disk sector size. */
157 sansa->sectorbuf = (unsigned char*)VirtualAlloc(NULL, bufsize, MEM_COMMIT, PAGE_READWRITE);
158 if (sansa->sectorbuf == NULL) {
159 sansa_print_error(" Error allocating a buffer: ");
160 return -1;
161 }
162 return 0;
163}
164
165int sansa_dealloc_buffer(struct sansa_t* sansa)
166{
167 if (sansa->sectorbuf == NULL) {
168 return -1;
169 }
170 if(!VirtualFree(sansa->sectorbuf, 0, MEM_RELEASE)) {
171 sansa_print_error(" Error releasing buffer ");
172 return -1;
173 }
174 sansa->sectorbuf = NULL;
175 return 0;
176}
177
178int sansa_seek(struct sansa_t* sansa, loff_t pos)
179{
180 LARGE_INTEGER li;
181
182 li.QuadPart = pos;
183
184 li.LowPart = SetFilePointer (sansa->dh, li.LowPart, &li.HighPart, FILE_BEGIN);
185
186 if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
187 sansa_print_error(" Seek error ");
188 return -1;
189 }
190 return 0;
191}
192
193int sansa_read(struct sansa_t* sansa, unsigned char* buf, int nbytes)
194{
195 unsigned long count;
196
197 if (!ReadFile(sansa->dh, buf, nbytes, &count, NULL)) {
198 sansa_print_error(" Error reading from disk: ");
199 return -1;
200 }
201
202 return count;
203}
204
205int sansa_write(struct sansa_t* sansa, int nbytes)
206{
207 unsigned long count;
208
209 if (!WriteFile(sansa->dh, sansa->sectorbuf, nbytes, &count, NULL)) {
210 sansa_print_error(" Error writing to disk: ");
211 return -1;
212 }
213
214 return count;
215}
216#endif
217
diff --git a/utils/sansapatcher/sansaio.h b/utils/sansapatcher/sansaio.h
new file mode 100644
index 0000000000..61e2f1d1b2
--- /dev/null
+++ b/utils/sansapatcher/sansaio.h
@@ -0,0 +1,88 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006-2007 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef __SANSAIO_H
23#define __SANSAIO_H
24
25#include <stdint.h>
26#if !defined(_MSC_VER)
27#include <unistd.h> /* not available on MSVC */
28#endif
29
30#if defined(__WIN32__) || defined(_WIN32)
31#include <windows.h>
32#define loff_t int64_t
33#else
34#define HANDLE int
35#define O_BINARY 0
36
37/* Only Linux seems to need lseek64 and loff_t */
38#if !defined(linux) && !defined (__linux)
39#define loff_t off_t
40#define lseek64 lseek
41#endif
42
43#endif
44
45#ifdef __cplusplus
46extern "C" {
47#endif
48
49struct sansa_partinfo_t {
50 unsigned long start; /* first sector (LBA) */
51 unsigned long size; /* number of sectors */
52 int type;
53};
54
55struct mi4header_t {
56 uint32_t version;
57 uint32_t length;
58 uint32_t crc32;
59 uint32_t enctype;
60 uint32_t mi4size;
61 uint32_t plaintext;
62};
63
64struct sansa_t {
65 HANDLE dh;
66 unsigned char* sectorbuf;
67 char diskname[4096];
68 int sector_size;
69 struct sansa_partinfo_t pinfo[4];
70 int hasoldbootloader;
71 char* targetname; /* "e200" or "c200" */
72 loff_t start; /* Offset in bytes of firmware partition from start of disk */
73};
74
75void sansa_print_error(char* msg);
76int sansa_open(struct sansa_t* sansa, int silent);
77int sansa_reopen_rw(struct sansa_t* sansa);
78int sansa_close(struct sansa_t* sansa);
79int sansa_seek(struct sansa_t* sansa, loff_t pos);
80int sansa_read(struct sansa_t* sansa, unsigned char* buf, int nbytes);
81int sansa_write(struct sansa_t* sansa, int nbytes);
82int sansa_alloc_buffer(struct sansa_t* sansa, int bufsize);
83int sansa_dealloc_buffer(struct sansa_t* sansa);
84
85#ifdef __cplusplus
86}
87#endif
88#endif
diff --git a/utils/sansapatcher/sansapatcher.c b/utils/sansapatcher/sansapatcher.c
new file mode 100644
index 0000000000..e3b105dcca
--- /dev/null
+++ b/utils/sansapatcher/sansapatcher.c
@@ -0,0 +1,975 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006-2007 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdio.h>
23#include <unistd.h>
24#include <fcntl.h>
25#include <string.h>
26#include <stdlib.h>
27#include <inttypes.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30
31#include "sansaio.h"
32#include "sansapatcher.h"
33
34/* The offset of the MI4 image header in the firmware partition */
35#define PPMI_OFFSET 0x80000
36#define NVPARAMS_OFFSET 0x780000
37#define NVPARAMS_SIZE (0x80000-0x200)
38
39int sansa_verbose = 0;
40
41/* Windows requires the buffer for disk I/O to be aligned in memory on a
42 multiple of the disk volume size - so we use a single global variable
43 and initialise it with sansa_alloc_buf() in main().
44*/
45
46static off_t filesize(int fd) {
47 struct stat buf;
48
49 if (fstat(fd,&buf) < 0) {
50 perror("[ERR] Checking filesize of input file");
51 return -1;
52 } else {
53 return(buf.st_size);
54 }
55}
56
57/* Partition table parsing code taken from Rockbox */
58
59#define MAX_SECTOR_SIZE 2048
60#define SECTOR_SIZE 512
61
62static inline int32_t le2int(const unsigned char* buf)
63{
64 int32_t res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
65
66 return res;
67}
68
69static inline uint32_t le2uint(const unsigned char* buf)
70{
71 uint32_t res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
72
73 return res;
74}
75
76static inline void int2le(unsigned int val, unsigned char* addr)
77{
78 addr[0] = val & 0xFF;
79 addr[1] = (val >> 8) & 0xff;
80 addr[2] = (val >> 16) & 0xff;
81 addr[3] = (val >> 24) & 0xff;
82}
83
84#define BYTES2INT32(array,pos)\
85 ((long)array[pos] | ((long)array[pos+1] << 8 ) |\
86 ((long)array[pos+2] << 16 ) | ((long)array[pos+3] << 24 ))
87
88int sansa_read_partinfo(struct sansa_t* sansa, int silent)
89{
90 int i;
91 unsigned long count;
92
93 count = sansa_read(sansa,sansa->sectorbuf, sansa->sector_size);
94
95 if (count <= 0) {
96 sansa_print_error(" Error reading from disk: ");
97 return -1;
98 }
99
100 if ((sansa->sectorbuf[510] == 0x55) && (sansa->sectorbuf[511] == 0xaa)) {
101 /* parse partitions */
102 for ( i = 0; i < 4; i++ ) {
103 unsigned char* ptr = sansa->sectorbuf + 0x1be + 16*i;
104 sansa->pinfo[i].type = ptr[4];
105 sansa->pinfo[i].start = BYTES2INT32(ptr, 8);
106 sansa->pinfo[i].size = BYTES2INT32(ptr, 12);
107
108 /* extended? */
109 if ( sansa->pinfo[i].type == 5 ) {
110 /* not handled yet */
111 }
112 }
113 } else if ((sansa->sectorbuf[0] == 'E') && (sansa->sectorbuf[1] == 'R')) {
114 if (!silent) fprintf(stderr,"[ERR] Bad boot sector signature\n");
115 return -1;
116 }
117
118 /* Calculate the starting position of the firmware partition */
119 sansa->start = (loff_t)sansa->pinfo[1].start*(loff_t)sansa->sector_size;
120 return 0;
121}
122
123/* NOTE: memmem implementation copied from glibc-2.2.4 - it's a GNU
124 extension and is not universally. In addition, early versions of
125 memmem had a serious bug - the meaning of needle and haystack were
126 reversed. */
127
128/* Copyright (C) 1991,92,93,94,96,97,98,2000 Free Software Foundation, Inc.
129 This file is part of the GNU C Library.
130
131 The GNU C Library is free software; you can redistribute it and/or
132 modify it under the terms of the GNU Lesser General Public
133 License as published by the Free Software Foundation; either
134 version 2.1 of the License, or (at your option) any later version.
135
136 The GNU C Library is distributed in the hope that it will be useful,
137 but WITHOUT ANY WARRANTY; without even the implied warranty of
138 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
139 Lesser General Public License for more details.
140
141 You should have received a copy of the GNU Lesser General Public
142 License along with the GNU C Library; if not, write to the Free
143 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
144 02111-1307 USA. */
145
146/* Return the first occurrence of NEEDLE in HAYSTACK. */
147static void *
148sansa_memmem (haystack, haystack_len, needle, needle_len)
149 const void *haystack;
150 size_t haystack_len;
151 const void *needle;
152 size_t needle_len;
153{
154 const char *begin;
155 const char *const last_possible
156 = (const char *) haystack + haystack_len - needle_len;
157
158 if (needle_len == 0)
159 /* The first occurrence of the empty string is deemed to occur at
160 the beginning of the string. */
161 return (void *) haystack;
162
163 /* Sanity check, otherwise the loop might search through the whole
164 memory. */
165 if (__builtin_expect (haystack_len < needle_len, 0))
166 return NULL;
167
168 for (begin = (const char *) haystack; begin <= last_possible; ++begin)
169 if (begin[0] == ((const char *) needle)[0] &&
170 !memcmp ((const void *) &begin[1],
171 (const void *) ((const char *) needle + 1),
172 needle_len - 1))
173 return (void *) begin;
174
175 return NULL;
176}
177
178/*
179 * CRC32 implementation taken from:
180 *
181 * efone - Distributed internet phone system.
182 *
183 * (c) 1999,2000 Krzysztof Dabrowski
184 * (c) 1999,2000 ElysiuM deeZine
185 *
186 * This program is free software; you can redistribute it and/or
187 * modify it under the terms of the GNU General Public License
188 * as published by the Free Software Foundation; either version
189 * 2 of the License, or (at your option) any later version.
190 *
191 */
192
193/* crc_tab[] -- this crcTable is being build by chksum_crc32GenTab().
194 * so make sure, you call it before using the other
195 * functions!
196 */
197static unsigned int crc_tab[256];
198
199/* chksum_crc() -- to a given block, this one calculates the
200 * crc32-checksum until the length is
201 * reached. the crc32-checksum will be
202 * the result.
203 */
204static unsigned int chksum_crc32 (const unsigned char *block, unsigned int length)
205{
206 register unsigned long crc;
207 unsigned long i;
208
209 crc = 0;
210 for (i = 0; i < length; i++)
211 {
212 crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ *block++) & 0xFF];
213 }
214 return (crc);
215}
216
217/* chksum_crc32gentab() -- to a global crc_tab[256], this one will
218 * calculate the crcTable for crc32-checksums.
219 * it is generated to the polynom [..]
220 */
221
222static void chksum_crc32gentab (void)
223{
224 unsigned long crc, poly;
225 int i, j;
226
227 poly = 0xEDB88320L;
228 for (i = 0; i < 256; i++)
229 {
230 crc = i;
231 for (j = 8; j > 0; j--)
232 {
233 if (crc & 1)
234 {
235 crc = (crc >> 1) ^ poly;
236 }
237 else
238 {
239 crc >>= 1;
240 }
241 }
242 crc_tab[i] = crc;
243 }
244}
245
246/* Known keys for Sansa E200 and C200 firmwares: */
247#define NUM_KEYS ((int)(sizeof(keys)/sizeof(keys[0])))
248static const uint32_t keys[][4] = {
249 { 0xe494e96e, 0x3ee32966, 0x6f48512b, 0xa93fbb42 }, /* "sansa" */
250 { 0xd7b10538, 0xc662945b, 0x1b3fce68, 0xf389c0e6 }, /* "sansa_gh" */
251 { 0x1d29ddc0, 0x2579c2cd, 0xce339e1a, 0x75465dfe }, /* sansa 103 */
252
253 { 0x2a7968de, 0x15127979, 0x142e60a7, 0xe49c1893 }, /* c200 1.00.03 */
254 { 0xbf2d06fa, 0xf0e23d59, 0x29738132, 0xe2d04ca7 }, /* c200 1.00.04 and up*/
255 { 0xa913d139, 0xf842f398, 0x3e03f1a6, 0x060ee012 }, /* c200 1.01.05 and up*/
256 { 0x0fe92902, 0xe8cc0f89, 0x6ff568ba, 0x1eff5161 }, /* c200 1.01.07 */
257};
258
259/*
260
261tea_decrypt() from http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm
262
263"Following is an adaptation of the reference encryption and decryption
264routines in C, released into the public domain by David Wheeler and
265Roger Needham:"
266
267*/
268
269/* NOTE: The mi4 version of TEA uses a different initial value to sum compared
270 to the reference implementation and the main loop is 8 iterations, not
271 32.
272*/
273
274static void tea_decrypt(uint32_t* v0, uint32_t* v1, const uint32_t* k) {
275 uint32_t sum=0xF1BBCDC8, i; /* set up */
276 uint32_t delta=0x9E3779B9; /* a key schedule constant */
277 uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
278 for(i=0; i<8; i++) { /* basic cycle start */
279 *v1 -= ((*v0<<4) + k2) ^ (*v0 + sum) ^ ((*v0>>5) + k3);
280 *v0 -= ((*v1<<4) + k0) ^ (*v1 + sum) ^ ((*v1>>5) + k1);
281 sum -= delta; /* end cycle */
282 }
283}
284
285/* mi4 files are encrypted in 64-bit blocks (two little-endian 32-bit
286 integers) and the key is incremented after each block
287 */
288
289static void tea_decrypt_buf(const unsigned char* src, unsigned char* dest,
290 size_t n, const uint32_t * initial_key)
291{
292 uint32_t v0, v1;
293 unsigned int i;
294 uint32_t key[4];
295
296 memcpy(key, initial_key, sizeof(key));
297 for (i = 0; i < (n / 8); i++) {
298 v0 = le2int(src);
299 v1 = le2int(src+4);
300
301 tea_decrypt(&v0, &v1, key);
302
303 int2le(v0, dest);
304 int2le(v1, dest+4);
305
306 src += 8;
307 dest += 8;
308
309 /* Now increment the key */
310 key[0]++;
311 if (key[0]==0) {
312 key[1]++;
313 if (key[1]==0) {
314 key[2]++;
315 if (key[2]==0) {
316 key[3]++;
317 }
318 }
319 }
320 }
321}
322
323static int get_mi4header(const unsigned char* buf,struct mi4header_t* mi4header)
324{
325 if (memcmp(buf,"PPOS",4)!=0)
326 return -1;
327
328 mi4header->version = le2int(buf+0x04);
329 mi4header->length = le2int(buf+0x08);
330 mi4header->crc32 = le2int(buf+0x0c);
331 mi4header->enctype = le2int(buf+0x10);
332 mi4header->mi4size = le2int(buf+0x14);
333 mi4header->plaintext = le2int(buf+0x18);
334
335 return 0;
336}
337
338static int set_mi4header(unsigned char* buf,const struct mi4header_t* mi4header)
339{
340 if (memcmp(buf,"PPOS",4)!=0)
341 return -1;
342
343 int2le(mi4header->version ,buf+0x04);
344 int2le(mi4header->length ,buf+0x08);
345 int2le(mi4header->crc32 ,buf+0x0c);
346 int2le(mi4header->enctype ,buf+0x10);
347 int2le(mi4header->mi4size ,buf+0x14);
348 int2le(mi4header->plaintext ,buf+0x18);
349
350 /* Add a dummy DSA signature */
351 memset(buf+0x1c,0,40);
352 buf[0x2f] = 1;
353
354 return 0;
355}
356
357static int sansa_seek_and_read(struct sansa_t* sansa, loff_t pos, unsigned char* buf, int nbytes)
358{
359 int n;
360
361 if (sansa_seek(sansa, pos) < 0) {
362 return -1;
363 }
364
365 if ((n = sansa_read(sansa,buf,nbytes)) < 0) {
366 return -1;
367 }
368
369 if (n < nbytes) {
370 fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n",
371 nbytes,n);
372 return -1;
373 }
374
375 return 0;
376}
377
378
379/* We identify an E200 based on the following criteria:
380
381 1) Exactly two partitions;
382 2) First partition is type "W95 FAT32" (0x0b or 0x0c);
383 3) Second partition is type "OS/2 hidden C: drive" (0x84);
384 4) The "PPBL" string appears at offset 0 in the 2nd partition;
385 5) The "PPMI" string appears at offset PPMI_OFFSET in the 2nd partition.
386*/
387
388int is_sansa(struct sansa_t* sansa)
389{
390 struct mi4header_t mi4header;
391 int ppmi_length;
392 int ppbl_length;
393
394 /* Check partition layout */
395 if (((sansa->pinfo[0].type != 0x06) &&
396 (sansa->pinfo[0].type != 0x0b) &&
397 (sansa->pinfo[0].type != 0x0c) &&
398 (sansa->pinfo[0].type != 0x0e)) ||
399 (sansa->pinfo[1].type != 0x84) ||
400 (sansa->pinfo[2].type != 0x00) ||
401 (sansa->pinfo[3].type != 0x00)) {
402 /* Bad partition layout, abort */
403 return -1;
404 }
405
406 /* Check Bootloader header */
407 if (sansa_seek_and_read(sansa, sansa->start, sansa->sectorbuf, 0x200) < 0) {
408 return -2;
409 }
410 if (memcmp(sansa->sectorbuf,"PPBL",4)!=0) {
411 /* No bootloader header, abort */
412 return -4;
413 }
414 ppbl_length = (le2int(sansa->sectorbuf+4) + 0x1ff) & ~0x1ff;
415
416 /* Sanity/safety check - the bootloader can't be larger than PPMI_OFFSET */
417 if (ppbl_length > PPMI_OFFSET)
418 {
419 return -5;
420 }
421
422 /* Load Sansa bootloader and check for "Sansa C200" magic string */
423 if (sansa_seek_and_read(sansa, sansa->start + 0x200, sansa->sectorbuf, ppbl_length) < 0) {
424 fprintf(stderr,"[ERR] Seek and read to 0x%08"PRIx64" in is_sansa failed.\n",
425 sansa->start+0x200);
426 return -6;
427 }
428 if (sansa_memmem(sansa->sectorbuf, ppbl_length, "Sansa C200", 10) != NULL) {
429 /* C200 */
430 sansa->targetname="c200";
431 } else {
432 /* E200 */
433 sansa->targetname="e200";
434 }
435
436 /* Check Main firmware header */
437 if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET, sansa->sectorbuf, 0x200) < 0) {
438 fprintf(stderr,"[ERR] Seek to 0x%"PRIx64" in is_sansa failed.\n",
439 sansa->start+PPMI_OFFSET);
440 return -5;
441 }
442 if (memcmp(sansa->sectorbuf,"PPMI",4)!=0) {
443 /* No bootloader header, abort */
444 return -7;
445 }
446 ppmi_length = le2int(sansa->sectorbuf+4);
447
448 /* Check main mi4 file header */
449 if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET+0x200, sansa->sectorbuf, 0x200) < 0) {
450 fprintf(stderr,"[ERR] Seek to 0x%"PRIx64" in is_sansa failed.\n",
451 sansa->start+PPMI_OFFSET+0x200);
452 return -5;
453 }
454
455 if (get_mi4header(sansa->sectorbuf,&mi4header) < 0) {
456 fprintf(stderr,"[ERR] Invalid mi4header\n");
457 return -6;
458 }
459
460 /* Some sanity checks:
461
462 1) Main MI4 image without RBBL and < 100000 bytes -> old install
463 2) Main MI4 image with RBBL but no second image -> old install
464 */
465
466 sansa->hasoldbootloader = 0;
467 if (memcmp(sansa->sectorbuf+0x1f8,"RBBL",4)==0) {
468 /* Look for an original firmware after the first image */
469 if (sansa_seek_and_read(sansa,
470 sansa->start + PPMI_OFFSET + 0x200 + ppmi_length,
471 sansa->sectorbuf, 512) < 0) {
472 return -7;
473 }
474
475 if (get_mi4header(sansa->sectorbuf,&mi4header)!=0) {
476 fprintf(stderr,"[ERR] No original firmware found\n");
477 sansa->hasoldbootloader = 1;
478 }
479 } else if (mi4header.mi4size < 100000) {
480 fprintf(stderr,"[ERR] Old bootloader found\n");
481 sansa->hasoldbootloader = 1;
482 }
483
484 return 0;
485}
486
487int sansa_scan(struct sansa_t* sansa)
488{
489 int i;
490 int n = 0;
491 char last_disk[4096];
492 int denied = 0;
493 int result;
494
495 printf("[INFO] Scanning disk devices...\n");
496
497 for (i = 0; i <= 25 ; i++) {
498#ifdef __WIN32__
499 sprintf(sansa->diskname,"\\\\.\\PhysicalDrive%d",i);
500#elif defined(linux) || defined (__linux)
501 sprintf(sansa->diskname,"/dev/sd%c",'a'+i);
502#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \
503 || defined(__bsdi__) || defined(__DragonFly__)
504 sprintf(sansa->diskname,"/dev/da%d",i);
505#elif defined(__APPLE__) && defined(__MACH__)
506 sprintf(sansa->diskname,"/dev/disk%d",i);
507#else
508#error No disk paths defined for this platform
509#endif
510 if ((result = sansa_open(sansa, 1)) < 0) {
511 if(result == -2) {
512 denied++;
513 }
514 sansa_close(sansa);
515 continue;
516 }
517
518 if (sansa_read_partinfo(sansa,1) < 0) {
519 sansa_close(sansa);
520 continue;
521 }
522
523 if (is_sansa(sansa) < 0) {
524 sansa_close(sansa);
525 continue;
526 }
527
528#ifdef __WIN32__
529 printf("[INFO] %s found - disk device %d\n",sansa->targetname, i);
530#else
531 printf("[INFO] %s found - %s\n",sansa->targetname, sansa->diskname);
532#endif
533 n++;
534 strcpy(last_disk,sansa->diskname);
535 sansa_close(sansa);
536 }
537
538 if (n==1) {
539 /* Remember the disk name */
540 strcpy(sansa->diskname,last_disk);
541 }
542 else if (n == 0 && denied) {
543 printf("[ERR] FATAL: Permission denied on %d device(s) and no sansa detected.\n", denied);
544#ifdef __WIN32__
545 printf("[ERR] You need to run this program with administrator priviledges!\n");
546#else
547 printf("[ERR] You need permissions for raw disc access for this program to work!\n");
548#endif
549 }
550
551 return (n == 0 && denied) ? -1 : n;
552}
553
554/* Prepare original firmware for writing to the firmware partition by decrypting
555 and updating the header */
556static int prepare_original_firmware(struct sansa_t* sansa, unsigned char* buf, struct mi4header_t* mi4header)
557{
558 unsigned char* tmpbuf;
559 int i;
560 int key_found;
561
562 get_mi4header(buf,mi4header);
563
564#if 0
565 printf("mi4header->version =0x%08x\n",mi4header->version);
566 printf("mi4header->length =0x%08x\n",mi4header->length);
567 printf("mi4header->crc32 =0x%08x\n",mi4header->crc32);
568 printf("mi4header->enctype =0x%08x\n",mi4header->enctype);
569 printf("mi4header->mi4size =0x%08x\n",mi4header->mi4size);
570 printf("mi4header->plaintext =0x%08x\n",mi4header->plaintext);
571#endif
572
573 /* Decrypt anything that needs decrypting. */
574 if (mi4header->plaintext < mi4header->mi4size - 0x200) {
575 /* TODO: Check different keys */
576 tmpbuf=malloc(mi4header->mi4size-(mi4header->plaintext+0x200));
577 if (tmpbuf==NULL) {
578 fprintf(stderr,"[ERR] Can not allocate memory\n");
579 return -1;
580 }
581
582 key_found=0;
583 for (i=0; i < NUM_KEYS && !key_found ; i++) {
584 tea_decrypt_buf(buf+(mi4header->plaintext+0x200),
585 tmpbuf,
586 mi4header->mi4size-(mi4header->plaintext+0x200),
587 keys[i]);
588 key_found = (le2uint(tmpbuf+mi4header->length-mi4header->plaintext-4) == 0xaa55aa55);
589 }
590
591 if (key_found) {
592 memcpy(buf+(mi4header->plaintext+0x200),tmpbuf,mi4header->mi4size-(mi4header->plaintext+0x200));
593 free(tmpbuf);
594 } else {
595 fprintf(stderr,"[ERR] Failed to decrypt image, aborting\n");
596 free(tmpbuf);
597 return -1;
598 }
599 }
600
601 /* Increase plaintext value to full file */
602 mi4header->plaintext = mi4header->mi4size - 0x200;
603
604 /* Update CRC checksum */
605 chksum_crc32gentab ();
606 mi4header->crc32 = chksum_crc32(buf+0x200,mi4header->mi4size-0x200);
607
608 set_mi4header(buf,mi4header);
609
610 /* Add Rockbox-specific header */
611 memcpy(buf+0x1f8,"RBOF",4);
612 memcpy(buf+0x1fc,sansa->targetname,4);
613
614 return 0;
615}
616
617static int load_original_firmware(struct sansa_t* sansa, unsigned char* buf, struct mi4header_t* mi4header)
618{
619 int ppmi_length;
620 int n;
621
622 /* Read 512 bytes from PPMI_OFFSET - the PPMI header plus the mi4 header */
623 if (sansa_seek_and_read(sansa, sansa->start + PPMI_OFFSET, buf, 512) < 0) {
624 return -1;
625 }
626
627 /* No need to check PPMI magic - it's done during init to confirm
628 this is an E200 */
629 ppmi_length = le2int(buf+4);
630
631 /* Firstly look for an original firmware after the first image */
632 if (sansa_seek_and_read(sansa, sansa->start + PPMI_OFFSET + 0x200 + ppmi_length, buf, 512) < 0) {
633 return -1;
634 }
635
636 if (get_mi4header(buf,mi4header)==0) {
637 /* We have a valid MI4 file after a bootloader, so we use this. */
638 if ((n = sansa_seek_and_read(sansa,
639 sansa->start + PPMI_OFFSET + 0x200 + ppmi_length,
640 buf, mi4header->mi4size)) < 0) {
641 return -1;
642 }
643 } else {
644 /* No valid MI4 file, so read the first image. */
645 if ((n = sansa_seek_and_read(sansa,
646 sansa->start + PPMI_OFFSET + 0x200,
647 buf, ppmi_length)) < 0) {
648 return -1;
649 }
650 }
651 return prepare_original_firmware(sansa, buf, mi4header);
652}
653
654int sansa_read_firmware(struct sansa_t* sansa, const char* filename)
655{
656 int res;
657 int outfile;
658 struct mi4header_t mi4header;
659
660 res = load_original_firmware(sansa,sansa->sectorbuf,&mi4header);
661 if (res < 0)
662 return res;
663
664 outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666);
665 if (outfile < 0) {
666 fprintf(stderr,"[ERR] Couldn't open file %s\n",filename);
667 return -1;
668 }
669
670 res = write(outfile,sansa->sectorbuf,mi4header.mi4size);
671 if (res != (int)mi4header.mi4size) {
672 fprintf(stderr,"[ERR] Write error - %d\n", res);
673 return -1;
674 }
675 close(outfile);
676
677 return 0;
678}
679
680unsigned int sansa_read_bootloader(struct sansa_t* sansa, const char* filename, unsigned char** bl_buffer)
681{
682 /* Step 1 - read bootloader into RAM. */
683 int infile;
684 unsigned int n;
685 unsigned int len;
686 infile=open(filename,O_RDONLY|O_BINARY);
687 if (infile < 0) {
688 fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename);
689 return 0;
690 }
691
692 len = filesize(infile);
693
694 unsigned char* b = malloc(len);
695 if (b == NULL) {
696 fprintf(stderr,"[ERR] Could not allocate memory for bootloader\n");
697 close(infile);
698 return 0;
699 }
700
701 n = read(infile,b,len);
702 close(infile);
703 if (n < len) {
704 fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n"
705 ,len,n);
706 return 0;
707 }
708
709 if (memcmp(b+0x1f8,"RBBL",4)!=0) {
710 fprintf(stderr,"[ERR] %s is not a Rockbox bootloader, aborting.\n",
711 filename);
712 return 0;
713 }
714 if (memcmp(b+0x1fc,sansa->targetname,4)!=0) {
715 fprintf(stderr,"[ERR] %s is not a Rockbox bootloader for %s, aborting.\n",
716 filename, sansa->targetname);
717 return 0;
718 }
719 *bl_buffer = b;
720 return len;
721}
722
723int sansa_add_bootloader(struct sansa_t* sansa, const unsigned char* bootloader, const unsigned int bl_length)
724{
725 int res;
726 struct mi4header_t mi4header;
727 int length;
728 int n;
729
730 /* Create PPMI header */
731 memset(sansa->sectorbuf,0,0x200);
732 memcpy(sansa->sectorbuf,"PPMI",4);
733 int2le(bl_length, sansa->sectorbuf+4);
734 int2le(0x00020000, sansa->sectorbuf+8);
735
736 /* copy bootloader to sansa->sectorbuf+0x200 */
737 memcpy(sansa->sectorbuf+0x200,bootloader,bl_length);
738
739 /* Load original firmware from Sansa to the space after the bootloader */
740 res = load_original_firmware(sansa,sansa->sectorbuf+0x200+bl_length,&mi4header);
741 if (res < 0)
742 return res;
743
744 /* Now write the whole thing back to the Sansa */
745
746 if (sansa_seek(sansa, sansa->start+PPMI_OFFSET) < 0) {
747 fprintf(stderr,"[ERR] Seek to 0x%08"PRIx64" in add_bootloader failed.\n",
748 sansa->start+PPMI_OFFSET);
749 return -5;
750 }
751
752 length = 0x200 + bl_length + mi4header.mi4size;
753
754 n=sansa_write(sansa, length);
755 if (n < length) {
756 fprintf(stderr,"[ERR] Short write in add_bootloader\n");
757 return -6;
758 }
759
760 return 0;
761}
762
763int sansa_delete_bootloader(struct sansa_t* sansa)
764{
765 int res;
766 struct mi4header_t mi4header;
767 int n;
768 int length;
769
770 /* Load original firmware from Sansa to sansa->sectorbuf+0x200 */
771 res = load_original_firmware(sansa,sansa->sectorbuf+0x200,&mi4header);
772 if (res < 0)
773 return res;
774
775 /* Create PPMI header */
776 memset(sansa->sectorbuf,0,0x200);
777 memcpy(sansa->sectorbuf,"PPMI",4);
778 int2le(mi4header.mi4size, sansa->sectorbuf+4);
779 int2le(0x00020000, sansa->sectorbuf+8);
780
781 /* Now write the whole thing back to the Sansa */
782
783 if (sansa_seek(sansa, sansa->start+PPMI_OFFSET) < 0) {
784 fprintf(stderr,"[ERR] Seek to 0x%08"PRIx64" in add_bootloader failed.\n",
785 sansa->start+PPMI_OFFSET);
786 return -5;
787 }
788
789 length = 0x200 + mi4header.mi4size;
790
791 n=sansa_write(sansa, length);
792 if (n < length) {
793 fprintf(stderr,"[ERR] Short write in delete_bootloader\n");
794 return -6;
795 }
796
797 return 0;
798}
799
800/** List number of MI4 images on the player, return number.
801 */
802int sansa_list_images(struct sansa_t* sansa)
803{
804 struct mi4header_t mi4header;
805 loff_t ppmi_length;
806 int num = 0;
807
808 /* Check Main firmware header */
809 if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET, sansa->sectorbuf, 0x200) < 0) {
810 return 0;
811 }
812
813 ppmi_length = le2int(sansa->sectorbuf+4);
814
815 printf("[INFO] Image 1 - %"PRIu64" bytes\n",ppmi_length);
816 num = 1;
817
818 /* Look for an original firmware after the first image */
819 if (sansa_seek_and_read(sansa, sansa->start + PPMI_OFFSET + 0x200 + ppmi_length, sansa->sectorbuf, 512) < 0) {
820 return 0;
821 }
822
823 if (get_mi4header(sansa->sectorbuf,&mi4header)==0) {
824 printf("[INFO] Image 2 - %d bytes\n",mi4header.mi4size);
825 num = 2;
826 }
827 return num;
828}
829
830int sansa_update_of(struct sansa_t* sansa, const char* filename)
831{
832 int n;
833 int infile = -1; /* Prevent an erroneous "may be used uninitialised" gcc warning */
834 int of_length = 0; /* Keep gcc happy when building for rbutil */
835 int ppmi_length;
836 struct mi4header_t mi4header;
837 unsigned char buf[512];
838
839 /* Step 1 - check we have an OF on the Sansa to upgrade. We expect the
840 Rockbox bootloader to be installed and the OF to be after it on disk. */
841
842 /* Read 512 bytes from PPMI_OFFSET - the PPMI header */
843 if (sansa_seek_and_read(sansa, sansa->start + PPMI_OFFSET,
844 buf, 512) < 0) {
845 return -1;
846 }
847
848 /* No need to check PPMI magic - it's done during init to confirm
849 this is an E200 */
850 ppmi_length = le2int(buf+4);
851
852 /* Look for an original firmware after the first image */
853 if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET+0x200+ppmi_length,
854 buf, 512) < 0) {
855 return -1;
856 }
857
858 if (get_mi4header(buf,&mi4header)!=0) {
859 /* We don't have a valid MI4 file after a bootloader, so do nothing. */
860 fprintf(stderr,"[ERR] No original firmware found at 0x%08"PRIx64"\n",
861 sansa->start+PPMI_OFFSET+0x200+ppmi_length);
862 return -1;
863 }
864
865 /* Step 2 - read OF into RAM. */
866 infile=open(filename,O_RDONLY|O_BINARY);
867 if (infile < 0) {
868 fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename);
869 return -1;
870 }
871
872 of_length = filesize(infile);
873
874 /* Load original firmware from file */
875 memset(sansa->sectorbuf,0,0x200);
876 n = read(infile,sansa->sectorbuf,of_length);
877 close(infile);
878 if (n < of_length) {
879 fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n"
880 , of_length, n);
881 return -1;
882 }
883
884 /* Check we have a valid MI4 file. */
885 if (get_mi4header(sansa->sectorbuf,&mi4header)!=0) {
886 fprintf(stderr,"[ERR] %s is not a valid mi4 file\n",filename);
887 return -1;
888 }
889
890 /* Decrypt and build the header */
891 if(prepare_original_firmware(sansa, sansa->sectorbuf, &mi4header)!=0){
892 fprintf(stderr,"[ERR] Unable to build decrypted mi4 from %s\n"
893 ,filename);
894 return -1;
895 }
896
897 /* Step 3 - write the OF to the Sansa */
898 if (sansa_seek(sansa, sansa->start+PPMI_OFFSET+0x200+ppmi_length) < 0) {
899 fprintf(stderr,"[ERR] Seek to 0x%08"PRIx64" in sansa_update_of failed.\n",
900 sansa->start+PPMI_OFFSET+0x200+ppmi_length);
901 return -1;
902 }
903
904 n=sansa_write(sansa, of_length);
905 if (n < of_length) {
906 fprintf(stderr,"[ERR] Short write in sansa_update_of\n");
907 return -1;
908 }
909
910 /* Step 4 - zero out the nvparams section - we have to do this or we end up
911 with multiple copies of the nvparams data and don't know which one to
912 work with for the database rebuild disabling trick in our bootloader */
913 if (strcmp(sansa->targetname,"e200") == 0) {
914 printf("[INFO] Resetting Original Firmware settings\n");
915 if (sansa_seek(sansa, sansa->start+NVPARAMS_OFFSET+0x200) < 0) {
916 fprintf(stderr,"[ERR] Seek to 0x%08"PRIx64" in sansa_update_of failed.\n",
917 sansa->start+NVPARAMS_OFFSET+0x200);
918 return -1;
919 }
920
921 memset(sansa->sectorbuf,0,NVPARAMS_SIZE);
922 n=sansa_write(sansa, NVPARAMS_SIZE);
923 if (n < NVPARAMS_SIZE) {
924 fprintf(stderr,"[ERR] Short write in sansa_update_of\n");
925 return -1;
926 }
927 }
928
929 return 0;
930}
931
932/* Update the PPBL (bootloader) image in the hidden firmware partition */
933int sansa_update_ppbl(struct sansa_t* sansa, const char* filename)
934{
935 int n;
936 int infile = -1; /* Prevent an erroneous "may be used uninitialised" gcc warning */
937 int ppbl_length = 0; /* Keep gcc happy when building for rbutil */
938
939 /* Step 1 - read bootloader into RAM. */
940 infile=open(filename,O_RDONLY|O_BINARY);
941 if (infile < 0) {
942 fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename);
943 return -1;
944 }
945
946 ppbl_length = filesize(infile);
947
948 n = read(infile,sansa->sectorbuf+0x200,ppbl_length);
949 close(infile);
950 if (n < ppbl_length) {
951 fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n", ppbl_length, n);
952 return -1;
953 }
954
955 /* Step 2 - Build the header */
956 memset(sansa->sectorbuf,0,0x200);
957 memcpy(sansa->sectorbuf,"PPBL",4);
958 int2le(ppbl_length, sansa->sectorbuf+4);
959 int2le(0x00010000, sansa->sectorbuf+8);
960
961 /* Step 3 - write the bootloader to the Sansa */
962 if (sansa_seek(sansa, sansa->start) < 0) {
963 fprintf(stderr,"[ERR] Seek to 0x%08"PRIx64" in sansa_update_ppbl failed.\n", sansa->start);
964 return -1;
965 }
966
967 n=sansa_write(sansa, ppbl_length + 0x200);
968 if (n < (ppbl_length+0x200)) {
969 fprintf(stderr,"[ERR] Short write in sansa_update_ppbl\n");
970 return -1;
971 }
972
973 return 0;
974}
975
diff --git a/utils/sansapatcher/sansapatcher.h b/utils/sansapatcher/sansapatcher.h
new file mode 100644
index 0000000000..259143e38a
--- /dev/null
+++ b/utils/sansapatcher/sansapatcher.h
@@ -0,0 +1,67 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006-2007 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef _SANSAPATCHER_H
23#define _SANSAPATCHER_H
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29#include "sansaio.h"
30
31/* exit codes */
32#define SANSA_OK 0
33#define SANSA_WRONG_ARGUMENTS 1
34#define SANSA_OPEN_INFILE_FAILED 2
35#define SANSA_PARTITION_ERROR 3
36#define SANSA_CANNOT_REOPEN 5
37#define SANSA_INSTALL_FAILED 6
38#define SANSA_UNINSTALL_FAILED 7
39#define SANSA_ACCESS_DENIED 10
40#define SANSA_NOT_FOUND 11
41#define SANSA_WRONG_DEVICE_COUNT 12
42#define SANSA_MULTIPLE_DEVICES 15
43#define SANSA_WRONG_TYPE 16
44#define SANSA_OLD_INSTALL 17
45#define SANSA_INTERNAL_ERROR 20
46
47extern int sansa_verbose;
48/* Size of buffer for disk I/O - 8MB is large enough for any version
49 of the Apple firmware, but not the Nano's RSRC image. */
50#define BUFFER_SIZE 8*1024*1024
51
52int sansa_read_partinfo(struct sansa_t* sansa, int silent);
53int is_sansa(struct sansa_t* sansa);
54int sansa_scan(struct sansa_t* sansa);
55int sansa_read_firmware(struct sansa_t* sansa, const char* filename);
56unsigned int sansa_read_bootloader(struct sansa_t* sansa, const char* filename, unsigned char** bl_buffer);
57int sansa_add_bootloader(struct sansa_t* sansa, const unsigned char* buf, unsigned int len);
58int sansa_delete_bootloader(struct sansa_t* sansa);
59int sansa_update_of(struct sansa_t* sansa,const char* filename);
60int sansa_update_ppbl(struct sansa_t* sansa,const char* filename);
61int sansa_list_images(struct sansa_t* sansa);
62
63#ifdef __cplusplus
64}
65#endif
66#endif
67
diff --git a/utils/sansapatcher/sansapatcher.manifest b/utils/sansapatcher/sansapatcher.manifest
new file mode 100644
index 0000000000..71bb153688
--- /dev/null
+++ b/utils/sansapatcher/sansapatcher.manifest
@@ -0,0 +1,13 @@
1<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
3 <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="sansapatcher.exe" type="win32"/>
4
5 <!-- Identify the application security requirements. -->
6 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
7 <security>
8 <requestedPrivileges>
9 <requestedExecutionLevel level="requireAdministrator"/>
10 </requestedPrivileges>
11 </security>
12 </trustInfo>
13</assembly>
diff --git a/utils/sansapatcher/sansapatcher.pro b/utils/sansapatcher/sansapatcher.pro
new file mode 100644
index 0000000000..f8308e6283
--- /dev/null
+++ b/utils/sansapatcher/sansapatcher.pro
@@ -0,0 +1,38 @@
1#
2# __________ __ ___.
3# Open \______ \ ____ ____ | | _\_ |__ _______ ___
4# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7# \/ \/ \/ \/ \/
8#
9# All files in this archive are subject to the GNU General Public License.
10# See the file COPYING in the source tree root for full license agreement.
11#
12# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
13# KIND, either express or implied.
14#
15
16TEMPLATE = app
17TARGET = sansapatcher
18QT -= core
19
20SOURCES += \
21 sansaio-posix.c \
22 sansaio-win32.c \
23 sansapatcher.c \
24 main.c
25
26HEADERS += \
27 parttypes.h \
28 sansaio.h \
29 sansapatcher.h \
30
31RC_FILE = sansapatcher.rc
32
33DEFINES += _LARGEFILE64_SOURCE
34
35unix {
36 target.path = /usr/local/bin
37 INSTALLS += target
38}
diff --git a/utils/sansapatcher/sansapatcher.rc b/utils/sansapatcher/sansapatcher.rc
new file mode 100644
index 0000000000..26bb8fe730
--- /dev/null
+++ b/utils/sansapatcher/sansapatcher.rc
@@ -0,0 +1 @@
1 24 MOVEABLE PURE "sansapatcher.manifest"
diff --git a/utils/tools/Makefile b/utils/tools/Makefile
new file mode 100644
index 0000000000..d10e2528bf
--- /dev/null
+++ b/utils/tools/Makefile
@@ -0,0 +1,31 @@
1
2ifndef V
3SILENT = @
4endif
5
6CFLAGS += -Wall -W -D_LARGEFILE64_SOURCE
7
8ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN)
9CROSS=
10CFLAGS+=-mno-cygwin
11else
12ifeq ($(findstring MINGW,$(shell uname)),MINGW)
13CROSS=
14else
15CROSS=i586-mingw32msvc-
16endif
17endif
18
19NATIVECC = gcc
20CC = $(CROSS)gcc
21WINDRES = $(CROSS)windres
22
23
24all: bin2c
25
26bin2c: bin2c.c
27 @echo CC $<
28 $(SILENT)$(NATIVECC) $(CFLAGS) -o bin2c bin2c.c
29
30clean:
31 $(RM) bin2c bin2c.exe
diff --git a/utils/tools/bin2c.c b/utils/tools/bin2c.c
new file mode 100644
index 0000000000..4600746d52
--- /dev/null
+++ b/utils/tools/bin2c.c
@@ -0,0 +1,174 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 Dave Chapman
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include <stdio.h>
22#include <string.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26#include <stdlib.h>
27#if !defined(_MSC_VER)
28#include <unistd.h>
29#else
30#include <io.h>
31#define snprintf _snprintf
32#define open _open
33#define close _close
34#define read _read
35#endif
36#include <libgen.h>
37
38#ifndef O_BINARY
39#define O_BINARY 0
40#endif
41
42static void usage(void)
43{
44 fprintf(stderr, "bin2c [options] infile cfile\n");
45 fprintf(stderr, " -i ipod mode\n");
46}
47
48
49static off_t filesize(int fd)
50{
51 struct stat buf;
52
53 fstat(fd,&buf);
54 return buf.st_size;
55}
56
57static int write_cfile(const unsigned char* buf, off_t len, const char* cname)
58{
59 char filename[256];
60 char filebase[256];
61 char* bn;
62 FILE* fp;
63 int i;
64
65 snprintf(filename,256,"%s.c",cname);
66 strncpy(filebase, cname, 256);
67 bn = basename(filebase);
68
69 fp = fopen(filename,"w+");
70 if (fp == NULL) {
71 fprintf(stderr,"Couldn't open %s\n",filename);
72 return -1;
73 }
74
75 fprintf(fp,"/* Generated by bin2c */\n\n");
76 fprintf(fp,"unsigned char %s[] = {",bn);
77
78 for (i=0;i<len;i++) {
79 if ((i % 16) == 0) {
80 fprintf(fp,"\n ");
81 }
82 if (i == (len-1)) {
83 fprintf(fp,"0x%02x",buf[i]);
84 } else {
85 fprintf(fp,"0x%02x, ",buf[i]);
86 }
87 }
88 fprintf(fp,"\n};\n");
89
90 fclose(fp);
91 return 0;
92}
93
94static int write_hfile(off_t len, const char* cname)
95{
96 char filename[256];
97 char filebase[256];
98 char* bn;
99 FILE* fp;
100
101 snprintf(filename,256,"%s.h",cname);
102 strncpy(filebase, cname, 256);
103 bn = basename(filebase);
104 fp = fopen(filename,"w+");
105 if (fp == NULL) {
106 fprintf(stderr,"Couldn't open %s\n",filename);
107 return -1;
108 }
109
110 fprintf(fp,"/* Generated by bin2c */\n\n");
111 fprintf(fp,"#define LEN_%s %d\n",bn,(int)len);
112 fprintf(fp,"extern unsigned char %s[];\n",bn);
113 fclose(fp);
114 return 0;
115}
116
117int main (int argc, char* argv[])
118{
119 char* infile;
120 char* cname;
121 int fd;
122 unsigned char* buf;
123 int len;
124 int n;
125 int skip = 0;
126 int opts = 0;
127
128
129 if(argc < 2) {
130 usage();
131 return 0;
132 }
133 if(strcmp(argv[1], "-i") == 0) {
134 skip = 8;
135 opts++;
136 }
137 if (argc < opts + 3) {
138 usage();
139 return 0;
140 }
141
142 infile=argv[opts + 1];
143 cname=argv[opts + 2];
144
145 fd = open(infile,O_RDONLY|O_BINARY);
146 if (fd < 0) {
147 fprintf(stderr,"Can not open %s\n",infile);
148 return 0;
149 }
150
151 len = filesize(fd) - skip;
152 n = lseek(fd, skip, SEEK_SET);
153 if (n != skip) {
154 fprintf(stderr,"Seek failed\n");
155 return 0;
156 }
157
158 buf = malloc(len);
159 n = read(fd,buf,len);
160 if (n < len) {
161 fprintf(stderr,"Short read, aborting\n");
162 return 0;
163 }
164 close(fd);
165
166 if (write_cfile(buf,len,cname) < 0) {
167 return -1;
168 }
169 if (write_hfile(len,cname) < 0) {
170 return -1;
171 }
172
173 return 0;
174}